misskey_api/endpoint/users/
followers.rs

1use crate::model::{following::Following, id::Id, user::User};
2
3use serde::{Deserialize, Serialize};
4use typed_builder::TypedBuilder;
5
6#[derive(Deserialize, Debug, Clone)]
7#[serde(rename_all = "camelCase")]
8pub struct FollowingWithFollower {
9    #[serde(flatten)]
10    pub following: Following,
11    pub follower: User,
12}
13
14impl crate::PaginationItem for FollowingWithFollower {
15    type Id = Id<User>;
16    fn item_id(&self) -> Id<User> {
17        self.following.follower_id
18    }
19}
20
21#[derive(Serialize, Debug, Clone, TypedBuilder)]
22#[serde(rename_all = "camelCase")]
23#[builder(doc)]
24pub struct RequestWithUserId {
25    pub user_id: Id<User>,
26    /// 1 .. 100
27    #[serde(skip_serializing_if = "Option::is_none")]
28    #[builder(default, setter(strip_option))]
29    pub limit: Option<u8>,
30    #[serde(skip_serializing_if = "Option::is_none")]
31    #[builder(default, setter(strip_option))]
32    pub since_id: Option<Id<User>>,
33    #[serde(skip_serializing_if = "Option::is_none")]
34    #[builder(default, setter(strip_option))]
35    pub until_id: Option<Id<User>>,
36}
37
38impl misskey_core::Request for RequestWithUserId {
39    type Response = Vec<FollowingWithFollower>;
40    const ENDPOINT: &'static str = "users/followers";
41}
42
43impl crate::PaginationRequest for RequestWithUserId {
44    type Item = FollowingWithFollower;
45
46    fn set_since_id(&mut self, id: Id<User>) {
47        self.since_id.replace(id);
48    }
49
50    fn set_until_id(&mut self, id: Id<User>) {
51        self.until_id.replace(id);
52    }
53
54    fn set_limit(&mut self, limit: u8) {
55        self.limit.replace(limit);
56    }
57}
58
59#[derive(Serialize, Debug, Clone, TypedBuilder)]
60#[serde(rename_all = "camelCase")]
61#[builder(doc)]
62pub struct RequestWithUsername {
63    #[builder(setter(into))]
64    pub username: String,
65    #[builder(default, setter(strip_option, into))]
66    pub host: Option<String>,
67    /// 1 .. 100
68    #[serde(skip_serializing_if = "Option::is_none")]
69    #[builder(default, setter(strip_option))]
70    pub limit: Option<u8>,
71    #[serde(skip_serializing_if = "Option::is_none")]
72    #[builder(default, setter(strip_option))]
73    pub since_id: Option<Id<User>>,
74    #[serde(skip_serializing_if = "Option::is_none")]
75    #[builder(default, setter(strip_option))]
76    pub until_id: Option<Id<User>>,
77}
78
79impl misskey_core::Request for RequestWithUsername {
80    type Response = Vec<FollowingWithFollower>;
81    const ENDPOINT: &'static str = "users/followers";
82}
83
84impl crate::PaginationRequest for RequestWithUsername {
85    type Item = FollowingWithFollower;
86
87    fn set_since_id(&mut self, id: Id<User>) {
88        self.since_id.replace(id);
89    }
90
91    fn set_until_id(&mut self, id: Id<User>) {
92        self.until_id.replace(id);
93    }
94
95    fn set_limit(&mut self, limit: u8) {
96        self.limit.replace(limit);
97    }
98}
99
100#[cfg(test)]
101mod tests {
102    use super::{RequestWithUserId, RequestWithUsername};
103    use crate::test::{ClientExt, TestClient};
104
105    #[tokio::test]
106    async fn request_with_id() {
107        let client = TestClient::new();
108        let user = client.me().await;
109
110        client
111            .test(RequestWithUserId {
112                user_id: user.id,
113                limit: None,
114                since_id: None,
115                until_id: None,
116            })
117            .await;
118    }
119
120    #[tokio::test]
121    async fn request_with_username() {
122        let client = TestClient::new();
123        let user = client.me().await;
124
125        client
126            .test(RequestWithUsername {
127                username: user.username,
128                host: None,
129                limit: None,
130                since_id: None,
131                until_id: None,
132            })
133            .await;
134    }
135
136    // TODO: request_with_username_and_host
137
138    #[tokio::test]
139    async fn request_with_limit() {
140        let client = TestClient::new();
141        let user = client.me().await;
142        client
143            .test(RequestWithUserId {
144                user_id: user.id,
145                limit: Some(100),
146                since_id: None,
147                until_id: None,
148            })
149            .await;
150    }
151
152    #[tokio::test]
153    async fn request_paginate() {
154        let client = TestClient::new();
155        let user = client.user.me().await;
156        let (new_user, new_user_client) = client.admin.create_user().await;
157        new_user_client
158            .test(crate::endpoint::following::create::Request {
159                user_id: user.id.clone(),
160            })
161            .await;
162
163        client
164            .user
165            .test(RequestWithUserId {
166                user_id: user.id,
167                limit: None,
168                since_id: Some(new_user.id.clone()),
169                until_id: Some(new_user.id.clone()),
170            })
171            .await;
172    }
173}