]> Untitled Git - lemmy.git/blob - crates/apub/src/protocol/activities/voting/vote.rs
Implement separate mod activities for feature, lock post (#2716)
[lemmy.git] / crates / apub / src / protocol / activities / voting / vote.rs
1 use crate::{
2   activities::verify_community_matches,
3   fetcher::post_or_comment::PostOrComment,
4   local_instance,
5   objects::{community::ApubCommunity, person::ApubPerson},
6   protocol::InCommunity,
7 };
8 use activitypub_federation::core::object_id::ObjectId;
9 use lemmy_api_common::context::LemmyContext;
10 use lemmy_utils::error::LemmyError;
11 use serde::{Deserialize, Serialize};
12 use std::convert::TryFrom;
13 use strum_macros::Display;
14 use url::Url;
15
16 #[derive(Clone, Debug, Deserialize, Serialize)]
17 #[serde(rename_all = "camelCase")]
18 pub struct Vote {
19   pub(crate) actor: ObjectId<ApubPerson>,
20   pub(crate) object: ObjectId<PostOrComment>,
21   #[serde(rename = "type")]
22   pub(crate) kind: VoteType,
23   pub(crate) id: Url,
24   pub(crate) audience: Option<ObjectId<ApubCommunity>>,
25 }
26
27 #[derive(Clone, Debug, Display, Deserialize, Serialize, PartialEq, Eq)]
28 pub enum VoteType {
29   Like,
30   Dislike,
31 }
32
33 impl TryFrom<i16> for VoteType {
34   type Error = LemmyError;
35
36   fn try_from(value: i16) -> Result<Self, Self::Error> {
37     match value {
38       1 => Ok(VoteType::Like),
39       -1 => Ok(VoteType::Dislike),
40       _ => Err(LemmyError::from_message("invalid vote value")),
41     }
42   }
43 }
44
45 impl From<&VoteType> for i16 {
46   fn from(value: &VoteType) -> i16 {
47     match value {
48       VoteType::Like => 1,
49       VoteType::Dislike => -1,
50     }
51   }
52 }
53
54 #[async_trait::async_trait(?Send)]
55 impl InCommunity for Vote {
56   async fn community(
57     &self,
58     context: &LemmyContext,
59     request_counter: &mut i32,
60   ) -> Result<ApubCommunity, LemmyError> {
61     let local_instance = local_instance(context).await;
62     let community = self
63       .object
64       .dereference(context, local_instance, request_counter)
65       .await?
66       .community(context, request_counter)
67       .await?;
68     if let Some(audience) = &self.audience {
69       verify_community_matches(audience, community.actor_id.clone())?;
70     }
71     Ok(community)
72   }
73 }