post_archiver/importer/
author.rs

1use chrono::{DateTime, Utc};
2
3use crate::{
4    manager::{PostArchiverConnection, PostArchiverManager},
5    AuthorId, PlatformId,
6};
7
8impl<T> PostArchiverManager<T>
9where
10    T: PostArchiverConnection,
11{
12    /// Import an author into the archive.
13    ///
14    /// If the author already exists (by aliases), it updates their name, aliases, and updated date.
15    ///
16    /// # Errors
17    ///
18    /// Returns `rusqlite::Error` if there was an error accessing the database.
19    pub fn import_author(&self, author: UnsyncAuthor) -> Result<AuthorId, rusqlite::Error> {
20        let id = self.find_author(author.aliases.as_slice())?;
21
22        let aliases = author
23            .aliases
24            .into_iter()
25            .map(|alias| (alias.source, alias.platform, alias.link))
26            .collect::<Vec<_>>();
27
28        match id {
29            Some(id) => {
30                self.set_author_name(id, author.name)?;
31
32                if let Some(updated) = author.updated {
33                    self.set_author_updated(id, updated)?;
34                }
35
36                self.add_author_aliases(id, aliases)?;
37
38                Ok(id)
39            }
40            None => {
41                let id = self.add_author(author.name, author.updated)?;
42
43                self.add_author_aliases(id, aliases)?;
44
45                Ok(id)
46            }
47        }
48    }
49}
50
51/// Represents an author that is not yet synced with the archive.
52#[derive(Debug, Clone, PartialEq, Eq, Hash)]
53pub struct UnsyncAuthor {
54    name: String,
55    updated: Option<DateTime<Utc>>,
56    aliases: Vec<UnsyncAlias>,
57}
58
59impl UnsyncAuthor {
60    pub fn new(name: String) -> Self {
61        Self {
62            name,
63            updated: None,
64            aliases: Vec::new(),
65        }
66    }
67
68    pub fn name(self, name: String) -> Self {
69        Self { name, ..self }
70    }
71    pub fn aliases(self, aliases: Vec<UnsyncAlias>) -> Self {
72        Self { aliases, ..self }
73    }
74    pub fn updated(self, updated: Option<DateTime<Utc>>) -> Self {
75        Self { updated, ..self }
76    }
77    /// Import it into the archive.
78    ///
79    /// If the author already exists (by aliases), it updates their name, aliases, and updated date.
80    ///
81    /// # Errors
82    ///
83    /// Returns `rusqlite::Error` if there was an error accessing the database.
84    pub fn sync<T>(self, manager: &PostArchiverManager<T>) -> Result<AuthorId, rusqlite::Error>
85    where
86        T: PostArchiverConnection,
87    {
88        manager.import_author(self)
89    }
90}
91
92/// Represents an alias for an author that is not yet synced with the archive.
93///
94/// This is used to track different platforms or identifiers for the same author.
95/// It can include links to their profiles or other relevant information.
96#[derive(Debug, Clone, PartialEq, Eq, Hash)]
97pub struct UnsyncAlias {
98    pub source: String,
99    pub platform: PlatformId,
100    pub link: Option<String>,
101}
102
103impl UnsyncAlias {
104    pub fn new(platform: PlatformId, source: String) -> Self {
105        Self {
106            link: None,
107            source,
108            platform,
109        }
110    }
111
112    pub fn source<S: Into<String>>(mut self, source: S) -> Self {
113        self.source = source.into();
114        self
115    }
116
117    pub fn platform(mut self, platform: PlatformId) -> Self {
118        self.platform = platform;
119        self
120    }
121
122    pub fn link<S: Into<String>>(mut self, link: S) -> Self {
123        self.link = Some(link.into());
124        self
125    }
126}