Skip to content

refactor(rust/signed-doc): Change collabs header to collaborators #395

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

Merged
merged 11 commits into from
Jul 3, 2025
1 change: 0 additions & 1 deletion .config/dictionaries/project.dic
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ ciphertexts
Coap
codegen
codepoints
collabs
coti
coverallsapp
cpus
Expand Down
2 changes: 0 additions & 2 deletions rust/signed_doc/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
<!-- cspell: words collabs -->

# Catalyst signed document

Catalyst signed document crate implementation based on this
Expand Down
34 changes: 23 additions & 11 deletions rust/signed_doc/src/metadata/collaborators.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
//! Catalyst Signed Document `collabs` field type definition.
//! Catalyst Signed Document `collaborators` field type definition.

use std::ops::Deref;
use std::{ops::Deref, str::FromStr};

/// 'collabs' field type definition, which is a JSON path string
use catalyst_types::catalyst_id::CatalystId;

/// 'collaborators' field type definition, which is a JSON path string
#[derive(Clone, Debug, PartialEq)]
pub struct Collaborators(Vec<String>);
pub struct Collaborators(Vec<CatalystId>);

impl Deref for Collaborators {
type Target = Vec<String>;
type Target = Vec<CatalystId>;

fn deref(&self) -> &Self::Target {
&self.0
Expand All @@ -26,7 +28,7 @@ impl minicbor::Encode<()> for Collaborators {
.map_err(minicbor::encode::Error::message)?,
)?;
for c in &self.0 {
e.str(c)?;
e.bytes(&c.to_string().into_bytes())?;
}
}
Ok(())
Expand All @@ -42,16 +44,26 @@ impl minicbor::Decode<'_, ()> for Collaborators {
"Must a definite size array",
));
};
let collabs = (0..items)
.map(|_| Ok(d.str()?.to_string()))
.collect::<Result<_, _>>()?;
Ok(Self(collabs))

(0..items)
.map(|_| d.bytes())
.collect::<Result<Vec<_>, _>>()?
.into_iter()
.map(CatalystId::try_from)
.collect::<Result<_, _>>()
.map(Self)
.map_err(minicbor::decode::Error::custom)
}
}

impl<'de> serde::Deserialize<'de> for Collaborators {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: serde::Deserializer<'de> {
Ok(Self(Vec::<String>::deserialize(deserializer)?))
Vec::<String>::deserialize(deserializer)?
.into_iter()
.map(|id| CatalystId::from_str(&id))
.collect::<Result<_, _>>()
.map(Self)
.map_err(serde::de::Error::custom)
}
}
12 changes: 6 additions & 6 deletions rust/signed_doc/src/metadata/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ mod document_refs;
mod section;
mod supported_field;

use catalyst_types::{problem_report::ProblemReport, uuid::UuidV7};
use catalyst_types::{catalyst_id::CatalystId, problem_report::ProblemReport, uuid::UuidV7};
pub use content_encoding::ContentEncoding;
pub use content_type::ContentType;
pub use doc_type::DocType;
Expand Down Expand Up @@ -119,12 +119,12 @@ impl Metadata {
.and_then(SupportedField::try_as_section_ref)
}

