indy_data_types/identifiers/
schema.rs

1use crate::did::DidValue;
2use crate::qualifiable::{self, qualifiable_type};
3use crate::{Qualifiable, Validatable, ValidationError};
4
5use super::DELIMITER;
6
7qualifiable_type!(SchemaId, "A V1 schema identifier");
8
9impl SchemaId {
10    pub const PREFIX: &'static str = "schema";
11    pub const MARKER: &'static str = "2";
12
13    pub fn new(did: &DidValue, name: &str, version: &str) -> SchemaId {
14        let id = format!(
15            "{}{}{}{}{}{}{}",
16            did.0,
17            DELIMITER,
18            Self::MARKER,
19            DELIMITER,
20            name,
21            DELIMITER,
22            version
23        );
24        Self::from(qualifiable::combine(
25            Self::PREFIX,
26            did.get_method(),
27            id.as_str(),
28        ))
29    }
30
31    pub fn parts(&self) -> Option<(Option<&str>, DidValue, String, String)> {
32        let parts = self.0.split_terminator(DELIMITER).collect::<Vec<&str>>();
33
34        if parts.len() == 1 {
35            // 1
36            return None;
37        }
38
39        if parts.len() == 4 {
40            // NcYxiDXkpYi6ov5FcYDi1e:2:gvt:1.0
41            let did = parts[0].to_string();
42            let name = parts[2].to_string();
43            let version = parts[3].to_string();
44            return Some((None, DidValue(did), name, version));
45        }
46
47        if parts.len() == 8 {
48            // schema:sov:did:sov:NcYxiDXkpYi6ov5FcYDi1e:2:gvt:1.0
49            let method = parts[1];
50            let did = parts[2..5].join(DELIMITER);
51            let name = parts[6].to_string();
52            let version = parts[7].to_string();
53            return Some((Some(method), DidValue(did), name, version));
54        }
55
56        None
57    }
58}
59
60impl Qualifiable for SchemaId {
61    fn prefix() -> &'static str {
62        Self::PREFIX
63    }
64
65    fn combine(method: Option<&str>, entity: &str) -> Self {
66        let sid = Self(entity.to_owned());
67        match sid.parts() {
68            Some((_, did, name, version)) => {
69                Self::new(&did.default_method(method), &name, &version)
70            }
71            None => sid,
72        }
73    }
74
75    fn to_unqualified(&self) -> Self {
76        match self.parts() {
77            Some((method, did, name, version)) => {
78                let did = if let Some(method) = method {
79                    did.remove_method(method)
80                } else {
81                    did
82                };
83                Self::new(&did, &name, &version)
84            }
85            None => self.clone(),
86        }
87    }
88}
89
90impl Validatable for SchemaId {
91    fn validate(&self) -> Result<(), ValidationError> {
92        if self.0.parse::<i32>().is_ok() {
93            return Ok(());
94        }
95
96        self.parts().ok_or(format!(
97            "SchemaId validation failed: {:?}, doesn't match pattern",
98            self.0
99        ))?;
100
101        Ok(())
102    }
103}
104
105#[cfg(test)]
106mod tests {
107    use super::*;
108
109    fn _did() -> DidValue {
110        DidValue("NcYxiDXkpYi6ov5FcYDi1e".to_string())
111    }
112
113    fn _did_qualified() -> DidValue {
114        DidValue("did:sov:NcYxiDXkpYi6ov5FcYDi1e".to_string())
115    }
116
117    fn _schema_id_seq_no() -> SchemaId {
118        SchemaId("1".to_string())
119    }
120
121    fn _schema_id_unqualified() -> SchemaId {
122        SchemaId("NcYxiDXkpYi6ov5FcYDi1e:2:gvt:1.0".to_string())
123    }
124
125    fn _schema_id_qualified() -> SchemaId {
126        SchemaId("schema:sov:did:sov:NcYxiDXkpYi6ov5FcYDi1e:2:gvt:1.0".to_string())
127    }
128
129    fn _schema_id_invalid() -> SchemaId {
130        SchemaId("NcYxiDXkpYi6ov5FcYDi1e:2".to_string())
131    }
132
133    mod to_unqualified {
134        use super::*;
135
136        #[test]
137        fn test_schema_id_unqualify_for_id_as_seq_no() {
138            assert_eq!(_schema_id_seq_no(), _schema_id_seq_no().to_unqualified());
139        }
140
141        #[test]
142        fn test_schema_id_parts_for_id_as_unqualified() {
143            assert_eq!(
144                _schema_id_unqualified(),
145                _schema_id_unqualified().to_unqualified()
146            );
147        }
148
149        #[test]
150        fn test_schema_id_parts_for_id_as_qualified() {
151            assert_eq!(
152                _schema_id_unqualified(),
153                _schema_id_qualified().to_unqualified()
154            );
155        }
156
157        #[test]
158        fn test_schema_id_parts_for_invalid_unqualified() {
159            assert_eq!(_schema_id_invalid(), _schema_id_invalid().to_unqualified());
160        }
161    }
162
163    mod parts {
164        use super::*;
165
166        #[test]
167        fn test_schema_id_parts_for_id_as_seq_no() {
168            assert!(_schema_id_seq_no().parts().is_none());
169        }
170
171        #[test]
172        fn test_schema_id_parts_for_id_as_unqualified() {
173            let (_, did, _, _) = _schema_id_unqualified().parts().unwrap();
174            assert_eq!(_did(), did);
175        }
176
177        #[test]
178        fn test_schema_id_parts_for_id_as_qualified() {
179            let (_, did, _, _) = _schema_id_qualified().parts().unwrap();
180            assert_eq!(_did_qualified(), did);
181        }
182
183        #[test]
184        fn test_schema_id_parts_for_invalid_unqualified() {
185            assert!(_schema_id_invalid().parts().is_none());
186        }
187    }
188
189    mod validate {
190        use super::*;
191
192        #[test]
193        fn test_validate_schema_id_as_seq_no() {
194            _schema_id_seq_no().validate().unwrap();
195        }
196
197        #[test]
198        fn test_validate_schema_id_as_unqualified() {
199            _schema_id_unqualified().validate().unwrap();
200        }
201
202        #[test]
203        fn test_validate_schema_id_as_fully_qualified() {
204            _schema_id_qualified().validate().unwrap();
205        }
206
207        #[test]
208        fn test_validate_schema_id_for_invalid_unqualified() {
209            _schema_id_invalid().validate().unwrap_err();
210        }
211
212        #[test]
213        fn test_validate_schema_id_for_invalid_fully_qualified() {
214            let id = SchemaId("schema:sov:NcYxiDXkpYi6ov5FcYDi1e:2:1.0".to_string());
215            id.validate().unwrap_err();
216        }
217    }
218
219    mod to_qualified {
220        use super::*;
221
222        #[test]
223        fn test_schema_to_qualified() {
224            assert_eq!(
225                _schema_id_unqualified().to_qualified("sov").unwrap(),
226                _schema_id_qualified()
227            )
228        }
229    }
230}