use std::path::PathBuf;
use std::io::Read;
use std::time::{SystemTime, UNIX_EPOCH};
+use time::{OffsetDateTime, format_description::well_known::Rfc2822};
+use serde::{Serialize, Deserialize};
+use serde_json;
+#[derive(Serialize, Deserialize)]
pub struct Metadata {
pub id: String,
- pub created_on: u128
+ #[serde(alias = "createdOn")]
+ pub created_on: u64
}
impl Metadata {
- pub fn serialize(&self) -> String {
- format!(r#"{{
- "id": "{}",
- "created_on": {}
-}}"#, 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, "created_on")
- // createdOn kept for compatibility with blog < 7.0.0
- .or_else(|| Metadata::read_field(&clean_input, "createdOn"))?;
-
- 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)
+ .map(|duration| duration.as_millis() as u64)
.unwrap_or_else(|_| 0);
return Metadata {
id: timestamp.to_string(),
}
}
+ pub fn created_on_utc(&self) -> Option<String> {
+ let date = OffsetDateTime::from_unix_timestamp_nanos(
+ (self.created_on * 1_000_000).into()
+ ).ok()?;
+ return date.format(&Rfc2822).ok();
+ }
+
+
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)
- })
+ serde_json::from_str(&contents).ok()
}
}