]>
Commit | Line | Data |
---|---|---|
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#"{{ | |
14 | "id": "{}", | |
15 | "created_on": {} | |
16 | }}"#, self.id, self.created_on) | |
17 | } | |
18 | ||
19 | pub fn deserialize(input: &str) -> Option<Metadata> { | |
20 | let clean_input = input | |
21 | .chars() | |
22 | .filter(|c| !c.is_whitespace()) | |
23 | .collect::<String>(); | |
24 | ||
25 | let id = Metadata::read_field(&clean_input, "id")?; | |
26 | let created_on = Metadata::read_field(&clean_input, "created_on") | |
27 | // createdOn kept for compatibility with blog < 7.0.0 | |
28 | .or_else(|| Metadata::read_field(&clean_input, "createdOn"))?; | |
29 | ||
30 | Some(Metadata { | |
31 | id, | |
32 | created_on: created_on.parse().ok()? | |
33 | }) | |
34 | } | |
35 | ||
36 | pub fn read_or_create(file_path: &PathBuf) -> Metadata { | |
37 | match Metadata::read_metadata_file(file_path) { | |
38 | Some(metadata) => metadata, | |
39 | None => { | |
40 | let timestamp = SystemTime::now() | |
41 | .duration_since(UNIX_EPOCH) | |
42 | .map(|duration| duration.as_millis() as u128) | |
43 | .unwrap_or_else(|_| 0); | |
44 | return Metadata { | |
45 | id: timestamp.to_string(), | |
46 | created_on: timestamp | |
47 | } | |
48 | } | |
49 | } | |
50 | } | |
51 | ||
52 | fn read_metadata_file(file_path: &PathBuf) -> Option<Metadata> { | |
53 | let mut file = File::open(file_path).ok()?; | |
54 | let mut contents = String::new(); | |
55 | file.read_to_string(&mut contents).ok()?; | |
56 | Metadata::deserialize(&contents) | |
57 | } | |
58 | ||
59 | ||
60 | fn read_field(input: &str, field_name: &str) -> Option<String> { | |
61 | let key_pattern = format!(r#""{}":"#, field_name); | |
62 | input.find(&key_pattern) | |
63 | .and_then(|start| { | |
64 | let value_start = start + key_pattern.len(); | |
65 | let value_end = input[value_start..] | |
66 | .find(|c: char| c == ',' || c == '}' || c == '\n') | |
67 | .unwrap_or_else(|| input[value_start..].len()) + value_start; | |
68 | ||
69 | let raw_value = &input[value_start..value_end]; | |
70 | let value = raw_value.trim_matches('"').to_string(); | |
71 | Some(value) | |
72 | }) | |
73 | } | |
74 | } |