provenance-cli 0.2.3

Command-line interface for Provenance requirements traceability
use crate::cli::sdk::QueryArgs;
use crate::output;
use provenance_core::ScopeId;
use provenance_store::operations::catalog;

/// Which structured query the caller asked for.
#[derive(Debug, Clone, Copy)]
pub(super) enum Operation {
    Get,
    Search,
    Neighbors,
    Trace,
    Impact,
    Evidence,
    Stale,
    ResolveSymbol,
}

/// Runs one structured query and writes its bounded answer.
///
/// Every primitive is one named operation with typed parameters read from
/// stdin, and every answer carries the protocol version that produced it.
pub(super) async fn handle(operation: Operation, args: QueryArgs) -> anyhow::Result<()> {
    let root = provenance_store::operations::discover_repository(args.repo)?;
    let settings = provenance_store::settings::Settings::load(
        &provenance_store::layout::ProvenanceLayout::new(root.clone()),
    )?;
    let policy =
        provenance_store::operations::read_policy::ReadPolicy::resolve(&settings, args.freshness);
    let scope = ScopeId::new(args.scope)?;
    let format = args.format;
    let context = catalog::PreparedContext::read(catalog::PreparedRead {
        root,
        scope: scope.clone(),
        policy,
        requested_target: String::new(),
        external: false,
    });
    match operation {
        Operation::Get => {
            let result =
                catalog::invoke_typed::<catalog::Get>(context, super::read_stdin_json()?).await?;
            output::print(format, &result)
        }
        Operation::Search => {
            let result =
                catalog::invoke_typed::<catalog::Search>(context, super::read_stdin_json()?)
                    .await?;
            output::print(format, &result)
        }
        Operation::Neighbors => {
            let result =
                catalog::invoke_typed::<catalog::Neighbors>(context, super::read_stdin_json()?)
                    .await?;
            output::print(format, &result)
        }
        Operation::Trace => {
            let result =
                catalog::invoke_typed::<catalog::Trace>(context, super::read_stdin_json()?).await?;
            output::print(format, &result)
        }
        Operation::Impact => {
            let result =
                catalog::invoke_typed::<catalog::Impact>(context, super::read_stdin_json()?)
                    .await?;
            output::print(format, &result)
        }
        Operation::Evidence => {
            let result =
                catalog::invoke_typed::<catalog::Evidence>(context, super::read_stdin_json()?)
                    .await?;
            output::print(format, &result)
        }
        Operation::Stale => {
            let result =
                catalog::invoke_typed::<catalog::Stale>(context, super::read_stdin_json()?).await?;
            output::print(format, &result)
        }
        Operation::ResolveSymbol => {
            let result =
                catalog::invoke_typed::<catalog::ResolveSymbol>(context, super::read_stdin_json()?)
                    .await?;
            output::print(format, &result)
        }
    }
}