diff options
| author | Ruben Beltran del Rio <git@r.bdr.sh> | 2024-02-25 22:06:19 +0000 |
|---|---|---|
| committer | Ruben Beltran del Rio <git@r.bdr.sh> | 2024-02-25 22:06:19 +0000 |
| commit | a9c6be4162bd15bd41ba3605127b56cb1eb32f32 (patch) | |
| tree | 6d97b0c6286b1eabb2ef5cab34b472f1622584e5 /src/metadata.rs | |
| parent | 53812065cf124b6c1bc40fceec46f8c161033e29 (diff) | |
Add part of the implementation for add
Diffstat (limited to 'src/metadata.rs')
| -rw-r--r-- | src/metadata.rs | 70 |
1 files changed, 70 insertions, 0 deletions
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<Metadata> { + let clean_input = input + .chars() + .filter(|c| !c.is_whitespace()) + .collect::<String>(); + + 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<Metadata> { + 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<String> { + 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) + }) + } +} |