0

I am trying to decode APER messages and have issue creating nested structs with traits. I am using the asn1 library, but I have provided an example to illustrate the issue.

I need a model that can take a value that can be any struct (more or less).

Using boxes does not work since the serial trait is Sized. I cannot seem to get generics to work either since the decode function does not return the type.

How can I get past this?

use std::fmt::Error;

pub trait serial: Sized {
    fn decode(&self) -> Result<Self, Error>;
}

pub struct Middle {
    pub bottomCode: i32,
    pub value: Box<dyn Bottom>,
}

impl serial for Middle {
    fn decode(&self) -> Result<Self, Error> {
        let code = 1;
        if code == 1 {
            Ok(Middle {
                bottomCode: code,
                value: Box::new(BottomA { a: 1 }),
            })
        } else {
            Ok(Middle {
                bottomCode: code,
                value: Box::new(BottomB { b: 1 }),
            })
        }
    }
}
pub trait Bottom: serial {}
pub struct BottomA {
    pub a: i32,
}
impl Bottom for BottomA {}

pub struct BottomB {
    pub b: i32,
}
impl Bottom for BottomB {}
error[E0038]: the trait `Bottom` cannot be made into an object
 --> src/lib.rs:9:5
  |
9 |     pub value: Box<dyn Bottom>,
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bottom` cannot be made into an object
  |
  = note: the trait cannot require that `Self : Sized`

error[E0277]: the trait bound `BottomA: serial` is not satisfied
  --> src/lib.rs:32:6
   |
32 | impl Bottom for BottomA {}
   |      ^^^^^^ the trait `serial` is not implemented for `BottomA`

error[E0277]: the trait bound `BottomB: serial` is not satisfied
  --> src/lib.rs:37:6
   |
37 | impl Bottom for BottomB {}
   |      ^^^^^^ the trait `serial` is not implemented for `BottomB`

The serial trait represents the APerElement trait I'm trying to use from the ASN1 library, thus the return type and signature.

I want to be able to call Middle.decode() which will result in all children being decoded alongside it, and any children of those etc. For that reason, it made sense to implement serial for it as well.

How would someone achieve such behavior? Is it possible?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Tobbeman
  • 11
  • 1
  • By the way, idiomatic Rust uses `snake_case` for variables, methods, macros, fields and modules; `UpperCamelCase` for types and enum variants; and `SCREAMING_SNAKE_CASE` for statics and constants. The compiler has provided a warning about this. – Shepmaster Apr 06 '20 at 17:18
  • It looks like your question might be answered by the answers of [What does a trait requiring Sized have to do with being unable to have trait objects of that trait?](https://stackoverflow.com/q/53987976/155423); [The trait cannot be made into an object](https://stackoverflow.com/q/45116984/155423); [Unable to create a polymorphic type because the trait cannot be made into an object](https://stackoverflow.com/q/39412626/155423); . If not, please **[edit]** your question to explain the differences. Otherwise, we can mark this question as already answered. – Shepmaster Apr 06 '20 at 17:19
  • [trait cannot be made into an object](https://stackoverflow.com/q/57668019/155423) – Shepmaster Apr 06 '20 at 17:20
  • 1
    Your question would be improved if you explained why you need to have the code structure that you are attempting. Why would you implement `decode` taking a reference to `Self` and then return a `Result`? Why does `Bottom` require that all implementors also implement `serial`? – Shepmaster Apr 06 '20 at 17:26
  • See also [How to implement `serde::Serialize` for a boxed trait object?](https://stackoverflow.com/a/50026869/155423); [How can deserialization of polymorphic trait objects be added in Rust if at all?](https://stackoverflow.com/q/44231020/155423) – Shepmaster Apr 06 '20 at 17:26
  • Wow, you sure work fast Shepmaster. Thanks for your reply, I hope my edit has made my question more understandable :) The serde example looks interesting, perhaps I am looking for serialization – Tobbeman Apr 07 '20 at 18:51

0 Answers0