use chrono::{Utc, TimeZone}; use serde::Deserialize; use derive_more::From; use super::Submission; #[derive(Deserialize)] pub struct LegacySubmission { #[serde(deserialize_with = "deserialize_id")] pub id: u64, pub images: Vec, pub username: String, } pub fn deserialize_id<'de, D>(deserializer: D) -> Result where D: serde::Deserializer<'de>, { let id_str: &str = serde::Deserialize::deserialize(deserializer)?; id_str.parse().map_err(serde::de::Error::custom) } #[derive(From, Debug)] pub enum LegacySubmissionParseError { BadAuthorId(std::num::ParseIntError), } impl LegacySubmission { pub fn parse(&self) -> Result, LegacySubmissionParseError> { let author_id = self.id; Ok(self.images .iter() .map(|image| { Submission { author_id, timestamp: { // The last number of the filename is either a discriminator or a datestamp // We can split apart the filename and check if it's >9999. In that case, // it's a datestamp. (|| image // Get filename without extension .split('.').next()? // Get last number .split('-') .last()? .parse() .ok() // Check if discriminator or timestamp, then convert .map(|number| if number > 9999 { Utc.timestamp_millis_opt(number).single() } else { None })?)() }, image: image.clone(), } }) .collect()) } }