gitkraft_core/utils/
time.rs1pub fn relative_time(dt: chrono::DateTime<chrono::Utc>) -> String {
15 let now = chrono::Utc::now();
16 let duration = now.signed_duration_since(dt);
17
18 let seconds = duration.num_seconds();
19 if seconds < 0 {
20 return "in the future".to_string();
21 }
22
23 let minutes = duration.num_minutes();
24 let hours = duration.num_hours();
25 let days = duration.num_days();
26 let weeks = days / 7;
27 let months = days / 30;
28 let years = days / 365;
29
30 if seconds < 60 {
31 "just now".to_string()
32 } else if minutes == 1 {
33 "1 minute ago".to_string()
34 } else if minutes < 60 {
35 format!("{minutes} minutes ago")
36 } else if hours == 1 {
37 "1 hour ago".to_string()
38 } else if hours < 24 {
39 format!("{hours} hours ago")
40 } else if days == 1 {
41 "1 day ago".to_string()
42 } else if days < 7 {
43 format!("{days} days ago")
44 } else if weeks == 1 {
45 "1 week ago".to_string()
46 } else if weeks < 5 {
47 format!("{weeks} weeks ago")
48 } else if months == 1 {
49 "1 month ago".to_string()
50 } else if months < 12 {
51 format!("{months} months ago")
52 } else if years == 1 {
53 "1 year ago".to_string()
54 } else {
55 format!("{years} years ago")
56 }
57}
58
59pub fn fmt_oid(oid: git2::Oid) -> String {
61 oid.to_string()
62}
63
64pub fn short_oid(oid: git2::Oid) -> String {
66 let full = oid.to_string();
67 full[..7.min(full.len())].to_string()
68}
69
70pub fn short_oid_str(oid: &str) -> &str {
72 match oid.char_indices().nth(7) {
73 Some((i, _)) => &oid[..i],
74 None => oid,
75 }
76}
77
78#[cfg(test)]
79mod tests {
80 use super::*;
81 use chrono::Utc;
82
83 #[test]
84 fn relative_time_just_now() {
85 let now = Utc::now();
86 assert_eq!(relative_time(now), "just now");
87 }
88
89 #[test]
90 fn relative_time_one_minute() {
91 let t = Utc::now() - chrono::Duration::minutes(1);
92 assert_eq!(relative_time(t), "1 minute ago");
93 }
94
95 #[test]
96 fn relative_time_minutes() {
97 let t = Utc::now() - chrono::Duration::minutes(5);
98 assert_eq!(relative_time(t), "5 minutes ago");
99 }
100
101 #[test]
102 fn relative_time_one_hour() {
103 let t = Utc::now() - chrono::Duration::hours(1);
104 assert_eq!(relative_time(t), "1 hour ago");
105 }
106
107 #[test]
108 fn relative_time_hours() {
109 let t = Utc::now() - chrono::Duration::hours(3);
110 assert_eq!(relative_time(t), "3 hours ago");
111 }
112
113 #[test]
114 fn relative_time_one_day() {
115 let t = Utc::now() - chrono::Duration::days(1);
116 assert_eq!(relative_time(t), "1 day ago");
117 }
118
119 #[test]
120 fn relative_time_days() {
121 let t = Utc::now() - chrono::Duration::days(4);
122 assert_eq!(relative_time(t), "4 days ago");
123 }
124
125 #[test]
126 fn relative_time_one_week() {
127 let t = Utc::now() - chrono::Duration::weeks(1);
128 assert_eq!(relative_time(t), "1 week ago");
129 }
130
131 #[test]
132 fn relative_time_weeks() {
133 let t = Utc::now() - chrono::Duration::weeks(3);
134 assert_eq!(relative_time(t), "3 weeks ago");
135 }
136
137 #[test]
138 fn relative_time_one_month() {
139 let t = Utc::now() - chrono::Duration::days(35);
140 assert_eq!(relative_time(t), "1 month ago");
141 }
142
143 #[test]
144 fn relative_time_months() {
145 let t = Utc::now() - chrono::Duration::days(180);
146 assert_eq!(relative_time(t), "6 months ago");
147 }
148
149 #[test]
150 fn relative_time_one_year() {
151 let t = Utc::now() - chrono::Duration::days(400);
152 assert_eq!(relative_time(t), "1 year ago");
153 }
154
155 #[test]
156 fn relative_time_years() {
157 let t = Utc::now() - chrono::Duration::days(800);
158 assert_eq!(relative_time(t), "2 years ago");
159 }
160
161 #[test]
162 fn relative_time_future() {
163 let t = Utc::now() + chrono::Duration::hours(1);
164 assert_eq!(relative_time(t), "in the future");
165 }
166
167 #[test]
168 fn fmt_oid_full() {
169 let oid = git2::Oid::from_str("abcdef1234567890abcdef1234567890abcdef12").unwrap();
170 assert_eq!(fmt_oid(oid), "abcdef1234567890abcdef1234567890abcdef12");
171 }
172
173 #[test]
174 fn short_oid_seven_chars() {
175 let oid = git2::Oid::from_str("abcdef1234567890abcdef1234567890abcdef12").unwrap();
176 assert_eq!(short_oid(oid), "abcdef1");
177 }
178
179 #[test]
180 fn short_oid_str_abbreviates() {
181 assert_eq!(short_oid_str("abcdef1234567890"), "abcdef1");
182 }
183
184 #[test]
185 fn short_oid_str_multibyte() {
186 assert_eq!(short_oid_str("\n\0\0O\0Oర"), "\n\0\0O\0Oర");
187 assert_eq!(short_oid_str("ఠఠఠఠఠఠఠఠ"), "ఠఠఠఠఠఠఠ");
188 }
189
190 #[test]
191 fn short_oid_str_short_input() {
192 assert_eq!(short_oid_str("abc"), "abc");
193 }
194}