diff --git a/Cargo.lock b/Cargo.lock index 92d419c..d9399a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -945,6 +945,7 @@ dependencies = [ "pile-dataset", "pile-toolbox", "serde", + "serde_json", "signal-hook", "tokio", "toml", diff --git a/crates/pile/Cargo.toml b/crates/pile/Cargo.toml index e07d268..c677f08 100644 --- a/crates/pile/Cargo.toml +++ b/crates/pile/Cargo.toml @@ -24,3 +24,4 @@ tracing-indicatif = { workspace = true } signal-hook = { workspace = true } anstyle = { workspace = true } toml = { workspace = true } +serde_json = { workspace = true } diff --git a/crates/pile/src/command/mod.rs b/crates/pile/src/command/mod.rs index 0b275d9..631b379 100644 --- a/crates/pile/src/command/mod.rs +++ b/crates/pile/src/command/mod.rs @@ -6,6 +6,7 @@ mod check; mod index; mod init; mod lookup; +mod probe; use crate::GlobalContext; @@ -34,6 +35,12 @@ pub enum SubCommand { #[command(flatten)] cmd: lookup::LookupCommand, }, + + /// Print all metadata from an item + Probe { + #[command(flatten)] + cmd: probe::ProbeCommand, + }, } impl CliCmdDispatch for SubCommand { @@ -43,6 +50,7 @@ impl CliCmdDispatch for SubCommand { Self::Check { cmd } => cmd.start(ctx), Self::Index { cmd } => cmd.start(ctx), Self::Lookup { cmd } => cmd.start(ctx), + Self::Probe { cmd } => cmd.start(ctx), } } } diff --git a/crates/pile/src/command/probe.rs b/crates/pile/src/command/probe.rs new file mode 100644 index 0000000..422e833 --- /dev/null +++ b/crates/pile/src/command/probe.rs @@ -0,0 +1,39 @@ +use anyhow::{Context, Result}; +use clap::Args; +use pile_config::Label; +use pile_dataset::{FileItem, PileValue, extract::MetaExtractor}; +use pile_toolbox::cancelabletask::{CancelFlag, CancelableTaskError}; +use std::{fmt::Debug, path::PathBuf, rc::Rc}; + +use crate::{CliCmd, GlobalContext}; + +#[derive(Debug, Args)] +pub struct ProbeCommand { + /// The file to probe + file: PathBuf, +} + +impl CliCmd for ProbeCommand { + #[expect(clippy::print_stdout)] + #[expect(clippy::unwrap_used)] + async fn run( + self, + _ctx: GlobalContext, + _flag: CancelFlag, + ) -> Result> { + let item = FileItem { + path: self.file.clone(), + source_name: Label::new("probe-source").unwrap(), + }; + + let value = PileValue::Extractor(Rc::new(MetaExtractor::new(&item))); + let json = value + .to_json() + .with_context(|| format!("while extracting {}", self.file.display()))?; + + let json = serde_json::to_string_pretty(&json).unwrap(); + + println!("{json}"); + return Ok(0); + } +}