]> git.r.bdr.sh - rbdr/blog/blob - src/metadata.rs
Add part of the implementation for add
[rbdr/blog] / src / metadata.rs
1 use std::fs::File;
2 use std::path::PathBuf;
3 use std::io::Read;
4 use std::time::{SystemTime, UNIX_EPOCH};
5
6 pub struct Metadata {
7 pub id: String,
8 pub created_on: u128
9 }
10
11 impl Metadata {
12 pub fn serialize(&self) -> String {
13 format!(r#"{{\n "id": "{}",\n "created_on": {}\n}}"#, self.id, self.created_on)
14 }
15
16 pub fn deserialize(input: &str) -> Option<Metadata> {
17 let clean_input = input
18 .chars()
19 .filter(|c| !c.is_whitespace())
20 .collect::<String>();
21
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"))?;
25
26 Some(Metadata {
27 id,
28 created_on: created_on.parse().ok()?
29 })
30 }
31
32 pub fn read_or_create(file_path: &PathBuf) -> Metadata {
33 match Metadata::read_metadata_file(file_path) {
34 Some(metadata) => metadata,
35 None => {
36 let timestamp = SystemTime::now()
37 .duration_since(UNIX_EPOCH)
38 .map(|duration| duration.as_millis() as u128)
39 .unwrap_or_else(|_| 0);
40 return Metadata {
41 id: timestamp.to_string(),
42 created_on: timestamp
43 }
44 }
45 }
46 }
47
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)
53 }
54
55
56 fn read_field(input: &str, field_name: &str) -> Option<String> {
57 let key_pattern = format!(r#""{}":""#, field_name);
58 input.find(&key_pattern)
59 .and_then(|start| {
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;
64
65 let raw_value = &input[value_start..value_end];
66 let value = raw_value.trim_matches('"').to_string();
67 Some(value)
68 })
69 }
70 }