misskey_api/endpoint/notes/
local_timeline.rs1use 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 #[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}