-
Notifications
You must be signed in to change notification settings - Fork 11
minicbor-serde: add support for serializing / deserializing custom CBOR tags #49
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
base: develop
Are you sure you want to change the base?
Conversation
Patch introduces wrapper tag types to enable deserialization and serialization of tagged values. Signed-off-by: Panav Munshi <mpanav@amazon.com>
Signed-off-by: Panav Munshi <mpanav@amazon.com>
Signed-off-by: Panav Munshi <mpanav@amazon.com>
Signed-off-by: Panav Munshi <mpanav@amazon.com>
twittner
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Overall this looks good to me. Just left some minor comments.
| match self.tagged { | ||
| true => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer an if-else.
| } | ||
|
|
||
| enum State { | ||
| Tag(u64), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not a minicbor::data::Tag?
| Tag(u64), | |
| Tag(Tag), |
|
|
||
| struct EnumTagAccess<'a, 'de: 'a> { | ||
| deserializer: &'a mut Deserializer<'de>, | ||
| tag: Option<u64>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| tag: Option<u64>, | |
| tag: Option<Tag>, |
| { | ||
| match self.state { | ||
| State::Tag(tag) => { | ||
| self.state = State::Value; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps the state should change after the tag was successfully deserialised? Probably does not make much of a difference in practice.
| /// custom aliases to ensure that [`crate::de::Deserializer`] is able to drive | ||
| /// the [`minicbor::Decoder`] correctly. | ||
| enum TagContainer<T> { | ||
| Tag(u64, T), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| Tag(u64, T), | |
| Tag(Tag, T), |
| found: u64, | ||
| expected: u64, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| found: u64, | |
| expected: u64, | |
| found: Tag, | |
| expected: Tag, |
| } | ||
|
|
||
| impl TagMismatchError { | ||
| fn new(found: u64, expected: u64) -> Self { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| fn new(found: u64, expected: u64) -> Self { | |
| fn new<A: Into<Tag>, B: Into<Tag>>(found: A, expected: B) -> Self { |
| /// | ||
| /// Tags will always be emitted during serialization | ||
| #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] | ||
| pub struct Required<const TAG: u64, T>(pub T); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| pub struct Required<const TAG: u64, T>(pub T); | |
| pub struct Required<const TAG: u64, T>(T); |
I would prefer not to expose the field publicly. Required is essentially Tagged, so the impl blocks from Tagged could be copied over here.
| /// | ||
| /// Tag will be emitted during serialization, if present | ||
| #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] | ||
| pub struct Optional<const TAG: u64, T>(pub Option<u64>, pub T); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| pub struct Optional<const TAG: u64, T>(pub Option<u64>, pub T); | |
| pub struct Optional<const TAG: u64, T>(Option<Tag>, T); | |
| impl<const TAG: u64, T> Optional<TAG, T> { | |
| pub fn tagged(val: T) -> Self { | |
| Self(Some(Tag::new(TAG)), val) | |
| } | |
| pub fn untagged(val: T) -> Self { | |
| Self(None, val) | |
| } | |
| pub fn tag(&self) -> Option<Tag> { | |
| self.0 | |
| } | |
| pub fn into_value(self) -> T { | |
| self.1 | |
| } | |
| } | |
| impl<const TAG: u64, T> Deref for Optional<TAG, T> { | |
| type Target = T; | |
| fn deref(&self) -> &Self::Target { | |
| &self.1 | |
| } | |
| } | |
| impl<const TAG: u64, T> DerefMut for Optional<TAG, T> { | |
| fn deref_mut(&mut self) -> &mut Self::Target { | |
| &mut self.1 | |
| } | |
| } |
Optional::tagged guarantees that the tag value matches the const TAG.
| /// | ||
| /// Tag will be emitted during serialization, if present | ||
| #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] | ||
| pub struct Any<T>(pub Option<u64>, pub T); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| pub struct Any<T>(pub Option<u64>, pub T); | |
| pub struct Any<T>(Option<Tag>, T); | |
| impl<T> Any<T> { | |
| pub fn tagged<N: Into<Tag>>(t: N, v: T) -> Self { | |
| Self(Some(t.into()), v) | |
| } | |
| pub fn untagged(v: T) -> Self { | |
| Self(None, v) | |
| } | |
| pub fn tag(&self) -> Option<Tag> { | |
| self.0 | |
| } | |
| pub fn into_value(self) -> T { | |
| self.1 | |
| } | |
| } | |
| impl<T> Deref for Any<T> { | |
| type Target = T; | |
| fn deref(&self) -> &Self::Target { | |
| &self.1 | |
| } | |
| } | |
| impl<T> DerefMut for Any<T> { | |
| fn deref_mut(&mut self) -> &mut Self::Target { | |
| &mut self.1 | |
| } | |
| } |
|
Thanks for the comments! I'll work through these and have a revision out soon :) |
Patch series adds support to deserialize / serialize custom tags in minicbor-serde.
See #44 for more details