|
1 | | -use core::assert_matches::debug_assert_matches; |
2 | | - |
3 | 1 | use alloc::borrow::Cow; |
4 | | -use alloc::string::{String, ToString}; |
5 | 2 | use alloc::vec::Vec; |
6 | | -use serde::{ |
7 | | - de::{DeserializeSeed, Error, Visitor}, |
8 | | - Deserialize, |
9 | | -}; |
10 | | -use serde_json::value::RawValue; |
| 3 | +use serde::Deserialize; |
11 | 4 |
|
12 | | -use crate::json_writer::JsonWriter; |
13 | 5 | use crate::util::{deserialize_optional_string_to_i64, deserialize_string_to_i64}; |
14 | 6 |
|
15 | 7 | use super::bucket_priority::BucketPriority; |
@@ -123,7 +115,8 @@ pub struct OplogEntry<'a> { |
123 | 115 |
|
124 | 116 | #[derive(Debug)] |
125 | 117 | pub enum OplogData<'a> { |
126 | | - JsonString { data: Cow<'a, str> }, |
| 118 | + /// A string encoding a well-formed JSON object representing values of the row. |
| 119 | + Json { data: Cow<'a, str> }, |
127 | 120 | // BsonDocument { data: Cow<'a, [u8]> }, |
128 | 121 | } |
129 | 122 |
|
@@ -154,147 +147,12 @@ impl<'a, 'de: 'a> Deserialize<'de> for OplogData<'a> { |
154 | 147 | where |
155 | 148 | D: serde::Deserializer<'de>, |
156 | 149 | { |
157 | | - struct ReadFromBsonVisitor; |
158 | | - |
159 | | - impl<'de> Visitor<'de> for ReadFromBsonVisitor { |
160 | | - type Value = OplogData<'de>; |
161 | | - |
162 | | - fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result { |
163 | | - formatter.write_str("a string or an object") |
164 | | - } |
165 | | - |
166 | | - fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E> |
167 | | - where |
168 | | - E: serde::de::Error, |
169 | | - { |
170 | | - // Sync service sent data as JSON string. We will save that same string into |
171 | | - // ps_oplog without any transformations. |
172 | | - Ok(OplogData::JsonString { |
173 | | - data: Cow::Borrowed(v), |
174 | | - }) |
175 | | - } |
176 | | - |
177 | | - fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> |
178 | | - where |
179 | | - E: serde::de::Error, |
180 | | - { |
181 | | - // Same case, but if the deserializer doesn't let us borrow the JSON string. |
182 | | - Ok(OplogData::JsonString { |
183 | | - data: Cow::Owned(v.to_string()), |
184 | | - }) |
185 | | - } |
186 | | - |
187 | | - fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error> |
188 | | - where |
189 | | - A: serde::de::MapAccess<'de>, |
190 | | - { |
191 | | - // Ok, we have a sub-document / JSON object. We can't save that as-is, we need to |
192 | | - // serialize it. serde_json's Serializer is std-only because they don't want to |
193 | | - // expose their custom no_std Write trait. So we have to use our own writer impl |
194 | | - // here. |
195 | | - |
196 | | - let mut writer = JsonWriter::new(); |
197 | | - |
198 | | - struct PendingKey<'a, 'de> { |
199 | | - key: &'de str, |
200 | | - writer: &'a mut JsonWriter, |
201 | | - } |
202 | | - |
203 | | - impl<'a, 'de> Visitor<'de> for PendingKey<'a, 'de> { |
204 | | - type Value = (); |
205 | | - |
206 | | - fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result { |
207 | | - formatter.write_str("SQLite-compatible value") |
208 | | - } |
209 | | - |
210 | | - fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> |
211 | | - where |
212 | | - E: serde::de::Error, |
213 | | - { |
214 | | - self.writer.write_str(self.key, v); |
215 | | - Ok(()) |
216 | | - } |
217 | | - |
218 | | - fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E> |
219 | | - where |
220 | | - E: serde::de::Error, |
221 | | - { |
222 | | - self.writer.write_f64(self.key, v); |
223 | | - Ok(()) |
224 | | - } |
225 | | - |
226 | | - fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E> |
227 | | - where |
228 | | - E: serde::de::Error, |
229 | | - { |
230 | | - self.writer.write_i64(self.key, v as i64); |
231 | | - Ok(()) |
232 | | - } |
233 | | - |
234 | | - fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E> |
235 | | - where |
236 | | - E: serde::de::Error, |
237 | | - { |
238 | | - self.writer.write_i64(self.key, v); |
239 | | - Ok(()) |
240 | | - } |
241 | | - } |
242 | | - |
243 | | - impl<'a, 'de> DeserializeSeed<'de> for PendingKey<'a, 'de> { |
244 | | - type Value = (); |
245 | | - |
246 | | - fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error> |
247 | | - where |
248 | | - D: serde::Deserializer<'de>, |
249 | | - { |
250 | | - deserializer.deserialize_any(self) |
251 | | - } |
252 | | - } |
253 | | - |
254 | | - while let Some(key) = map.next_key::<&'de str>()? { |
255 | | - let pending = PendingKey { |
256 | | - key, |
257 | | - writer: &mut writer, |
258 | | - }; |
259 | | - map.next_value_seed(pending)?; |
260 | | - } |
261 | | - |
262 | | - Ok(OplogData::JsonString { |
263 | | - data: Cow::Owned(writer.finish()), |
264 | | - }) |
265 | | - } |
266 | | - } |
267 | | - |
268 | | - // Regardless of whether we're deserializing JSON or BSON, oplog data is represented either |
269 | | - // as a string (representing a JSON-encoded object) or an object (representing the values |
270 | | - // directly). |
271 | | - |
272 | | - let is_from_bson = !deserializer.is_human_readable(); |
273 | | - if is_from_bson { |
274 | | - deserializer.deserialize_any(ReadFromBsonVisitor) |
275 | | - } else { |
276 | | - // We're already coming from JSON, so we either have a JSON string or a JSON object. |
277 | | - // Let's take a look at the serialized JSON string. |
278 | | - let data: &'de RawValue = Deserialize::deserialize(deserializer)?; |
279 | | - let str = data.get(); |
280 | | - |
281 | | - if matches!(str.chars().nth(0), Some('"')) { |
282 | | - // We have a JSON object serialized into a string. We'll have to deserialize once |
283 | | - // so that we have the JSON form of the object itself to forward to the database. |
284 | | - // This turns `"{\"foo\"": 1}"` into `{"foo": 1}` |
285 | | - let content: String = serde_json::from_str(str) |
286 | | - .map_err(|_| D::Error::custom("could not deserialize json string"))?; |
287 | | - Ok(OplogData::JsonString { |
288 | | - data: content.into(), |
289 | | - }) |
290 | | - } else { |
291 | | - debug_assert_matches!(str.chars().nth(0), Some('{')); |
292 | | - |
293 | | - // It's an embedded object that we now have as a string. How convenient, we'll save |
294 | | - // that into the database without further modifications. |
295 | | - Ok(OplogData::JsonString { data: str.into() }) |
296 | | - } |
297 | | - } |
| 150 | + // For now, we will always get oplog data as a string. In the future, there may be the |
| 151 | + // option of the sync service sending BSON-encoded data lines too, but that's not relevant |
| 152 | + // for now. |
| 153 | + return Ok(OplogData::Json { |
| 154 | + data: Deserialize::deserialize(deserializer)?, |
| 155 | + }); |
298 | 156 | } |
299 | 157 | } |
300 | 158 |
|
|
0 commit comments