You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently cddl-codegen does not support .cbor or .cborseq
I would be nice to support .cbor since it's used in multiple places in both the Byron spec and also it's used in the Babbage spec
I think the logic for .cbor is fairly similar -- just generate the same code as we do now but wrap the generated code in a (de)serialization of a cbor wrapper for the data.
impl cbor_event::se::SerializeforAddrdistrEnum{fnserialize<'se,W:Write>(&self,serializer:&'se mutSerializer<W>) -> cbor_event::Result<&'se mutSerializer<W>>{// note: this wrapping in `se` is what was added for the `.cbor` wrapperletmut se = Serializer::new_vec();let inner_cbor = matchself{AddrdistrEnum::BootstrapEraDistr(x) => x.serialize(&mut se),AddrdistrEnum::SingleKeyDistr(x) => x.serialize(&mut se),}?;
serializer.write_bytes(&inner_cbor.finalize())}}
and this kind of deserialization code
implDeserializeforAddrdistrEnum{fndeserialize<R:BufRead + Seek>(raw:&mutDeserializer<R>) -> Result<Self,DeserializeError>{(|| -> Result<_,DeserializeError>{// note: this line here is what was added for the .cbor wrapperletmut inner = &mutDeserializer::from(std::io::Cursor::new(raw.bytes()?));let len = inner.array()?;letmut read_len = CBORReadLen::new(len);let initial_position = inner.as_mut_ref().seek(SeekFrom::Current(0)).unwrap();match(|inner:&mutDeserializer<_>| -> Result<_,DeserializeError>{Ok(BootstrapEraDistr::deserialize_as_embedded_group(inner, len)?)})(inner){Ok(variant) => returnOk(AddrdistrEnum::BootstrapEraDistr(variant)),Err(_) => inner.as_mut_ref().seek(SeekFrom::Start(initial_position)).unwrap(),};match(|inner:&mutDeserializer<_>| -> Result<_,DeserializeError>{Ok(SingleKeyDistr::deserialize_as_embedded_group(inner, len)?)})(inner){Ok(variant) => returnOk(AddrdistrEnum::SingleKeyDistr(variant)),Err(_) => inner.as_mut_ref().seek(SeekFrom::Start(initial_position)).unwrap(),};match len {
cbor_event::Len::Len(_) => read_len.finish()?,
cbor_event::Len::Indefinite => match inner.special()? {CBORSpecial::Break => read_len.finish()?,
_ => returnErr(DeserializeFailure::EndingBreakMissing.into()),},}Err(DeserializeError::new("AddrdistrEnum",DeserializeFailure::NoVariantMatched.into()))})().map_err(|e| e.annotate("AddrdistrEnum"))}}
Ways to implement
I think there are three main ways to implement this:
We change the struct definition to pub struct Outer(Inner);. Keeping track of this is kind of complicated when you also think about having to support structs and enums - notably because handling structs would mean we have to keep track of whether or not something is cbor-in-cbor inside the intermediate representation. We can't have it in RustField since it's possibly only once choice of a field is cbor-in-cbor. We can't put it in anything that relies solely on Type2 because the operator lives in Type1.
We keep it as pub struct Outer(Vec<u8>), but in the (de)serialization logic we properly add to cbor-in-cbor logic. Additionally, we can provide From<...> implementations to convert the bytes to the inner type
We create some new wrapper type in the prelude like Cbor<Inner> and then make the struct pub struct Outer(Cbor<Inner>). This way we can keep everything in Outer just working with bytes and put all the cbor-in-cbor logic inside the Cbor<..> wrapper logic and have some generic From<...> implementation. This is the simplest solution I think to cover all cases, but the UX is kind of ugly. Also, this solution doesn't work for type aliases that map to primitives (ex: Vec<u8>) as they don't implement (de)serialize traits (and there isn't a good workaround for that because of Allow newtype pattern instead of type aliasing #44). Ignoring that issue, the best place for this in the intermediate representation would probably to change the new_type function to either add extra information to the Alias case or create a new CborInCbor case.
Also, these approaches are much harder on anonymous types so it's probably best to only support foo .cbor ident instead of allowing anonymous types where ident is
Lastly, I also didn't check the relation between this feature and `#6.24
The text was updated successfully, but these errors were encountered:
Currently
cddl-codegen
does not support.cbor
or.cborseq
I would be nice to support
.cbor
since it's used in multiple places in both the Byron spec and also it's used in the Babbage specI think the logic for
.cbor
is fairly similar -- just generate the same code as we do now but wrap the generated code in a (de)serialization of a cbor wrapper for the data.More information: https://datatracker.ietf.org/doc/html/rfc8610#section-3.8.4
Example
I would expect the following definition
to generate this kind of serialization code
and this kind of deserialization code
Ways to implement
I think there are three main ways to implement this:
pub struct Outer(Inner);
. Keeping track of this is kind of complicated when you also think about having to support structs and enums - notably because handling structs would mean we have to keep track of whether or not something is cbor-in-cbor inside the intermediate representation. We can't have it inRustField
since it's possibly only once choice of a field is cbor-in-cbor. We can't put it in anything that relies solely on Type2 because the operator lives in Type1.pub struct Outer(Vec<u8>)
, but in the (de)serialization logic we properly add to cbor-in-cbor logic. Additionally, we can provideFrom<...>
implementations to convert the bytes to the inner typeCbor<Inner>
and then make the structpub struct Outer(Cbor<Inner>)
. This way we can keep everything inOuter
just working with bytes and put all the cbor-in-cbor logic inside theCbor<..>
wrapper logic and have some genericFrom<...>
implementation. This is the simplest solution I think to cover all cases, but the UX is kind of ugly. Also, this solution doesn't work for type aliases that map to primitives (ex:Vec<u8>
) as they don't implement (de)serialize traits (and there isn't a good workaround for that because of Allow newtype pattern instead of type aliasing #44). Ignoring that issue, the best place for this in the intermediate representation would probably to change thenew_type
function to either add extra information to the Alias case or create a new CborInCbor case.Also, these approaches are much harder on anonymous types so it's probably best to only support
foo .cbor ident
instead of allowing anonymous types where ident isLastly, I also didn't check the relation between this feature and `#6.24
The text was updated successfully, but these errors were encountered: