use super::validate_identity;
use crate::error::ModelError;
pub const AGENT_ID_MAX_LEN: usize = 128;
arc_str_newtype! {
#[cfg_attr(feature = "schema", schemars(schema_with = "crate::schema::agent_id"))]
pub struct AgentId;
}
impl AgentId {
pub fn validate_format(&self) -> Result<(), ModelError> {
validate_identity("agent_id", self.as_str(), AGENT_ID_MAX_LEN)
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::sync::Arc;
#[test]
fn exposes_string_identity_hashing_and_shared_clones() {
use std::collections::HashSet;
let id = AgentId::new("agent-a").unwrap();
assert_eq!(id.as_str(), "agent-a");
assert_eq!(format!("{id}"), "agent-a");
assert_eq!(id, *"agent-a");
let mut set = HashSet::new();
set.insert(id.clone());
set.insert(AgentId::new("agent-b").unwrap());
set.insert(AgentId::new("agent-a").unwrap());
assert_eq!(set.len(), 2);
let cloned = id.clone();
let a: Arc<str> = id.into_inner();
let b: Arc<str> = cloned.into_inner();
assert!(Arc::ptr_eq(&a, &b));
}
#[test]
fn serde_is_transparent() {
let id = AgentId::new("550e8400-e29b-41d4-a716-446655440000").unwrap();
let json = serde_json::to_string(&id).unwrap();
assert_eq!(json, r#""550e8400-e29b-41d4-a716-446655440000""#);
assert_eq!(serde_json::from_str::<AgentId>(&json).unwrap(), id);
}
#[test]
fn validation_accepts_safe_values_and_rejects_unsafe_values() {
for valid in [
"550e8400-e29b-41d4-a716-446655440000",
"worker-pod-7b9f4",
"agent.eu-west-1.01",
] {
AgentId::new(valid).unwrap();
}
for invalid in ["", "agent with space", "agent/path"] {
assert!(AgentId::new(invalid).is_err(), "must reject {invalid:?}");
}
}
}