Skip to main content

things3_common/
lib.rs

1//! Things Common - Shared utilities and types for Things 3 integration
2//!
3//! This crate provides shared utilities and constants for Things 3 integration.
4//!
5//! # Examples
6//!
7//! ```
8//! use things3_common::{DATABASE_FILENAME, truncate_string, format_date};
9//! use chrono::NaiveDate;
10//!
11//! // Use constants
12//! assert_eq!(DATABASE_FILENAME, "main.sqlite");
13//!
14//! // Use utility functions
15//! let truncated = truncate_string("hello world", 5);
16//! assert_eq!(truncated, "he...");
17//!
18//! let date = NaiveDate::from_ymd_opt(2023, 12, 25).unwrap();
19//! let formatted = format_date(&date);
20//! assert_eq!(formatted, "2023-12-25");
21//! ```
22
23pub mod constants;
24pub mod utils;
25
26pub use constants::{
27    DATABASE_DIR, DATABASE_FILENAME, DATETIME_FORMATS, DATE_FORMATS, DEFAULT_MCP_PORT,
28    DEFAULT_QUERY_LIMIT, MAX_QUERY_LIMIT, THINGS_CONTAINER,
29};
30pub use utils::{format_date, format_datetime, is_valid_uuid, parse_date, truncate_string};
31
32#[cfg(test)]
33mod tests {
34    use super::*;
35
36    #[test]
37    fn test_re_exported_constants() {
38        // Test that constants are properly re-exported from the crate root
39        assert_eq!(DATABASE_FILENAME, "main.sqlite");
40        assert_eq!(DATABASE_DIR, "Things Database.thingsdatabase");
41        assert_eq!(THINGS_CONTAINER, "JLMPQHK8H4.com.culturedcode.Things3");
42        assert_eq!(DEFAULT_QUERY_LIMIT, 100);
43        assert_eq!(MAX_QUERY_LIMIT, 1000);
44        assert_eq!(DEFAULT_MCP_PORT, 3000);
45
46        // Test that arrays are accessible
47        assert_eq!(DATE_FORMATS.len(), 3);
48        assert_eq!(DATETIME_FORMATS.len(), 3);
49
50        // Test that we can access specific array elements
51        assert_eq!(DATE_FORMATS[0], "%Y-%m-%d");
52        assert_eq!(DATETIME_FORMATS[0], "%Y-%m-%d %H:%M:%S");
53    }
54
55    #[test]
56    fn test_re_exported_functions() {
57        // Test that utility functions are properly re-exported from the crate root
58        use chrono::{NaiveDate, Utc};
59
60        // Test format_date
61        let date = NaiveDate::from_ymd_opt(2023, 12, 25).unwrap();
62        let formatted = format_date(&date);
63        assert_eq!(formatted, "2023-12-25");
64
65        // Test format_datetime
66        let dt = Utc::now();
67        let formatted = format_datetime(&dt);
68        assert!(formatted.contains("UTC"));
69
70        // Test parse_date
71        let result = parse_date("2023-12-25");
72        assert!(result.is_ok());
73
74        // Test is_valid_uuid
75        assert!(is_valid_uuid("550e8400-e29b-41d4-a716-446655440000"));
76        assert!(!is_valid_uuid("invalid-uuid"));
77
78        // Test truncate_string
79        assert_eq!(truncate_string("hello world", 5), "he...");
80        assert_eq!(truncate_string("hi", 10), "hi");
81    }
82
83    #[test]
84    fn test_module_accessibility() {
85        // Test that modules are accessible and contain expected items
86
87        // Test constants module
88        assert_eq!(constants::DATABASE_FILENAME, "main.sqlite");
89        assert_eq!(constants::DEFAULT_QUERY_LIMIT, 100);
90
91        // Test utils module
92        let result = utils::truncate_string("hello world", 5);
93        assert_eq!(result, "he...");
94
95        // Test that we can use module-qualified names
96        assert!(utils::is_valid_uuid("550e8400-e29b-41d4-a716-446655440000"));
97        assert_eq!(utils::truncate_string("test", 2), "...");
98    }
99
100    #[test]
101    fn test_crate_level_imports() {
102        // Test that importing from crate root works as expected
103        // This ensures the pub use statements are working correctly
104
105        // Test importing constants directly
106        use crate::{DATABASE_FILENAME, DATE_FORMATS, DEFAULT_QUERY_LIMIT};
107        // Test importing functions directly
108        use crate::{format_date, is_valid_uuid, truncate_string};
109
110        assert_eq!(DATABASE_FILENAME, "main.sqlite");
111        assert_eq!(DEFAULT_QUERY_LIMIT, 100);
112        assert_eq!(DATE_FORMATS.len(), 3);
113
114        assert!(is_valid_uuid("550e8400-e29b-41d4-a716-446655440000"));
115        assert_eq!(truncate_string("hello", 3), "...");
116
117        let date = chrono::NaiveDate::from_ymd_opt(2023, 1, 1).unwrap();
118        let formatted = format_date(&date);
119        assert_eq!(formatted, "2023-01-01");
120    }
121
122    #[test]
123    fn test_wildcard_imports() {
124        // Test that wildcard imports work correctly
125        // This tests the pub use *; statements
126
127        // Create a scope to test wildcard import
128        {
129            use crate::constants::*;
130            assert_eq!(DATABASE_FILENAME, "main.sqlite");
131            assert_eq!(DEFAULT_QUERY_LIMIT, 100);
132        }
133
134        {
135            use crate::utils::*;
136            assert!(is_valid_uuid("550e8400-e29b-41d4-a716-446655440000"));
137            assert_eq!(truncate_string("test", 2), "...");
138
139            let date = chrono::NaiveDate::from_ymd_opt(2023, 6, 15).unwrap();
140            let formatted = format_date(&date);
141            assert_eq!(formatted, "2023-06-15");
142        }
143    }
144}