chaincodec_core/
schema.rs1use crate::chain::ChainId;
4use crate::event::EventFingerprint;
5use crate::types::CanonicalType;
6use serde::{Deserialize, Serialize};
7use std::collections::HashMap;
8
9#[derive(Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
11#[serde(rename_all = "snake_case")]
12pub enum TrustLevel {
13 #[default]
14 Unverified,
15 CommunityVerified,
16 MaintainerVerified,
17 ProtocolVerified,
18}
19
20impl std::fmt::Display for TrustLevel {
21 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
22 let s = match self {
23 TrustLevel::Unverified => "unverified",
24 TrustLevel::CommunityVerified => "community_verified",
25 TrustLevel::MaintainerVerified => "maintainer_verified",
26 TrustLevel::ProtocolVerified => "protocol_verified",
27 };
28 write!(f, "{s}")
29 }
30}
31
32#[derive(Debug, Clone, Serialize, Deserialize)]
34pub struct FieldDef {
35 pub ty: CanonicalType,
37 pub indexed: bool,
39 pub nullable: bool,
41 #[serde(skip_serializing_if = "Option::is_none")]
43 pub description: Option<String>,
44}
45
46#[derive(Debug, Clone, Default, Serialize, Deserialize)]
48pub struct SchemaMeta {
49 #[serde(skip_serializing_if = "Option::is_none")]
51 pub protocol: Option<String>,
52 #[serde(skip_serializing_if = "Option::is_none")]
54 pub category: Option<String>,
55 pub verified: bool,
57 pub trust_level: TrustLevel,
59 #[serde(skip_serializing_if = "Option::is_none")]
61 pub provenance_sig: Option<String>,
62}
63
64#[derive(Debug, Clone, Serialize, Deserialize)]
67pub struct Schema {
68 pub name: String,
70 pub version: u32,
72 pub chains: Vec<String>,
74 #[serde(skip_serializing_if = "Option::is_none")]
76 pub address: Option<Vec<String>>,
77 pub event: String,
79 pub fingerprint: EventFingerprint,
81 #[serde(skip_serializing_if = "Option::is_none")]
83 pub supersedes: Option<String>,
84 #[serde(skip_serializing_if = "Option::is_none")]
86 pub superseded_by: Option<String>,
87 pub deprecated: bool,
89 pub fields: Vec<(String, FieldDef)>,
91 pub meta: SchemaMeta,
93}
94
95impl Schema {
96 pub fn fields_map(&self) -> HashMap<&str, &FieldDef> {
98 self.fields.iter().map(|(k, v)| (k.as_str(), v)).collect()
99 }
100
101 pub fn indexed_fields(&self) -> Vec<(&str, &FieldDef)> {
103 self.fields
104 .iter()
105 .filter(|(_, f)| f.indexed)
106 .map(|(k, v)| (k.as_str(), v))
107 .collect()
108 }
109
110 pub fn data_fields(&self) -> Vec<(&str, &FieldDef)> {
112 self.fields
113 .iter()
114 .filter(|(_, f)| !f.indexed)
115 .map(|(k, v)| (k.as_str(), v))
116 .collect()
117 }
118}
119
120pub trait SchemaRegistry: Send + Sync {
123 fn get_by_fingerprint(&self, fp: &EventFingerprint) -> Option<Schema>;
125
126 fn get_by_name(&self, name: &str, version: Option<u32>) -> Option<Schema>;
129
130 fn list_for_chain(&self, chain_slug: &str) -> Vec<Schema>;
132
133 fn history(&self, name: &str) -> Vec<Schema>;
135}