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?