Skip to content

Commit ff80c79

Browse files
committed
feat(rust/catalyst-types): CBOR encode and decode for UUID types with context
1 parent 08ec6a4 commit ff80c79

File tree

3 files changed

+63
-34
lines changed

3 files changed

+63
-34
lines changed

rust/catalyst-types/src/uuid/mod.rs

Lines changed: 59 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
mod uuid_v4;
44
mod uuid_v7;
55

6+
use minicbor::data::Tag;
67
pub use uuid_v4::UuidV4 as V4;
78
pub use uuid_v7::UuidV7 as V7;
89

@@ -23,31 +24,34 @@ pub enum CborContext {
2324
Optional,
2425
}
2526

27+
/// Validate UUID CBOR Tag.
28+
fn validate_uuid_tag(tag: u64) -> Result<(), minicbor::decode::Error> {
29+
if UUID_CBOR_TAG != tag {
30+
return Err(minicbor::decode::Error::message(format!(
31+
"tag value must be: {UUID_CBOR_TAG}, provided: {tag}"
32+
)));
33+
}
34+
Ok(())
35+
}
36+
2637
/// Decode from `CBOR` into `UUID`
2738
fn decode_cbor_uuid(
2839
d: &mut minicbor::Decoder<'_>, ctx: &mut CborContext,
2940
) -> Result<uuid::Uuid, minicbor::decode::Error> {
3041
let bytes = match ctx {
3142
CborContext::Untagged => d.bytes()?,
3243
CborContext::Tagged => {
33-
let tag = d.tag()?.as_u64();
34-
if UUID_CBOR_TAG == tag {
35-
return Err(minicbor::decode::Error::message(format!(
36-
"tag value must be: {UUID_CBOR_TAG}, provided: {tag}"
37-
)));
38-
}
44+
let tag = d.tag()?;
45+
validate_uuid_tag(tag.as_u64())?;
3946
d.bytes()?
4047
},
4148
CborContext::Optional => {
49+
let pos = d.position();
4250
if let Ok(tag) = d.tag() {
43-
let tag = tag.as_u64();
44-
if UUID_CBOR_TAG == tag {
45-
return Err(minicbor::decode::Error::message(format!(
46-
"tag value must be: {UUID_CBOR_TAG}, provided: {tag}"
47-
)));
48-
}
51+
validate_uuid_tag(tag.as_u64())?;
4952
d.bytes()?
5053
} else {
54+
d.set_position(pos);
5155
d.bytes()?
5256
}
5357
},
@@ -60,27 +64,27 @@ fn decode_cbor_uuid(
6064
}
6165

6266
/// Encode `UUID` into `CBOR`
63-
fn encode_cbor_uuid<C, W: minicbor::encode::Write>(
64-
uuid: uuid::Uuid, e: &mut minicbor::Encoder<W>, _ctx: &mut C,
67+
fn encode_cbor_uuid<W: minicbor::encode::Write>(
68+
uuid: uuid::Uuid, e: &mut minicbor::Encoder<W>, ctx: &mut CborContext,
6569
) -> Result<(), minicbor::encode::Error<W::Error>> {
70+
if let CborContext::Tagged = ctx {
71+
e.tag(Tag::new(UUID_CBOR_TAG))?;
72+
}
6673
e.bytes(uuid.as_bytes())?;
6774
Ok(())
6875
}
6976

7077
#[cfg(test)]
7178
mod tests {
72-
use minicbor::data::{Tag, Tagged};
7379

7480
use super::{V4, V7};
7581
use crate::uuid::CborContext;
7682

77-
const UUID_CBOR_TAG: u64 = 37;
78-
7983
#[test]
8084
fn test_cbor_uuid_v4_roundtrip() {
8185
let uuid: V4 = uuid::Uuid::new_v4().into();
8286
let mut bytes = Vec::new();
83-
minicbor::encode(uuid, &mut bytes).unwrap();
87+
minicbor::encode_with(uuid, &mut bytes, &mut CborContext::Untagged).unwrap();
8488
let decoded = minicbor::decode_with(bytes.as_slice(), &mut CborContext::Untagged).unwrap();
8589
assert_eq!(uuid, decoded);
8690
}
@@ -89,29 +93,54 @@ mod tests {
8993
fn test_cbor_uuid_v7_roundtrip() {
9094
let uuid: V7 = uuid::Uuid::now_v7().into();
9195
let mut bytes = Vec::new();
92-
minicbor::encode(uuid, &mut bytes).unwrap();
96+
minicbor::encode_with(uuid, &mut bytes, &mut CborContext::Untagged).unwrap();
9397
let decoded = minicbor::decode_with(bytes.as_slice(), &mut CborContext::Untagged).unwrap();
9498
assert_eq!(uuid, decoded);
9599
}
96100

97101
#[test]
98-
fn test_cbor_tagged_uuid_v4_roundtrip() {
102+
fn test_tagged_cbor_uuid_v4_roundtrip() {
99103
let uuid: V4 = uuid::Uuid::new_v4().into();
100-
let tagged: Tagged<UUID_CBOR_TAG, V4> = uuid.into();
101104
let mut bytes = Vec::new();
102-
minicbor::encode(tagged, &mut bytes).unwrap();
103-
let decoded = minicbor::decode_with(bytes.as_slice(), &mut CborContext::Untagged).unwrap();
104-
assert_eq!(tagged, decoded);
105+
minicbor::encode_with(uuid, &mut bytes, &mut CborContext::Tagged).unwrap();
106+
let decoded = minicbor::decode_with(bytes.as_slice(), &mut CborContext::Tagged).unwrap();
107+
assert_eq!(uuid, decoded);
105108
}
106109

107110
#[test]
108-
fn test_cbor_tagged_uuid_v7_roundtrip() {
111+
fn test_tagged_cbor_uuid_v7_roundtrip() {
109112
let uuid: V7 = uuid::Uuid::now_v7().into();
110-
let tagged: Tagged<UUID_CBOR_TAG, V7> = uuid.into();
111113
let mut bytes = Vec::new();
112-
minicbor::encode(tagged, &mut bytes).unwrap();
113-
let decoded = minicbor::decode_with(bytes.as_slice(), &mut CborContext::Untagged).unwrap();
114-
assert_eq!(tagged, decoded);
115-
assert_eq!(tagged.tag(), Tag::new(UUID_CBOR_TAG));
114+
minicbor::encode_with(uuid, &mut bytes, &mut CborContext::Tagged).unwrap();
115+
let decoded = minicbor::decode_with(bytes.as_slice(), &mut CborContext::Tagged).unwrap();
116+
assert_eq!(uuid, decoded);
117+
}
118+
119+
#[test]
120+
fn test_optional_cbor_uuid_v4_roundtrip() {
121+
let uuid: V4 = uuid::Uuid::new_v4().into();
122+
let mut bytes = Vec::new();
123+
minicbor::encode_with(uuid, &mut bytes, &mut CborContext::Optional).unwrap();
124+
let decoded = minicbor::decode_with(bytes.as_slice(), &mut CborContext::Optional).unwrap();
125+
assert_eq!(uuid, decoded);
126+
}
127+
128+
#[test]
129+
fn test_optional_cbor_uuid_v7_roundtrip() {
130+
let uuid: V7 = uuid::Uuid::now_v7().into();
131+
let mut bytes = Vec::new();
132+
minicbor::encode_with(uuid, &mut bytes, &mut CborContext::Optional).unwrap();
133+
let decoded = minicbor::decode_with(bytes.as_slice(), &mut CborContext::Optional).unwrap();
134+
assert_eq!(uuid, decoded);
135+
136+
let mut bytes = Vec::new();
137+
minicbor::encode_with(uuid, &mut bytes, &mut CborContext::Untagged).unwrap();
138+
let decoded = minicbor::decode_with(bytes.as_slice(), &mut CborContext::Optional).unwrap();
139+
assert_eq!(uuid, decoded);
140+
141+
let mut bytes = Vec::new();
142+
minicbor::encode_with(uuid, &mut bytes, &mut CborContext::Tagged).unwrap();
143+
let decoded = minicbor::decode_with(bytes.as_slice(), &mut CborContext::Optional).unwrap();
144+
assert_eq!(uuid, decoded);
116145
}
117146
}

rust/catalyst-types/src/uuid/uuid_v4.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@ impl Decode<'_, CborContext> for UuidV4 {
5050
}
5151
}
5252

53-
impl<C> Encode<C> for UuidV4 {
53+
impl Encode<CborContext> for UuidV4 {
5454
fn encode<W: minicbor::encode::Write>(
55-
&self, e: &mut minicbor::Encoder<W>, ctx: &mut C,
55+
&self, e: &mut minicbor::Encoder<W>, ctx: &mut CborContext,
5656
) -> Result<(), minicbor::encode::Error<W::Error>> {
5757
encode_cbor_uuid(self.uuid(), e, ctx)
5858
}

rust/catalyst-types/src/uuid/uuid_v7.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@ impl Decode<'_, CborContext> for UuidV7 {
5050
}
5151
}
5252

53-
impl<C> Encode<C> for UuidV7 {
53+
impl Encode<CborContext> for UuidV7 {
5454
fn encode<W: minicbor::encode::Write>(
55-
&self, e: &mut minicbor::Encoder<W>, ctx: &mut C,
55+
&self, e: &mut minicbor::Encoder<W>, ctx: &mut CborContext,
5656
) -> Result<(), minicbor::encode::Error<W::Error>> {
5757
encode_cbor_uuid(self.uuid(), e, ctx)
5858
}

0 commit comments

Comments
 (0)