Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Newtypes with #[rasn(delegate)] #161

Closed
orthecreedence opened this issue Sep 27, 2023 · 3 comments
Closed

Newtypes with #[rasn(delegate)] #161

orthecreedence opened this issue Sep 27, 2023 · 3 comments

Comments

@orthecreedence
Copy link
Contributor

orthecreedence commented Sep 27, 2023

I'm seeing an issue with #[rasn(delegate)] which I'm not sure if it's expected or not. In short, delegate works on newtypes that wrap basic types, but not newtypes that wrap more complex types:

#[derive(Clone, Debug, rasn::AsnType, rasn::Encode, rasn::Decode)]
#[rasn(choice)]
enum Choose {
    #[rasn(tag(explicit(0)))]
    Single(String),
}

#[derive(Debug, rasn::AsnType, rasn::Encode, rasn::Decode)]
#[rasn(delegate)]
struct Nt1(Choose);

#[derive(Debug)]
struct Nt2(Choose);

#[derive(Debug, rasn::AsnType, rasn::Encode, rasn::Decode)]
#[rasn(delegate)]
struct Nt3(String);

impl rasn::AsnType for Nt2 {
    const TAG: rasn::Tag = rasn::Tag::EOC;
}

impl rasn::Encode for Nt2 {
    fn encode_with_tag<E: rasn::Encoder>(&self, encoder: &mut E, _tag: rasn::Tag) -> std::result::Result<(), E::Error> {
        self.0.encode(encoder)?;
        Ok(())
    }
}

impl rasn::Decode for Nt2 {
    fn decode_with_tag<D: rasn::Decoder>(decoder: &mut D, _tag: rasn::Tag) -> std::result::Result<Self, D::Error> {
        let inner = <Choose>::decode(decoder)?;
        Ok(Self(inner))
    }
}

let choose = Choose::Single("hi".into());
let str1 = "hi".to_string();
let nt1 = Nt1(choose.clone());
let nt2 = Nt2(choose.clone());
let nt3 = Nt3(str1.clone());

let ser_choose = rasn::der::encode(&choose).unwrap();
let ser_str1 = rasn::der::encode(&str1).unwrap();
let ser_nt1 = rasn::der::encode(&nt1).unwrap();
let ser_nt2 = rasn::der::encode(&nt2).unwrap();
let ser_nt3 = rasn::der::encode(&nt3).unwrap();

println!("Ch1 --- {:?}", ser_choose);
println!("Nt1 --- {:?}", ser_nt1);
println!("Nt2 --- {:?}", ser_nt2);
println!("St1 --- {:?}", ser_str1);
println!("Nt3 --- {:?}", ser_nt3);

The output of this is:

Ch1 --- [160, 4, 12, 2, 104, 105]
Nt1 --- [32, 6, 160, 4, 12, 2, 104, 105]
Nt2 --- [160, 4, 12, 2, 104, 105]
St1 --- [12, 2, 104, 105]
Nt3 --- [12, 2, 104, 105]

I expected Nt1 and Nt2 to have the same output, but Nt1 prepends a tag even though #[rasn(delegate)] is used. However, if wrapping a String type, delegation seems to work fine.

Is this expected, and should I implement Encode/Decode manually for newtypes wrapping complex types? If not, I can try to dig into the proc macro and see if there's a fix =].

Thanks!

@orthecreedence
Copy link
Contributor Author

Forgive me, I was using an older release (0.7) and I need to test if this is still an issue.

One thing I'm seeing in 0.9 is a possible reversion on #86, but I need to confirm.

@orthecreedence
Copy link
Contributor Author

Ok, opened a new PR for the Result thing.

After upgrading to rasn 0.9.5 and updating the above code:

#[derive(Clone, Debug, rasn::AsnType, rasn::Encode, rasn::Decode)]
#[rasn(choice)]
enum Choose {
    #[rasn(tag(explicit(0)))]
    Single(String),
}

#[derive(Debug, rasn::AsnType, rasn::Encode, rasn::Decode)]
#[rasn(delegate)]
struct Nt1(Choose);

#[derive(Debug)]
struct Nt2(Choose);

#[derive(Debug, rasn::AsnType, rasn::Encode, rasn::Decode)]
#[rasn(delegate)]
struct Nt3(String);

impl rasn::AsnType for Nt2 {
    const TAG: rasn::Tag = rasn::Tag::EOC;
}

impl rasn::Encode for Nt2 {
    fn encode_with_tag_and_constraints<E: rasn::Encoder>(&self, encoder: &mut E, _tag: rasn::Tag, _constraints: rasn::types::constraints::Constraints) -> std::result::Result<(), E::Error> {
        self.0.encode(encoder)?;
        Ok(())
    }
}

impl rasn::Decode for Nt2 {
    fn decode_with_tag_and_constraints<D: rasn::Decoder>(decoder: &mut D, _tag: rasn::Tag, _constraints: rasn::types::constraints::Constraints) -> std::result::Result<Self, D::Error> {
        let inner = <Choose>::decode(decoder)?;
        Ok(Self(inner))
    }
}

let choose = Choose::Single("hi".into());
let str1 = "hi".to_string();
let nt1 = Nt1(choose.clone());
let nt2 = Nt2(choose.clone());
let nt3 = Nt3(str1.clone());

let ser_choose = rasn::der::encode(&choose).unwrap();
let ser_str1 = rasn::der::encode(&str1).unwrap();
let ser_nt1 = rasn::der::encode(&nt1).unwrap();
let ser_nt2 = rasn::der::encode(&nt2).unwrap();
let ser_nt3 = rasn::der::encode(&nt3).unwrap();

println!("Ch1 --- {:?}", ser_choose);
println!("Nt1 --- {:?}", ser_nt1);
println!("Nt2 --- {:?}", ser_nt2);
println!("St1 --- {:?}", ser_str1);
println!("Nt3 --- {:?}", ser_nt3);

I'm still seeing the result:

Ch1 --- [160, 4, 12, 2, 104, 105]
Nt1 --- [32, 6, 160, 4, 12, 2, 104, 105]
Nt2 --- [160, 4, 12, 2, 104, 105]
St1 --- [12, 2, 104, 105]
Nt3 --- [12, 2, 104, 105]

@orthecreedence
Copy link
Contributor Author

Closed by #163

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant