chaincodec_core/
schema.rs1use crate::event::EventFingerprint;
4use crate::types::CanonicalType;
5use serde::{Deserialize, Serialize};
6use std::collections::HashMap;
7
8#[derive(Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
10#[serde(rename_all = "snake_case")]
11pub enum TrustLevel {
12 #[default]
13 Unverified,
14 CommunityVerified,
15 MaintainerVerified,
16 ProtocolVerified,
17}
18
19impl std::fmt::Display for TrustLevel {
20 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
21 let s = match self {
22 TrustLevel::Unverified => "unverified",
23 TrustLevel::CommunityVerified => "community_verified",
24 TrustLevel::MaintainerVerified => "maintainer_verified",
25 TrustLevel::ProtocolVerified => "protocol_verified",
26 };
27 write!(f, "{s}")
28 }
29}
30
31#[derive(Debug, Clone, Serialize, Deserialize)]
33pub struct FieldDef {
34 pub ty: CanonicalType,
36 pub indexed: bool,
38 pub nullable: bool,
40 #[serde(skip_serializing_if = "Option::is_none")]
42 pub description: Option<String>,
43}
44
45#[derive(Debug, Clone, Default, Serialize, Deserialize)]
47pub struct SchemaMeta {
48 #[serde(skip_serializing_if = "Option::is_none")]
50 pub protocol: Option<String>,
51 #[serde(skip_serializing_if = "Option::is_none")]
53 pub category: Option<String>,
54 pub verified: bool,
56 pub trust_level: TrustLevel,
58 #[serde(skip_serializing_if = "Option::is_none")]
60 pub provenance_sig: Option<String>,
61}
62
63#[derive(Debug, Clone, Serialize, Deserialize)]
66pub struct Schema {
67 pub name: String,
69 pub version: u32,
71 pub chains: Vec<String>,
73 #[serde(skip_serializing_if = "Option::is_none")]
75 pub address: Option<Vec<String>>,
76 pub event: String,
78 pub fingerprint: EventFingerprint,
80 #[serde(skip_serializing_if = "Option::is_none")]
82 pub supersedes: Option<String>,
83 #[serde(skip_serializing_if = "Option::is_none")]
85 pub superseded_by: Option<String>,
86 pub deprecated: bool,
88 pub fields: Vec<(String, FieldDef)>,
90 pub meta: SchemaMeta,
92}
93
94impl Schema {
95 pub fn fields_map(&self) -> HashMap<&str, &FieldDef> {
97 self.fields.iter().map(|(k, v)| (k.as_str(), v)).collect()
98 }
99
100 pub fn indexed_fields(&self) -> Vec<(&str, &FieldDef)> {
102 self.fields
103 .iter()
104 .filter(|(_, f)| f.indexed)
105 .map(|(k, v)| (k.as_str(), v))
106 .collect()
107 }
108
109 pub fn data_fields(&self) -> Vec<(&str, &FieldDef)> {
111 self.fields
112 .iter()
113 .filter(|(_, f)| !f.indexed)
114 .map(|(k, v)| (k.as_str(), v))
115 .collect()
116 }
117}
118
119pub trait SchemaRegistry: Send + Sync {
122 fn get_by_fingerprint(&self, fp: &EventFingerprint) -> Option<Schema>;
124
125 fn get_by_name(&self, name: &str, version: Option<u32>) -> Option<Schema>;
128
129 fn list_for_chain(&self, chain_slug: &str) -> Vec<Schema>;
131
132 fn history(&self, name: &str) -> Vec<Schema>;
134}