use crate::command_options::{
Arity, DEFAULT_MODE, OptionError, OptionSpec, ParsedOptions, UNREAD, parse_options, row,
};
use crate::command_options_query::{WrapperFlags, split_wrapper_flags};
use crate::escape_hatch::WORKTREE_ENFORCEMENT_ESCAPE_HATCH;
use std::ffi::OsString;
pub const MIXED: u16 = 1;
pub const SOFT: u16 = 2;
pub const HARD: u16 = 3;
pub const MERGE: u16 = 4;
pub const KEEP: u16 = 5;
pub const RESET_TABLE: &[OptionSpec] = &[
row(UNREAD, Some(b'q'), Some("quiet"), Arity::None, true),
row(UNREAD, None, Some("no-refresh"), Arity::None, true),
row(MIXED, None, Some("mixed"), Arity::None, false),
row(SOFT, None, Some("soft"), Arity::None, false),
row(HARD, None, Some("hard"), Arity::None, false),
row(MERGE, None, Some("merge"), Arity::None, false),
row(KEEP, None, Some("keep"), Arity::None, false),
row(
UNREAD,
None,
Some("recurse-submodules"),
Arity::Optional,
true,
),
row(UNREAD, Some(b'p'), Some("patch"), Arity::None, true),
row(UNREAD, None, Some("auto-advance"), Arity::None, true),
row(UNREAD, Some(b'U'), Some("unified"), Arity::Required, false),
row(
UNREAD,
None,
Some("inter-hunk-context"),
Arity::Required,
false,
),
row(UNREAD, Some(b'N'), Some("intent-to-add"), Arity::None, true),
row(
UNREAD,
None,
Some("pathspec-from-file"),
Arity::Required,
true,
),
row(UNREAD, None, Some("pathspec-file-nul"), Arity::None, true),
];
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum ResetMode {
Mixed,
Soft,
Hard,
Merge,
Keep,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct ResetRegion {
pub mode: Option<ResetMode>,
pub wrapper: WrapperFlags,
}
fn mode_of(id: u16) -> Option<ResetMode> {
if id == MIXED {
return Some(ResetMode::Mixed);
}
if id == SOFT {
return Some(ResetMode::Soft);
}
if id == HARD {
return Some(ResetMode::Hard);
}
if id == MERGE {
return Some(ResetMode::Merge);
}
if id == KEEP {
return Some(ResetMode::Keep);
}
return None;
}
pub fn parse_reset_region(
region: &[OsString],
wrapper_flags: &[&[u8]],
) -> Result<ResetRegion, OptionError> {
let mut flags: Vec<&[u8]> = Vec::<&[u8]>::with_capacity(wrapper_flags.len() + 1);
flags.push(WORKTREE_ENFORCEMENT_ESCAPE_HATCH.as_bytes());
for flag in wrapper_flags {
flags.push(*flag);
}
let parsed: ParsedOptions = parse_options(region, RESET_TABLE, DEFAULT_MODE, flags.as_slice())?;
let mut mode: Option<ResetMode> = None;
for occurrence in &parsed.occurrences {
let stated: Option<ResetMode> = mode_of(occurrence.id);
if stated.is_some() {
mode = stated;
}
}
return Ok(ResetRegion {
mode,
wrapper: split_wrapper_flags(parsed.wrapper.as_slice()),
});
}
pub fn reset_changes_worktree(region: &ResetRegion) -> bool {
return region.mode == Some(ResetMode::Hard)
|| region.mode == Some(ResetMode::Merge)
|| region.mode == Some(ResetMode::Keep);
}
#[cfg(test)]
#[path = "command_reset_tests.rs"]
mod tests;