magi-code 0.96.1

Repository-aware CLI coding agent for terminal work
Documentation
pub(crate) fn parse_rewind_target(arg: Option<&str>) -> Result<ParsedRewindTarget, String> {
    let Some(arg) = arg.map(str::trim).filter(|arg| !arg.is_empty()) else {
        return Ok(ParsedRewindTarget::NeedsSelection);
    };
    let mut dry_run = false;
    let mut target = None;
    let mut mode = super::RewindMode::default();
    let mut tokens = arg.split_whitespace();
    while let Some(token) = tokens.next() {
        match token {
            "--dry-run" => dry_run = true,
            "--mode" => {
                mode = match tokens.next() {
                    Some("conversation") => super::RewindMode::Conversation,
                    Some("files") => super::RewindMode::Files,
                    Some("both") => super::RewindMode::Both,
                    _ => return Err("mode must be conversation, files, or both".to_string()),
                };
            }
            "--to" => {
                let Some(value) = tokens.next() else {
                    return Err("missing turn after --to".to_string());
                };
                target = Some(parse_positive_turn(value)?);
            }
            value if target.is_none() => target = Some(parse_positive_turn(value)?),
            _ => return Err("unexpected rewind argument".to_string()),
        }
    }
    let Some(target_turn) = target else {
        return Err("missing rewind target turn".to_string());
    };
    Ok(ParsedRewindTarget::Target {
        target_turn,
        dry_run,
        mode,
    })
}

fn parse_positive_turn(value: &str) -> Result<u64, String> {
    if value.contains("..") || value.starts_with('-') {
        return Err("rewind target must be a positive turn number".to_string());
    }
    let turn = value
        .parse::<u64>()
        .map_err(|_| "rewind target must be a positive turn number".to_string())?;
    if turn == 0 {
        return Err("rewind target must be positive".to_string());
    }
    Ok(turn)
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum ParsedRewindTarget {
    NeedsSelection,
    Target {
        target_turn: u64,
        dry_run: bool,
        mode: super::RewindMode,
    },
}