]> git.r.bdr.sh - rbdr/blog/blobdiff - src/metadata.rs
Add part of the implementation for add
[rbdr/blog] / src / metadata.rs
diff --git a/src/metadata.rs b/src/metadata.rs
new file mode 100644 (file)
index 0000000..97ef0d3
--- /dev/null
@@ -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)
+            })
+    }
+}