#![deny(rust_2018_idioms)]
pub const SCHEMA_VERSION: &str = "1.0";
pub fn new_task_id() -> String {
format!(
"tj-{}",
&ulid::Ulid::new().to_string()[10..20].to_lowercase()
)
}
#[cfg(test)]
mod task_id_tests {
use super::new_task_id;
use std::collections::HashSet;
#[test]
fn new_task_id_has_expected_shape() {
let id = new_task_id();
assert!(id.starts_with("tj-"), "{id}");
assert_eq!(id.len(), 13, "{id}");
assert!(
id[3..]
.chars()
.all(|c| c.is_ascii_lowercase() || c.is_ascii_digit()),
"{id}"
);
}
#[test]
fn new_task_id_unique_over_ten_thousand() {
let mut seen = HashSet::with_capacity(10_000);
for _ in 0..10_000 {
let id = new_task_id();
assert!(seen.insert(id.clone()), "collision: {id}");
}
}
}
pub mod classifier;
pub mod db;
pub mod event;
pub mod pack;
pub mod paths;
pub mod project_hash;
pub mod session;
pub mod storage;
#[cfg(test)]
mod schema_version_tests {
#[test]
fn pack_assembler_does_not_inline_schema_version_literal() {
let pack_src = include_str!("pack.rs");
assert!(
!pack_src.contains("schema_version: \""),
"pack.rs has an inline schema_version string literal — use crate::SCHEMA_VERSION"
);
}
#[test]
fn schema_version_matches_event_default() {
let evt = crate::event::Event::new(
"tj-x",
crate::event::EventType::Open,
crate::event::Author::User,
crate::event::Source::Cli,
"x".into(),
);
assert_eq!(evt.schema_version, super::SCHEMA_VERSION);
}
}