harmos_domain/
registration.rs1use serde::Serialize;
20use crate::identity::artifact_subset;
22
23#[derive(Clone, Debug, PartialEq, Eq, Serialize, serde::Deserialize)]
32pub struct Registration {
33 pub namespace: String,
34 pub schema: u32,
35 pub payload: Vec<u8>,
36}
37
38#[derive(Debug, Default)]
39pub struct Registrar {
40 registrations: Vec<Registration>,
41}
42
43#[derive(Debug, thiserror::Error)]
46pub enum RegistrationError {
47 #[error("`{namespace}` is not a portable registration namespace")]
48 InvalidNamespace { namespace: String },
49
50 #[error("registration `{namespace}` has a zero schema ordinal")]
51 ZeroSchema { namespace: String },
52
53 #[error("registration namespace `{namespace}` was declared more than once")]
54 DuplicateNamespace { namespace: String },
55
56 #[error("registration `{namespace}` could not be encoded: {source}")]
57 Encode {
58 namespace: String,
59
60 #[source]
61 source: serde_json::Error,
62 },
63}
64
65impl Registrar {
70 pub fn new() -> Self {
71 Self::default()
72 }
73
74 pub fn register<T: Serialize>(&mut self, namespace: impl Into<String>, schema: u32, value: &T) -> Result<(), RegistrationError> {
75 let namespace = namespace.into();
76 if !artifact_subset(&namespace) {
77 return Err(RegistrationError::InvalidNamespace { namespace });
78 }
79 if schema == 0 {
80 return Err(RegistrationError::ZeroSchema { namespace });
81 }
82 if self.registrations.iter().any(|entry| entry.namespace == namespace) {
83 return Err(RegistrationError::DuplicateNamespace { namespace });
84 }
85 let payload = serde_json::to_vec(value).map_err(|source| RegistrationError::Encode { namespace: namespace.clone(), source })?;
86 self.registrations.push(Registration { namespace, schema, payload });
87 Ok(())
88 }
89
90 pub fn finish(mut self) -> Vec<Registration> {
91 self.registrations.sort_by(|left, right| left.namespace.cmp(&right.namespace));
92 self.registrations
93 }
94}
95
96