Skip to main content

tranquility/model/
link.rs

1//! A post on reddit.
2
3use crate::{
4    auth::Auth,
5    client::{route::Route, Client},
6    error::Error,
7    model::{
8        award::Award, comment::Comment, misc::Fullname, misc::Params, subreddit::Subreddit,
9        user::User,
10    },
11};
12use serde::{Deserialize, Serialize};
13
14/// The struct representing a post on reddit.
15#[derive(Clone, Debug, Serialize, Deserialize)]
16pub struct Link {
17    /// The title of the link.
18    pub title: String,
19    /// The username of the author who submitted the link.
20    pub author: String,
21    /// The score of this post, fuzzed.
22    pub score: i64,
23    /// The amount of comments.
24    pub num_comments: u64,
25    /// The name of this subreddit.
26    pub subreddit: String,
27    /// The fullname of this Link.
28    pub name: Fullname,
29    /// All awards belonging to this Link.
30    pub all_awardings: Vec<Award>,
31}
32
33impl Link {
34    /// Retrieves the User struct of the author.
35    pub async fn author<T: Auth + Send + Sync>(&self, client: &Client<T>) -> Result<User, Error> {
36        client.user(&self.author).await
37    }
38
39    /// Retrieves the Subreddit struct where this Link was posted.
40    pub async fn subreddit<T: Auth + Send + Sync>(
41        &self,
42        client: &Client<T>,
43    ) -> Result<Subreddit, Error> {
44        client.subreddit(&self.subreddit).await
45    }
46
47    /// Returns the first-level replies to this post.
48    pub async fn replies<T: Auth + Send + Sync>(
49        &self,
50        _client: &Client<T>,
51    ) -> Result<Vec<Comment>, Error> {
52        todo!()
53    }
54
55    /// Creates a top-level comment in this Link.
56    pub async fn reply<T: Auth + Send + Sync>(
57        &self,
58        client: &Client<T>,
59        body: &str,
60    ) -> Result<(), Error> {
61        client.submit_comment(self.name.as_ref(), body).await
62    }
63
64    /// Spoilers the Link assuming you have the permission to do so.
65    pub async fn spoiler<T: Auth + Send + Sync>(&self, client: &Client<T>) -> Result<(), Error> {
66        client
67            .post(Route::Spoiler, &Params::new().add("id", self.name.as_ref()))
68            .await
69            .and(Ok(()))
70    }
71
72    /// Unspoilers the Link assuming you have the permission to do so.
73    pub async fn unspoiler<T: Auth + Send + Sync>(&self, client: &Client<T>) -> Result<(), Error> {
74        client
75            .post(
76                Route::Unspoiler,
77                &Params::new().add("id", self.name.as_ref()),
78            )
79            .await
80            .and(Ok(()))
81    }
82
83    /// Adds the NSFW mark to the Link assuming you have the permission to do so.
84    pub async fn set_nsfw<T: Auth + Send + Sync>(&self, client: &Client<T>) -> Result<(), Error> {
85        client
86            .post(Route::SetNSFW, &Params::new().add("id", self.name.as_ref()))
87            .await
88            .and(Ok(()))
89    }
90
91    /// Removes the NSFW mark from the Link assuming you have the permission to do so.
92    pub async fn unset_nsfw<T: Auth + Send + Sync>(&self, client: &Client<T>) -> Result<(), Error> {
93        client
94            .post(
95                Route::UnsetNSFW,
96                &Params::new().add("id", self.name.as_ref()),
97            )
98            .await
99            .and(Ok(()))
100    }
101
102    /// Locks the Link assuming you have the permission to do so.
103    pub async fn lock<T: Auth + Send + Sync>(&self, client: &Client<T>) -> Result<(), Error> {
104        client
105            .post(Route::Lock, &Params::new().add("id", self.name.as_ref()))
106            .await
107            .and(Ok(()))
108    }
109
110    /// Unlocks the Link assuming you have the permission to do so.
111    pub async fn unlock<T: Auth + Send + Sync>(&self, client: &Client<T>) -> Result<(), Error> {
112        client
113            .post(Route::Unlock, &Params::new().add("id", self.name.as_ref()))
114            .await
115            .and(Ok(()))
116    }
117
118    /// Start following this link.
119    pub async fn follow<T: Auth + Send + Sync>(&self, client: &Client<T>) -> Result<(), Error> {
120        client
121            .post(
122                Route::Follow,
123                &Params::new()
124                    .add("id", self.name.as_ref())
125                    .add("follow", "1"),
126            )
127            .await
128            .and(Ok(()))
129    }
130
131    /// Stop following this link.
132    pub async fn unfollow<T: Auth + Send + Sync>(&self, client: &Client<T>) -> Result<(), Error> {
133        client
134            .post(
135                Route::Follow,
136                &Params::new()
137                    .add("id", self.name.as_ref())
138                    .add("follow", "0"),
139            )
140            .await
141            .and(Ok(()))
142    }
143}