feat: introduce obitaxonomy crate for hierarchical taxonomy parsing
Adds the `obitaxonomy` crate to parse and validate hierarchical taxonomy paths using a strict `taxonomy:/name@rank/...` syntax. Replaces generic string-based path matching in predicates with structured `TaxPath` and `TaxPattern` types, enforcing explicit anchor constraints and rank-aware semantics. Updates filtering documentation to clarify optional leading slashes and segment-boundary matching rules.
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum TaxError {
|
||||
/// Stored value does not start with the `taxonomy:/` prefix.
|
||||
MissingPrefix,
|
||||
/// Stored path contains no segments after the prefix.
|
||||
EmptyPath,
|
||||
/// Query pattern contains no segments (after stripping anchors).
|
||||
EmptyPattern,
|
||||
/// A segment has an empty name (e.g. consecutive `/`).
|
||||
EmptySegmentName,
|
||||
/// A segment has a trailing `@` with no rank name.
|
||||
EmptyRankName { segment: String },
|
||||
/// A segment contains more than one `@`.
|
||||
AmbiguousRank { segment: String },
|
||||
}
|
||||
|
||||
impl fmt::Display for TaxError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
TaxError::MissingPrefix =>
|
||||
write!(f, "taxonomy path must start with \"taxonomy:/\""),
|
||||
TaxError::EmptyPath =>
|
||||
write!(f, "taxonomy path has no segments"),
|
||||
TaxError::EmptyPattern =>
|
||||
write!(f, "taxonomy query pattern has no segments"),
|
||||
TaxError::EmptySegmentName =>
|
||||
write!(f, "segment has an empty name"),
|
||||
TaxError::EmptyRankName { segment } =>
|
||||
write!(f, "segment has '@' with no rank name: {segment:?}"),
|
||||
TaxError::AmbiguousRank { segment } =>
|
||||
write!(f, "segment contains more than one '@': {segment:?}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for TaxError {}
|
||||
Reference in New Issue
Block a user