use clap::{Args, Parser, Subcommand};
use navactor::director;
use navactor::json_decoder;
use navactor::message::Message;
use navactor::message::Message::EndOfStream;
use navactor::stdin_actor;
use navactor::stdout_actor;
use navactor::store_actor_sqlite;
use tokio::runtime::Runtime;
#[derive(Parser)]
#[command(
author,
version,
about,
long_about = "nv is the CLI for the DtLaboratory project"
)] #[command(propagate_version = true)]
struct Cli {
#[arg(short, long)]
dbfile: Option<String>,
#[arg(short, long)]
buffer: Option<usize>,
#[arg(short, long, action = clap::ArgAction::Count)]
verbose: u8,
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
Update(Namespace),
Inspect(NvPath),
}
#[derive(Args)]
struct Namespace {
namespace: String,
}
#[derive(Args)]
struct NoArg {}
#[derive(Args)]
struct NvPath {
path: String,
}
#[derive(Args)]
struct Extractor {
extractor: String,
}
fn update(namespace: Namespace, bufsz: usize, runtime: Runtime) {
let result = run_async_update(namespace, bufsz);
runtime.block_on(result).expect("An error occurred")
}
async fn run_async_update(namespace: Namespace, bufsz: usize) -> Result<(), String> {
let output = stdout_actor::new(bufsz); let store_actor = store_actor_sqlite::new(bufsz, namespace.namespace.clone()); let director_w_persist =
director::new(namespace.namespace, bufsz, Some(output), Some(store_actor));
let json_decoder_actor = json_decoder::new(bufsz, director_w_persist); let input = stdin_actor::new(bufsz, json_decoder_actor); match input.ask(Message::ReadAllCmd {}).await {
EndOfStream {} => Ok(()),
_ => Err("END and response: sucks.".to_string()),
}
}
fn inspect(path: NvPath, bufsz: usize, runtime: Runtime) {
let result = run_async_inspect(path, bufsz);
runtime.block_on(result).expect("An error occurred");
}
async fn run_async_inspect(path: NvPath, bufsz: usize) -> Result<(), String> {
let p = std::path::Path::new(&path.path);
let ns = p
.components()
.find(|c| c == &std::path::Component::RootDir)
.unwrap()
.as_os_str()
.to_str()
.unwrap();
log::trace!("inspect of ns {}", ns);
let output = stdout_actor::new(bufsz); let store_actor = store_actor_sqlite::new(bufsz, String::from(ns)); let director = director::new(path.path.clone(), bufsz, None, Some(store_actor));
let m = director.ask(Message::Query { path: path.path }).await;
output.tell(m).await;
match output.ask(Message::EndOfStream {}).await {
EndOfStream {} => Ok(()),
_ => Err("END and response: sucks.".to_string()),
}
}
fn main() {
env_logger::init();
log::info!("nv started");
let cli = Cli::parse();
let bufsz: usize = cli.buffer.unwrap_or(8);
let runtime = Runtime::new().unwrap_or_else(|e| panic!("Error creating runtime: {}", e));
match cli.command {
Commands::Update(namespace) => update(namespace, bufsz, runtime),
Commands::Inspect(path) => inspect(path, bufsz, runtime),
}
log::info!("nv stopped");
}