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