From c72cd65c2b640b31afa74d427ca447a77edcfad4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Haudebourg?= Date: Wed, 10 Jul 2024 16:49:40 +0200 Subject: [PATCH 1/3] Add credential type parameters. --- .../crates/vc/src/v1/syntax/credential.rs | 242 +++++++++++++++--- .../crates/vc/src/v2/syntax/credential.rs | 242 +++++++++++++++--- 2 files changed, 418 insertions(+), 66 deletions(-) diff --git a/crates/claims/crates/vc/src/v1/syntax/credential.rs b/crates/claims/crates/vc/src/v1/syntax/credential.rs index d8e2ce4bd..45f3c343e 100644 --- a/crates/claims/crates/vc/src/v1/syntax/credential.rs +++ b/crates/claims/crates/vc/src/v1/syntax/credential.rs @@ -8,10 +8,13 @@ use ssi_rdf::{Interpretation, LdEnvironment}; use std::{borrow::Cow, collections::BTreeMap, hash::Hash}; use xsd_types::DateTime; -use crate::syntax::{ - not_null, value_or_array, IdOr, IdentifiedObject, IdentifiedTypedObject, - MaybeIdentifiedTypedObject, RequiredContextList, RequiredType, RequiredTypeSet, - TypeSerializationPolicy, Types, +use crate::{ + syntax::{ + not_null, value_or_array, IdOr, IdentifiedObject, IdentifiedTypedObject, + MaybeIdentifiedTypedObject, RequiredContextList, RequiredType, RequiredTypeSet, + TypeSerializationPolicy, Types, + }, + Identified, MaybeIdentified, Typed, }; use super::Context; @@ -42,13 +45,23 @@ pub type JsonCredential = SpecializedJsonCredential; /// [`JsonCredential`] type alias instead. #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(bound( - serialize = "S: Serialize", - deserialize = "S: Deserialize<'de>, C: RequiredContextList, T: RequiredTypeSet" + serialize = "Subject: Serialize, Issuer: Serialize, Status: Serialize, Evidence: Serialize, Schema: Serialize, RefreshService: Serialize, TermsOfUse: Serialize", + deserialize = "Subject: Deserialize<'de>, RequiredContext: RequiredContextList, RequiredType: RequiredTypeSet, Issuer: Deserialize<'de>, Status: Deserialize<'de>, Evidence: Deserialize<'de>, Schema: Deserialize<'de>, RefreshService: Deserialize<'de>, TermsOfUse: Deserialize<'de>" ))] -pub struct SpecializedJsonCredential { +pub struct SpecializedJsonCredential< + Subject = json_syntax::Object, + RequiredContext = (), + RequiredType = (), + Issuer = IdOr, + Status = IdentifiedTypedObject, + Evidence = MaybeIdentifiedTypedObject, + Schema = IdentifiedTypedObject, + RefreshService = IdentifiedTypedObject, + TermsOfUse = MaybeIdentifiedTypedObject, +> { /// JSON-LD context. #[serde(rename = "@context")] - pub context: Context, + pub context: Context, /// Credential identifier. #[serde( @@ -60,7 +73,7 @@ pub struct SpecializedJsonCredential { /// Credential type. #[serde(rename = "type")] - pub types: JsonCredentialTypes, + pub types: JsonCredentialTypes, /// Credential subjects. #[serde(rename = "credentialSubject")] @@ -69,10 +82,10 @@ pub struct SpecializedJsonCredential { default, skip_serializing_if = "Vec::is_empty" )] - pub credential_subjects: Vec, + pub credential_subjects: Vec, /// Issuer. - pub issuer: IdOr, + pub issuer: Issuer, /// Issuance date. /// @@ -92,7 +105,7 @@ pub struct SpecializedJsonCredential { default, skip_serializing_if = "Vec::is_empty" )] - pub credential_status: Vec, + pub credential_status: Vec, /// Terms of use. #[serde(rename = "termsOfUse")] @@ -101,7 +114,7 @@ pub struct SpecializedJsonCredential { default, skip_serializing_if = "Vec::is_empty" )] - pub terms_of_use: Vec, + pub terms_of_use: Vec, /// Evidence. #[serde( @@ -109,7 +122,7 @@ pub struct SpecializedJsonCredential { default, skip_serializing_if = "Vec::is_empty" )] - pub evidence: Vec, + pub evidence: Vec, #[serde(rename = "credentialSchema")] #[serde( @@ -117,7 +130,7 @@ pub struct SpecializedJsonCredential { default, skip_serializing_if = "Vec::is_empty" )] - pub credential_schema: Vec, + pub credential_schema: Vec, #[serde(rename = "refreshService")] #[serde( @@ -125,19 +138,44 @@ pub struct SpecializedJsonCredential { default, skip_serializing_if = "Vec::is_empty" )] - pub refresh_services: Vec, + pub refresh_services: Vec, #[serde(flatten)] pub additional_properties: BTreeMap, } -impl SpecializedJsonCredential { +impl< + Subject, + RequiredContext, + RequiredType, + Issuer, + Status, + Evidence, + Schema, + RefreshService, + TermsOfUse, + > + SpecializedJsonCredential< + Subject, + RequiredContext, + RequiredType, + Issuer, + Status, + Evidence, + Schema, + RefreshService, + TermsOfUse, + > +where + RequiredContext: RequiredContextList, + RequiredType: RequiredTypeSet, +{ /// Creates a new credential. pub fn new( id: Option, - issuer: IdOr, + issuer: Issuer, issuance_date: xsd_types::DateTime, - credential_subjects: Vec, + credential_subjects: Vec, ) -> Self { Self { context: Context::default(), @@ -157,19 +195,86 @@ impl SpecializedJsonCredential JsonLdObject for SpecializedJsonCredential { +impl< + Subject, + RequiredContext, + RequiredType, + Issuer, + Status, + Evidence, + Schema, + RefreshService, + TermsOfUse, + > JsonLdObject + for SpecializedJsonCredential< + Subject, + RequiredContext, + RequiredType, + Issuer, + Status, + Evidence, + Schema, + RefreshService, + TermsOfUse, + > +{ fn json_ld_context(&self) -> Option> { Some(Cow::Borrowed(self.context.as_ref())) } } -impl JsonLdNodeObject for SpecializedJsonCredential { +impl< + Subject, + RequiredContext, + RequiredType, + Issuer, + Status, + Evidence, + Schema, + RefreshService, + TermsOfUse, + > JsonLdNodeObject + for SpecializedJsonCredential< + Subject, + RequiredContext, + RequiredType, + Issuer, + Status, + Evidence, + Schema, + RefreshService, + TermsOfUse, + > +{ fn json_ld_type(&self) -> JsonLdTypes { self.types.to_json_ld_types() } } -impl ValidateClaims for SpecializedJsonCredential +impl< + Subject, + RequiredContext, + RequiredType, + Issuer: Identified, + Status: Identified + Typed, + Evidence: MaybeIdentified + Typed, + Schema: Identified + Typed, + RefreshService: Identified + Typed, + TermsOfUse: MaybeIdentified + Typed, + E, + P, + > ValidateClaims + for SpecializedJsonCredential< + Subject, + RequiredContext, + RequiredType, + Issuer, + Status, + Evidence, + Schema, + RefreshService, + TermsOfUse, + > where E: DateTimeProvider, { @@ -178,20 +283,64 @@ where } } -impl crate::MaybeIdentified for SpecializedJsonCredential { +impl< + Subject, + RequiredContext, + RequiredType, + Issuer, + Status, + Evidence, + Schema, + RefreshService, + TermsOfUse, + > crate::MaybeIdentified + for SpecializedJsonCredential< + Subject, + RequiredContext, + RequiredType, + Issuer, + Status, + Evidence, + Schema, + RefreshService, + TermsOfUse, + > +{ fn id(&self) -> Option<&Uri> { self.id.as_deref() } } -impl crate::v1::Credential for SpecializedJsonCredential { - type Subject = S; - type Issuer = IdOr; - type Status = IdentifiedTypedObject; - type RefreshService = IdentifiedTypedObject; - type TermsOfUse = MaybeIdentifiedTypedObject; - type Evidence = MaybeIdentifiedTypedObject; - type Schema = IdentifiedTypedObject; +impl< + Subject, + RequiredContext, + RequiredType, + Issuer: Identified, + Status: Identified + Typed, + Evidence: MaybeIdentified + Typed, + Schema: Identified + Typed, + RefreshService: Identified + Typed, + TermsOfUse: MaybeIdentified + Typed, + > crate::v1::Credential + for SpecializedJsonCredential< + Subject, + RequiredContext, + RequiredType, + Issuer, + Status, + Evidence, + Schema, + RefreshService, + TermsOfUse, + > +{ + type Subject = Subject; + type Issuer = Issuer; + type Status = Status; + type RefreshService = RefreshService; + type TermsOfUse = TermsOfUse; + type Evidence = Evidence; + type Schema = Schema; fn id(&self) -> Option<&Uri> { self.id.as_deref() @@ -238,9 +387,36 @@ impl crate::v1::Credential for SpecializedJsonCredential { } } -impl ssi_json_ld::Expandable for SpecializedJsonCredential +impl< + Subject, + RequiredContext, + RequiredType, + Issuer, + Status, + Evidence, + Schema, + RefreshService, + TermsOfUse, + > ssi_json_ld::Expandable + for SpecializedJsonCredential< + Subject, + RequiredContext, + RequiredType, + Issuer, + Status, + Evidence, + Schema, + RefreshService, + TermsOfUse, + > where - S: Serialize, + Subject: Serialize, + Issuer: Serialize, + Status: Serialize, + Evidence: Serialize, + Schema: Serialize, + RefreshService: Serialize, + TermsOfUse: Serialize, { type Error = JsonLdError; diff --git a/crates/claims/crates/vc/src/v2/syntax/credential.rs b/crates/claims/crates/vc/src/v2/syntax/credential.rs index eda771e68..35b9e8d10 100644 --- a/crates/claims/crates/vc/src/v2/syntax/credential.rs +++ b/crates/claims/crates/vc/src/v2/syntax/credential.rs @@ -1,10 +1,13 @@ use std::{borrow::Cow, collections::BTreeMap, hash::Hash}; use super::{Context, InternationalString, RelatedResource}; -use crate::syntax::{ - non_empty_value_or_array, not_null, value_or_array, IdOr, IdentifiedObject, - IdentifiedTypedObject, MaybeIdentifiedTypedObject, NonEmptyObject, NonEmptyVec, - RequiredContextList, RequiredTypeSet, TypedObject, +use crate::{ + syntax::{ + non_empty_value_or_array, not_null, value_or_array, IdOr, IdentifiedObject, + IdentifiedTypedObject, MaybeIdentifiedTypedObject, NonEmptyObject, NonEmptyVec, + RequiredContextList, RequiredTypeSet, TypedObject, + }, + Identified, MaybeIdentified, Typed, }; use iref::{Uri, UriBuf}; use rdf_types::VocabularyMut; @@ -28,13 +31,23 @@ pub type JsonCredential = SpecializedJsonCredential; /// [`JsonCredential`] type alias instead. #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(bound( - serialize = "S: Serialize", - deserialize = "S: Deserialize<'de>, C: RequiredContextList, T: RequiredTypeSet" + serialize = "Subject: Serialize, Issuer: Serialize, Status: Serialize, Evidence: Serialize, Schema: Serialize, RefreshService: Serialize, TermsOfUse: Serialize", + deserialize = "Subject: Deserialize<'de>, RequiredContext: RequiredContextList, RequiredType: RequiredTypeSet, Issuer: Deserialize<'de>, Status: Deserialize<'de>, Evidence: Deserialize<'de>, Schema: Deserialize<'de>, RefreshService: Deserialize<'de>, TermsOfUse: Deserialize<'de>" ))] -pub struct SpecializedJsonCredential { +pub struct SpecializedJsonCredential< + Subject = NonEmptyObject, + RequiredContext = (), + RequiredType = (), + Issuer = IdOr, + Status = MaybeIdentifiedTypedObject, + Evidence = MaybeIdentifiedTypedObject, + Schema = IdentifiedTypedObject, + RefreshService = TypedObject, + TermsOfUse = MaybeIdentifiedTypedObject, +> { /// JSON-LD context. #[serde(rename = "@context")] - pub context: Context, + pub context: Context, /// Credential identifier. #[serde( @@ -46,15 +59,15 @@ pub struct SpecializedJsonCredential { /// Credential type. #[serde(rename = "type")] - pub types: JsonCredentialTypes, + pub types: JsonCredentialTypes, /// Credential subjects. #[serde(rename = "credentialSubject")] #[serde(with = "non_empty_value_or_array")] - pub credential_subjects: NonEmptyVec, + pub credential_subjects: NonEmptyVec, /// Issuer. - pub issuer: IdOr, + pub issuer: Issuer, /// Issuance date. #[serde(rename = "validFrom")] @@ -73,7 +86,7 @@ pub struct SpecializedJsonCredential { default, skip_serializing_if = "Vec::is_empty" )] - pub credential_status: Vec, + pub credential_status: Vec, /// Terms of use. #[serde(rename = "termsOfUse")] @@ -82,7 +95,7 @@ pub struct SpecializedJsonCredential { default, skip_serializing_if = "Vec::is_empty" )] - pub terms_of_use: Vec, + pub terms_of_use: Vec, /// Evidence. #[serde( @@ -90,7 +103,7 @@ pub struct SpecializedJsonCredential { default, skip_serializing_if = "Vec::is_empty" )] - pub evidence: Vec, + pub evidence: Vec, #[serde(rename = "credentialSchema")] #[serde( @@ -98,7 +111,7 @@ pub struct SpecializedJsonCredential { default, skip_serializing_if = "Vec::is_empty" )] - pub credential_schema: Vec, + pub credential_schema: Vec, #[serde(rename = "refreshService")] #[serde( @@ -106,18 +119,43 @@ pub struct SpecializedJsonCredential { default, skip_serializing_if = "Vec::is_empty" )] - pub refresh_services: Vec, + pub refresh_services: Vec, #[serde(flatten)] pub extra_properties: BTreeMap, } -impl SpecializedJsonCredential { +impl< + Subject, + RequiredContext, + RequiredType, + Issuer, + Status, + Evidence, + Schema, + RefreshService, + TermsOfUse, + > + SpecializedJsonCredential< + Subject, + RequiredContext, + RequiredType, + Issuer, + Status, + Evidence, + Schema, + RefreshService, + TermsOfUse, + > +where + RequiredContext: RequiredContextList, + RequiredType: RequiredTypeSet, +{ /// Creates a new credential. pub fn new( id: Option, - issuer: IdOr, - credential_subjects: NonEmptyVec, + issuer: Issuer, + credential_subjects: NonEmptyVec, ) -> Self { Self { context: Context::default(), @@ -137,19 +175,86 @@ impl SpecializedJsonCredential JsonLdObject for SpecializedJsonCredential { +impl< + Subject, + RequiredContext, + RequiredType, + Issuer, + Status, + Evidence, + Schema, + RefreshService, + TermsOfUse, + > JsonLdObject + for SpecializedJsonCredential< + Subject, + RequiredContext, + RequiredType, + Issuer, + Status, + Evidence, + Schema, + RefreshService, + TermsOfUse, + > +{ fn json_ld_context(&self) -> Option> { Some(Cow::Borrowed(self.context.as_ref())) } } -impl JsonLdNodeObject for SpecializedJsonCredential { +impl< + Subject, + RequiredContext, + RequiredType, + Issuer, + Status, + Evidence, + Schema, + RefreshService, + TermsOfUse, + > JsonLdNodeObject + for SpecializedJsonCredential< + Subject, + RequiredContext, + RequiredType, + Issuer, + Status, + Evidence, + Schema, + RefreshService, + TermsOfUse, + > +{ fn json_ld_type(&self) -> JsonLdTypes { self.types.to_json_ld_types() } } -impl ValidateClaims for SpecializedJsonCredential +impl< + Subject, + RequiredContext, + RequiredType, + Issuer: Identified, + Status: MaybeIdentified + Typed, + Evidence: MaybeIdentified + Typed, + Schema: Identified + Typed, + RefreshService: Typed, + TermsOfUse: MaybeIdentified + Typed, + E, + P, + > ValidateClaims + for SpecializedJsonCredential< + Subject, + RequiredContext, + RequiredType, + Issuer, + Status, + Evidence, + Schema, + RefreshService, + TermsOfUse, + > where E: DateTimeProvider, { @@ -158,21 +263,65 @@ where } } -impl crate::MaybeIdentified for SpecializedJsonCredential { +impl< + Subject, + RequiredContext, + RequiredType, + Issuer, + Status, + Evidence, + Schema, + RefreshService, + TermsOfUse, + > crate::MaybeIdentified + for SpecializedJsonCredential< + Subject, + RequiredContext, + RequiredType, + Issuer, + Status, + Evidence, + Schema, + RefreshService, + TermsOfUse, + > +{ fn id(&self) -> Option<&Uri> { self.id.as_deref() } } -impl crate::v2::Credential for SpecializedJsonCredential { - type Subject = S; +impl< + Subject, + RequiredContext, + RequiredType, + Issuer: Identified, + Status: MaybeIdentified + Typed, + Evidence: MaybeIdentified + Typed, + Schema: Identified + Typed, + RefreshService: Typed, + TermsOfUse: MaybeIdentified + Typed, + > crate::v2::Credential + for SpecializedJsonCredential< + Subject, + RequiredContext, + RequiredType, + Issuer, + Status, + Evidence, + Schema, + RefreshService, + TermsOfUse, + > +{ + type Subject = Subject; type Description = InternationalString; - type Issuer = IdOr; - type Status = MaybeIdentifiedTypedObject; - type RefreshService = TypedObject; - type TermsOfUse = MaybeIdentifiedTypedObject; - type Evidence = MaybeIdentifiedTypedObject; - type Schema = IdentifiedTypedObject; + type Issuer = Issuer; + type Status = Status; + type RefreshService = RefreshService; + type TermsOfUse = TermsOfUse; + type Evidence = Evidence; + type Schema = Schema; type RelatedResource = RelatedResource; fn additional_types(&self) -> &[String] { @@ -216,9 +365,36 @@ impl crate::v2::Credential for SpecializedJsonCredential { } } -impl ssi_json_ld::Expandable for SpecializedJsonCredential +impl< + Subject, + RequiredContext, + RequiredType, + Issuer, + Status, + Evidence, + Schema, + RefreshService, + TermsOfUse, + > ssi_json_ld::Expandable + for SpecializedJsonCredential< + Subject, + RequiredContext, + RequiredType, + Issuer, + Status, + Evidence, + Schema, + RefreshService, + TermsOfUse, + > where - S: Serialize, + Subject: Serialize, + Issuer: Serialize, + Status: Serialize, + Evidence: Serialize, + Schema: Serialize, + RefreshService: Serialize, + TermsOfUse: Serialize, { type Error = JsonLdError; From dc5bbf4461c715e9e08942f8c1466420f4f1fa1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Haudebourg?= Date: Wed, 10 Jul 2024 16:59:43 +0200 Subject: [PATCH 2/3] Update doc. --- crates/claims/crates/vc/src/v1/syntax/credential.rs | 9 +++++---- crates/claims/crates/vc/src/v2/syntax/credential.rs | 9 +++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/crates/claims/crates/vc/src/v1/syntax/credential.rs b/crates/claims/crates/vc/src/v1/syntax/credential.rs index 45f3c343e..02182ed2a 100644 --- a/crates/claims/crates/vc/src/v1/syntax/credential.rs +++ b/crates/claims/crates/vc/src/v1/syntax/credential.rs @@ -35,13 +35,14 @@ pub type JsonCredentialTypes = Types; /// JSON Credential, without required context nor type. /// -/// If you care about required context and/or type, use the -/// [`SpecializedJsonCredential`] type directly. +/// If you care about required context and/or type, or want to customize other +/// aspects of the credential, use the [`SpecializedJsonCredential`] type +/// directly. pub type JsonCredential = SpecializedJsonCredential; -/// Specialized JSON Credential with custom required context and type. +/// Specialized JSON Credential with custom types for each component. /// -/// If you don't care about required context and/or type, you can use the +/// If you don't care about the type of each component, you can use the /// [`JsonCredential`] type alias instead. #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(bound( diff --git a/crates/claims/crates/vc/src/v2/syntax/credential.rs b/crates/claims/crates/vc/src/v2/syntax/credential.rs index 35b9e8d10..3e0fb1f96 100644 --- a/crates/claims/crates/vc/src/v2/syntax/credential.rs +++ b/crates/claims/crates/vc/src/v2/syntax/credential.rs @@ -21,13 +21,14 @@ pub use crate::v1::syntax::{CredentialType, JsonCredentialTypes, VERIFIABLE_CRED /// JSON Credential, without required context nor type. /// -/// If you care about required context and/or type, use the -/// [`SpecializedJsonCredential`] type directly. +/// If you care about required context and/or type, or want to customize other +/// aspects of the credential, use the [`SpecializedJsonCredential`] type +/// directly. pub type JsonCredential = SpecializedJsonCredential; -/// Specialized JSON Credential with custom required context and type. +/// Specialized JSON Credential with custom types for each component. /// -/// If you don't care about required context and/or type, you can use the +/// If you don't care about the type of each component, you can use the /// [`JsonCredential`] type alias instead. #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(bound( From 1512c686d90caa38b5edc7734de9c30001daffa3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Haudebourg?= Date: Thu, 11 Jul 2024 11:09:02 +0200 Subject: [PATCH 3/3] Add a type parameter for credential extra properties. --- .../crates/vc/src/v1/syntax/credential.rs | 25 ++++++++++++++++--- .../crates/vc/src/v2/syntax/credential.rs | 25 ++++++++++++++++--- 2 files changed, 42 insertions(+), 8 deletions(-) diff --git a/crates/claims/crates/vc/src/v1/syntax/credential.rs b/crates/claims/crates/vc/src/v1/syntax/credential.rs index 02182ed2a..9dcb6e5ac 100644 --- a/crates/claims/crates/vc/src/v1/syntax/credential.rs +++ b/crates/claims/crates/vc/src/v1/syntax/credential.rs @@ -46,8 +46,8 @@ pub type JsonCredential = SpecializedJsonCredential; /// [`JsonCredential`] type alias instead. #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(bound( - serialize = "Subject: Serialize, Issuer: Serialize, Status: Serialize, Evidence: Serialize, Schema: Serialize, RefreshService: Serialize, TermsOfUse: Serialize", - deserialize = "Subject: Deserialize<'de>, RequiredContext: RequiredContextList, RequiredType: RequiredTypeSet, Issuer: Deserialize<'de>, Status: Deserialize<'de>, Evidence: Deserialize<'de>, Schema: Deserialize<'de>, RefreshService: Deserialize<'de>, TermsOfUse: Deserialize<'de>" + serialize = "Subject: Serialize, Issuer: Serialize, Status: Serialize, Evidence: Serialize, Schema: Serialize, RefreshService: Serialize, TermsOfUse: Serialize, ExtraProperties: Serialize", + deserialize = "Subject: Deserialize<'de>, RequiredContext: RequiredContextList, RequiredType: RequiredTypeSet, Issuer: Deserialize<'de>, Status: Deserialize<'de>, Evidence: Deserialize<'de>, Schema: Deserialize<'de>, RefreshService: Deserialize<'de>, TermsOfUse: Deserialize<'de>, ExtraProperties: Deserialize<'de>" ))] pub struct SpecializedJsonCredential< Subject = json_syntax::Object, @@ -59,6 +59,7 @@ pub struct SpecializedJsonCredential< Schema = IdentifiedTypedObject, RefreshService = IdentifiedTypedObject, TermsOfUse = MaybeIdentifiedTypedObject, + ExtraProperties = BTreeMap, > { /// JSON-LD context. #[serde(rename = "@context")] @@ -142,7 +143,7 @@ pub struct SpecializedJsonCredential< pub refresh_services: Vec, #[serde(flatten)] - pub additional_properties: BTreeMap, + pub additional_properties: ExtraProperties, } impl< @@ -155,6 +156,7 @@ impl< Schema, RefreshService, TermsOfUse, + ExtraProperties, > SpecializedJsonCredential< Subject, @@ -166,10 +168,12 @@ impl< Schema, RefreshService, TermsOfUse, + ExtraProperties, > where RequiredContext: RequiredContextList, RequiredType: RequiredTypeSet, + ExtraProperties: Default, { /// Creates a new credential. pub fn new( @@ -191,7 +195,7 @@ where evidence: Vec::new(), credential_schema: Vec::new(), refresh_services: Vec::new(), - additional_properties: BTreeMap::new(), + additional_properties: ExtraProperties::default(), } } } @@ -206,6 +210,7 @@ impl< Schema, RefreshService, TermsOfUse, + ExtraProperties, > JsonLdObject for SpecializedJsonCredential< Subject, @@ -217,6 +222,7 @@ impl< Schema, RefreshService, TermsOfUse, + ExtraProperties, > { fn json_ld_context(&self) -> Option> { @@ -234,6 +240,7 @@ impl< Schema, RefreshService, TermsOfUse, + ExtraProperties, > JsonLdNodeObject for SpecializedJsonCredential< Subject, @@ -245,6 +252,7 @@ impl< Schema, RefreshService, TermsOfUse, + ExtraProperties, > { fn json_ld_type(&self) -> JsonLdTypes { @@ -262,6 +270,7 @@ impl< Schema: Identified + Typed, RefreshService: Identified + Typed, TermsOfUse: MaybeIdentified + Typed, + ExtraProperties, E, P, > ValidateClaims @@ -275,6 +284,7 @@ impl< Schema, RefreshService, TermsOfUse, + ExtraProperties, > where E: DateTimeProvider, @@ -294,6 +304,7 @@ impl< Schema, RefreshService, TermsOfUse, + ExtraProperties, > crate::MaybeIdentified for SpecializedJsonCredential< Subject, @@ -305,6 +316,7 @@ impl< Schema, RefreshService, TermsOfUse, + ExtraProperties, > { fn id(&self) -> Option<&Uri> { @@ -322,6 +334,7 @@ impl< Schema: Identified + Typed, RefreshService: Identified + Typed, TermsOfUse: MaybeIdentified + Typed, + ExtraProperties, > crate::v1::Credential for SpecializedJsonCredential< Subject, @@ -333,6 +346,7 @@ impl< Schema, RefreshService, TermsOfUse, + ExtraProperties, > { type Subject = Subject; @@ -398,6 +412,7 @@ impl< Schema, RefreshService, TermsOfUse, + ExtraProperties, > ssi_json_ld::Expandable for SpecializedJsonCredential< Subject, @@ -409,6 +424,7 @@ impl< Schema, RefreshService, TermsOfUse, + ExtraProperties, > where Subject: Serialize, @@ -418,6 +434,7 @@ where Schema: Serialize, RefreshService: Serialize, TermsOfUse: Serialize, + ExtraProperties: Serialize, { type Error = JsonLdError; diff --git a/crates/claims/crates/vc/src/v2/syntax/credential.rs b/crates/claims/crates/vc/src/v2/syntax/credential.rs index 3e0fb1f96..559b6c973 100644 --- a/crates/claims/crates/vc/src/v2/syntax/credential.rs +++ b/crates/claims/crates/vc/src/v2/syntax/credential.rs @@ -32,8 +32,8 @@ pub type JsonCredential = SpecializedJsonCredential; /// [`JsonCredential`] type alias instead. #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(bound( - serialize = "Subject: Serialize, Issuer: Serialize, Status: Serialize, Evidence: Serialize, Schema: Serialize, RefreshService: Serialize, TermsOfUse: Serialize", - deserialize = "Subject: Deserialize<'de>, RequiredContext: RequiredContextList, RequiredType: RequiredTypeSet, Issuer: Deserialize<'de>, Status: Deserialize<'de>, Evidence: Deserialize<'de>, Schema: Deserialize<'de>, RefreshService: Deserialize<'de>, TermsOfUse: Deserialize<'de>" + serialize = "Subject: Serialize, Issuer: Serialize, Status: Serialize, Evidence: Serialize, Schema: Serialize, RefreshService: Serialize, TermsOfUse: Serialize, ExtraProperties: Serialize", + deserialize = "Subject: Deserialize<'de>, RequiredContext: RequiredContextList, RequiredType: RequiredTypeSet, Issuer: Deserialize<'de>, Status: Deserialize<'de>, Evidence: Deserialize<'de>, Schema: Deserialize<'de>, RefreshService: Deserialize<'de>, TermsOfUse: Deserialize<'de>, ExtraProperties: Deserialize<'de>" ))] pub struct SpecializedJsonCredential< Subject = NonEmptyObject, @@ -45,6 +45,7 @@ pub struct SpecializedJsonCredential< Schema = IdentifiedTypedObject, RefreshService = TypedObject, TermsOfUse = MaybeIdentifiedTypedObject, + ExtraProperties = BTreeMap, > { /// JSON-LD context. #[serde(rename = "@context")] @@ -123,7 +124,7 @@ pub struct SpecializedJsonCredential< pub refresh_services: Vec, #[serde(flatten)] - pub extra_properties: BTreeMap, + pub extra_properties: ExtraProperties, } impl< @@ -136,6 +137,7 @@ impl< Schema, RefreshService, TermsOfUse, + ExtraProperties, > SpecializedJsonCredential< Subject, @@ -147,10 +149,12 @@ impl< Schema, RefreshService, TermsOfUse, + ExtraProperties, > where RequiredContext: RequiredContextList, RequiredType: RequiredTypeSet, + ExtraProperties: Default, { /// Creates a new credential. pub fn new( @@ -171,7 +175,7 @@ where evidence: Vec::new(), credential_schema: Vec::new(), refresh_services: Vec::new(), - extra_properties: BTreeMap::new(), + extra_properties: ExtraProperties::default(), } } } @@ -186,6 +190,7 @@ impl< Schema, RefreshService, TermsOfUse, + ExtraProperties, > JsonLdObject for SpecializedJsonCredential< Subject, @@ -197,6 +202,7 @@ impl< Schema, RefreshService, TermsOfUse, + ExtraProperties, > { fn json_ld_context(&self) -> Option> { @@ -214,6 +220,7 @@ impl< Schema, RefreshService, TermsOfUse, + ExtraProperties, > JsonLdNodeObject for SpecializedJsonCredential< Subject, @@ -225,6 +232,7 @@ impl< Schema, RefreshService, TermsOfUse, + ExtraProperties, > { fn json_ld_type(&self) -> JsonLdTypes { @@ -242,6 +250,7 @@ impl< Schema: Identified + Typed, RefreshService: Typed, TermsOfUse: MaybeIdentified + Typed, + ExtraProperties, E, P, > ValidateClaims @@ -255,6 +264,7 @@ impl< Schema, RefreshService, TermsOfUse, + ExtraProperties, > where E: DateTimeProvider, @@ -274,6 +284,7 @@ impl< Schema, RefreshService, TermsOfUse, + ExtraProperties, > crate::MaybeIdentified for SpecializedJsonCredential< Subject, @@ -285,6 +296,7 @@ impl< Schema, RefreshService, TermsOfUse, + ExtraProperties, > { fn id(&self) -> Option<&Uri> { @@ -302,6 +314,7 @@ impl< Schema: Identified + Typed, RefreshService: Typed, TermsOfUse: MaybeIdentified + Typed, + ExtraProperties, > crate::v2::Credential for SpecializedJsonCredential< Subject, @@ -313,6 +326,7 @@ impl< Schema, RefreshService, TermsOfUse, + ExtraProperties, > { type Subject = Subject; @@ -376,6 +390,7 @@ impl< Schema, RefreshService, TermsOfUse, + ExtraProperties, > ssi_json_ld::Expandable for SpecializedJsonCredential< Subject, @@ -387,6 +402,7 @@ impl< Schema, RefreshService, TermsOfUse, + ExtraProperties, > where Subject: Serialize, @@ -396,6 +412,7 @@ where Schema: Serialize, RefreshService: Serialize, TermsOfUse: Serialize, + ExtraProperties: Serialize, { type Error = JsonLdError;