1pub fn quote_ident(name: &str) -> String {
14 format!("\"{}\"", name.replace('"', "\"\""))
15}
16
17pub fn now_iso() -> String {
25 use std::time::{SystemTime, UNIX_EPOCH};
26 let secs = SystemTime::now()
27 .duration_since(UNIX_EPOCH)
28 .unwrap_or_default()
29 .as_secs();
30 epoch_to_iso(secs)
31}
32
33pub fn epoch_to_iso(secs: u64) -> String {
35 let days = secs / 86400;
36 let time_of_day = secs % 86400;
37 let hours = time_of_day / 3600;
38 let minutes = (time_of_day % 3600) / 60;
39 let seconds = time_of_day % 60;
40
41 let mut y = 1970i64;
42 let mut remaining = days as i64;
43 loop {
44 let days_in_year = if is_leap(y) { 366 } else { 365 };
45 if remaining < days_in_year {
46 break;
47 }
48 remaining -= days_in_year;
49 y += 1;
50 }
51 let leap = is_leap(y);
52 let month_days: [i64; 12] = [
53 31,
54 if leap { 29 } else { 28 },
55 31,
56 30,
57 31,
58 30,
59 31,
60 31,
61 30,
62 31,
63 30,
64 31,
65 ];
66 let mut m = 0usize;
67 for (i, &md) in month_days.iter().enumerate() {
68 if remaining < md {
69 m = i;
70 break;
71 }
72 remaining -= md;
73 }
74 let d = remaining + 1;
75 format!(
76 "{:04}-{:02}-{:02}T{:02}:{:02}:{:02}Z",
77 y,
78 m + 1,
79 d,
80 hours,
81 minutes,
82 seconds
83 )
84}
85
86pub fn is_leap(y: i64) -> bool {
88 (y % 4 == 0 && y % 100 != 0) || y % 400 == 0
89}
90
91pub fn is_safe_file_id(id: &str) -> bool {
98 !id.is_empty()
99 && !id.contains("..")
100 && !id.contains('/')
101 && !id.contains('\\')
102 && !id.starts_with('.')
103}
104
105#[cfg(test)]
106mod tests {
107 use super::*;
108
109 #[test]
110 fn quote_ident_basic() {
111 assert_eq!(quote_ident("users"), "\"users\"");
112 }
113
114 #[test]
115 fn quote_ident_escapes_embedded_quote() {
116 assert_eq!(quote_ident("weird\"name"), "\"weird\"\"name\"");
117 }
118
119 #[test]
120 fn now_iso_format() {
121 let s = now_iso();
122 assert_eq!(s.len(), 20);
123 assert!(s.ends_with('Z'));
124 assert_eq!(s.chars().nth(4), Some('-'));
125 assert_eq!(s.chars().nth(10), Some('T'));
126 }
127
128 #[test]
129 fn epoch_to_iso_zero() {
130 assert_eq!(epoch_to_iso(0), "1970-01-01T00:00:00Z");
131 }
132
133 #[test]
134 fn epoch_to_iso_known() {
135 assert_eq!(epoch_to_iso(1704067200), "2024-01-01T00:00:00Z");
137 }
138
139 #[test]
140 fn leap_year_detection() {
141 assert!(is_leap(2000));
142 assert!(is_leap(2024));
143 assert!(!is_leap(1900));
144 assert!(!is_leap(2023));
145 }
146
147 #[test]
148 fn safe_file_id_accepts_normal() {
149 assert!(is_safe_file_id("file_abc123"));
150 }
151
152 #[test]
153 fn safe_file_id_rejects_traversal() {
154 assert!(!is_safe_file_id(""));
155 assert!(!is_safe_file_id(".."));
156 assert!(!is_safe_file_id("../etc/passwd"));
157 assert!(!is_safe_file_id("a/b"));
158 assert!(!is_safe_file_id(".hidden"));
159 }
160}