A file-based task manager
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Clean up warnings: collapse write_task/write_attrs wrappers

Removed the parameterless `write_task` / `write_attrs` convenience
wrappers (only ever used from tests after the rich-message refactor)
and merged them into a single function each that always takes
event/detail. Test call sites pass `"write", None` explicitly. The
write_task_with_event / write_attrs_with_event names go away.

Also:
- Replace two clippy `get(k).is_none()` warnings with `!contains_key(k)`.

Build is now warning-free; clippy --all-targets is silent.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

+45 -29
+8 -16
src/backend.rs
··· 425 425 Ok(None) 426 426 } 427 427 428 - pub fn write_task(store: &dyn Store, id: Id, title: &str, body: &str, loc: Loc) -> Result<()> { 429 - write_task_with_event(store, id, title, body, loc, "write", None) 430 - } 431 - 432 - pub fn write_task_with_event( 428 + pub fn write_task( 433 429 store: &dyn Store, 434 430 id: Id, 435 431 title: &str, ··· 518 514 .collect()) 519 515 } 520 516 521 - pub fn write_attrs(store: &dyn Store, id: Id, attrs: &BTreeMap<String, String>) -> Result<()> { 522 - write_attrs_with_event(store, id, attrs, "write", None) 523 - } 524 - 525 - pub fn write_attrs_with_event( 517 + pub fn write_attrs( 526 518 store: &dyn Store, 527 519 id: Id, 528 520 attrs: &BTreeMap<String, String>, ··· 892 884 let id2 = next_id(s).unwrap(); 893 885 assert_eq!(id2, Id(2)); 894 886 895 - write_task(s, id, "title", "body", Loc::Active).unwrap(); 887 + write_task(s, id, "title", "body", Loc::Active, "write", None).unwrap(); 896 888 let (t, b, loc) = read_task(s, id).unwrap().unwrap(); 897 889 assert_eq!(t, "title"); 898 890 assert_eq!(b, "body"); ··· 905 897 906 898 let mut attrs = BTreeMap::new(); 907 899 attrs.insert("foo".to_string(), "bar".to_string()); 908 - write_attrs(s, id, &attrs).unwrap(); 900 + write_attrs(s, id, &attrs, "write", None).unwrap(); 909 901 assert_eq!(read_attrs(s, id).unwrap(), attrs); 910 902 911 903 let mut bl = HashSet::new(); ··· 915 907 assert_eq!(read_backlinks(s, id).unwrap(), bl); 916 908 917 909 // Empty attrs/backlinks delete the blob. 918 - write_attrs(s, id, &BTreeMap::new()).unwrap(); 910 + write_attrs(s, id, &BTreeMap::new(), "write", None).unwrap(); 919 911 assert!(read_attrs(s, id).unwrap().is_empty()); 920 912 write_backlinks(s, id, &HashSet::new()).unwrap(); 921 913 assert!(read_backlinks(s, id).unwrap().is_empty()); ··· 1000 992 fn test_list_active_archive_helpers() { 1001 993 let (_d, file, git) = store_pair(); 1002 994 for s in [file.as_ref(), git.as_ref()] { 1003 - write_task(s, Id(1), "t1", "", Loc::Active).unwrap(); 1004 - write_task(s, Id(2), "t2", "", Loc::Archived).unwrap(); 1005 - write_task(s, Id(3), "t3", "", Loc::Active).unwrap(); 995 + write_task(s, Id(1), "t1", "", Loc::Active, "write", None).unwrap(); 996 + write_task(s, Id(2), "t2", "", Loc::Archived, "write", None).unwrap(); 997 + write_task(s, Id(3), "t3", "", Loc::Active, "write", None).unwrap(); 1006 998 assert_eq!(list_active(s).unwrap(), vec![Id(1), Id(3)]); 1007 999 assert_eq!(list_archive(s).unwrap(), vec![Id(2)]); 1008 1000 }
+37 -13
src/workspace.rs
··· 380 380 381 381 pub fn new_task(&self, title: String, body: String) -> Result<Task> { 382 382 let id = self.next_id()?; 383 - backend::write_task_with_event( 383 + backend::write_task( 384 384 self.store(), 385 385 id, 386 386 &title, ··· 449 449 Some(l) => l, 450 450 None => Loc::Active, 451 451 }; 452 - backend::write_task_with_event( 452 + backend::write_task( 453 453 self.store(), 454 454 task.id, 455 455 &task.title, ··· 458 458 "edited", 459 459 None, 460 460 )?; 461 - backend::write_attrs_with_event(self.store(), task.id, &task.attributes, "edited", None)?; 461 + backend::write_attrs(self.store(), task.id, &task.attributes, "edited", None)?; 462 462 self.log(task.id, "edited", None)?; 463 463 // After editing, refresh stack title for this id. 464 464 self.update_stack_title(task.id, &task.title)?; ··· 508 508 } 509 509 let mut attrs = backend::read_attrs(self.store(), id)?; 510 510 attrs.insert(key.to_string(), value.to_string()); 511 - backend::write_attrs_with_event(self.store(), id, &attrs, "prop-set", Some(key))?; 511 + backend::write_attrs(self.store(), id, &attrs, "prop-set", Some(key))?; 512 512 self.log(id, "prop-set", Some(key))?; 513 513 if old_target != new_target { 514 514 if let Some(t) = old_target { ··· 522 522 } else { 523 523 let mut attrs = backend::read_attrs(self.store(), id)?; 524 524 attrs.insert(key.to_string(), value.to_string()); 525 - backend::write_attrs_with_event(self.store(), id, &attrs, "prop-set", Some(key))?; 525 + backend::write_attrs(self.store(), id, &attrs, "prop-set", Some(key))?; 526 526 self.log(id, "prop-set", Some(key)) 527 527 } 528 528 } ··· 532 532 let mut attrs = backend::read_attrs(self.store(), id)?; 533 533 let removed = attrs.remove(key); 534 534 if let Some(prev) = removed { 535 - backend::write_attrs_with_event(self.store(), id, &attrs, "prop-unset", Some(key))?; 535 + backend::write_attrs(self.store(), id, &attrs, "prop-unset", Some(key))?; 536 536 self.log(id, "prop-unset", Some(key))?; 537 537 if let Some(pair) = inverse_pair_for(key) 538 538 && let Some(t) = parse_internal_link(&prev) ··· 593 593 } else { 594 594 attrs.insert(inverse_key.to_string(), format_link_list(&ids)); 595 595 } 596 - backend::write_attrs(self.store(), target, &attrs)?; 596 + backend::write_attrs(self.store(), target, &attrs, "prop-set", Some(inverse_key))?; 597 597 self.log(target, "prop-set", Some(inverse_key))?; 598 598 Ok(()) 599 599 } ··· 1701 1701 let assigned_link = format!("[[{target_ns}/tsk-{}]]", src_id.0); 1702 1702 let mut my_attrs = backend::read_attrs(self.store(), src_id)?; 1703 1703 my_attrs.insert("assigned".into(), assigned_link.clone()); 1704 - backend::write_attrs(self.store(), src_id, &my_attrs)?; 1704 + backend::write_attrs( 1705 + self.store(), 1706 + src_id, 1707 + &my_attrs, 1708 + "assigned", 1709 + Some(&assigned_link), 1710 + )?; 1705 1711 self.log(src_id, "assigned", Some(&assigned_link))?; 1706 1712 Ok(key) 1707 1713 } ··· 1751 1757 // Drop any "assigned" carried over — it was set by the source workspace 1752 1758 // before export; the new local copy isn't itself assigned anywhere. 1753 1759 attrs.remove("assigned"); 1754 - backend::write_attrs(self.store(), new_id, &attrs)?; 1760 + backend::write_attrs(self.store(), new_id, &attrs, "accepted", None)?; 1755 1761 self.store().delete(&key)?; 1756 1762 self.log( 1757 1763 new_id, ··· 1991 1997 let t = ws.new_task("Indexed".into(), "ok".into()).unwrap(); 1992 1998 ws.push_task(t).unwrap(); 1993 1999 // Write an unindexed task directly to the store. 1994 - backend::write_task(ws.store(), Id(999), "orphan", "", Loc::Active).unwrap(); 2000 + backend::write_task( 2001 + ws.store(), 2002 + Id(999), 2003 + "orphan", 2004 + "", 2005 + Loc::Active, 2006 + "write", 2007 + None, 2008 + ) 2009 + .unwrap(); 1995 2010 1996 2011 let active_before = backend::list_active(ws.store()).unwrap(); 1997 2012 assert!(active_before.contains(&Id(999))); ··· 2313 2328 ); 2314 2329 2315 2330 // command_clean: orphan a task in active that isn't on the stack 2316 - backend::write_task(ws.store(), Id(99_999), "orphan", "", Loc::Active).unwrap(); 2331 + backend::write_task( 2332 + ws.store(), 2333 + Id(99_999), 2334 + "orphan", 2335 + "", 2336 + Loc::Active, 2337 + "write", 2338 + None, 2339 + ) 2340 + .unwrap(); 2317 2341 assert!( 2318 2342 backend::list_active(ws.store()) 2319 2343 .unwrap() ··· 2863 2887 ws.set_property(c2_id, "parent", &format!("[[{p2_id}]]")) 2864 2888 .unwrap(); 2865 2889 let old = backend::read_attrs(ws.store(), parent_id).unwrap(); 2866 - assert!(old.get("children").is_none(), "old parent should be empty"); 2890 + assert!(!old.contains_key("children"), "old parent should be empty"); 2867 2891 let new = backend::read_attrs(ws.store(), p2_id).unwrap(); 2868 2892 assert!( 2869 2893 new.get("children") ··· 2952 2976 2953 2977 // Unset removes the property. 2954 2978 ws.unset_property(id1, "priority").unwrap(); 2955 - assert!(ws.properties(id1).unwrap().get("priority").is_none()); 2979 + assert!(!ws.properties(id1).unwrap().contains_key("priority")); 2956 2980 // Unset of non-existent is fine. 2957 2981 ws.unset_property(id1, "nope").unwrap(); 2958 2982 }