luminol_data/shared/
script.rs1use base64::Engine;
19use rand::Rng;
20
21#[allow(missing_docs)]
22#[derive(Debug, Clone)]
23pub struct Script {
24 pub id: u32,
25 pub name: String,
26 pub script_text: String,
27}
28
29impl Script {
30 pub fn new(name: impl Into<String>, script_text: impl Into<String>) -> Self {
32 Self {
33 id: rand::thread_rng().gen_range(0..=99999999),
34 name: name.into(),
35 script_text: script_text.into(),
36 }
37 }
38}
39
40impl<'de> alox_48::Deserialize<'de> for Script {
41 fn deserialize<D>(deserializer: D) -> Result<Self, alox_48::DeError>
42 where
43 D: alox_48::DeserializerTrait<'de>,
44 {
45 struct Visitor;
46
47 impl<'de> alox_48::Visitor<'de> for Visitor {
48 type Value = Script;
49
50 fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
51 formatter.write_str("an array")
52 }
53
54 fn visit_array<A>(self, mut array: A) -> Result<Self::Value, alox_48::DeError>
55 where
56 A: alox_48::ArrayAccess<'de>,
57 {
58 use std::io::Read;
59
60 let Some(id) = array.next_element()? else {
61 return Err(alox_48::DeError::missing_field("id".into()));
62 };
63
64 let Some(name) = array.next_element()? else {
65 return Err(alox_48::DeError::missing_field("name".into()));
66 };
67
68 let Some(data) = array.next_element::<alox_48::RbString>()? else {
69 return Err(alox_48::DeError::missing_field("data".into()));
70 };
71
72 let mut decoder = flate2::bufread::ZlibDecoder::new(data.data.as_slice());
73 let mut script = String::new();
74 decoder
75 .read_to_string(&mut script)
76 .map_err(alox_48::DeError::custom)?;
77
78 Ok(Script {
79 id,
80 name,
81 script_text: script,
82 })
83 }
84 }
85
86 deserializer.deserialize(Visitor)
87 }
88}
89
90impl alox_48::Serialize for Script {
91 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, alox_48::SerError>
92 where
93 S: alox_48::SerializerTrait,
94 {
95 use alox_48::SerializeArray;
96 use std::io::Write;
97
98 let mut array = serializer.serialize_array(3)?;
99
100 let mut encoder = flate2::write::ZlibEncoder::new(Vec::new(), Default::default());
101 let data = encoder
102 .write_all(self.script_text.as_bytes())
103 .and_then(|_| encoder.finish())
104 .map_err(alox_48::SerError::custom)?;
105
106 array.serialize_element(&self.id)?;
107 array.serialize_element(&self.name)?;
108 array.serialize_element(&alox_48::RbString { data })?;
109
110 array.end()
111 }
112}
113
114impl<'de> serde::Deserialize<'de> for Script {
115 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
116 where
117 D: serde::Deserializer<'de>,
118 {
119 struct Visitor;
120
121 impl<'de> serde::de::Visitor<'de> for Visitor {
122 type Value = Script;
123
124 fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
125 formatter.write_str("a key-value mapping")
126 }
127
128 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
129 where
130 A: serde::de::MapAccess<'de>,
131 {
132 use serde::de::Error;
133 use std::io::Read;
134
135 let mut id = None;
136 let mut name = None;
137 let mut data = None;
138
139 while let Some(key) = map.next_key::<String>()? {
140 match key.as_str() {
141 "id" => id = Some(map.next_value()?),
142 "name" => name = Some(map.next_value()?),
143 "data" => data = Some(map.next_value::<String>()?),
144 _ => {}
145 }
146 }
147
148 let Some(name) = name else {
149 return Err(A::Error::missing_field("name"));
150 };
151
152 let Some(data) = data else {
153 return Err(A::Error::missing_field("data"));
154 };
155
156 let mut decoder = flate2::bufread::ZlibDecoder::new(std::io::Cursor::new(
157 base64::engine::general_purpose::STANDARD
158 .decode(data)
159 .map_err(A::Error::custom)?,
160 ));
161 let mut script = String::new();
162 decoder
163 .read_to_string(&mut script)
164 .map_err(A::Error::custom)?;
165
166 Ok(if let Some(id) = id {
167 Script {
168 id,
169 name,
170 script_text: script,
171 }
172 } else {
173 Script::new(name, script)
174 })
175 }
176 }
177
178 deserializer.deserialize_any(Visitor)
179 }
180}
181
182impl serde::Serialize for Script {
183 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
184 where
185 S: serde::Serializer,
186 {
187 use serde::ser::Error;
188 use serde::ser::SerializeMap;
189 use std::io::Write;
190
191 let mut map = serializer.serialize_map(Some(3))?;
192
193 let mut encoder = flate2::write::ZlibEncoder::new(Vec::new(), Default::default());
194 let data = encoder
195 .write_all(self.script_text.as_bytes())
196 .and_then(|_| encoder.finish())
197 .map_err(S::Error::custom)?;
198
199 map.serialize_entry("id", &self.id)?;
200 map.serialize_entry("name", &self.name)?;
201 map.serialize_entry(
202 "data",
203 &base64::engine::general_purpose::STANDARD.encode(data),
204 )?;
205
206 map.end()
207 }
208}