2 use std::path::PathBuf;
4 use std::time::{SystemTime, UNIX_EPOCH};
12 pub fn serialize(&self) -> String {
13 format!(r#"{{\n "id": "{}",\n "created_on": {}\n}}"#, self.id, self.created_on)
16 pub fn deserialize(input: &str) -> Option<Metadata> {
17 let clean_input = input
19 .filter(|c| !c.is_whitespace())
22 let id = Metadata::read_field(&clean_input, "id")?;
23 let created_on = Metadata::read_field(&clean_input, "createdOn")
24 .or_else(|| Metadata::read_field(&clean_input, "created_on"))?;
28 created_on: created_on.parse().ok()?
32 pub fn read_or_create(file_path: &PathBuf) -> Metadata {
33 match Metadata::read_metadata_file(file_path) {
34 Some(metadata) => metadata,
36 let timestamp = SystemTime::now()
37 .duration_since(UNIX_EPOCH)
38 .map(|duration| duration.as_millis() as u128)
39 .unwrap_or_else(|_| 0);
41 id: timestamp.to_string(),
48 fn read_metadata_file(file_path: &PathBuf) -> Option<Metadata> {
49 let mut file = File::open(file_path).ok()?;
50 let mut contents = String::new();
51 file.read_to_string(&mut contents).ok()?;
52 Metadata::deserialize(&contents)
56 fn read_field(input: &str, field_name: &str) -> Option<String> {
57 let key_pattern = format!(r#""{}":""#, field_name);
58 input.find(&key_pattern)
60 let value_start = start + key_pattern.len();
61 let value_end = input[value_start..]
62 .find(|c: char| c == ',' || c == '}' || c == '\n')
63 .unwrap_or_else(|| input[value_start..].len()) + value_start;
65 let raw_value = &input[value_start..value_end];
66 let value = raw_value.trim_matches('"').to_string();