ave_common/
schematype.rs

1use std::fmt::Display;
2
3use borsh::{BorshDeserialize, BorshSerialize};
4use serde::{Deserialize, Deserializer, Serialize, Serializer};
5
6#[derive(
7    Default,
8    Debug,
9    Clone,
10    Hash,
11    PartialEq,
12    Eq,
13    Ord,
14    PartialOrd,
15    BorshSerialize,
16    BorshDeserialize,
17)]
18pub enum SchemaType {
19    #[default]
20    Governance,
21    Type(String),
22    AllSchemas,
23}
24
25impl std::str::FromStr for SchemaType {
26    type Err = String;
27
28    fn from_str(s: &str) -> Result<Self, Self::Err> {
29        // Special case: empty string deserializes to default (empty) digest
30        if s.is_empty() {
31            return Err("Schema_id can not be empty".to_string());
32        }
33
34        match s {
35            "governance" => Ok(SchemaType::Governance),
36            "all_schemas" => Ok(SchemaType::AllSchemas),
37            _ => Ok(SchemaType::Type(s.to_string())),
38        }
39    }
40}
41
42impl SchemaType {
43    pub fn len(&self) -> usize {
44        match self {
45            SchemaType::Governance => "governance".len(),
46            SchemaType::Type(schema_id) => schema_id.len(),
47            SchemaType::AllSchemas => "all_schemas".len(),
48        }
49    }
50
51    pub fn is_empty(&self) -> bool {
52        match self {
53            SchemaType::Governance => false,
54            SchemaType::Type(schschema_id) => schschema_id.is_empty(),
55            SchemaType::AllSchemas => false,
56        }
57    }
58
59    pub fn is_valid(&self) -> bool {
60        match self {
61            SchemaType::Governance => true,
62            SchemaType::AllSchemas => true,
63            SchemaType::Type(schema_id) => {
64                !schema_id.is_empty()
65                    && schema_id != "governance"
66                    && schema_id != "all_schemas"
67                    && schema_id.trim().len() == schema_id.len()
68            }
69        }
70    }
71}
72
73impl Display for SchemaType {
74    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
75        match self {
76            SchemaType::AllSchemas => write!(f, "all_schemas"),
77            SchemaType::Governance => write!(f, "governance"),
78            SchemaType::Type(schema_id) => write!(f, "{}", schema_id),
79        }
80    }
81}
82
83impl SchemaType {
84    pub fn is_gov(&self) -> bool {
85        matches!(self, SchemaType::Governance)
86    }
87}
88
89impl<'de> Deserialize<'de> for SchemaType {
90    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
91    where
92        D: Deserializer<'de>,
93    {
94        let s = <String as serde::Deserialize>::deserialize(deserializer)?;
95        if s.is_empty() {
96            return Err(serde::de::Error::custom(
97                "Schema can not be empty".to_string(),
98            ));
99        }
100
101        Ok(match s.as_str() {
102            "governance" => SchemaType::Governance,
103            "all_schemas" => SchemaType::AllSchemas,
104            _ => SchemaType::Type(s),
105        })
106    }
107}
108
109impl Serialize for SchemaType {
110    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
111    where
112        S: Serializer,
113    {
114        match self {
115            SchemaType::AllSchemas => serializer.serialize_str("all_schemas"),
116            SchemaType::Governance => serializer.serialize_str("governance"),
117            SchemaType::Type(schema) => serializer.serialize_str(schema),
118        }
119    }
120}