ssi_data_integrity_core/
document.rs

1use std::{borrow::Cow, collections::BTreeMap, hash::Hash};
2
3use rdf_types::VocabularyMut;
4use serde::{Deserialize, Serialize};
5use ssi_claims_core::ValidateClaims;
6use ssi_core::OneOrMany;
7use ssi_json_ld::{JsonLdError, JsonLdNodeObject, JsonLdObject, Loader};
8use ssi_rdf::{Interpretation, LdEnvironment, LinkedDataResource, LinkedDataSubject, Vocabulary};
9
10/// Any Data-Integrity-compatible document.
11///
12/// The only assumption made by this type is that the JSON-LD `@type` attribute
13/// is aliased to `type`, which is common practice (for instance with
14/// Verifiable Credentials).
15///
16/// Note that this type represents an *unsecured* document.
17/// The type for any Data-Integrity-secured document (with the cryptosuite `S`)
18/// is [`DataIntegrity<DataIntegrityDocument, S>`](crate::DataIntegrity).
19#[derive(Debug, Clone, Serialize, Deserialize)]
20pub struct DataIntegrityDocument {
21    #[serde(rename = "@context", skip_serializing_if = "Option::is_none")]
22    pub context: Option<ssi_json_ld::syntax::Context>,
23
24    #[serde(
25        rename = "type",
26        alias = "@type",
27        default,
28        skip_serializing_if = "OneOrMany::is_empty"
29    )]
30    pub types: OneOrMany<String>,
31
32    #[serde(flatten)]
33    pub properties: BTreeMap<String, ssi_json_ld::syntax::Value>,
34}
35
36impl ssi_json_ld::Expandable for DataIntegrityDocument {
37    type Error = JsonLdError;
38
39    type Expanded<I: Interpretation, V: Vocabulary>
40        = ssi_json_ld::ExpandedDocument<V::Iri, V::BlankId>
41    where
42        I: Interpretation,
43        V: VocabularyMut,
44        V::Iri: LinkedDataResource<I, V> + LinkedDataSubject<I, V>,
45        V::BlankId: LinkedDataResource<I, V> + LinkedDataSubject<I, V>;
46
47    #[allow(async_fn_in_trait)]
48    async fn expand_with<I, V>(
49        &self,
50        ld: &mut LdEnvironment<V, I>,
51        loader: &impl Loader,
52    ) -> Result<Self::Expanded<I, V>, Self::Error>
53    where
54        I: Interpretation,
55        V: VocabularyMut,
56        V::Iri: Clone + Eq + Hash + LinkedDataResource<I, V> + LinkedDataSubject<I, V>,
57        V::BlankId: Clone + Eq + Hash + LinkedDataResource<I, V> + LinkedDataSubject<I, V>,
58    {
59        let json = ssi_json_ld::CompactJsonLd(json_syntax::to_value(self).unwrap());
60        json.expand_with(ld, loader).await
61    }
62}
63
64impl JsonLdObject for DataIntegrityDocument {
65    fn json_ld_context(&'_ self) -> Option<Cow<'_, ssi_json_ld::syntax::Context>> {
66        self.context.as_ref().map(Cow::Borrowed)
67    }
68}
69
70impl JsonLdNodeObject for DataIntegrityDocument {
71    fn json_ld_type(&'_ self) -> ssi_json_ld::JsonLdTypes<'_> {
72        ssi_json_ld::JsonLdTypes::new(&[], Cow::Borrowed(self.types.as_slice()))
73    }
74}
75
76impl<E, P> ValidateClaims<E, P> for DataIntegrityDocument {
77    fn validate_claims(&self, _env: &E, _proof: &P) -> ssi_claims_core::ClaimsValidity {
78        Ok(())
79    }
80}