summaryrefslogtreecommitdiff
path: root/src/types/path.rs
diff options
context:
space:
mode:
authorPROINT <>2026-07-22 14:41:42 +0700
committerPROINT <>2026-07-22 14:41:42 +0700
commit9cb86b850699dc5b19e2582f5a2c64c5acc0a24b (patch)
tree8ea8b9392646efd2b000c4064d72b96572de77ee /src/types/path.rs
parent2fb9ff9efbafa582ca7e83f12c61548d8e7a93ed (diff)
Added AccountRepository trait
Diffstat (limited to 'src/types/path.rs')
-rw-r--r--src/types/path.rs37
1 files changed, 37 insertions, 0 deletions
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<Self, PathError> {
+ 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())
+ }
+}