94 lines
2.2 KiB
Rust
94 lines
2.2 KiB
Rust
use std::{fmt, str::FromStr};
|
|
|
|
use eyre::OptionExt;
|
|
use serde::{Deserialize, Serialize};
|
|
use uuid::Uuid;
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Deserialize)]
|
|
#[serde(rename_all = "snake_case")]
|
|
pub enum UploadKind {
|
|
Thumbnail,
|
|
Screenshot,
|
|
File,
|
|
}
|
|
|
|
impl UploadKind {
|
|
pub const fn as_str(self) -> &'static str {
|
|
match self {
|
|
Self::Thumbnail => "t",
|
|
Self::Screenshot => "s",
|
|
Self::File => "f",
|
|
}
|
|
}
|
|
}
|
|
|
|
impl FromStr for UploadKind {
|
|
type Err = eyre::Report;
|
|
|
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
Ok(match s {
|
|
"t" => Self::Thumbnail,
|
|
"s" => Self::Screenshot,
|
|
"f" => Self::File,
|
|
_ => eyre::bail!("wrong upload kind"),
|
|
})
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct UploadId {
|
|
pub novel: String,
|
|
pub id: Uuid,
|
|
pub kind: UploadKind,
|
|
}
|
|
|
|
impl UploadId {
|
|
pub fn to_file_name(&self) -> String {
|
|
format!("{}-{}", self.id, self.kind.as_str())
|
|
}
|
|
}
|
|
|
|
impl FromStr for UploadId {
|
|
type Err = eyre::Report;
|
|
|
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
let Some((novel, id_and_kind)) = s.rsplit_once('/') else {
|
|
eyre::bail!("invalid upload id")
|
|
};
|
|
if id_and_kind.is_empty() {
|
|
eyre::bail!("invalid upload id");
|
|
}
|
|
let (id, kind) = id_and_kind.split_at(id_and_kind.len().checked_sub(1).ok_or_eyre("loh")?);
|
|
|
|
Ok(Self {
|
|
novel: novel.to_owned(),
|
|
kind: kind.parse()?,
|
|
id: id.parse()?,
|
|
})
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for UploadId {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
write!(f, "{}/{}{}", self.novel, self.id, self.kind.as_str())
|
|
}
|
|
}
|
|
|
|
impl Serialize for UploadId {
|
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
where
|
|
S: serde::Serializer,
|
|
{
|
|
serializer.serialize_str(&self.to_string())
|
|
}
|
|
}
|
|
|
|
impl<'de> Deserialize<'de> for UploadId {
|
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
|
where
|
|
D: serde::Deserializer<'de>,
|
|
{
|
|
let s = <&str>::deserialize(deserializer)?;
|
|
s.parse().map_err(|e| serde::de::Error::custom(e))
|
|
}
|
|
}
|