diff --git a/yama/src/bin/yama.rs b/yama/src/bin/yama.rs index bb63adf..8564f34 100644 --- a/yama/src/bin/yama.rs +++ b/yama/src/bin/yama.rs @@ -56,8 +56,9 @@ enum PileCommand { pointer_name: String, /// Limited expression(s) of files to retrieve. + /// LIMITATION OF CURRENT VERSION: ONLY ONE EXACT PATH ALLOWED, PLEASE. #[clap(short, long)] - subset: Vec, + subset: Option, destination: PathBuf, @@ -118,7 +119,7 @@ fn wrapped_main() -> anyhow::Result { match &opts.command { PileCommand::Retrieve { pointer_name, - subset: _, + subset, destination, num_workers: workers, } => { @@ -136,10 +137,25 @@ fn wrapped_main() -> anyhow::Result { fully_integrate_pointer_node(&pile, &mut root_tree_node.node, &mut pointer)?; + let mut node_to_extract = &mut root_tree_node.node; + + if let Some(subset) = subset { + for path_to_descend in subset.split('/').filter(|s| ! s.is_empty()) { + match node_to_extract.child(path_to_descend) { + Ok(new_node) => { + node_to_extract = new_node; + } + Err(msg) => { + bail!("Can't descend into {path_to_descend:?}: {msg}"); + } + } + } + } + // todo allow disabling apply metadata extracting::extract( destination, - &mut root_tree_node.node, + node_to_extract, &pile, true, workers.unwrap_or(2), diff --git a/yama/src/definitions.rs b/yama/src/definitions.rs index b5c441d..29ea33e 100644 --- a/yama/src/definitions.rs +++ b/yama/src/definitions.rs @@ -270,6 +270,31 @@ impl TreeNode { } } } + + /// Recurses into a child by name, or returns Err with a reason. + pub fn child(&mut self, name: &str) -> Result<&mut TreeNode, &'static str> { + match self { + TreeNode::NormalFile { .. } => { + Err("not a directory: normal file") + } + TreeNode::Directory { children, .. } => { + match children.get_mut(name) { + None => { + Err("child not in directory") + } + Some(node) => { + Ok(node) + } + } + } + TreeNode::SymbolicLink { .. } => { + Err("not a directory: symlink") + } + TreeNode::Deleted => { + Err("not a directory: deleted") + } + } + } } #[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq, Eq)]