Skip to main content

corpus_ipc/models/
metadata.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2
3use serde::{Deserialize, Serialize};
4
5use crate::validation::{
6    ProtocolLimits, Validate, ValidationError, check_count, check_opt_string, check_string,
7};
8
9use super::de::{de_metadata_custom, de_source};
10
11/// Optional batch metadata for debugging and monitoring.
12#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default)]
13#[serde(try_from = "BatchMetadataWire")]
14pub struct BatchMetadata {
15    /// Processing latency in nanoseconds.
16    pub processing_latency_ns: Option<u64>,
17    /// Source identifier (for example, "encoder", "compute_layer_2").
18    pub source: Option<String>,
19    /// Additional metadata fields.
20    pub custom: std::collections::HashMap<String, String>,
21}
22
23#[derive(Deserialize)]
24struct BatchMetadataWire {
25    processing_latency_ns: Option<u64>,
26    #[serde(default, deserialize_with = "de_source")]
27    source: Option<String>,
28    #[serde(default, deserialize_with = "de_metadata_custom")]
29    custom: std::collections::HashMap<String, String>,
30}
31
32impl TryFrom<BatchMetadataWire> for BatchMetadata {
33    type Error = ValidationError;
34
35    fn try_from(wire: BatchMetadataWire) -> Result<Self, Self::Error> {
36        let metadata = BatchMetadata {
37            processing_latency_ns: wire.processing_latency_ns,
38            source: wire.source,
39            custom: wire.custom,
40        };
41        metadata.validate()?;
42        Ok(metadata)
43    }
44}
45
46impl Validate for BatchMetadata {
47    fn validate_with(&self, limits: ProtocolLimits) -> Result<(), ValidationError> {
48        check_opt_string("source", self.source.as_deref(), limits)?;
49        check_count("custom", self.custom.len(), limits.max_metadata_entries)?;
50        for (key, value) in &self.custom {
51            if key.is_empty() {
52                return Err(ValidationError::nested_metadata("custom.<empty>"));
53            }
54            check_string("custom.<key>", key, limits)?;
55            check_string("custom.<value>", value, limits)?;
56        }
57        Ok(())
58    }
59}