Skip to main content

onebot_api/message/
segment_builder.rs

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}