Skip to content

Commit 3450891

Browse files
committed
Ignore unknown sync lines
1 parent 2edd4c3 commit 3450891

File tree

2 files changed

+71
-10
lines changed

2 files changed

+71
-10
lines changed

crates/core/src/sync/line.rs

Lines changed: 64 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use alloc::borrow::Cow;
22
use alloc::vec::Vec;
3+
use serde::de::{IgnoredAny, VariantAccess, Visitor};
34
use serde::Deserialize;
45

56
use crate::util::{deserialize_optional_string_to_i64, deserialize_string_to_i64};
@@ -13,24 +14,63 @@ use super::Checksum;
1314
/// internal copy).
1415
type SyncLineStr<'a> = Cow<'a, str>;
1516

16-
#[derive(Deserialize, Debug)]
17+
#[derive(Debug)]
1718

1819
pub enum SyncLine<'a> {
19-
#[serde(rename = "checkpoint", borrow)]
2020
Checkpoint(Checkpoint<'a>),
21-
#[serde(rename = "checkpoint_diff", borrow)]
2221
CheckpointDiff(CheckpointDiff<'a>),
23-
24-
#[serde(rename = "checkpoint_complete")]
2522
CheckpointComplete(CheckpointComplete),
26-
#[serde(rename = "partial_checkpoint_complete")]
2723
CheckpointPartiallyComplete(CheckpointPartiallyComplete),
28-
29-
#[serde(rename = "data", borrow)]
3024
Data(DataLine<'a>),
31-
32-
#[serde(rename = "token_expires_in")]
3325
KeepAlive(TokenExpiresIn),
26+
UnknownSyncLine,
27+
}
28+
29+
impl<'de> Deserialize<'de> for SyncLine<'de> {
30+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
31+
where
32+
D: serde::Deserializer<'de>,
33+
{
34+
struct SyncLineVisitor;
35+
36+
impl<'de> Visitor<'de> for SyncLineVisitor {
37+
type Value = SyncLine<'de>;
38+
39+
fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
40+
write!(formatter, "a sync line")
41+
}
42+
43+
fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
44+
where
45+
A: serde::de::EnumAccess<'de>,
46+
{
47+
let (name, payload) = data.variant::<&'de str>()?;
48+
Ok(match name {
49+
"checkpoint" => SyncLine::Checkpoint(payload.newtype_variant::<Checkpoint>()?),
50+
"checkpoint_diff" => {
51+
SyncLine::CheckpointDiff(payload.newtype_variant::<CheckpointDiff>()?)
52+
}
53+
"checkpoint_complete" => SyncLine::CheckpointComplete(
54+
payload.newtype_variant::<CheckpointComplete>()?,
55+
),
56+
"partial_checkpoint_complete" => SyncLine::CheckpointPartiallyComplete(
57+
payload.newtype_variant::<CheckpointPartiallyComplete>()?,
58+
),
59+
"data" => SyncLine::Data(payload.newtype_variant::<DataLine>()?),
60+
"token_expires_in" => {
61+
SyncLine::KeepAlive(payload.newtype_variant::<TokenExpiresIn>()?)
62+
}
63+
_ => {
64+
payload.newtype_variant::<IgnoredAny>()?;
65+
66+
SyncLine::UnknownSyncLine
67+
}
68+
})
69+
}
70+
}
71+
72+
deserializer.deserialize_enum("SyncLine", &[], SyncLineVisitor)
73+
}
3474
}
3575

3676
#[derive(Deserialize, Debug)]
@@ -160,6 +200,8 @@ impl<'a, 'de: 'a> Deserialize<'de> for OplogData<'a> {
160200
mod tests {
161201
use core::assert_matches::assert_matches;
162202

203+
use alloc::string::ToString;
204+
163205
use super::*;
164206

165207
fn deserialize(source: &str) -> SyncLine {
@@ -305,4 +347,16 @@ mod tests {
305347
}
306348
);
307349
}
350+
351+
#[test]
352+
fn parse_unknown() {
353+
assert_matches!(deserialize("{\"foo\": {}}"), SyncLine::UnknownSyncLine);
354+
assert_matches!(deserialize("{\"foo\": 123}"), SyncLine::UnknownSyncLine);
355+
}
356+
357+
#[test]
358+
fn parse_invalid_duplicate_key() {
359+
let e = serde_json::from_str::<SyncLine>(r#"{"foo": {}, "bar": {}}"#).unwrap_err();
360+
assert_eq!(e.to_string(), "expected value at line 1 column 10");
361+
}
308362
}

crates/core/src/sync/streaming_sync.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,13 @@ impl StreamingSyncIteration {
398398
SyncStateMachineTransition::Empty
399399
}
400400
}
401+
SyncLine::UnknownSyncLine => {
402+
event.instructions.push(Instruction::LogLine {
403+
severity: LogSeverity::DEBUG,
404+
line: "Unknown sync line".into(),
405+
});
406+
SyncStateMachineTransition::Empty
407+
}
401408
})
402409
}
403410

0 commit comments

Comments
 (0)