transbeam/src/state/v0.rs

93 lines
2.2 KiB
Rust

use super::prelude::*;
use serde_with::{FromInto, PickFirst};
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct UploadedFile {
pub name: String,
pub size: u64,
#[serde(with = "timestamp")]
pub modtime: OffsetDateTime,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct FileSet {
pub files: Vec<UploadedFile>,
// Optional for backwards compatibility only
pub directory_name: Option<String>,
}
impl From<Vec<UploadedFile>> for FileSet {
fn from(files: Vec<UploadedFile>) -> Self {
Self {
files,
directory_name: None,
}
}
}
#[serde_as]
#[skip_serializing_none]
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct StoredFile {
pub name: String,
pub size: u64,
#[serde(with = "timestamp")]
pub modtime: OffsetDateTime,
#[serde(with = "timestamp")]
pub expiry: OffsetDateTime,
#[serde_as(as = "Option<PickFirst<(_, FromInto<Vec<UploadedFile>>)>>")]
#[serde(default)]
pub contents: Option<FileSet>,
}
#[derive(Debug, Default, Deserialize, Serialize)]
pub struct StoredFiles(pub HashMap<String, StoredFile>);
pub type State = StoredFiles;
impl jsondb::SchemaV0 for State {
const VERSION_OPTIONAL: bool = true;
}
mod timestamp {
use core::fmt;
use serde::{de::Visitor, Deserializer, Serializer};
use time::OffsetDateTime;
pub(crate) fn serialize<S: Serializer>(
time: &OffsetDateTime,
ser: S,
) -> Result<S::Ok, S::Error> {
ser.serialize_i64(time.unix_timestamp())
}
struct I64Visitor;
impl<'de> Visitor<'de> for I64Visitor {
type Value = i64;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "an integer")
}
fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E> {
Ok(v)
}
fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E> {
Ok(v as i64)
}
}
pub(crate) fn deserialize<'de, D: Deserializer<'de>>(
de: D,
) -> Result<OffsetDateTime, D::Error> {
Ok(
OffsetDateTime::from_unix_timestamp(de.deserialize_i64(I64Visitor)?)
.unwrap_or_else(|_| OffsetDateTime::now_utc()),
)
}
}