post_archiver/
file_meta.rs1use serde::{Deserialize, Serialize};
2
3use serde_json::Value;
4#[cfg(feature = "typescript")]
5use ts_rs::TS;
6
7use std::{collections::HashMap, hash::Hash, path::PathBuf};
8
9use crate::id::{FileMetaId, PostId};
10
11pub const POSTS_PRE_CHUNK: u32 = 2048;
13
14#[cfg_attr(feature = "typescript", derive(TS))]
16#[cfg_attr(feature = "typescript", ts(export))]
17#[derive(Deserialize, Serialize, Debug, Clone, PartialEq, Eq)]
18pub struct FileMeta {
19 pub id: FileMetaId,
20 pub filename: String,
21 pub post: PostId,
22 pub mime: String,
23 #[cfg_attr(feature = "typescript", ts(type = "Record<string, any>"))]
24 pub extra: HashMap<String, Value>,
25}
26
27impl FileMeta {
28 pub fn path(&self) -> PathBuf {
53 let id = self.post.raw();
54 let chunk = id / POSTS_PRE_CHUNK;
55 let index = id % POSTS_PRE_CHUNK;
56 PathBuf::from(chunk.to_string())
57 .join(index.to_string())
58 .join(&self.filename)
59 }
60}
61
62impl Hash for FileMeta {
63 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
64 self.id.hash(state);
65 self.post.hash(state);
66 self.filename.hash(state);
67 self.mime.hash(state);
68 }
70}
71
72#[cfg(feature = "utils")]
73crate::utils::macros::as_table!(
74 FileMeta {
75 id: "id",
76 post: "post",
77 filename: "filename",
78 mime: "mime",
79 extra: "extra" => json,
80 }
81);