1use serde::{Deserialize, Serialize};
2
3#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
13pub struct SchemaMetadata {
14 pub schema_version: Option<u32>,
16 pub schema_fingerprint: Option<String>,
18}
19
20impl SchemaMetadata {
21 pub fn new(
23 schema_version: Option<u32>,
24 schema_fingerprint: Option<String>,
25 ) -> Result<Self, SchemaMetadataError> {
26 let metadata = Self {
27 schema_version,
28 schema_fingerprint,
29 };
30 metadata.validate()?;
31 Ok(metadata)
32 }
33
34 pub fn validate(&self) -> Result<(), SchemaMetadataError> {
36 if self.schema_version == Some(0) {
37 return Err(SchemaMetadataError::InvalidVersion);
38 }
39
40 let Some(fingerprint) = &self.schema_fingerprint else {
41 return Ok(());
42 };
43
44 if fingerprint.is_empty() {
45 return Err(SchemaMetadataError::EmptyFingerprint);
46 }
47 if fingerprint.len() > 256 {
48 return Err(SchemaMetadataError::FingerprintTooLong);
49 }
50 if !fingerprint.is_ascii() {
51 return Err(SchemaMetadataError::NonAsciiFingerprint);
52 }
53 if fingerprint.bytes().any(|byte| byte.is_ascii_control()) {
54 return Err(SchemaMetadataError::ControlCharacterFingerprint);
55 }
56
57 Ok(())
58 }
59}
60
61#[derive(Clone, Debug, Eq, thiserror::Error, PartialEq)]
66pub enum SchemaMetadataError {
67 #[error("schema_version must be greater than zero when present")]
69 InvalidVersion,
70 #[error("schema_fingerprint must not be empty when present")]
72 EmptyFingerprint,
73 #[error("schema_fingerprint must be at most 256 bytes")]
75 FingerprintTooLong,
76 #[error("schema_fingerprint must be ASCII")]
78 NonAsciiFingerprint,
79 #[error("schema_fingerprint must not contain ASCII control characters")]
81 ControlCharacterFingerprint,
82}