use std::path::PathBuf;
use crate::encryption::EncryptionScheme;
use crate::fs::{FileId, FsKind, StreamId};
use crate::registry::ContainerFormat;
use crate::volume::VolumeScheme;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Guid(pub [u8; 16]);
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum SnapshotRef {
VssStore(usize),
ApfsXid(u64),
}
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum NodeAddr {
Path(Vec<Vec<u8>>),
File(FileId),
Both { path: Vec<Vec<u8>>, id: FileId },
}
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Layer {
Os { path: PathBuf },
Range { start: u64, len: u64 },
Container { format: ContainerFormat },
Volume {
scheme: VolumeScheme,
index: usize,
guid: Option<Guid>,
},
Encryption { scheme: EncryptionScheme },
Snapshot { store: SnapshotRef },
Fs { kind: FsKind, at: NodeAddr },
Stream { id: StreamId },
Archive { member: Option<usize> },
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct PathSpec {
pub layer: Layer,
pub parent: Option<Box<PathSpec>>,
}
impl PathSpec {
#[must_use]
pub fn os(path: impl Into<PathBuf>) -> Self {
Self {
layer: Layer::Os { path: path.into() },
parent: None,
}
}
#[must_use]
pub fn root(layer: Layer) -> Self {
Self {
layer,
parent: None,
}
}
#[must_use]
pub fn push(self, layer: Layer) -> Self {
Self {
layer,
parent: Some(Box::new(self)),
}
}
#[must_use]
pub fn depth(&self) -> usize {
1 + self.parent.as_ref().map_or(0, |p| p.depth())
}
#[must_use]
pub fn base(&self) -> &PathSpec {
match &self.parent {
Some(p) => p.base(),
None => self,
}
}
#[must_use]
pub fn layers(&self) -> Vec<&Layer> {
let mut out = match &self.parent {
Some(p) => p.layers(),
None => Vec::new(),
};
out.push(&self.layer);
out
}
}