1#[derive(Debug, PartialEq, Eq)]
11pub struct Plan {
12 pub base: String,
13 pub delete_feature: Option<String>,
15}
16
17pub fn plan(current: Option<&str>, base: &str, dirty: bool) -> Result<Plan, String> {
20 if dirty {
21 return Err("working tree has uncommitted changes — commit or stash before stmb".into());
22 }
23 match current {
24 None => Err("detached HEAD — checkout a branch before stmb".into()),
25 Some(cur) if cur == base => Ok(Plan {
26 base: base.to_string(),
27 delete_feature: None,
28 }),
29 Some(cur) => Ok(Plan {
30 base: base.to_string(),
31 delete_feature: Some(cur.to_string()),
32 }),
33 }
34}
35
36#[cfg(test)]
37mod tests {
38 use super::*;
39
40 #[test]
41 fn refuses_dirty_tree() {
42 assert!(plan(Some("feat"), "dev", true)
43 .unwrap_err()
44 .contains("uncommitted"));
45 }
46
47 #[test]
48 fn refuses_detached() {
49 assert!(plan(None, "dev", false).unwrap_err().contains("detached"));
50 }
51
52 #[test]
53 fn on_base_deletes_nothing() {
54 assert_eq!(
55 plan(Some("dev"), "dev", false).unwrap(),
56 Plan {
57 base: "dev".into(),
58 delete_feature: None
59 }
60 );
61 }
62
63 #[test]
64 fn on_feature_deletes_it() {
65 assert_eq!(
66 plan(Some("feat-x"), "dev", false).unwrap(),
67 Plan {
68 base: "dev".into(),
69 delete_feature: Some("feat-x".into())
70 }
71 );
72 }
73}