/// Return `collabs` field.
/// Return `collaborators` field.
#[must_use]
pub fn collabs(&self) -> &[String] {
pub fn collaborators(&self) -> &[CatalystId] {
self.0
.get(&SupportedLabel::Collabs)
.and_then(SupportedField::try_as_collabs_ref)
.get(&SupportedLabel::Collaborators)
.and_then(SupportedField::try_as_collaborators_ref)
.map_or(&[], |v| &**v)
}

Expand Down Expand Up @@ -206,7 +206,7 @@ impl Display for Metadata {
writeln!(f, " template: {:?},", self.template())?;
writeln!(f, " reply: {:?},", self.reply())?;
writeln!(f, " section: {:?},", self.section())?;
writeln!(f, " collabs: {:?},", self.collabs())?;
writeln!(f, " collaborators: {:?},", self.collaborators())?;
writeln!(f, " parameters: {:?},", self.parameters())?;
writeln!(f, " }},")?;
writeln!(f, "}}")
Expand Down
24 changes: 13 additions & 11 deletions rust/signed_doc/src/metadata/supported_field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,16 +94,16 @@ pub(crate) enum SupportedField {
Type(DocType) = 4,
/// `reply` field.
Reply(DocumentRefs) = 5,
/// `collabs` field.
Collabs(Collaborators) = 7,
/// `section` field.
Section(Section) = 8,
Section(Section) = 6,
/// `template` field.
Template(DocumentRefs) = 9,
Template(DocumentRefs) = 7,
/// `parameters` field.
Parameters(DocumentRefs) = 10,
Parameters(DocumentRefs) = 8,
/// `collaborators` field.
Collaborators(Collaborators) = 9,
/// `Content-Encoding` field.
ContentEncoding(ContentEncoding) = 11,
ContentEncoding(ContentEncoding) = 10,
}

impl SupportedLabel {
Expand All @@ -117,7 +117,7 @@ impl SupportedLabel {
Label::Str("ver") => Some(Self::Ver),
Label::Str("type") => Some(Self::Type),
Label::Str("reply") => Some(Self::Reply),
Label::Str("collabs") => Some(Self::Collabs),
Label::Str("collaborators") => Some(Self::Collaborators),
Label::Str("section") => Some(Self::Section),
Label::Str("template") => Some(Self::Template),
Label::Str("parameters" | "brand_id" | "campaign_id" | "category_id") => {
Expand All @@ -139,7 +139,7 @@ impl SupportedLabel {
Self::Ver => Label::Str("ver"),
Self::Type => Label::Str("type"),
Self::Reply => Label::Str("reply"),
Self::Collabs => Label::Str("collabs"),
Self::Collaborators => Label::Str("collaborators"),
Self::Section => Label::Str("section"),
Self::Template => Label::Str("template"),
Self::Parameters => Label::Str("parameters"),
Expand Down Expand Up @@ -167,7 +167,9 @@ impl<'de> serde::de::DeserializeSeed<'de> for SupportedLabel {
SupportedLabel::Ver => Deserialize::deserialize(d).map(SupportedField::Ver),
SupportedLabel::Type => Deserialize::deserialize(d).map(SupportedField::Type),
SupportedLabel::Reply => Deserialize::deserialize(d).map(SupportedField::Reply),
SupportedLabel::Collabs => Deserialize::deserialize(d).map(SupportedField::Collabs),
SupportedLabel::Collaborators => {
Deserialize::deserialize(d).map(SupportedField::Collaborators)
},
SupportedLabel::Section => Deserialize::deserialize(d).map(SupportedField::Section),
SupportedLabel::Template => Deserialize::deserialize(d).map(SupportedField::Template),
SupportedLabel::Parameters => {
Expand Down Expand Up @@ -218,7 +220,7 @@ impl minicbor::Decode<'_, crate::decode_context::DecodeContext> for Option<Suppo
},
SupportedLabel::Type => d.decode_with(ctx).map(SupportedField::Type),
SupportedLabel::Reply => d.decode_with(ctx).map(SupportedField::Reply),
SupportedLabel::Collabs => d.decode().map(SupportedField::Collabs),
SupportedLabel::Collaborators => d.decode().map(SupportedField::Collaborators),
SupportedLabel::Section => d.decode().map(SupportedField::Section),
SupportedLabel::Template => d.decode_with(ctx).map(SupportedField::Template),
SupportedLabel::Parameters => d.decode_with(ctx).map(SupportedField::Parameters),
Expand Down Expand Up @@ -255,7 +257,7 @@ impl minicbor::Encode<()> for SupportedField {
| SupportedField::Template(document_ref)
| SupportedField::Parameters(document_ref) => document_ref.encode(e, ctx),
SupportedField::Type(doc_type) => doc_type.encode(e, ctx),
SupportedField::Collabs(collabs) => collabs.encode(e, ctx),
SupportedField::Collaborators(collaborators) => collaborators.encode(e, ctx),
SupportedField::Section(section) => section.encode(e, ctx),
SupportedField::ContentEncoding(content_encoding) => content_encoding.encode(e, ctx),
}
Expand Down
11 changes: 8 additions & 3 deletions rust/signed_doc/tests/decoding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ fn signed_doc_with_random_header_field_case(field: &'static str) -> TestCase {
anyhow::ensure!(doc.doc_meta().reply().is_none());
anyhow::ensure!(doc.doc_meta().section().is_none());
anyhow::ensure!(doc.doc_meta().parameters().is_none());
anyhow::ensure!(doc.doc_meta().collabs().is_empty());
anyhow::ensure!(doc.doc_meta().collaborators().is_empty());

if field == "content-type" {
anyhow::ensure!(doc.doc_meta().content_type().is_err());
Expand Down Expand Up @@ -595,7 +595,12 @@ fn signed_doc_with_complete_metadata_fields_case() -> TestCase {
.encode_with(doc_ref.clone(), &mut ())?;
p_headers.str("section")?.encode("$")?;

p_headers.str("collabs")?.encode(["collaborator 1", "collaborator 2"])?;
/* cspell:disable */
p_headers.str("collaborators")?;
p_headers.array(2)?;
p_headers.bytes(b"cardano/FftxFnOrj2qmTuB2oZG2v0YEWJfKvQ9Gg8AgNAhDsKE")?;
p_headers.bytes(b"id.catalyst://preprod.cardano/FftxFnOrj2qmTuB2oZG2v0YEWJfKvQ9Gg8AgNAhDsKE/7/3")?;
/* cspell:enable */
p_headers.str("parameters")?.encode_with(uuid_v7, &mut catalyst_types::uuid::CborContext::Tagged)?;

e.bytes(p_headers.into_writer().as_slice())?;
Expand Down Expand Up @@ -1196,7 +1201,7 @@ fn catalyst_signed_doc_decoding_test() {
signed_doc_with_random_header_field_case("template"),
signed_doc_with_random_header_field_case("reply"),
signed_doc_with_random_header_field_case("section"),
signed_doc_with_random_header_field_case("collabs"),
signed_doc_with_random_header_field_case("collaborators"),
signed_doc_with_random_header_field_case("parameters"),
signed_doc_with_random_header_field_case("content-encoding"),
signed_doc_with_parameters_and_aliases_case(&["parameters", "category_id"]),
Expand Down
7 changes: 6 additions & 1 deletion rust/signed_doc/tests/signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,12 @@ fn metadata() -> serde_json::Value {
"reply": {"id": UuidV7::new(), "ver": UuidV7::new()},
"template": {"id": UuidV7::new(), "ver": UuidV7::new()},
"section": "$",
"collabs": vec!["Alex1", "Alex2"],
"collaborators": vec![
/* cspell:disable */
"cardano/FftxFnOrj2qmTuB2oZG2v0YEWJfKvQ9Gg8AgNAhDsKE",
"id.catalyst://preprod.cardano/FftxFnOrj2qmTuB2oZG2v0YEWJfKvQ9Gg8AgNAhDsKE/7/3"
/* cspell:enable */
],
"parameters": {"id": UuidV7::new(), "ver": UuidV7::new()},
})
}
Expand Down