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

input-output-hk / catalyst-libs / 20016983869

08 Dec 2025 04:45AM UTC coverage: 67.756% (-0.08%) from 67.835%
20016983869

push

github

web-flow
feat(rust/signed-doc): Catalyst Signed Documents extended validation capabilities  (#680)

* try

* make CatalystSignedDocumentProvider and CatalystIdProvider dyn compatible

* wip

* wip

* wip

* use async_trait

* fix

* fix

* fix

* fix

* fix

* added `extend_rules_per_document` fn

254 of 269 new or added lines in 27 files covered. (94.42%)

1 existing line in 1 file now uncovered.

13997 of 20658 relevant lines covered (67.76%)

2968.48 hits per line

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

58.7
/rust/signed_doc/src/validator/mod.rs
1
//! Catalyst Signed Documents validation logic
2

3
pub(crate) mod rules;
4

5
use std::{fmt::Debug, sync::LazyLock};
6

7
use dashmap::DashMap;
8
use futures::{StreamExt, TryStreamExt};
9

10
use crate::{
11
    CatalystSignedDocument,
12
    metadata::DocType,
13
    providers::{
14
        CatalystIdProvider, CatalystSignedDocumentAndCatalystIdProvider,
15
        CatalystSignedDocumentProvider,
16
    },
17
    validator::rules::documents_rules_from_spec,
18
};
19

20
/// `CatalystSignedDocument` validation rule trait
21
#[async_trait::async_trait]
22
pub trait CatalystSignedDocumentValidationRule: 'static + Send + Sync + Debug {
23
    /// Validates `CatalystSignedDocument`, return `false` if the provided
24
    /// `CatalystSignedDocument` violates some validation rules with properly filling the
25
    /// problem report.
26
    async fn check(
27
        &self,
28
        doc: &CatalystSignedDocument,
29
        provider: &dyn CatalystSignedDocumentAndCatalystIdProvider,
30
    ) -> anyhow::Result<bool>;
31
}
32

33
/// Struct represented a collection of rules
34
pub(crate) type Rules = Vec<Box<dyn CatalystSignedDocumentValidationRule>>;
35

36
/// A table representing a full set or validation rules per document id.
37
static DOCUMENT_RULES: LazyLock<DashMap<DocType, Rules>> = LazyLock::new(document_rules_init);
38

39
/// `DOCUMENT_RULES` initialization function
40
#[allow(clippy::expect_used)]
41
fn document_rules_init() -> DashMap<DocType, Rules> {
106✔
42
    let document_rules_map: DashMap<DocType, Rules> = documents_rules_from_spec()
106✔
43
        .expect("cannot fail to initialize validation rules")
106✔
44
        .collect();
106✔
45

46
    document_rules_map
106✔
47
}
106✔
48

49
/// A comprehensive document type based validation of the `CatalystSignedDocument`.
50
/// Includes time based validation of the `id` and `ver` fields based on the provided
51
/// `future_threshold` and `past_threshold` threshold values (in seconds).
52
/// Return true if it is valid, otherwise return false.
53
///
54
/// # Errors
55
/// If `provider` returns error, fails fast throwing that error.
56
pub async fn validate<Provider>(
105✔
57
    doc: &CatalystSignedDocument,
105✔
58
    provider: &Provider,
105✔
59
) -> anyhow::Result<bool>
105✔
60
where
105✔
61
    Provider: CatalystSignedDocumentProvider + CatalystIdProvider,
105✔
62
{
105✔
63
    let Ok(doc_type) = doc.doc_type() else {
105✔
64
        doc.report().missing_field(
×
65
            "type",
×
66
            "Can't get a document type during the validation process",
×
67
        );
68
        return Ok(false);
×
69
    };
70

71
    let Some(rules) = DOCUMENT_RULES.get(doc_type) else {
105✔
72
        doc.report().invalid_value(
×
73
            "`type`",
×
74
            &doc.doc_type()?.to_string(),
×
75
            "Must be a known document type value",
×
76
            "Unsupported document type",
×
77
        );
78
        return Ok(false);
×
79
    };
80

81
    let iter = rules.iter().map(|v| v.check(doc, provider));
1,575✔
82
    let res = futures::stream::iter(iter)
105✔
83
        .buffer_unordered(rules.len())
105✔
84
        .try_collect::<Vec<_>>()
105✔
85
        .await?
105✔
86
        .iter()
105✔
87
        .all(|res| *res);
105✔
88
    Ok(res)
105✔
89
}
105✔
90

91
/// Extend the current defined validation rules set for the provided document type.
NEW
92
pub fn extend_rules_per_document(
×
NEW
93
    doc_type: DocType,
×
NEW
94
    rule: impl CatalystSignedDocumentValidationRule,
×
NEW
95
) {
×
NEW
96
    DOCUMENT_RULES
×
NEW
97
        .entry(doc_type)
×
NEW
98
        .or_default()
×
NEW
99
        .push(Box::new(rule));
×
UNCOV
100
}
×
101

102
#[cfg(test)]
103
mod tests {
104
    use crate::validator::document_rules_init;
105

106
    #[test]
107
    fn document_rules_init_test() {
1✔
108
        document_rules_init();
1✔
109
    }
1✔
110
}
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