diff --git a/crates/pile/src/command/item.rs b/crates/pile/src/command/item.rs index 5c9ba9c..db1e3a2 100644 --- a/crates/pile/src/command/item.rs +++ b/crates/pile/src/command/item.rs @@ -20,6 +20,13 @@ pub struct ItemCommand { #[arg(long, short = 'p')] path: Option, + /// If present, print the schema fields instead of item data + #[arg(long)] + fields: bool, + + #[arg(long, short = 'x')] + exclude: Vec, + /// Path to dataset config #[arg(long, short = 'c', default_value = "./pile.toml")] config: PathBuf, @@ -42,24 +49,57 @@ impl CliCmd for ItemCommand { let state = ExtractState { ignore_mime: false }; + let item = ds.get(&source, &self.key).await.ok_or_else(|| { + anyhow::anyhow!("{:?} not found in source {:?}", self.key, self.source) + })?; + let pv = PileValue::Item(item); + + if self.fields { + let mut map = serde_json::Map::new(); + for (name, spec) in &ds.config.schema { + if self.exclude.contains(&name.to_string()) { + continue; + } + + let mut value = None; + for path in &spec.path { + let v = pv + .query(&state, path) + .await + .with_context(|| format!("while extracting field {name}"))?; + if let Some(v) = v { + let j = v + .to_json(&state) + .await + .with_context(|| format!("while extracting field {name}"))?; + value = Some(j); + break; + } + } + map.insert(name.to_string(), value.unwrap_or(serde_json::Value::Null)); + } + let json = serde_json::to_string_pretty(&serde_json::Value::Object(map)).unwrap(); + println!("{json}"); + return Ok(0); + } + let json = if let Some(path_str) = self.path { let path: ObjectPath = path_str .parse() .with_context(|| format!("invalid path {path_str:?}"))?; - ds.get_field(&state, &source, &self.key, &path) + let v = pv + .query(&state, &path) .await .with_context(|| format!("while extracting {}", self.key))? .ok_or_else(|| { anyhow::anyhow!("{:?} not found in source {:?}", self.key, self.source) - })? + })?; + v.to_json(&state) + .await + .with_context(|| format!("while extracting {}", self.key))? } else { - let item = ds.get(&source, &self.key).await.ok_or_else(|| { - anyhow::anyhow!("{:?} not found in source {:?}", self.key, self.source) - })?; - - let item = PileValue::Item(item); - item.to_json(&state) + pv.to_json(&state) .await .with_context(|| format!("while extracting {}", self.key))? };