use super::constraint::TypeConstraint;
use super::section::SectionSchema;
pub fn image_schema() -> SectionSchema {
SectionSchema::new("image")
.description("Image capture metadata")
.field("width", TypeConstraint::AnyUnsigned)
.field("height", TypeConstraint::AnyUnsigned)
.field("format", TypeConstraint::AnyString) .field("bit_depth", TypeConstraint::AnyUnsigned) .field("timestamp", TypeConstraint::AnyEagleTime)
.field("exposure_time", TypeConstraint::AnyFloat) .field("iso", TypeConstraint::AnyUnsigned)
.field("focal_length", TypeConstraint::AnyFloat) .field("aperture", TypeConstraint::AnyFloat) }
pub fn camera_schema() -> SectionSchema {
SectionSchema::new("camera")
.description("Camera hardware configuration")
.field("model", TypeConstraint::AnyString)
.field("serial", TypeConstraint::AnyString)
.field("sensor_width", TypeConstraint::AnyFloat) .field("sensor_height", TypeConstraint::AnyFloat) .field("resolution_x", TypeConstraint::AnyUnsigned)
.field("resolution_y", TypeConstraint::AnyUnsigned)
.field("pixel_size", TypeConstraint::AnyFloat) .field("calibrated", TypeConstraint::AnyUnsigned) .field("timestamp", TypeConstraint::AnyEagleTime)
}
pub fn audio_schema() -> SectionSchema {
SectionSchema::new("audio")
.description("Audio stream metadata")
.field("sample_rate", TypeConstraint::AnyUnsigned) .field("channels", TypeConstraint::AnyUnsigned) .field("bit_depth", TypeConstraint::AnyUnsigned) .field("format", TypeConstraint::AnyString) .field("duration", TypeConstraint::AnyFloat) .field("timestamp", TypeConstraint::AnyEagleTime)
}
pub fn network_peer_schema() -> SectionSchema {
SectionSchema::new("network_peer")
.description("Network peer information")
.field("handle_hash", TypeConstraint::Blake3Provenance)
.field("device_pubkey", TypeConstraint::X25519Key)
.field("ip_address", TypeConstraint::AnyString)
.field("port", TypeConstraint::AnyUnsigned)
.field("last_seen", TypeConstraint::AnyEagleTime)
.field("protocol_version", TypeConstraint::AnyUnsigned)
}
pub fn announce_schema() -> SectionSchema {
SectionSchema::new("announce")
.description("FGTW bootstrap announce message")
.field("challenge_hash", TypeConstraint::Blake3Rolling)
.field("handle_hash", TypeConstraint::Blake3Provenance)
.field("port", TypeConstraint::AnyUnsigned)
.field("protocol_version", TypeConstraint::AnyUnsigned)
}
pub fn register_official_schemas(registry: &super::registry::SchemaRegistry) {
registry.register(image_schema());
registry.register(camera_schema());
registry.register(audio_schema());
registry.register(network_peer_schema());
registry.register(announce_schema());
}
#[cfg(test)]
mod tests {
use super::*;
use crate::schema::registry::SchemaRegistry;
#[test]
fn test_image_schema_creation() {
let schema = image_schema();
assert_eq!(schema.name, "image");
assert!(schema.fields.len() >= 5);
}
#[test]
fn test_camera_schema_creation() {
let schema = camera_schema();
assert_eq!(schema.name, "camera");
assert!(schema.fields.len() >= 5);
}
#[test]
fn test_audio_schema_creation() {
let schema = audio_schema();
assert_eq!(schema.name, "audio");
assert!(schema.fields.iter().any(|f| f.name == "sample_rate"));
}
#[test]
fn test_network_peer_schema() {
let schema = network_peer_schema();
assert_eq!(schema.name, "network_peer");
assert!(schema.fields.iter().any(|f| f.name == "handle_hash"));
}
#[test]
fn test_announce_schema() {
let schema = announce_schema();
assert_eq!(schema.name, "announce");
assert!(schema.fields.iter().any(|f| f.name == "challenge_hash"));
}
#[test]
fn test_register_all() {
let registry = SchemaRegistry::new();
register_official_schemas(®istry);
assert!(registry.get("image").is_ok());
assert!(registry.get("camera").is_ok());
assert!(registry.get("audio").is_ok());
assert!(registry.get("network_peer").is_ok());
assert!(registry.get("announce").is_ok());
}
}