From 9cb86b850699dc5b19e2582f5a2c64c5acc0a24b Mon Sep 17 00:00:00 2001 From: PROINT <> Date: Wed, 22 Jul 2026 14:41:42 +0700 Subject: Added AccountRepository trait --- src/types/path.rs | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 src/types/path.rs (limited to 'src/types/path.rs') diff --git a/src/types/path.rs b/src/types/path.rs new file mode 100644 index 0000000..1d095cd --- /dev/null +++ b/src/types/path.rs @@ -0,0 +1,37 @@ +use ulid::Ulid; + +use super::ids::AccountId; + +#[derive(Debug, thiserror::Error)] +pub enum PathError { + #[error("path is empty")] + Empty, + #[error("invalid ULID segment: {0}")] + BadSegment(String), +} + +#[derive(Clone)] +pub struct MaterializedPath(String); + +impl MaterializedPath { + pub fn parse(s: &str) -> Result { + if s.is_empty() { + return Err(PathError::Empty); + } + for seg in s.split('/') { + Ulid::from_string(seg).map_err(|_| PathError::BadSegment(seg.to_string()))?; + } + Ok(MaterializedPath(s.to_string())) + } + pub fn as_str(&self) -> &str { &self.0 } + pub fn depth(&self) -> usize { self.0.split('/').count() } + pub fn is_ancestor_of(&self, other: &MaterializedPath) -> bool { + other.0.starts_with(&self.0) && other.0.as_bytes().get(self.0.len()) == Some(&b'/') + } + pub fn with_child(&self, id: AccountId) -> MaterializedPath { + MaterializedPath(format!("{}/{}", self.0, id.as_ulid())) + } + pub fn root(id: AccountId) -> MaterializedPath { + MaterializedPath(id.as_ulid().to_string()) + } +} -- cgit v1.3