use std::path::PathBuf;
use clap::{Parser, ValueEnum};
#[derive(Debug, Clone, Parser)]
#[command(name = "ripsync", version, about, long_about = None)]
pub struct Args {
pub src: PathBuf,
pub dst: PathBuf,
#[arg(short = 'n', long)]
pub dry_run: bool,
#[arg(long)]
pub delete: bool,
#[arg(long)]
pub yes: bool,
#[arg(short = 'c', long)]
pub checksum: bool,
#[arg(long)]
pub delta: bool,
#[arg(long, value_enum, default_value_t = ReflinkArg::Auto)]
pub reflink: ReflinkArg,
#[arg(long, value_enum, default_value_t = FsyncArg::Auto)]
pub fsync: FsyncArg,
#[arg(long, value_enum, default_value_t = BackendArg::Auto)]
pub backend: BackendArg,
#[arg(long, value_enum, default_value_t = VerifyArg::None)]
pub verify: VerifyArg,
#[arg(long = "no-index", action = clap::ArgAction::SetFalse, default_value_t = true)]
pub index: bool,
#[arg(short = 'H', long)]
pub hard_links: bool,
#[arg(short = 'S', long)]
pub sparse: bool,
#[arg(long)]
pub xattrs: bool,
#[arg(long)]
pub acls: bool,
#[arg(long)]
pub owner: bool,
#[arg(long)]
pub group: bool,
#[arg(long, value_name = "PAT")]
pub exclude: Vec<String>,
#[arg(long, value_name = "PAT")]
pub include: Vec<String>,
#[arg(long, value_name = "RULE", allow_hyphen_values = true)]
pub filter: Vec<String>,
#[arg(long, value_name = "FILE")]
pub files_from: Option<PathBuf>,
#[arg(long, value_name = "RATE")]
pub bwlimit: Option<String>,
#[arg(long)]
pub partial: bool,
#[arg(long)]
pub watch: bool,
#[arg(long, value_name = "MS", default_value_t = 300)]
pub debounce: u64,
#[arg(long)]
pub no_tui: bool,
#[arg(long, value_enum, default_value_t = OutputFormat::Human)]
pub output: OutputFormat,
#[arg(short = 'j', long, value_name = "N")]
pub threads: Option<usize>,
#[arg(long, value_enum, default_value_t = ProfileArg::Auto)]
pub profile: ProfileArg,
#[arg(short = 'v', long, action = clap::ArgAction::Count)]
pub verbose: u8,
#[arg(short = 'q', long)]
pub quiet: bool,
#[arg(long)]
pub stats: bool,
#[arg(long, hide = true)]
pub server: bool,
#[arg(short = 'e', long, value_name = "CMD", default_value = "ssh")]
pub rsh: String,
#[arg(short = 'W', long = "whole-file")]
pub whole_file: bool,
#[arg(short = 'z', long)]
pub compress: bool,
#[arg(long, value_name = "N", default_value_t = 3)]
pub compress_level: i32,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
pub enum ProfileArg {
Auto,
Low,
Balanced,
High,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
pub enum OutputFormat {
Human,
Json,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
pub enum ReflinkArg {
Auto,
Always,
Never,
}
impl From<ReflinkArg> for ripsync_core::copy::ReflinkMode {
fn from(a: ReflinkArg) -> Self {
match a {
ReflinkArg::Auto => Self::Auto,
ReflinkArg::Always => Self::Always,
ReflinkArg::Never => Self::Never,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
pub enum FsyncArg {
Auto,
Always,
Never,
}
impl From<FsyncArg> for ripsync_core::copy::FsyncMode {
fn from(a: FsyncArg) -> Self {
match a {
FsyncArg::Auto => Self::Auto,
FsyncArg::Always => Self::Always,
FsyncArg::Never => Self::Never,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
pub enum BackendArg {
Auto,
Uring,
Portable,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
pub enum VerifyArg {
None,
Changed,
All,
}
impl From<VerifyArg> for ripsync_core::verify::VerifyMode {
fn from(value: VerifyArg) -> Self {
match value {
VerifyArg::None => Self::None,
VerifyArg::Changed => Self::Changed,
VerifyArg::All => Self::All,
}
}
}
impl From<BackendArg> for ripsync_core::apply::Backend {
fn from(a: BackendArg) -> Self {
match a {
BackendArg::Auto => Self::Auto,
BackendArg::Uring => Self::Uring,
BackendArg::Portable => Self::Portable,
}
}
}
impl Args {
#[must_use]
pub fn resolve_profile(&self) -> ripsync_core::tune::Profile {
use ripsync_core::tune::Profile;
match self.profile {
ProfileArg::Auto => ripsync_core::tune::detect(),
ProfileArg::Low => Profile::Low,
ProfileArg::Balanced => Profile::Balanced,
ProfileArg::High => Profile::High,
}
}
#[must_use]
pub fn thread_count(&self) -> usize {
if let Some(t) = self.threads {
return t;
}
self.resolve_profile().params(num_cpus::get()).threads
}
}