triplets_core/
metadata.rs1use chrono::NaiveDate;
2use std::fmt::Display;
3
4pub use crate::constants::metadata::{META_FIELD_DATE, METADATA_DELIMITER};
5
6#[derive(Clone, Copy, Debug, PartialEq, Eq)]
8pub struct MetadataKey {
9 name: &'static str,
10}
11
12impl MetadataKey {
13 pub const fn new(name: &'static str) -> Self {
15 Self { name }
16 }
17
18 pub const fn as_str(&self) -> &'static str {
20 self.name
21 }
22
23 pub fn encode(&self, value: impl Display) -> String {
25 format!("{}{}{}", self.name, METADATA_DELIMITER, value)
26 }
27
28 pub fn strip<'a>(&self, entry: &'a str) -> Option<&'a str> {
30 entry
31 .strip_prefix(self.name)
32 .and_then(|rest| rest.strip_prefix(METADATA_DELIMITER))
33 }
34}
35
36pub fn build_date_meta_values(date: &NaiveDate) -> Vec<crate::types::MetaValue> {
39 let mut vals = vec![
40 date.format("%Y-%m-%d").to_string(), date.format("%b. %-d, %Y").to_string(), date.format("%B %-d, %Y").to_string(), date.format("%d.%m.%Y").to_string(), date.format("%m/%d/%Y").to_string(), date.format("%b %-d, %Y").to_string(), ];
47 vals.sort();
48 vals.dedup();
49 vals
50}
51
52#[cfg(test)]
53mod tests {
54 use super::*;
55
56 #[test]
57 fn metadata_key_encodes_and_strips_values() {
58 let encoded = META_FIELD_DATE.encode("2025-02-23");
59 assert_eq!(encoded, "date=2025-02-23");
60 assert_eq!(META_FIELD_DATE.strip(&encoded), Some("2025-02-23"));
61 assert_eq!(META_FIELD_DATE.strip("other=2025-02-23"), None);
62 }
63
64 #[test]
65 fn date_meta_values_are_deduped_and_include_expected_formats() {
66 let date = NaiveDate::from_ymd_opt(2025, 2, 25).unwrap();
67 let values = build_date_meta_values(&date);
68
69 assert!(values.contains(&"2025-02-25".to_string()));
70 assert!(values.contains(&"02/25/2025".to_string()));
71 assert!(values.contains(&"25.02.2025".to_string()));
72
73 let mut uniq = values.clone();
74 uniq.sort();
75 uniq.dedup();
76 assert_eq!(uniq.len(), values.len());
77 }
78
79 #[test]
80 fn metadata_key_new_and_as_str_work() {
81 const CUSTOM: MetadataKey = MetadataKey::new("custom");
82 assert_eq!(CUSTOM.as_str(), "custom");
83 assert_eq!(CUSTOM.encode(42), "custom=42");
84 assert_eq!(CUSTOM.strip("custom=42"), Some("42"));
85 assert_eq!(CUSTOM.strip("custom42"), None);
86
87 let runtime_key = MetadataKey::new("runtime");
88 assert_eq!(runtime_key.as_str(), "runtime");
89 }
90}