1pub(crate) mod access;
2pub(crate) mod core;
3
4pub use core::CQDeserializer;
5
6use serde::Deserialize;
7
8use crate::Result;
9
10pub fn from_str<'de, T: Deserialize<'de>>(input: &'de str) -> Result<T> {
25 Deserialize::deserialize(&mut CQDeserializer::new(input))
26}
27
28mod test {
29 #[test]
30 fn test_de() {
31 use super::*;
32 use crate::data::CQCode;
33
34 assert_eq!(
35 vec![
36 CQCode::from(("text", [("text", "[你好]")])),
37 CQCode::from(("face", [("id", "1")])),
38 CQCode::from(("image", [("file", "example.jpg")])),
39 CQCode::from(("at", [("qq", "123456")])),
40 CQCode::from(("emoji", [("id", "128512")]))
41 ],
42 from_str::<Vec<CQCode>>("[你好][CQ:face,id=1][CQ:image,file=example.jpg][CQ:at,qq=123456][CQ:emoji,id=128512]").unwrap());
43 }
44
45 #[test]
46 fn test_de_enum() {
47 use super::*;
48
49 #[derive(Deserialize, Debug, PartialEq)]
50 #[serde(rename_all = "lowercase")]
51 enum Segment {
52 Text { text: String },
53 Face { id: u32 },
54 Image { file: String },
55 At { qq: u64 },
56 Emoji { id: u32 },
57 }
58
59 let input =
60 "[你好][CQ:face,id=1][CQ:image,file=example.jpg][CQ:at,qq=123456][CQ:emoji,id=128512]";
61 let expected = vec![
62 Segment::Text {
63 text: "[你好]".to_string(),
64 },
65 Segment::Face { id: 1 },
66 Segment::Image {
67 file: "example.jpg".to_string(),
68 },
69 Segment::At { qq: 123456 },
70 Segment::Emoji { id: 128512 },
71 ];
72
73 let result: Vec<Segment> = from_str(input).unwrap();
74 assert_eq!(result, expected);
75 }
76}