post_archiver/importer/file_meta.rs
1use std::{collections::HashMap, hash::Hash};
2
3use serde_json::Value;
4
5use crate::{
6 manager::{PostArchiverConnection, PostArchiverManager},
7 FileMetaId, PostId,
8};
9
10impl<T> PostArchiverManager<T>
11where
12 T: PostArchiverConnection,
13{
14 /// Create or update a file metadata entry in the archive.
15 ///
16 /// Takes a file metadata object and either creates a new entry or updates an existing one.
17 /// if a file metadata with the same filename (and post id) already exists, it only updates metadata
18 ///
19 /// # Errors
20 ///
21 /// Returns `rusqlite::Error` if there was an error accessing the database.
22 ///
23 /// # Examples
24 ///
25 /// ```
26 /// # use post_archiver::manager::PostArchiverManager;
27 /// # use post_archiver::importer::UnsyncFileMeta;
28 /// # use post_archiver::PostId;
29 /// # use std::collections::HashMap;
30 /// fn example(manager: &PostArchiverManager, post_id: PostId) -> Result<(), rusqlite::Error> {
31 /// let file_meta = UnsyncFileMeta {
32 /// filename: "image.jpg".to_string(),
33 /// mime: "image/jpeg".to_string(),
34 /// extra: HashMap::new(),
35 /// data: (),
36 /// };
37 /// let meta = manager.import_file_meta(post_id, &file_meta)?;
38 ///
39 /// Ok(())
40 /// }
41 /// ```
42 pub fn import_file_meta<U>(
43 &self,
44 post: PostId,
45 file_meta: &UnsyncFileMeta<U>,
46 ) -> Result<FileMetaId, rusqlite::Error> {
47 match self.find_file_meta(post, &file_meta.filename)? {
48 Some(id) => {
49 // mime should not change
50 self.set_file_meta_extra(id, file_meta.extra.clone())?;
51 Ok(id)
52 }
53 None => self.add_file_meta(
54 post,
55 file_meta.filename.clone(),
56 file_meta.mime.clone(),
57 file_meta.extra.clone(),
58 ),
59 }
60 }
61}
62
63/// Represents a file metadata that is not yet synced to the database.
64#[derive(Debug, Clone)]
65pub struct UnsyncFileMeta<T> {
66 pub filename: String,
67 pub mime: String,
68 pub extra: HashMap<String, Value>,
69 pub data: T,
70}
71
72impl<T> Hash for UnsyncFileMeta<T> {
73 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
74 self.filename.hash(state);
75 self.mime.hash(state);
76 }
77}
78
79impl<T> PartialEq for UnsyncFileMeta<T> {
80 fn eq(&self, other: &Self) -> bool {
81 self.filename == other.filename && self.mime == other.mime && self.extra == other.extra
82 }
83}
84
85impl<T> Eq for UnsyncFileMeta<T> {}
86
87impl<T> UnsyncFileMeta<T> {
88 pub fn new(filename: String, mime: String, data: T) -> Self {
89 Self {
90 filename,
91 mime,
92 data,
93 extra: HashMap::new(),
94 }
95 }
96
97 pub fn extra(mut self, extra: HashMap<String, Value>) -> Self {
98 self.extra = extra;
99 self
100 }
101}