Add item subcommand

This commit is contained in:
2026-03-21 08:49:48 -07:00
parent 2f2eb323d5
commit ed169b3ab4
4 changed files with 226 additions and 35 deletions

View File

@@ -0,0 +1,71 @@
use anyhow::{Context, Result};
use clap::Args;
use pile_config::{Label, objectpath::ObjectPath};
use pile_dataset::Datasets;
use pile_toolbox::cancelabletask::{CancelFlag, CancelableTaskError};
use pile_value::{extract::traits::ExtractState, value::PileValue};
use std::path::PathBuf;
use crate::{CliCmd, GlobalContext};
#[derive(Debug, Args)]
pub struct ItemCommand {
/// Source name (as defined in pile.toml)
source: String,
/// Item key within the source
key: String,
/// If present, extract a specific field
#[arg(long, short = 'p')]
path: Option<String>,
/// Path to dataset config
#[arg(long, short = 'c', default_value = "./pile.toml")]
config: PathBuf,
}
impl CliCmd for ItemCommand {
#[expect(clippy::print_stdout)]
#[expect(clippy::unwrap_used)]
async fn run(
self,
_ctx: GlobalContext,
_flag: CancelFlag,
) -> Result<i32, CancelableTaskError<anyhow::Error>> {
let source = Label::new(&self.source)
.ok_or_else(|| anyhow::anyhow!("invalid source name {:?}", self.source))?;
let ds = Datasets::open(&self.config)
.await
.with_context(|| format!("while opening dataset for {}", self.config.display()))?;
let state = ExtractState { ignore_mime: false };
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)
.await
.with_context(|| format!("while extracting {}", self.key))?
.ok_or_else(|| {
anyhow::anyhow!("{:?} not found in source {:?}", self.key, self.source)
})?
} 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)
.await
.with_context(|| format!("while extracting {}", self.key))?
};
let json = serde_json::to_string_pretty(&json).unwrap();
println!("{json}");
return Ok(0);
}
}