ssi_vc/syntax/
presentation.rs

1use std::{borrow::Cow, hash::Hash};
2
3use rdf_types::VocabularyMut;
4use serde::{Deserialize, Serialize};
5use ssi_claims_core::{ClaimsValidity, ValidateClaims};
6use ssi_json_ld::{JsonLdError, JsonLdNodeObject, JsonLdObject, JsonLdTypes, Loader};
7use ssi_rdf::{Interpretation, LdEnvironment, LinkedDataResource, LinkedDataSubject, Vocabulary};
8
9use crate::{v1, v2};
10
11/// Any JSON presentation using VCDM v1 or v2.
12#[derive(Debug, Clone, Serialize, Deserialize)]
13#[serde(untagged)]
14pub enum AnyJsonPresentation<C1 = v1::syntax::JsonCredential, C2 = v2::syntax::JsonCredential> {
15    V1(v1::syntax::JsonPresentation<C1>),
16    V2(v2::syntax::JsonPresentation<C2>),
17}
18
19impl<C1, C2> JsonLdObject for AnyJsonPresentation<C1, C2> {
20    fn json_ld_context(&self) -> Option<Cow<ssi_json_ld::syntax::Context>> {
21        match self {
22            Self::V1(p) => p.json_ld_context(),
23            Self::V2(p) => p.json_ld_context(),
24        }
25    }
26}
27
28impl<C1, C2> JsonLdNodeObject for AnyJsonPresentation<C1, C2> {
29    fn json_ld_type(&self) -> JsonLdTypes {
30        match self {
31            Self::V1(p) => p.json_ld_type(),
32            Self::V2(p) => p.json_ld_type(),
33        }
34    }
35}
36
37impl<C1, C2, E, P> ValidateClaims<E, P> for AnyJsonPresentation<C1, C2> {
38    fn validate_claims(&self, env: &E, proof: &P) -> ClaimsValidity {
39        match self {
40            Self::V1(p) => p.validate_claims(env, proof),
41            Self::V2(p) => p.validate_claims(env, proof),
42        }
43    }
44}
45
46impl<C1, C2> ssi_json_ld::Expandable for AnyJsonPresentation<C1, C2>
47where
48    C1: Serialize,
49    C2: Serialize,
50{
51    type Error = JsonLdError;
52
53    type Expanded<I: Interpretation, V: Vocabulary>
54        = ssi_json_ld::ExpandedDocument<V::Iri, V::BlankId>
55    where
56        I: Interpretation,
57        V: VocabularyMut,
58        V::Iri: LinkedDataResource<I, V> + LinkedDataSubject<I, V>,
59        V::BlankId: LinkedDataResource<I, V> + LinkedDataSubject<I, V>;
60
61    #[allow(async_fn_in_trait)]
62    async fn expand_with<I, V>(
63        &self,
64        ld: &mut LdEnvironment<V, I>,
65        loader: &impl Loader,
66    ) -> Result<Self::Expanded<I, V>, Self::Error>
67    where
68        I: Interpretation,
69        V: VocabularyMut,
70        V::Iri: Clone + Eq + Hash + LinkedDataResource<I, V> + LinkedDataSubject<I, V>,
71        V::BlankId: Clone + Eq + Hash + LinkedDataResource<I, V> + LinkedDataSubject<I, V>,
72    {
73        let json = ssi_json_ld::CompactJsonLd(json_syntax::to_value(self).unwrap());
74        json.expand_with(ld, loader).await
75    }
76}