use anyhow::Context as _;
use clap::{Arg, ArgAction, ArgMatches, Command};
use reedline_repl_rs::Repl;
use s_macro::s;
use wildland_corex::api::{SpecialFileOperations, SpecialFileType};
use crate::{match_context, Context};
#[tracing::instrument(level = "trace", err(Debug), skip(_args, context))]
fn h_sfo_init(_args: ArgMatches, context: &mut Context) -> anyhow::Result<Option<String>> {
match_context!(context, cargo => None, sfo => None)?;
context.init_sfo("./sfo")?;
Ok(Some(s!(
"Special File Operations Service initialised with an empty registry"
)))
}
#[tracing::instrument(level = "trace", err(Debug), skip(args, context))]
fn h_sfo_create_special_file(
args: ArgMatches,
context: &mut Context,
) -> anyhow::Result<Option<String>> {
match_context!(context, sfo => Some(_))?;
let file_name: String = args
.get_one::<String>("file_name")
.context("file name not provided")?
.to_owned();
let file_type: SpecialFileType = args
.get_one::<String>("file_type")
.context("file type not provided")?
.to_owned()
.try_into()?;
let input_stream = None;
context.sfo.as_mut().unwrap().create_special_file(
file_name.to_owned(),
file_type,
input_stream,
)?;
Ok(Some(s!("Special File created: {}", file_name)))
}
#[tracing::instrument(level = "trace", err(Debug), skip(args, context))]
fn h_sfo_remove_special_file(
args: ArgMatches,
context: &mut Context,
) -> anyhow::Result<Option<String>> {
match_context!(context, sfo => Some(_))?;
let file_name: String = args
.get_one::<String>("file_name")
.context("file name not provided")?
.to_owned();
let file_type: SpecialFileType = args
.get_one::<String>("file_type")
.context("file type not provided")?
.to_owned()
.try_into()?;
context
.sfo
.as_mut()
.unwrap()
.remove_special_file(file_name.to_owned(), file_type.to_owned())?;
Ok(Some(s!(
"Special File ({:?}) removed: {}",
file_type,
file_name
)))
}
#[tracing::instrument(level = "trace", err(Debug), skip(context))]
fn h_sfo_get_special_file_path(
args: ArgMatches,
context: &mut Context,
) -> anyhow::Result<Option<String>> {
match_context!(context, sfo => Some(_))?;
let file_name: String = args
.get_one::<String>("file_name")
.context("file name not provided")?
.to_owned();
let file_type: SpecialFileType = args
.get_one::<String>("file_type")
.context("file type not provided")?
.to_owned()
.try_into()?;
let file_path = context
.sfo
.as_ref()
.unwrap()
.get_special_file_path(file_name, file_type)?;
Ok(Some(s!("Special file registry\n {:?}", file_path)))
}
#[tracing::instrument(level = "trace", err(Debug), skip(args, context))]
fn h_sfo_read_from_special_file(
args: ArgMatches,
context: &mut Context,
) -> anyhow::Result<Option<String>> {
match_context!(context, sfo => Some(_))?;
let file_name: String = args
.get_one::<String>("file_name")
.context("file name not provided")?
.to_owned();
let file_type: SpecialFileType = args
.get_one::<String>("file_type")
.context("file type not provided")?
.to_owned()
.try_into()?;
let contents = context
.sfo
.as_mut()
.unwrap()
.read_from_special_file(file_name, file_type)?;
if args
.get_one::<bool>("interpret as ascii")
.unwrap()
.to_owned()
{
Ok(Some(s!(
"Special File contents: {}",
String::from_utf8(contents)?
)))
} else {
Ok(Some(s!("Special File contents: {:?}", contents)))
}
}
#[tracing::instrument(level = "trace", err(Debug), skip(args, context))]
fn h_sfo_write_to_special_file(
args: ArgMatches,
context: &mut Context,
) -> anyhow::Result<Option<String>> {
match_context!(context, sfo => Some(_))?;
let file_name: String = args
.get_one::<String>("file_name")
.context("file name not provided")?
.to_owned();
let file_type: SpecialFileType = args
.get_one::<String>("file_type")
.context("file type not provided")?
.to_owned()
.try_into()?;
let truncate = args.get_one::<bool>("append").unwrap().to_owned();
let new_contents = args
.get_one::<String>("input")
.context("input not provided")?
.to_owned();
context.sfo.as_mut().unwrap().write_to_special_file(
file_name.to_owned(),
file_type,
new_contents.into_bytes(),
truncate,
)?;
Ok(Some(s!("Data written to file: {}", file_name)))
}
pub fn extend(repl: Repl<Context, anyhow::Error>) -> Repl<Context, anyhow::Error> {
repl.with_command(
Command::new("sfo-init").about("Initialise SfoService"),
h_sfo_init,
)
.with_command(
Command::new("sfo-create")
.about("Create a new special file")
.arg(Arg::new("file_name").required(true))
.arg(Arg::new("file_type").required(true)),
h_sfo_create_special_file,
)
.with_command(
Command::new("sfo-remove")
.about("Remove a special file")
.arg(Arg::new("file_name").required(true))
.arg(Arg::new("file_type").required(true)),
h_sfo_remove_special_file,
)
.with_command(
Command::new("sfo-get-path")
.arg(Arg::new("file_name").required(true))
.arg(Arg::new("file_type").required(true))
.about("Get the path of a special file"),
h_sfo_get_special_file_path,
)
.with_command(
Command::new("sfo-read")
.about("Read a special file contents")
.arg(Arg::new("file_name").required(true))
.arg(Arg::new("file_type").required(true))
.arg(
Arg::new("interpret as ascii")
.action(ArgAction::SetTrue)
.short('a')
.long("ascii"),
),
h_sfo_read_from_special_file,
)
.with_command(
Command::new("sfo-write")
.about("Write to a special file")
.arg(Arg::new("file_name").required(true))
.arg(Arg::new("file_type").required(true))
.arg(Arg::new("input").required(true))
.arg(
Arg::new("append")
.action(ArgAction::SetTrue)
.short('a')
.long("append"),
),
h_sfo_write_to_special_file,
)
}