type_bridge_contract/
schema_fingerprint.rs1use serde::Serialize;
4
5use crate::diagnostic::{Diagnostic, DiagnosticCategory};
6use crate::fingerprint::{
7 CanonicalizationVersion, Fingerprint, FingerprintDomain, SemanticProfileId,
8};
9
10const SCHEMA_CANONICALIZATION: &str = "typebridge.schema-canonical-json/v1";
11const SCHEMA_DOCUMENT_SET_CANONICALIZATION: &str = "typebridge.schema-document-set/v1";
12const MANAGED_DECLARED_CANONICALIZATION: &str = "typebridge.managed-declared/v1";
13const MANAGED_SEMANTIC_CANONICALIZATION: &str = "typebridge.managed-semantic/v1";
14
15#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
17#[serde(transparent)]
18pub struct SchemaDocumentSetFingerprint(Fingerprint);
19
20impl SchemaDocumentSetFingerprint {
21 pub fn compute(canonical_bytes: &[u8]) -> Result<Self, Diagnostic> {
23 Ok(Self(Fingerprint::compute(
24 FingerprintDomain::new("typebridge.schema.document-set")?,
25 CanonicalizationVersion::new(SCHEMA_DOCUMENT_SET_CANONICALIZATION)?,
26 None,
27 canonical_bytes,
28 )))
29 }
30
31 #[must_use]
33 pub const fn as_fingerprint(&self) -> &Fingerprint {
34 &self.0
35 }
36}
37
38#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
40#[serde(transparent)]
41pub struct SemanticSchemaFingerprint(Fingerprint);
42
43impl SemanticSchemaFingerprint {
44 pub fn compute(profile: SemanticProfileId, canonical_bytes: &[u8]) -> Result<Self, Diagnostic> {
46 Ok(Self(Fingerprint::compute(
47 FingerprintDomain::new("typebridge.schema.semantic")?,
48 CanonicalizationVersion::new(SCHEMA_CANONICALIZATION)?,
49 Some(profile),
50 canonical_bytes,
51 )))
52 }
53
54 #[must_use]
56 pub const fn as_fingerprint(&self) -> &Fingerprint {
57 &self.0
58 }
59}
60
61#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
63#[serde(transparent)]
64pub struct ManagedDeclaredIdentityFingerprint(Fingerprint);
65
66impl ManagedDeclaredIdentityFingerprint {
67 pub fn compute(canonical_bytes: &[u8]) -> Result<Self, Diagnostic> {
69 Ok(Self(Fingerprint::compute(
70 FingerprintDomain::new("typebridge.schema.managed-declared-identity")?,
71 CanonicalizationVersion::new(MANAGED_DECLARED_CANONICALIZATION)?,
72 None,
73 canonical_bytes,
74 )))
75 }
76
77 #[must_use]
79 pub const fn as_fingerprint(&self) -> &Fingerprint {
80 &self.0
81 }
82
83 pub(crate) fn from_wire(fingerprint: Fingerprint) -> Result<Self, Diagnostic> {
84 if fingerprint.domain().as_str() != "typebridge.schema.managed-declared-identity"
85 || fingerprint.canonicalization().as_str() != MANAGED_DECLARED_CANONICALIZATION
86 || fingerprint.semantic_profile().is_some()
87 {
88 return Err(Diagnostic::stable(
89 DiagnosticCategory::Integrity,
90 "invalid_managed_declared_identity_fingerprint",
91 "managed declared-identity fingerprint metadata is invalid",
92 ));
93 }
94 Ok(Self(fingerprint))
95 }
96}
97
98#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
100#[serde(transparent)]
101pub struct ManagedSemanticSchemaFingerprint(Fingerprint);
102
103impl ManagedSemanticSchemaFingerprint {
104 pub fn compute(profile: SemanticProfileId, canonical_bytes: &[u8]) -> Result<Self, Diagnostic> {
106 Ok(Self(Fingerprint::compute(
107 FingerprintDomain::new("typebridge.schema.managed-semantic")?,
108 CanonicalizationVersion::new(MANAGED_SEMANTIC_CANONICALIZATION)?,
109 Some(profile),
110 canonical_bytes,
111 )))
112 }
113
114 #[must_use]
116 pub const fn as_fingerprint(&self) -> &Fingerprint {
117 &self.0
118 }
119
120 pub(crate) fn from_wire(fingerprint: Fingerprint) -> Result<Self, Diagnostic> {
121 if fingerprint.domain().as_str() != "typebridge.schema.managed-semantic"
122 || fingerprint.canonicalization().as_str() != MANAGED_SEMANTIC_CANONICALIZATION
123 || fingerprint.semantic_profile().is_none()
124 {
125 return Err(Diagnostic::stable(
126 DiagnosticCategory::Integrity,
127 "invalid_managed_semantic_schema_fingerprint",
128 "managed semantic-schema fingerprint metadata is invalid",
129 ));
130 }
131 Ok(Self(fingerprint))
132 }
133}
134
135impl SemanticSchemaFingerprint {
136 pub(crate) fn from_wire(fingerprint: Fingerprint) -> Result<Self, Diagnostic> {
138 if fingerprint.domain().as_str() != "typebridge.schema.semantic"
139 || fingerprint.canonicalization().as_str() != SCHEMA_CANONICALIZATION
140 || fingerprint.semantic_profile().is_none()
141 {
142 return Err(crate::diagnostic::Diagnostic::stable(
143 crate::diagnostic::DiagnosticCategory::Integrity,
144 "invalid_semantic_schema_fingerprint",
145 "semantic schema fingerprint wire metadata is inconsistent",
146 ));
147 }
148 Ok(Self(fingerprint))
149 }
150}