use super::{OwnedEditAction, OwnedMatchOptions};
use crate::diagnostic::{Diagnostic, DiagnosticCode, DiagnosticResult};
use crate::{EditActionArgs, TickStatus};
fn conflicting_edit_flag_error(action: &str, flag: &str) -> Diagnostic {
Diagnostic::new(
DiagnosticCode::E0802ConflictingArgs,
format!("Cannot use {flag} with --{action}"),
"edit action",
)
}
fn reject_selector_flags_for_value_action(
action: &str,
args: &EditActionArgs,
) -> DiagnosticResult<()> {
if args.at.is_some() {
return Err(conflicting_edit_flag_error(action, "--at"));
}
if args.exact {
return Err(conflicting_edit_flag_error(action, "--exact"));
}
if args.regex {
return Err(conflicting_edit_flag_error(action, "--regex"));
}
if args.all {
return Err(conflicting_edit_flag_error(action, "--all"));
}
Ok(())
}
pub(crate) fn owned_edit_action(args: &EditActionArgs) -> DiagnosticResult<OwnedEditAction> {
let action_count = usize::from(args.set.is_some())
+ usize::from(args.add.is_some())
+ usize::from(args.tick.is_some())
+ usize::from(args.remove.is_some());
if action_count == 0 {
if args.stdin {
reject_selector_flags_for_value_action("set (inferred from --stdin)", args)?;
return Ok(OwnedEditAction::Set {
value: Some(None),
stdin: true,
});
}
return Err(Diagnostic::new(
DiagnosticCode::E0801MissingRequiredArg,
"exactly one edit action is required",
"edit action",
));
}
if action_count > 1 {
return Err(Diagnostic::new(
DiagnosticCode::E0802ConflictingArgs,
"Cannot use multiple edit actions at once",
"edit action",
));
}
if let Some(value) = &args.set {
reject_selector_flags_for_value_action("set", args)?;
return Ok(OwnedEditAction::Set {
value: Some(value.clone()),
stdin: args.stdin,
});
}
if let Some(value) = &args.add {
reject_selector_flags_for_value_action("add", args)?;
return Ok(OwnedEditAction::Add {
value: Some(value.clone()),
stdin: args.stdin,
});
}
if let Some(status) = args.tick {
if args.stdin {
return Err(conflicting_edit_flag_error("tick", "--stdin"));
}
if args.all {
return Err(Diagnostic::new(
DiagnosticCode::E0802ConflictingArgs,
"Cannot use --all with --tick; tick requires a single target",
"edit action",
));
}
return Ok(OwnedEditAction::Tick {
match_opts: OwnedMatchOptions {
pattern: None,
at: args.at,
exact: args.exact,
regex: args.regex,
all: args.all,
},
status,
});
}
if args.remove.is_some() {
if args.stdin {
return Err(conflicting_edit_flag_error("remove", "--stdin"));
}
return Ok(OwnedEditAction::Remove {
match_opts: OwnedMatchOptions {
pattern: args.remove.clone().flatten(),
at: args.at,
exact: args.exact,
regex: args.regex,
all: args.all,
},
});
}
unreachable!("action_count guarantees exactly one action branch")
}
pub(crate) fn set_action(value: Option<String>, stdin: bool) -> OwnedEditAction {
OwnedEditAction::Set {
value: Some(value),
stdin,
}
}
pub(crate) fn add_action(value: Option<String>, stdin: bool) -> OwnedEditAction {
OwnedEditAction::Add {
value: Some(value),
stdin,
}
}
pub(crate) fn remove_action(match_opts: OwnedMatchOptions) -> OwnedEditAction {
OwnedEditAction::Remove { match_opts }
}
pub(crate) fn tick_action(match_opts: OwnedMatchOptions, status: TickStatus) -> OwnedEditAction {
OwnedEditAction::Tick { match_opts, status }
}