|
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