]> Untitled Git - lemmy.git/blob - crates/apub/src/fetcher/post_or_comment.rs
7971cedba322c56c46f68c4b01df22b382fb108c
[lemmy.git] / crates / apub / src / fetcher / post_or_comment.rs
1 use crate::objects::{comment::Note, post::Page, FromApub};
2 use activitystreams::chrono::NaiveDateTime;
3 use diesel::PgConnection;
4 use lemmy_apub_lib::traits::ApubObject;
5 use lemmy_db_schema::source::{
6   comment::{Comment, CommentForm},
7   post::{Post, PostForm},
8 };
9 use lemmy_utils::LemmyError;
10 use lemmy_websocket::LemmyContext;
11 use serde::Deserialize;
12 use url::Url;
13
14 #[derive(Clone, Debug)]
15 pub enum PostOrComment {
16   Comment(Box<Comment>),
17   Post(Box<Post>),
18 }
19
20 pub enum PostOrCommentForm {
21   PostForm(PostForm),
22   CommentForm(CommentForm),
23 }
24
25 #[derive(Deserialize)]
26 pub enum PageOrNote {
27   Page(Page),
28   Note(Note),
29 }
30
31 #[async_trait::async_trait(?Send)]
32 impl ApubObject for PostOrComment {
33   type DataType = PgConnection;
34
35   fn last_refreshed_at(&self) -> Option<NaiveDateTime> {
36     None
37   }
38
39   // TODO: this can probably be implemented using a single sql query
40   fn read_from_apub_id(conn: &PgConnection, object_id: Url) -> Result<Option<Self>, LemmyError>
41   where
42     Self: Sized,
43   {
44     let post = Post::read_from_apub_id(conn, object_id.clone())?;
45     Ok(match post {
46       Some(o) => Some(PostOrComment::Post(Box::new(o))),
47       None => {
48         Comment::read_from_apub_id(conn, object_id)?.map(|c| PostOrComment::Comment(Box::new(c)))
49       }
50     })
51   }
52 }
53
54 #[async_trait::async_trait(?Send)]
55 impl FromApub for PostOrComment {
56   type ApubType = PageOrNote;
57
58   async fn from_apub(
59     apub: &PageOrNote,
60     context: &LemmyContext,
61     expected_domain: &Url,
62     request_counter: &mut i32,
63   ) -> Result<Self, LemmyError>
64   where
65     Self: Sized,
66   {
67     Ok(match apub {
68       PageOrNote::Page(p) => PostOrComment::Post(Box::new(
69         Post::from_apub(p, context, expected_domain, request_counter).await?,
70       )),
71       PageOrNote::Note(n) => PostOrComment::Comment(Box::new(
72         Comment::from_apub(n, context, expected_domain, request_counter).await?,
73       )),
74     })
75   }
76 }
77
78 impl PostOrComment {
79   pub(crate) fn ap_id(&self) -> Url {
80     match self {
81       PostOrComment::Post(p) => p.ap_id.clone(),
82       PostOrComment::Comment(c) => c.ap_id.clone(),
83     }
84     .into()
85   }
86 }