Skip to content

Commit 6f4007a

Browse files
committed
refactor, add test
1 parent d34ac1f commit 6f4007a

File tree

2 files changed

+85
-81
lines changed

2 files changed

+85
-81
lines changed

rust/signed_doc/src/metadata/extra_fields.rs

Lines changed: 78 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -59,61 +59,49 @@ pub struct ExtraFields {
5959
}
6060

6161
impl ExtraFields {
62-
/// Returns the COSE Sign protected header REST fields.
63-
///
64-
/// # Errors
65-
/// If any internal field cannot be converted into `Value`.
66-
pub fn header_rest(&self) -> anyhow::Result<Vec<(String, Value)>> {
67-
self.try_into()
68-
}
69-
}
70-
71-
impl TryFrom<&ExtraFields> for Vec<(String, Value)> {
72-
type Error = anyhow::Error;
73-
74-
fn try_from(fields: &ExtraFields) -> anyhow::Result<Self> {
75-
let mut vec = Vec::new();
76-
77-
if let Some(doc_ref) = &fields.doc_ref {
78-
vec.push((REF_KEY.to_string(), Value::try_from(*doc_ref)?));
62+
/// Fill the COSE hedear `ExtraFields` data into the header builder.
63+
pub(super) fn fill_cose_header_fields(
64+
&self, mut builder: coset::HeaderBuilder,
65+
) -> anyhow::Result<coset::HeaderBuilder> {
66+
if let Some(doc_ref) = &self.doc_ref {
67+
builder = builder.text_value(REF_KEY.to_string(), Value::try_from(*doc_ref)?);
7968
}
80-
81-
if let Some(template) = &fields.template {
82-
vec.push((TEMPLATE_KEY.to_string(), Value::try_from(*template)?));
69+
if let Some(template) = &self.template {
70+
builder = builder.text_value(TEMPLATE_KEY.to_string(), Value::try_from(*template)?);
8371
}
84-
85-
if let Some(reply) = &fields.reply {
86-
vec.push((REPLY_KEY.to_string(), Value::try_from(*reply)?));
72+
if let Some(reply) = &self.reply {
73+
builder = builder.text_value(REPLY_KEY.to_string(), Value::try_from(*reply)?);
8774
}
8875

89-
if let Some(section) = &fields.section {
90-
vec.push((SECTION_KEY.to_string(), Value::Text(section.clone())));
76+
if let Some(section) = &self.section {
77+
builder = builder.text_value(SECTION_KEY.to_string(), Value::Text(section.clone()));
9178
}
9279

93-
if !fields.collabs.is_empty() {
94-
vec.push((
80+
if !self.collabs.is_empty() {
81+
builder = builder.text_value(
9582
COLLABS_KEY.to_string(),
96-
Value::Array(fields.collabs.iter().cloned().map(Value::Text).collect()),
97-
));
83+
Value::Array(self.collabs.iter().cloned().map(Value::Text).collect()),
84+
);
9885
}
99-
100-
if let Some(brand_id) = &fields.brand_id {
101-
vec.push((BRAND_ID_KEY.to_string(), encode_cbor_uuid(brand_id)?));
86+
if let Some(brand_id) = &self.brand_id {
87+
builder = builder.text_value(BRAND_ID_KEY.to_string(), encode_cbor_uuid(brand_id)?);
10288
}
10389

104-
if let Some(campaign_id) = &fields.campaign_id {
105-
vec.push((CAMPAIGN_ID_KEY.to_string(), encode_cbor_uuid(campaign_id)?));
90+
if let Some(campaign_id) = &self.campaign_id {
91+
builder =
92+
builder.text_value(CAMPAIGN_ID_KEY.to_string(), encode_cbor_uuid(campaign_id)?);
10693
}
10794

108-
if let Some(election_id) = &fields.election_id {
109-
vec.push((ELECTION_ID_KEY.to_string(), encode_cbor_uuid(election_id)?));
95+
if let Some(election_id) = &self.election_id {
96+
builder =
97+
builder.text_value(ELECTION_ID_KEY.to_string(), encode_cbor_uuid(election_id)?);
11098
}
11199

112-
if let Some(category_id) = &fields.category_id {
113-
vec.push((CATEGORY_ID_KEY.to_string(), encode_cbor_uuid(*category_id)?));
100+
if let Some(category_id) = &self.category_id {
101+
builder =
102+
builder.text_value(CATEGORY_ID_KEY.to_string(), encode_cbor_uuid(*category_id)?);
114103
}
115-
116-
Ok(vec)
104+
Ok(builder)
117105
}
118106
}
119107

@@ -280,3 +268,53 @@ impl TryFrom<&ProtectedHeader> for ExtraFields {
280268
}
281269
}
282270
}
271+
272+
#[cfg(test)]
273+
mod tests {
274+
use catalyst_types::uuid::{V4, V7};
275+
276+
use super::*;
277+
278+
#[test]
279+
fn extra_fields_json_serde_test() {
280+
let extra = ExtraFields::default();
281+
282+
let json = serde_json::to_value(extra).unwrap();
283+
assert_eq!(json, serde_json::json!({}));
284+
285+
let uuid_v7 = V7::new();
286+
let uuid_v4 = V4::new();
287+
let section = "some section".to_string();
288+
let collabs = vec!["collab1".to_string(), "collab2".to_string()];
289+
let extra = ExtraFields {
290+
doc_ref: Some(DocumentRef::Latest { id: uuid_v7 }),
291+
reply: Some(DocumentRef::WithVer {
292+
id: uuid_v7,
293+
ver: uuid_v7,
294+
}),
295+
template: Some(DocumentRef::Latest { id: uuid_v7 }),
296+
section: Some(section.clone()),
297+
collabs: collabs.clone(),
298+
campaign_id: Some(uuid_v4),
299+
election_id: Some(uuid_v4),
300+
brand_id: Some(uuid_v4),
301+
category_id: Some(uuid_v4),
302+
};
303+
304+
let json = serde_json::to_value(extra).unwrap();
305+
assert_eq!(
306+
json,
307+
serde_json::json!({
308+
"ref": {"id": uuid_v7.to_string()},
309+
"reply": {"id": uuid_v7.to_string(), "ver": uuid_v7.to_string()},
310+
"template": {"id": uuid_v7.to_string()},
311+
"section": section,
312+
"collabs": collabs,
313+
"campaign_id": uuid_v4.to_string(),
314+
"election_id": uuid_v4.to_string(),
315+
"brand_id": uuid_v4.to_string(),
316+
"category_id": uuid_v4.to_string(),
317+
})
318+
);
319+
}
320+
}

rust/signed_doc/src/metadata/mod.rs

Lines changed: 7 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -115,62 +115,28 @@ impl Display for Metadata {
115115
}
116116

117117
impl TryFrom<&Metadata> for coset::Header {
118-
type Error = crate::error::Error;
118+
type Error = anyhow::Error;
119119

120120
fn try_from(meta: &Metadata) -> Result<Self, Self::Error> {
121121
let mut builder = coset::HeaderBuilder::new()
122122
.algorithm(meta.alg.into())
123123
.content_format(CoapContentFormat::from(meta.content_type()));
124124

125-
let mut errors = Vec::new();
126-
127125
if let Some(content_encoding) = meta.content_encoding() {
128126
builder = builder.text_value(
129127
CONTENT_ENCODING_KEY.to_string(),
130128
format!("{content_encoding}").into(),
131129
);
132130
}
133131

134-
match coset::cbor::Value::try_from(meta.doc_type) {
135-
Ok(value) => {
136-
builder = builder.text_value(TYPE_KEY.to_string(), value);
137-
},
138-
Err(e) => {
139-
errors.push(anyhow::anyhow!("Invalid document type UUID: {e}"));
140-
},
141-
}
132+
builder = builder
133+
.text_value(TYPE_KEY.to_string(), meta.doc_type.try_into()?)
134+
.text_value(ID_KEY.to_string(), meta.id.try_into()?)
135+
.text_value(VER_KEY.to_string(), meta.ver.try_into()?);
142136

143-
match coset::cbor::Value::try_from(meta.id) {
144-
Ok(value) => {
145-
builder = builder.text_value(ID_KEY.to_string(), value);
146-
},
147-
Err(e) => {
148-
errors.push(anyhow::anyhow!("Invalid document id UUID: {e}"));
149-
},
150-
}
137+
builder = meta.extra.fill_cose_header_fields(builder)?;
151138

152-
match coset::cbor::Value::try_from(meta.ver) {
153-
Ok(value) => {
154-
builder = builder.text_value(VER_KEY.to_string(), value);
155-
},
156-
Err(e) => {
157-
errors.push(anyhow::anyhow!("Invalid document ver UUID: {e}"));
158-
},
159-
}
160-
161-
if let Ok(rest) = meta.extra().header_rest() {
162-
for (label, value) in rest {
163-
builder = builder.text_value(label, value);
164-
}
165-
}
166-
167-
let header = builder.build();
168-
169-
if errors.is_empty() {
170-
Ok(header)
171-
} else {
172-
Err(crate::error::Error::from(errors))
173-
}
139+
Ok(builder.build())
174140
}
175141
}
176142

0 commit comments

Comments
 (0)