use std::collections::HashMap; use serde::{Deserialize, Deserializer, de}; use smartstring::{LazyCompact, SmartString}; use thiserror::Error; use crate::{Label, objectpath::PathParseError as ObjectPathError}; mod parser; pub use parser::GroupSegment; #[derive(Debug, Error, PartialEq)] pub enum GroupPatternParseError { /// A `{` or `}` appeared in an invalid position, or a `{` was never closed. #[error("syntax error at index {position}")] Syntax { position: usize }, /// The contents of a `{...}` block could not be parsed as an object path. #[error("invalid object path {path:?}: {source}")] InvalidObjectPath { start: usize, end: usize, path: SmartString, source: ObjectPathError, }, } #[derive(Debug, Clone, Default)] pub struct GroupPattern { pub pattern: HashMap>, } impl<'de> Deserialize<'de> for GroupPattern { fn deserialize>(deserializer: D) -> Result { let raw = HashMap::::deserialize(deserializer)?; let mut parts = HashMap::with_capacity(raw.len()); for (key, value) in raw { let label = Label::try_from(key.as_str()).map_err(de::Error::custom)?; let segments = parser::Parser::new() .parse(&value) .map_err(de::Error::custom)? .into_iter() .map(|(_, seg)| seg) .collect(); parts.insert(label, segments); } Ok(GroupPattern { pattern: parts }) } }