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}