use std::path::PathBuf;
use clap::Args;
use clap::Parser;
use clap::value_parser;
use directories::ProjectDirs;
use lazy_static::lazy_static;
lazy_static! {
pub(crate) static ref PROJECT_NAME: String =
env!("CARGO_CRATE_NAME").to_uppercase().to_string();
pub(crate) static ref DATA_FOLDER: Option<PathBuf> =
std::env::var(format!("{}_DATA", PROJECT_NAME.clone()))
.ok()
.map(PathBuf::from);
pub(crate) static ref CONFIG_FOLDER: Option<PathBuf> =
std::env::var(format!("{}_CONFIG", PROJECT_NAME.clone()))
.ok()
.map(PathBuf::from);
pub(crate) static ref LOG_ENV: String = format!("{}_LOGLEVEL", PROJECT_NAME.clone());
pub(crate) static ref LOG_FILE: String = format!("{}.log", env!("CARGO_PKG_NAME"));
}
pub(crate) const DEFAULT_INTERRUPT_CYCLE: u32 = 1_000_000;
pub(crate) const MANIFEST_DIR: &str = env!("CARGO_MANIFEST_DIR");
pub(crate) const EXAMPLE_PROGRAM_PATH: &str = "examples/program.tasm";
include!(concat!(env!("OUT_DIR"), "/version.rs"));
#[derive(Debug, Clone, PartialEq, Parser)]
#[command(author, version = version(), about)]
pub(crate) struct TuiArgs {
#[command(flatten)]
pub input_args: Option<InputArgs>,
#[arg(long, value_name = "file", group = "state")]
pub initial_state: Option<String>,
#[arg(
long,
value_name = "u32",
default_value = DEFAULT_INTERRUPT_CYCLE.to_string(),
value_parser = value_parser!(u32).range(1..)
)]
pub interrupt_cycle: u32,
}
#[derive(Debug, Clone, PartialEq, Args)]
#[group(required = false, multiple = true, conflicts_with = "state")]
pub(crate) struct InputArgs {
pub program: String,
#[arg(short, long, value_name = "file")]
pub input: Option<String>,
#[arg(short, long, value_name = "file")]
pub non_determinism: Option<String>,
}
impl Default for TuiArgs {
fn default() -> Self {
let program = format!("{MANIFEST_DIR}/{EXAMPLE_PROGRAM_PATH}");
let input_args = Some(InputArgs {
program,
input: None,
non_determinism: None,
});
Self {
input_args,
initial_state: None,
interrupt_cycle: DEFAULT_INTERRUPT_CYCLE,
}
}
}
fn project_directory() -> Option<ProjectDirs> {
ProjectDirs::from(
"org.triton-vm.triton-tui",
"Triton VM",
env!("CARGO_PKG_NAME"),
)
}
pub(crate) fn get_data_dir() -> PathBuf {
DATA_FOLDER
.clone()
.or_else(|| project_directory().map(|dirs| dirs.data_local_dir().to_path_buf()))
.unwrap_or_else(|| PathBuf::from(".").join(".data"))
}
pub(crate) fn get_config_dir() -> PathBuf {
CONFIG_FOLDER
.clone()
.or_else(|| project_directory().map(|dirs| dirs.config_local_dir().to_path_buf()))
.unwrap_or_else(|| PathBuf::from(".").join(".config"))
}
pub(crate) fn version() -> String {
let author = clap::crate_authors!();
let config_dir_path = get_config_dir().display().to_string();
let data_dir_path = get_data_dir().display().to_string();
format!(
"{CURR_VERSION}\n\n\
Authors: {author}\n\n\
Config directory: {config_dir_path}\n\
Data directory: {data_dir_path}"
)
}