Skip to content

Commit cc4e46f

Browse files
committed
chore: fix trailing characters parser error
1 parent 01dbc68 commit cc4e46f

File tree

3 files changed

+76
-5
lines changed

3 files changed

+76
-5
lines changed

frontend/rust-lib/flowy-grid/src/util.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ pub fn make_default_board() -> BuildGridContext {
4949
let done_option = SelectOptionPB::with_color("Done", SelectOptionColorPB::Yellow);
5050
let single_select_type_option = SingleSelectTypeOptionBuilder::default()
5151
.add_option(to_do_option.clone())
52-
.add_option(doing_option.clone())
53-
.add_option(done_option.clone());
52+
.add_option(doing_option)
53+
.add_option(done_option);
5454
let single_select_field = FieldBuilder::new(single_select_type_option)
5555
.name("Status")
5656
.visibility(true)
Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,76 @@
11
use crate::revision::{TrashRevision, WorkspaceRevision};
2-
use serde::{Deserialize, Serialize};
2+
use serde::de::{MapAccess, Visitor};
3+
use serde::{de, Deserialize, Deserializer, Serialize};
4+
use std::fmt;
35
use std::sync::Arc;
46

5-
#[derive(Debug, Default, Deserialize, Serialize, Clone, Eq, PartialEq)]
7+
#[derive(Debug, Default, Serialize, Clone, Eq, PartialEq)]
68
pub struct FolderRevision {
79
pub workspaces: Vec<Arc<WorkspaceRevision>>,
810
pub trash: Vec<Arc<TrashRevision>>,
911
}
12+
13+
impl<'de> Deserialize<'de> for FolderRevision {
14+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
15+
where
16+
D: Deserializer<'de>,
17+
{
18+
struct FolderVisitor<'a>(&'a mut Option<FolderRevision>);
19+
impl<'de, 'a> Visitor<'de> for FolderVisitor<'a> {
20+
type Value = ();
21+
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
22+
formatter.write_str("Expect struct FolderRevision")
23+
}
24+
25+
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
26+
where
27+
A: MapAccess<'de>,
28+
{
29+
let f = |map: &mut A,
30+
workspaces: &mut Option<Vec<WorkspaceRevision>>,
31+
trash: &mut Option<Vec<TrashRevision>>| match map.next_key::<String>()
32+
{
33+
Ok(Some(key)) => {
34+
if key == "workspaces" && workspaces.is_none() {
35+
*workspaces = Some(map.next_value::<Vec<WorkspaceRevision>>().ok()?);
36+
}
37+
if key == "trash" && trash.is_none() {
38+
*trash = Some(map.next_value::<Vec<TrashRevision>>().ok()?);
39+
}
40+
Some(())
41+
}
42+
Ok(None) => None,
43+
Err(_e) => None,
44+
};
45+
46+
let mut workspaces: Option<Vec<WorkspaceRevision>> = None;
47+
let mut trash: Option<Vec<TrashRevision>> = None;
48+
while f(&mut map, &mut workspaces, &mut trash).is_some() {
49+
if workspaces.is_some() && trash.is_some() {
50+
break;
51+
}
52+
}
53+
54+
*self.0 = Some(FolderRevision {
55+
workspaces: workspaces.unwrap_or_default().into_iter().map(Arc::new).collect(),
56+
trash: trash.unwrap_or_default().into_iter().map(Arc::new).collect(),
57+
});
58+
Ok(())
59+
}
60+
}
61+
62+
let mut folder_rev: Option<FolderRevision> = None;
63+
const FIELDS: &[&str] = &["workspaces", "trash"];
64+
let _ = serde::Deserializer::deserialize_struct(
65+
deserializer,
66+
"FolderRevision",
67+
FIELDS,
68+
FolderVisitor(&mut folder_rev),
69+
);
70+
71+
match folder_rev {
72+
None => Err(de::Error::missing_field("workspaces or trash")),
73+
Some(folder_rev) => Ok(folder_rev),
74+
}
75+
}
76+
}

shared-lib/flowy-sync/src/client_folder/folder_pad.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use flowy_folder_data_model::revision::{AppRevision, FolderRevision, TrashRevisi
1212
use lib_infra::util::move_vec_element;
1313
use lib_ot::core::*;
1414

15+
use serde::Deserialize;
1516
use std::sync::Arc;
1617

1718
#[derive(Debug, Clone, Eq, PartialEq)]
@@ -44,7 +45,9 @@ impl FolderPad {
4445
pub fn from_delta(delta: FolderDelta) -> CollaborateResult<Self> {
4546
// TODO: Reconvert from history if delta.to_str() failed.
4647
let content = delta.content()?;
47-
let folder_rev: FolderRevision = serde_json::from_str(&content).map_err(|e| {
48+
let mut deserializer = serde_json::Deserializer::from_reader(content.as_bytes());
49+
50+
let folder_rev = FolderRevision::deserialize(&mut deserializer).map_err(|e| {
4851
tracing::error!("Deserialize folder from {} failed", content);
4952
return CollaborateError::internal().context(format!("Deserialize delta to folder failed: {}", e));
5053
})?;
@@ -457,6 +460,7 @@ mod tests {
457460
#![allow(clippy::all)]
458461
use crate::{client_folder::folder_pad::FolderPad, entities::folder::FolderDelta};
459462
use chrono::Utc;
463+
use serde::Deserialize;
460464

461465
use flowy_folder_data_model::revision::{
462466
AppRevision, FolderRevision, TrashRevision, ViewRevision, WorkspaceRevision,

0 commit comments

Comments
 (0)