use std::{
fmt::Display,
net::{IpAddr, Ipv4Addr},
path::PathBuf,
};
use crate::{commands::PutType, wasm_runtime::ExecutorConfig};
use clap::ValueEnum;
use freenet::{config::ConfigPathsArgs, dev_tool::OperationMode};
use semver::Version;
#[derive(clap::Parser, Clone)]
#[clap(name = "Freenet Development Tool")]
#[clap(author = "The Freenet Project Inc.")]
#[clap(version = env!("CARGO_PKG_VERSION"))]
pub struct Config {
#[clap(subcommand)]
pub sub_command: SubCommand,
#[clap(flatten)]
pub additional: BaseConfig,
}
#[derive(clap::Parser, Clone)]
pub struct BaseConfig {
#[clap(flatten)]
pub(crate) paths: ConfigPathsArgs,
#[arg(value_enum, default_value_t=OperationMode::Local, env = "MODE")]
pub mode: OperationMode,
#[arg(short, long, default_value = "7509", env = "WS_API_PORT")]
pub(crate) port: u16,
#[arg(short, long, default_value_t = IpAddr::V4(Ipv4Addr::LOCALHOST))]
pub(crate) address: IpAddr,
}
#[derive(clap::Subcommand, Clone)]
pub enum SubCommand {
Init(InitPackageConfig),
New(NewPackageConfig),
Build(BuildToolConfig),
Inspect(crate::inspect::InspectConfig),
Publish(PutConfig),
Query {},
Diagnostics {
#[arg(long = "contract")]
contract_keys: Vec<String>,
},
WasmRuntime(ExecutorConfig),
Execute(RunCliConfig),
Test(crate::testing::TestConfig),
NetworkMetricsServer(crate::network_metrics_server::ServerConfig),
GetContractId(crate::commands::GetContractIdConfig),
VerifyState(crate::verify_state::VerifyStateConfig),
}
impl SubCommand {
pub fn is_child(&self) -> bool {
if let SubCommand::Test(config) = self {
if let crate::testing::TestMode::Network(config) = &config.command {
return matches!(config.mode, crate::testing::network::Process::Peer);
}
}
false
}
}
#[derive(clap::Parser, Clone)]
pub struct RunCliConfig {
#[clap(subcommand)]
pub command: NodeCommand,
}
#[derive(clap::Subcommand, Clone)]
pub enum NodeCommand {
Put(PutConfig),
Get(GetConfig),
Update(UpdateConfig),
Subscribe(SubscribeConfig),
GetContractId(crate::commands::GetContractIdConfig),
}
#[derive(clap::Parser, Clone)]
pub struct GetConfig {
pub(crate) key: String,
#[arg(long)]
pub(crate) return_code: bool,
#[arg(short, long)]
pub(crate) output: Option<PathBuf>,
}
#[derive(clap::Parser, Clone)]
pub struct SubscribeConfig {
pub(crate) key: String,
#[arg(short, long)]
pub(crate) output: Option<PathBuf>,
}
#[derive(clap::Parser, Clone)]
pub struct UpdateConfig {
pub(crate) key: String,
#[arg(short, long, default_value_t = IpAddr::V4(Ipv4Addr::LOCALHOST))]
pub(crate) address: IpAddr,
pub(crate) delta: PathBuf,
pub(crate) release: bool,
}
#[derive(clap::Parser, Clone)]
pub struct PutConfig {
#[arg(long)]
pub(crate) code: PathBuf,
#[arg(long)]
pub(crate) parameters: Option<PathBuf>,
#[arg(long)]
pub(crate) release: bool,
#[clap(subcommand)]
pub(crate) package_type: PutType,
#[arg(long)]
pub(crate) subscribe: bool,
}
#[derive(clap::Parser, Clone, Debug)]
pub struct BuildToolConfig {
#[arg(long)]
pub(crate) features: Option<String>,
#[arg(long, value_parser = parse_version, default_value_t=Version::new(0, 0, 1))]
pub(crate) version: Version,
#[arg(long, value_enum, default_value_t=PackageType::default())]
pub(crate) package_type: PackageType,
#[arg(long)]
pub(crate) debug: bool,
}
#[derive(Default, Debug, Clone, Copy, ValueEnum)]
pub(crate) enum PackageType {
#[default]
Contract,
Delegate,
}
impl PackageType {
pub fn feature(&self) -> &'static str {
match self {
PackageType::Contract => "freenet-main-contract",
PackageType::Delegate => "freenet-main-delegate",
}
}
}
impl Display for PackageType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
PackageType::Contract => write!(f, "contract"),
PackageType::Delegate => write!(f, "delegate"),
}
}
}
impl Default for BuildToolConfig {
fn default() -> Self {
Self {
features: None,
version: Version::new(0, 0, 1),
package_type: PackageType::default(),
debug: false,
}
}
}
fn parse_version(src: &str) -> Result<Version, String> {
Version::parse(src).map_err(|e| e.to_string())
}
#[derive(clap::Parser, Clone)]
pub struct InitPackageConfig {
#[arg(id = "type", value_enum)]
pub(crate) kind: ContractKind,
#[arg(short, long, value_name = "PATH", value_hint = clap::ValueHint::DirPath)]
pub(crate) path: Option<PathBuf>,
}
impl From<NewPackageConfig> for InitPackageConfig {
fn from(NewPackageConfig { kind, path }: NewPackageConfig) -> Self {
Self {
kind,
path: path.into(),
}
}
}
#[derive(clap::Parser, Clone)]
pub struct NewPackageConfig {
#[arg(id = "type", value_enum)]
pub(crate) kind: ContractKind,
#[arg(value_name = "PATH", value_hint = clap::ValueHint::DirPath)]
pub(crate) path: PathBuf,
}
#[derive(clap::ValueEnum, Clone)]
pub(crate) enum ContractKind {
WebApp,
Contract,
}