• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

input-output-hk / catalyst-libs / 16646523141

31 Jul 2025 10:28AM UTC coverage: 67.341% (+3.8%) from 63.544%
16646523141

push

github

web-flow
feat(rust/signed-doc): Implement new Catalyst Signed Doc (#338)

* chore: add new line to open pr

Signed-off-by: bkioshn <bkioshn@gmail.com>

* chore: revert

Signed-off-by: bkioshn <bkioshn@gmail.com>

* feat(rust/signed-doc): add new type `DocType` (#339)

* feat(signed-doc): add new type DocType

Signed-off-by: bkioshn <bkioshn@gmail.com>

* fix(signed-doc): add conversion policy

Signed-off-by: bkioshn <bkioshn@gmail.com>

* fix(signed-doc): doc type

Signed-off-by: bkioshn <bkioshn@gmail.com>

* fix(signed-doc): doc type error

Signed-off-by: bkioshn <bkioshn@gmail.com>

* fix(signed-doc): seperate test

Signed-off-by: bkioshn <bkioshn@gmail.com>

* fix(signed-doc): format

Signed-off-by: bkioshn <bkioshn@gmail.com>

---------

Signed-off-by: bkioshn <bkioshn@gmail.com>

* feat(rust/signed-doc): Add initial decoding tests for the Catalyst Signed Documents (#349)

* wip

* wip

* fix fmt

* fix spelling

* fix clippy

* fix(rust/signed-doc): Apply new `DocType` (#347)

* feat(signed-doc): add new type DocType

Signed-off-by: bkioshn <bkioshn@gmail.com>

* wip: apply doctype

Signed-off-by: bkioshn <bkioshn@gmail.com>

* fix(signed-doc): add more function to DocType

Signed-off-by: bkioshn <bkioshn@gmail.com>

* fix(signed-doc): map old doctype to new doctype

Signed-off-by: bkioshn <bkioshn@gmail.com>

* fix(signed-doc): add eq to uuidv4

Signed-off-by: bkioshn <bkioshn@gmail.com>

* fix(signed-doc): fix validator

Signed-off-by: bkioshn <bkioshn@gmail.com>

* fix(signed-doc): minor fixes

Signed-off-by: bkioshn <bkioshn@gmail.com>

* fix(catalyst-types): add hash to uuidv4

Signed-off-by: bkioshn <bkioshn@gmail.com>

* fix(signed-doc): decoding test

Signed-off-by: bkioshn <bkioshn@gmail.com>

* fix(signed-doc): doctype

Signed-off-by: bkioshn <bkioshn@gmail.com>

* fix(signed-doc): minor fixes

Signed-off-by: bkioshn <bkioshn@gmail.com>

* chore(sign-doc): fix comment

Signed-off-by: bkioshn <bkioshn@gmail.com>

* fix(catalyst-types): add froms... (continued)

2453 of 2675 new or added lines in 38 files covered. (91.7%)

19 existing lines in 7 files now uncovered.

11312 of 16798 relevant lines covered (67.34%)

2525.16 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.4
/rust/signed_doc/src/validator/rules/param_link_ref.rs
1
//! Parameter linked reference rule impl.
2

3
use crate::{
4
    providers::CatalystSignedDocumentProvider, validator::utils::validate_doc_refs,
5
    CatalystSignedDocument,
6
};
7

8
/// Filed that is being used for linked ref
9
pub(crate) enum LinkField {
10
    /// Ref field
11
    Ref,
12
    /// Template field
13
    Template,
14
}
15

16
/// Parameter Link reference validation rule
17
pub(crate) enum ParameterLinkRefRule {
18
    /// Link ref specified
19
    Specified {
20
        /// Filed that is being used for linked ref
21
        field: LinkField,
22
    },
23
    /// Link ref is not specified
24
    #[allow(dead_code)]
25
    NotSpecified,
26
}
27

28
impl ParameterLinkRefRule {
29
    /// Validation rule
30
    pub(crate) async fn check<Provider>(
16✔
31
        &self, doc: &CatalystSignedDocument, provider: &Provider,
16✔
32
    ) -> anyhow::Result<bool>
16✔
33
    where Provider: CatalystSignedDocumentProvider {
16✔
34
        let context: &str = "Parameter link ref rule check";
16✔
35
        if let Self::Specified { field } = self {
16✔
36
            let param_link_ref_validator = |ref_doc: CatalystSignedDocument| {
16✔
37
                // The parameters MUST be the same, if not record the error
38
                if doc.doc_meta().parameters() != ref_doc.doc_meta().parameters() {
13✔
39
                    doc.report().invalid_value(
4✔
40
                        "parameters",
4✔
41
                        &format!("Reference doc param: {:?}", ref_doc.doc_meta().parameters()),
4✔
42
                        &format!("Doc param: {:?}", doc.doc_meta().parameters()),
4✔
43
                        &format!("{context}, parameters must be the same"),
4✔
44
                    );
45
                    return false;
4✔
46
                }
9✔
47
                true
9✔
48
            };
13✔
49
            // Which field is use for linked reference
50
            let param_link_ref = match field {
16✔
51
                LinkField::Ref => doc.doc_meta().doc_ref(),
7✔
52
                LinkField::Template => doc.doc_meta().template(),
9✔
53
            };
54

55
            let Some(param_link_ref) = param_link_ref else {
16✔
56
                doc.report()
3✔
57
                    .missing_field("Link ref", &format!("{context}: Invalid link reference"));
3✔
58
                return Ok(false);
3✔
59
            };
60

61
            return validate_doc_refs(
13✔
62
                param_link_ref,
13✔
63
                provider,
13✔
64
                doc.report(),
13✔
65
                param_link_ref_validator,
13✔
66
            )
13✔
67
            .await;
13✔
NEW
68
        }
×
NEW
69
        Ok(true)
×
70
    }
16✔
71
}
72

73
#[cfg(test)]
74
mod tests {
75
    use catalyst_types::uuid::{UuidV4, UuidV7};
76

77
    use crate::{
78
        builder::tests::Builder,
79
        metadata::SupportedField,
80
        providers::tests::TestCatalystSignedDocumentProvider,
81
        validator::rules::param_link_ref::{LinkField, ParameterLinkRefRule},
82
        DocLocator, DocumentRef,
83
    };
84
    #[tokio::test]
85
    async fn param_link_ref_specified_test() {
1✔
86
        let mut provider = TestCatalystSignedDocumentProvider::default();
1✔
87

88
        let doc1_id = UuidV7::new();
1✔
89
        let doc1_ver = UuidV7::new();
1✔
90
        let doc2_id = UuidV7::new();
1✔
91
        let doc2_ver = UuidV7::new();
1✔
92

93
        let doc_type = UuidV4::new();
1✔
94

95
        let category_id = UuidV7::new();
1✔
96
        let category_ver = UuidV7::new();
1✔
97
        let category_type = UuidV4::new();
1✔
98

99
        let campaign_id = UuidV7::new();
1✔
100
        let campaign_ver = UuidV7::new();
1✔
101
        let campaign_type = UuidV4::new();
1✔
102

103
        // Prepare provider documents
104
        {
1✔
105
            // Doc being referenced - parameter MUST match
1✔
106
            let doc = Builder::new()
1✔
107
                .with_metadata_field(SupportedField::Id(doc1_id))
1✔
108
                .with_metadata_field(SupportedField::Ver(doc1_ver))
1✔
109
                .with_metadata_field(SupportedField::Type(doc_type.into()))
1✔
110
                .with_metadata_field(SupportedField::Parameters(
1✔
111
                    vec![
1✔
112
                        DocumentRef::new(category_id, category_ver, DocLocator::default()),
1✔
113
                        DocumentRef::new(campaign_id, campaign_ver, DocLocator::default()),
1✔
114
                    ]
1✔
115
                    .into(),
1✔
116
                ))
1✔
117
                .build();
1✔
118
            provider.add_document(None, &doc).unwrap();
1✔
119

1✔
120
            // Doc being referenced - parameter does not match
1✔
121
            let doc = Builder::new()
1✔
122
                .with_metadata_field(SupportedField::Id(doc2_id))
1✔
123
                .with_metadata_field(SupportedField::Ver(doc2_ver))
1✔
124
                .with_metadata_field(SupportedField::Type(doc_type.into()))
1✔
125
                .with_metadata_field(SupportedField::Parameters(
1✔
126
                    vec![DocumentRef::new(
1✔
127
                        campaign_id,
1✔
128
                        campaign_ver,
1✔
129
                        DocLocator::default(),
1✔
130
                    )]
1✔
131
                    .into(),
1✔
132
                ))
1✔
133
                .build();
1✔
134
            provider.add_document(None, &doc).unwrap();
1✔
135

1✔
136
            // Category doc
1✔
137
            let doc = Builder::new()
1✔
138
                .with_metadata_field(SupportedField::Id(category_id))
1✔
139
                .with_metadata_field(SupportedField::Ver(category_ver))
1✔
140
                .with_metadata_field(SupportedField::Type(category_type.into()))
1✔
141
                .build();
1✔
142
            provider.add_document(None, &doc).unwrap();
1✔
143

1✔
144
            // Campaign doc
1✔
145
            let doc = Builder::new()
1✔
146
                .with_metadata_field(SupportedField::Id(campaign_id))
1✔
147
                .with_metadata_field(SupportedField::Ver(campaign_ver))
1✔
148
                .with_metadata_field(SupportedField::Type(campaign_type.into()))
1✔
149
                .build();
1✔
150
            provider.add_document(None, &doc).unwrap();
1✔
151
        }
1✔
152

153
        // Use Ref as a linked reference
154
        let rule = ParameterLinkRefRule::Specified {
1✔
155
            field: LinkField::Ref,
1✔
156
        };
1✔
157
        // Parameter must match
158
        let doc = Builder::new()
1✔
159
            .with_metadata_field(SupportedField::Ref(
1✔
160
                vec![DocumentRef::new(doc1_id, doc1_ver, DocLocator::default())].into(),
1✔
161
            ))
1✔
162
            .with_metadata_field(SupportedField::Parameters(
1✔
163
                vec![
1✔
164
                    DocumentRef::new(category_id, category_ver, DocLocator::default()),
1✔
165
                    DocumentRef::new(campaign_id, campaign_ver, DocLocator::default()),
1✔
166
                ]
1✔
167
                .into(),
1✔
168
            ))
1✔
169
            .build();
1✔
170
        assert!(rule.check(&doc, &provider).await.unwrap());
1✔
171

172
        // Parameter does not match
173
        let doc = Builder::new()
1✔
174
            .with_metadata_field(SupportedField::Ref(
1✔
175
                vec![DocumentRef::new(doc2_id, doc2_ver, DocLocator::default())].into(),
1✔
176
            ))
1✔
177
            .with_metadata_field(SupportedField::Parameters(
1✔
178
                vec![
1✔
179
                    DocumentRef::new(category_id, category_ver, DocLocator::default()),
1✔
180
                    DocumentRef::new(campaign_id, campaign_ver, DocLocator::default()),
1✔
181
                ]
1✔
182
                .into(),
1✔
183
            ))
1✔
184
            .build();
1✔
185
        assert!(!rule.check(&doc, &provider).await.unwrap());
1✔
186
    }
1✔
187
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc