Use ULID suffix for short display IDs and resolution

Amolith created

Change summary

src/db.rs              |  5 +++--
tests/cli_dep.rs       | 10 +++++++---
tests/cli_list_show.rs | 12 +++++++-----
tests/cli_log.rs       |  5 ++++-
4 files changed, 21 insertions(+), 11 deletions(-)

Detailed changes

src/db.rs 🔗

@@ -143,7 +143,7 @@ impl TaskId {
     }
 
     pub fn short(&self) -> String {
-        self.0.chars().take(7).collect()
+        self.0[self.0.len() - 7..].to_string()
     }
 }
 
@@ -491,9 +491,10 @@ pub fn resolve_task_id(store: &Store, raw: &str, include_deleted: bool) -> Resul
         store.list_tasks()?
     };
 
+    let upper = raw.to_ascii_uppercase();
     let matches: Vec<TaskId> = tasks
         .into_iter()
-        .filter(|t| t.id.as_str().starts_with(raw))
+        .filter(|t| t.id.as_str().ends_with(&upper))
         .map(|t| t.id)
         .collect();
 

tests/cli_dep.rs 🔗

@@ -103,9 +103,13 @@ fn dep_tree_shows_children() {
         .current_dir(&tmp)
         .assert()
         .success()
-        .stdout(predicate::str::contains(&parent[..7]))
-        .stdout(predicate::str::contains(&subtask_one_id[..7]))
-        .stdout(predicate::str::contains(&subtask_two_id[..7]));
+        .stdout(predicate::str::contains(&parent[parent.len() - 7..]))
+        .stdout(predicate::str::contains(
+            &subtask_one_id[subtask_one_id.len() - 7..],
+        ))
+        .stdout(predicate::str::contains(
+            &subtask_two_id[subtask_two_id.len() - 7..],
+        ));
 }
 
 #[test]

tests/cli_list_show.rs 🔗

@@ -168,7 +168,7 @@ fn show_displays_task() {
         .assert()
         .success()
         .stdout(predicate::str::contains("Details here"))
-        .stdout(predicate::str::contains(&id[..7]));
+        .stdout(predicate::str::contains(&id[id.len() - 7..]));
 }
 
 #[test]
@@ -248,10 +248,12 @@ fn show_annotates_closed_blockers() {
         .assert()
         .success()
         .stdout(predicate::str::contains("blockers"))
-        .stdout(predicate::str::contains(&open_blocker[..7]))
+        .stdout(predicate::str::contains(
+            &open_blocker[open_blocker.len() - 7..],
+        ))
         .stdout(predicate::str::contains(&format!(
             "{} [closed]",
-            &closed_blocker[..7]
+            &closed_blocker[closed_blocker.len() - 7..]
         )));
 }
 
@@ -280,7 +282,7 @@ fn show_all_closed_blockers_prefixed() {
         .success()
         .stdout(predicate::str::contains("blocker"))
         .stdout(predicate::str::contains("[all closed]"))
-        .stdout(predicate::str::contains(&blocker[..7]));
+        .stdout(predicate::str::contains(&blocker[blocker.len() - 7..]));
 }
 
 #[test]
@@ -304,7 +306,7 @@ fn show_single_open_blocker_singular_label() {
 
     // Singular "blocker", no "blockers".
     assert!(stdout.contains("blocker"));
-    assert!(stdout.contains(&blocker[..7]));
+    assert!(stdout.contains(&blocker[blocker.len() - 7..]));
     // Should not contain [closed] or [all closed].
     assert!(!stdout.contains("[closed]"));
 }

tests/cli_log.rs 🔗

@@ -38,7 +38,10 @@ fn log_human_reports_task_id() {
         .current_dir(&tmp)
         .assert()
         .success()
-        .stdout(predicate::str::contains(format!("logged to {}", &id[..7])));
+        .stdout(predicate::str::contains(format!(
+            "logged to {}",
+            &id[id.len() - 7..]
+        )));
 }
 
 #[test]