mod error; mod impl_mergeable_tree; mod impl_tree; pub use error::*; use crate::{Node, NodeContent}; /// Applying [`FileSystemTree`](crate::FileSystemTree) to the filesystem. /// /// **Generic parameters:** /// * `Name`: Identification of a child item. /// * `Error`: Error type used by the other functions. pub trait Build: Node + Sized where Self::DirectoryContent: IntoIterator, { /// Build target. type BorrowedPath: ToOwned + ?Sized; /// Locations of the items in the filesystem. type OwnedPath: AsRef; /// Add prefix to the root of the tree. fn join(prefix: &Self::BorrowedPath, name: &Name) -> Self::OwnedPath; /// Write content to a file. fn write_file(path: &Self::BorrowedPath, content: &Self::FileContent) -> Result<(), Error>; /// Create a directory at root. fn create_dir(path: &Self::BorrowedPath) -> Result<(), Error>; /// Build the tree into the filesystem. fn build(self, path: Path) -> Result<(), BuildError> where Path: AsRef, { let path = path.as_ref(); let children = match self.read() { NodeContent::File(content) => { return Self::write_file(path, &content).map_err(|error| BuildError { operation: FailedOperation::WriteFile, path: path.to_owned(), error, }) } NodeContent::Directory(children) => children, }; Self::create_dir(path).map_err(|error| BuildError { operation: FailedOperation::CreateDir, path: path.to_owned(), error, })?; for (name, child) in children { child.build(Self::join(path, &name))?; } Ok(()) } }