X-Git-Url: https://git.r.bdr.sh/rbdr/blog/blobdiff_plain/53812065cf124b6c1bc40fceec46f8c161033e29..a9c6be4162bd15bd41ba3605127b56cb1eb32f32:/src/metadata.rs diff --git a/src/metadata.rs b/src/metadata.rs new file mode 100644 index 0000000..97ef0d3 --- /dev/null +++ b/src/metadata.rs @@ -0,0 +1,70 @@ +use std::fs::File; +use std::path::PathBuf; +use std::io::Read; +use std::time::{SystemTime, UNIX_EPOCH}; + +pub struct Metadata { + pub id: String, + pub created_on: u128 +} + +impl Metadata { + pub fn serialize(&self) -> String { + format!(r#"{{\n "id": "{}",\n "created_on": {}\n}}"#, self.id, self.created_on) + } + + pub fn deserialize(input: &str) -> Option { + let clean_input = input + .chars() + .filter(|c| !c.is_whitespace()) + .collect::(); + + let id = Metadata::read_field(&clean_input, "id")?; + let created_on = Metadata::read_field(&clean_input, "createdOn") + .or_else(|| Metadata::read_field(&clean_input, "created_on"))?; + + Some(Metadata { + id, + created_on: created_on.parse().ok()? + }) + } + + pub fn read_or_create(file_path: &PathBuf) -> Metadata { + match Metadata::read_metadata_file(file_path) { + Some(metadata) => metadata, + None => { + let timestamp = SystemTime::now() + .duration_since(UNIX_EPOCH) + .map(|duration| duration.as_millis() as u128) + .unwrap_or_else(|_| 0); + return Metadata { + id: timestamp.to_string(), + created_on: timestamp + } + } + } + } + + fn read_metadata_file(file_path: &PathBuf) -> Option { + let mut file = File::open(file_path).ok()?; + let mut contents = String::new(); + file.read_to_string(&mut contents).ok()?; + Metadata::deserialize(&contents) + } + + + fn read_field(input: &str, field_name: &str) -> Option { + let key_pattern = format!(r#""{}":""#, field_name); + input.find(&key_pattern) + .and_then(|start| { + let value_start = start + key_pattern.len(); + let value_end = input[value_start..] + .find(|c: char| c == ',' || c == '}' || c == '\n') + .unwrap_or_else(|| input[value_start..].len()) + value_start; + + let raw_value = &input[value_start..value_end]; + let value = raw_value.trim_matches('"').to_string(); + Some(value) + }) + } +}