60 lines
No EOL
1.9 KiB
Rust
60 lines
No EOL
1.9 KiB
Rust
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<String>,
|
|
pub username: String,
|
|
}
|
|
|
|
pub fn deserialize_id<'de, D>(deserializer: D) -> Result<u64, D::Error>
|
|
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<Vec<Submission>, 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())
|
|
}
|
|
} |