misskey_api/endpoint/notes/
local_timeline.rs

1use crate::model::{id::Id, note::Note};
2
3use chrono::{serde::ts_milliseconds_option, DateTime, Utc};
4use mime::Mime;
5use serde::Serialize;
6use typed_builder::TypedBuilder;
7
8#[derive(Serialize, Default, Debug, Clone, TypedBuilder)]
9#[serde(rename_all = "camelCase")]
10#[builder(doc)]
11pub struct Request {
12    #[serde(skip_serializing_if = "Option::is_none")]
13    #[builder(default, setter(strip_option))]
14    pub with_files: Option<bool>,
15    #[serde(skip_serializing_if = "Option::is_none")]
16    #[builder(default, setter(strip_option))]
17    pub exclude_nsfw: Option<bool>,
18    #[serde(
19        skip_serializing_if = "Option::is_none",
20        serialize_with = "crate::serde::serialize_string_vec_option"
21    )]
22    #[builder(default, setter(strip_option))]
23    pub file_type: Option<Vec<Mime>>,
24    /// 1 .. 100
25    #[serde(skip_serializing_if = "Option::is_none")]
26    #[builder(default, setter(strip_option))]
27    pub limit: Option<u8>,
28    #[serde(skip_serializing_if = "Option::is_none")]
29    #[builder(default, setter(strip_option))]
30    pub since_id: Option<Id<Note>>,
31    #[serde(skip_serializing_if = "Option::is_none")]
32    #[builder(default, setter(strip_option))]
33    pub until_id: Option<Id<Note>>,
34    #[serde(
35        skip_serializing_if = "Option::is_none",
36        with = "ts_milliseconds_option"
37    )]
38    #[builder(default, setter(strip_option, into))]
39    pub since_date: Option<DateTime<Utc>>,
40    #[serde(
41        skip_serializing_if = "Option::is_none",
42        with = "ts_milliseconds_option"
43    )]
44    #[builder(default, setter(strip_option, into))]
45    pub until_date: Option<DateTime<Utc>>,
46}
47
48impl misskey_core::Request for Request {
49    type Response = Vec<Note>;
50    const ENDPOINT: &'static str = "notes/local-timeline";
51}
52
53impl_pagination!(Request, Note);
54
55#[cfg(test)]
56mod tests {
57    use super::Request;
58    use crate::test::{ClientExt, TestClient};
59
60    use mime::IMAGE_PNG;
61
62    #[tokio::test]
63    async fn request() {
64        let client = TestClient::new();
65        client.test(Request::default()).await;
66    }
67
68    #[tokio::test]
69    async fn request_with_options() {
70        let client = TestClient::new();
71        client
72            .test(Request {
73                with_files: Some(true),
74                exclude_nsfw: Some(true),
75                file_type: None,
76                limit: None,
77                since_id: None,
78                until_id: None,
79                since_date: None,
80                until_date: None,
81            })
82            .await;
83    }
84
85    #[tokio::test]
86    async fn request_with_file_type() {
87        let client = TestClient::new();
88        client
89            .test(Request {
90                with_files: None,
91                exclude_nsfw: None,
92                file_type: Some(vec![IMAGE_PNG]),
93                limit: None,
94                since_id: None,
95                until_id: None,
96                since_date: None,
97                until_date: None,
98            })
99            .await;
100    }
101
102    #[tokio::test]
103    async fn request_with_limit() {
104        let client = TestClient::new();
105        client
106            .test(Request {
107                with_files: None,
108                exclude_nsfw: None,
109                file_type: None,
110                limit: Some(100),
111                since_id: None,
112                until_id: None,
113                since_date: None,
114                until_date: None,
115            })
116            .await;
117    }
118
119    #[tokio::test]
120    async fn request_paginate() {
121        let client = TestClient::new();
122        let note = client.create_note(Some("test"), None, None).await;
123
124        client
125            .test(Request {
126                with_files: None,
127                exclude_nsfw: None,
128                file_type: None,
129                limit: None,
130                since_id: Some(note.id.clone()),
131                until_id: Some(note.id.clone()),
132                since_date: None,
133                until_date: None,
134            })
135            .await;
136    }
137
138    #[tokio::test]
139    async fn request_with_date() {
140        let client = TestClient::new();
141        let now = chrono::Utc::now();
142
143        client
144            .test(Request {
145                with_files: None,
146                exclude_nsfw: None,
147                file_type: None,
148                limit: None,
149                since_id: None,
150                until_id: None,
151                since_date: Some(now),
152                until_date: Some(now),
153            })
154            .await;
155    }
156}