Skip to main content

track/models/
vcs_mode.rs

1use serde::Serialize;
2use std::fmt;
3use std::str::FromStr;
4
5/// Version control backend for task workspaces.
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Default)]
7#[serde(rename_all = "lowercase")]
8pub enum VcsMode {
9    /// Jujutsu via agent-skill-jj (`jj-task` + `$jj` skill). Default.
10    #[default]
11    Jj,
12    /// Plain git worktrees and branches.
13    Git,
14}
15
16impl VcsMode {
17    pub const KEY: &'static str = "vcs_mode";
18
19    pub fn as_str(self) -> &'static str {
20        match self {
21            Self::Jj => "jj",
22            Self::Git => "git",
23        }
24    }
25}
26
27impl fmt::Display for VcsMode {
28    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
29        f.write_str(self.as_str())
30    }
31}
32
33impl FromStr for VcsMode {
34    type Err = String;
35
36    fn from_str(s: &str) -> Result<Self, Self::Err> {
37        match s.trim().to_ascii_lowercase().as_str() {
38            "jj" | "jujutsu" => Ok(Self::Jj),
39            "git" => Ok(Self::Git),
40            other => Err(format!(
41                "unknown vcs mode '{other}' (expected 'jj' or 'git')"
42            )),
43        }
44    }
45}
46
47#[cfg(test)]
48mod tests {
49    use super::*;
50
51    #[test]
52    fn parse_vcs_mode() {
53        assert_eq!("jj".parse::<VcsMode>().unwrap(), VcsMode::Jj);
54        assert_eq!("git".parse::<VcsMode>().unwrap(), VcsMode::Git);
55        assert!("svn".parse::<VcsMode>().is_err());
56    }
57}