1use super::send_segment::*;
2use super::signal_segment_builder::*;
3use super::utils::*;
4
5#[derive(Default, Debug, Clone)]
6pub struct SegmentBuilder {
7 segments: Vec<SendSegment>,
8}
9
10impl From<Vec<SendSegment>> for SegmentBuilder {
11 fn from(value: Vec<SendSegment>) -> Self {
12 Self { segments: value }
13 }
14}
15
16impl SegmentBuilder {
17 pub fn new() -> Self {
18 Self::default()
19 }
20
21 pub fn build(self) -> Vec<SendSegment> {
22 self.segments
23 }
24
25 pub fn push(&mut self, segment: impl SendSegmentData) {
26 self.segments.push(segment.into_send_segment());
27 }
28
29 pub fn and_push(mut self, segment: impl SendSegmentData) -> Self {
30 self.segments.push(segment.into_send_segment());
31 self
32 }
33
34 pub fn text(self, text: impl ToString) -> Self {
35 self.and_push(TextData {
36 text: text.to_string(),
37 })
38 }
39
40 pub fn face(self, id: impl ToString) -> Self {
41 self.and_push(FaceData { id: id.to_string() })
42 }
43
44 pub fn image_with_options(
45 self,
46 file: impl ToString,
47 image_type: Option<ImageType>,
48 cache: Option<bool>,
49 proxy: Option<bool>,
50 timeout: Option<i32>,
51 ) -> Self {
52 self.and_push(ImageData {
53 file: file.to_string(),
54 image_type,
55 cache,
56 proxy,
57 timeout,
58 })
59 }
60
61 pub fn image(self, file: impl ToString) -> Self {
62 self.image_with_options(file, None, None, None, None)
63 }
64
65 pub fn image_builder(self, file: impl ToString) -> ImageDataBuilder {
66 ImageDataBuilder::new(self, file)
67 }
68
69 pub fn record_with_options(
70 self,
71 file: impl ToString,
72 magic: Option<String>,
73 cache: Option<bool>,
74 proxy: Option<bool>,
75 timeout: Option<i32>,
76 ) -> Self {
77 self.and_push(RecordData {
78 file: file.to_string(),
79 magic,
80 cache,
81 proxy,
82 timeout,
83 })
84 }
85
86 pub fn record(self, file: impl ToString) -> Self {
87 self.record_with_options(file, None, None, None, None)
88 }
89
90 pub fn video_with_options(
91 self,
92 file: impl ToString,
93 cache: Option<bool>,
94 proxy: Option<bool>,
95 timeout: Option<i32>,
96 ) -> Self {
97 self.and_push(VideoData {
98 file: file.to_string(),
99 cache,
100 proxy,
101 timeout,
102 })
103 }
104
105 pub fn video(self, file: impl ToString) -> Self {
106 self.video_with_options(file, None, None, None)
107 }
108
109 pub fn at(self, qq: AtType) -> Self {
110 self.and_push(AtData { qq })
111 }
112
113 pub fn at_all(self) -> Self {
114 self.at(AtType::All)
115 }
116
117 pub fn at_id(self, id: String) -> Self {
118 self.at(AtType::Id(id))
119 }
120
121 pub fn rps(self) -> Self {
122 self.and_push(RpsData {})
123 }
124
125 pub fn dice(self) -> Self {
126 self.and_push(DiceData {})
127 }
128
129 pub fn shake(self) -> Self {
130 self.and_push(ShakeData {})
131 }
132
133 pub fn poke(self, poke_type: impl ToString, id: impl ToString) -> Self {
134 self.and_push(PokeData {
135 poke_type: poke_type.to_string(),
136 id: id.to_string(),
137 })
138 }
139
140 pub fn anonymous(self, ignore: Option<bool>) -> Self {
141 self.and_push(AnonymousData { ignore })
142 }
143
144 pub fn share(
145 self,
146 url: impl ToString,
147 title: impl ToString,
148 content: impl ToString,
149 image: impl ToString,
150 ) -> Self {
151 self.and_push(ShareData {
152 url: url.to_string(),
153 title: title.to_string(),
154 content: content.to_string(),
155 image: image.to_string(),
156 })
157 }
158
159 pub fn contact(self, contact_type: ContactType, id: impl ToString) -> Self {
160 self.and_push(ContactData {
161 contact_type,
162 id: id.to_string(),
163 })
164 }
165
166 pub fn contact_qq(self, id: impl ToString) -> Self {
167 self.contact(ContactType::QQ, id)
168 }
169
170 pub fn contact_group(self, id: impl ToString) -> Self {
171 self.contact(ContactType::Group, id)
172 }
173
174 pub fn location(
175 self,
176 lat: impl ToString,
177 lon: impl ToString,
178 title: Option<String>,
179 content: Option<String>,
180 ) -> Self {
181 self.and_push(LocationData {
182 lat: lat.to_string(),
183 lon: lon.to_string(),
184 title,
185 content,
186 })
187 }
188
189 #[allow(clippy::too_many_arguments)]
190 pub fn music(
191 self,
192 music_type: MusicType,
193 id: Option<String>,
194 url: Option<String>,
195 audio: Option<String>,
196 title: Option<String>,
197 content: Option<String>,
198 image: Option<String>,
199 ) -> Self {
200 self.and_push(MusicData {
201 music_type,
202 id,
203 url,
204 audio,
205 title,
206 content,
207 image,
208 })
209 }
210
211 pub fn music_typed(self, music_type: MusicType, id: impl ToString) -> Self {
212 self.music(
213 music_type,
214 Some(id.to_string()),
215 None,
216 None,
217 None,
218 None,
219 None,
220 )
221 }
222
223 pub fn music_qq(self, id: impl ToString) -> Self {
224 self.music_typed(MusicType::QQ, id)
225 }
226
227 pub fn music_163(self, id: impl ToString) -> Self {
228 self.music_typed(MusicType::NetEaseCloudMusic, id)
229 }
230
231 pub fn music_xm(self, id: impl ToString) -> Self {
232 self.music_typed(MusicType::Xm, id)
233 }
234
235 pub fn music_custom(
236 self,
237 url: impl ToString,
238 audio: impl ToString,
239 title: impl ToString,
240 content: impl ToString,
241 image: impl ToString,
242 ) -> Self {
243 self.music(
244 MusicType::Custom,
245 None,
246 Some(url.to_string()),
247 Some(audio.to_string()),
248 Some(title.to_string()),
249 Some(content.to_string()),
250 Some(image.to_string()),
251 )
252 }
253
254 pub fn reply(self, id: impl ToString) -> Self {
255 self.and_push(ReplyData { id: id.to_string() })
256 }
257
258 pub fn forward(self) -> Self {
259 self.and_push(ForwardData {})
260 }
261
262 pub fn node(
263 self,
264 id: Option<String>,
265 user_id: Option<String>,
266 nickname: Option<String>,
267 content: Option<Vec<SendSegment>>,
268 ) -> Self {
269 self.and_push(NodeData {
270 id,
271 user_id,
272 nickname,
273 content,
274 })
275 }
276
277 pub fn node_forward(self, id: impl ToString) -> Self {
278 self.node(Some(id.to_string()), None, None, None)
279 }
280
281 pub fn node_custom(
282 self,
283 user_id: impl ToString,
284 nickname: impl ToString,
285 content: Vec<SendSegment>,
286 ) -> Self {
287 self.node(
288 None,
289 Some(user_id.to_string()),
290 Some(nickname.to_string()),
291 Some(content),
292 )
293 }
294
295 pub fn xml(self, data: impl ToString) -> Self {
296 self.and_push(XmlData {
297 data: data.to_string(),
298 })
299 }
300
301 pub fn json(self, data: impl ToString) -> Self {
302 self.and_push(JsonData {
303 data: data.to_string(),
304 })
305 }
306}
307
308#[macro_export]
309macro_rules! text {
310 ( $( $arg: tt )* ) => {
311 {
312 $crate::message::segment_builder::SegmentBuilder::new().text( format!( $( $arg )* ) ).build()
313 }
314 };
315}