use std::{ops::Deref, borrow::Borrow};
use ref_cast::RefCast;
use serde::{Serialize, Deserialize};
use crate::Id;
#[derive(Debug, Hash, PartialEq, Eq, RefCast)]
#[repr(transparent)]
pub struct IdPath([Id]);
#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
pub struct IdPathBuf(Vec<Id>);
impl IdPath {
pub fn root() -> &'static Self {
Self::ref_cast(&[])
}
pub fn is_root(&self) -> bool {
self.0.is_empty()
}
pub fn head(&self) -> Option<Id> {
self.0.first().cloned()
}
pub fn tail(&self) -> &Self {
Self::ref_cast(&self.0[1..])
}
pub fn child(&self, id: impl Into<Id>) -> IdPathBuf {
self.to_owned().child(id)
}
pub fn join(&self, path: &IdPath) -> IdPathBuf {
self.to_owned().join(path)
}
}
impl IdPathBuf {
pub fn root() -> Self {
Self(Vec::new())
}
pub fn child(&self, id: impl Into<Id>) -> Self {
let mut components = self.0.clone();
components.push(id.into());
Self(components)
}
pub fn join(&self, path: &IdPath) -> Self {
let mut components = self.0.clone();
components.extend(path.0.into_iter().cloned());
Self(components)
}
}
impl ToOwned for IdPath {
type Owned = IdPathBuf;
fn to_owned(&self) -> IdPathBuf {
IdPathBuf(self.0.to_vec())
}
}
impl Default for IdPathBuf {
fn default() -> Self {
Self::root()
}
}
impl From<Id> for IdPathBuf {
fn from(id: Id) -> Self {
Self(vec![id])
}
}
impl Deref for IdPathBuf {
type Target = IdPath;
fn deref(&self) -> &IdPath {
IdPath::ref_cast(&self.0[..])
}
}
impl AsRef<IdPath> for IdPathBuf {
fn as_ref(&self) -> &IdPath {
self.deref()
}
}
impl Borrow<IdPath> for IdPathBuf {
fn borrow(&self) -> &IdPath {
self.deref()
}
}