1#![deny(rust_2018_idioms)]
4
5pub const SCHEMA_VERSION: &str = "1.0";
9
10pub fn new_task_id() -> String {
16 format!(
17 "tj-{}",
18 &ulid::Ulid::new().to_string()[10..20].to_lowercase()
19 )
20}
21
22#[cfg(test)]
23mod task_id_tests {
24 use super::new_task_id;
25 use std::collections::HashSet;
26
27 #[test]
28 fn new_task_id_has_expected_shape() {
29 let id = new_task_id();
30 assert!(id.starts_with("tj-"), "{id}");
31 assert_eq!(id.len(), 13, "{id}");
32 assert!(
33 id[3..]
34 .chars()
35 .all(|c| c.is_ascii_lowercase() || c.is_ascii_digit()),
36 "{id}"
37 );
38 }
39
40 #[test]
41 fn new_task_id_unique_over_ten_thousand() {
42 let mut seen = HashSet::with_capacity(10_000);
43 for _ in 0..10_000 {
44 let id = new_task_id();
45 assert!(seen.insert(id.clone()), "collision: {id}");
46 }
47 }
48}
49
50pub mod artifacts;
51pub mod classifier;
52pub mod completeness;
53pub mod consolidate;
54pub mod db;
55pub mod dream;
56pub mod embed;
57pub mod event;
58pub mod frontmatter;
59pub mod fts;
60pub mod llm;
61pub mod memory;
62pub mod pack;
63pub mod paths;
64pub mod project_hash;
65pub mod recall;
66pub mod reminder;
67pub mod session;
68pub mod session_id;
69pub mod storage;
70pub mod title;
71
72#[cfg(test)]
73mod schema_version_tests {
74 #[test]
78 fn pack_assembler_does_not_inline_schema_version_literal() {
79 let pack_src = include_str!("pack.rs");
80 assert!(
81 !pack_src.contains("schema_version: \""),
82 "pack.rs has an inline schema_version string literal — use crate::SCHEMA_VERSION"
83 );
84 }
85
86 #[test]
87 fn schema_version_matches_event_default() {
88 let evt = crate::event::Event::new(
89 "tj-x",
90 crate::event::EventType::Open,
91 crate::event::Author::User,
92 crate::event::Source::Cli,
93 "x".into(),
94 );
95 assert_eq!(evt.schema_version, super::SCHEMA_VERSION);
96 }
97}