use chrono::{DateTime, NaiveDate, Utc};
#[must_use]
pub fn format_date(date: &NaiveDate) -> String {
date.format("%Y-%m-%d").to_string()
}
#[must_use]
pub fn format_datetime(dt: &DateTime<Utc>) -> String {
dt.format("%Y-%m-%d %H:%M:%S UTC").to_string()
}
pub fn parse_date(date_str: &str) -> Result<NaiveDate, chrono::ParseError> {
NaiveDate::parse_from_str(date_str, "%Y-%m-%d")
}
#[must_use]
pub fn is_valid_uuid(uuid_str: &str) -> bool {
uuid::Uuid::parse_str(uuid_str).is_ok()
}
#[must_use]
pub fn truncate_string(s: &str, max_len: usize) -> String {
if s.len() <= max_len {
s.to_string()
} else {
format!("{}...", &s[..max_len.saturating_sub(3)])
}
}
#[cfg(test)]
mod tests {
use super::*;
use chrono::{Datelike, TimeZone, Utc};
#[test]
fn test_format_date() {
let date = NaiveDate::from_ymd_opt(2023, 12, 25).unwrap();
let formatted = format_date(&date);
assert_eq!(formatted, "2023-12-25");
let date = NaiveDate::from_ymd_opt(2024, 1, 1).unwrap();
let formatted = format_date(&date);
assert_eq!(formatted, "2024-01-01");
let date = NaiveDate::from_ymd_opt(2024, 2, 29).unwrap(); let formatted = format_date(&date);
assert_eq!(formatted, "2024-02-29");
}
#[test]
fn test_format_datetime() {
let dt = Utc.with_ymd_and_hms(2023, 12, 25, 15, 30, 45).unwrap();
let formatted = format_datetime(&dt);
assert_eq!(formatted, "2023-12-25 15:30:45 UTC");
let dt = Utc.with_ymd_and_hms(2024, 1, 1, 0, 0, 0).unwrap();
let formatted = format_datetime(&dt);
assert_eq!(formatted, "2024-01-01 00:00:00 UTC");
}
#[test]
fn test_parse_date_valid() {
let result = parse_date("2023-12-25");
assert!(result.is_ok());
let date = result.unwrap();
assert_eq!(date.year(), 2023);
assert_eq!(date.month(), 12);
assert_eq!(date.day(), 25);
assert!(parse_date("2024-01-01").is_ok());
assert!(parse_date("2024-02-29").is_ok()); }
#[test]
fn test_parse_date_invalid() {
assert!(parse_date("2023/12/25").is_err());
assert!(parse_date("2023-13-01").is_err()); assert!(parse_date("2023-02-30").is_err()); assert!(parse_date("").is_err());
assert!(parse_date("not-a-date").is_err());
assert!(parse_date("2023-02-29").is_err()); }
#[test]
fn test_is_valid_uuid_valid() {
assert!(is_valid_uuid("550e8400-e29b-41d4-a716-446655440000"));
assert!(is_valid_uuid("6ba7b810-9dad-11d1-80b4-00c04fd430c8"));
assert!(is_valid_uuid("00000000-0000-0000-0000-000000000000"));
assert!(is_valid_uuid("ffffffff-ffff-ffff-ffff-ffffffffffff"));
assert!(is_valid_uuid("FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF")); }
#[test]
fn test_is_valid_uuid_invalid() {
assert!(!is_valid_uuid(""));
assert!(!is_valid_uuid("not-a-uuid"));
assert!(!is_valid_uuid("550e8400-e29b-41d4-a716")); assert!(!is_valid_uuid("550e8400-e29b-41d4-a716-44665544000g")); assert!(!is_valid_uuid("550e8400-e29b-41d4-a716-446655440000-extra")); }
#[test]
fn test_truncate_string() {
assert_eq!(truncate_string("hello", 10), "hello");
assert_eq!(truncate_string("hello", 5), "hello");
assert_eq!(truncate_string("hello world", 8), "hello...");
assert_eq!(truncate_string("hello world", 5), "he...");
assert_eq!(truncate_string("hello", 3), "...");
assert_eq!(truncate_string("hello", 4), "h...");
assert_eq!(truncate_string("", 10), "");
assert_eq!(truncate_string("", 0), "");
assert_eq!(truncate_string("test", 0), "...");
}
#[test]
fn test_integration() {
let date_str = "2023-12-25";
let parsed_date = parse_date(date_str).unwrap();
let formatted_date = format_date(&parsed_date);
assert_eq!(formatted_date, date_str);
let uuid = "550e8400-e29b-41d4-a716-446655440000";
assert!(is_valid_uuid(uuid));
let truncated = truncate_string(uuid, 20);
assert_eq!(truncated, "550e8400-e29b-41d...");
}
#[test]
fn test_comprehensive_coverage() {
for month in 1..=12 {
let date = NaiveDate::from_ymd_opt(2023, month, 1).unwrap();
let formatted = format_date(&date);
assert!(formatted.contains(&format!("{month:02}")));
}
let times = [(0, 0, 0), (12, 0, 0), (23, 59, 59)];
for (hour, min, sec) in times {
let dt = Utc.with_ymd_and_hms(2023, 6, 15, hour, min, sec).unwrap();
let formatted = format_datetime(&dt);
assert!(formatted.contains(&format!("{hour:02}:{min:02}:{sec:02}")));
assert!(formatted.ends_with("UTC"));
}
let invalid_dates = [
"2023",
"2023-01",
"01-01-2023",
"2023.01.01",
"2023-00-01",
"2023-01-00",
"2023-04-31",
];
for date_str in &invalid_dates {
assert!(parse_date(date_str).is_err());
}
let invalid_uuids = [
"550e8400_e29b_41d4_a716_446655440000", "550e8400.e29b.41d4.a716.446655440000", " 550e8400-e29b-41d4-a716-446655440000", "550e8400-e29b-41d4-a716-446655440000 ", ];
for uuid in &invalid_uuids {
assert!(!is_valid_uuid(uuid));
}
assert_eq!(truncate_string("hello δΈη", 8), "hello...");
assert_eq!(truncate_string("π¦π¦π¦", 3), "...");
}
}