Skip to content

Commit 7b165d3

Browse files
committed
refactor(NodeSeq): support name without @
Signed-off-by: Woshiluo Luo <woshiluo.luo@outlook.com>
1 parent c3e7264 commit 7b165d3

File tree

7 files changed

+144
-67
lines changed

7 files changed

+144
-67
lines changed

src/de_mut/cursor.rs

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,15 @@ pub enum MoveResult {
2828
Others,
2929
}
3030

31+
#[derive(Clone, Copy, Debug)]
32+
pub(super) struct MultiNodeCursor {
33+
pub start_cursor: BodyCursor,
34+
pub next_cursor: BodyCursor,
35+
pub skip_cursor: BodyCursor,
36+
#[allow(unused)]
37+
pub node_count: u32,
38+
}
39+
3140
impl<T: Type> AnyCursor<T> {
3241
/// 移动 `n` 格。
3342
pub fn step_n(&mut self, len: usize) {
@@ -147,12 +156,13 @@ impl TitleCursor {
147156
}
148157

149158
/// 生成组光标。
150-
pub fn take_group_on(&self, dtb: RefDtb, name: &str) -> (BodyCursor, usize, BodyCursor) {
159+
pub fn take_group_on(&self, dtb: RefDtb, name: &str) -> MultiNodeCursor {
151160
let name_bytes = name.as_bytes();
152161
let name_skip = align(name_bytes.len() + 1, BLOCK_LEN);
153162
let group = AnyCursor::<Body>(self.0, PhantomData);
154163

155-
let mut body = AnyCursor::<Body>(self.0 + 1 + name_skip, PhantomData);
164+
let title_body = AnyCursor::<Body>(self.0 + 1 + name_skip, PhantomData);
165+
let mut body = title_body;
156166
let mut len = 1;
157167

158168
let structure = &dtb.borrow().structure;
@@ -171,19 +181,30 @@ impl TitleCursor {
171181
}
172182
break;
173183
}
174-
(group, len, body)
184+
MultiNodeCursor {
185+
start_cursor: group,
186+
next_cursor: body,
187+
skip_cursor: title_body,
188+
node_count: len,
189+
}
175190
}
176191

177192
/// 生成节点光标。
178-
pub fn take_node_on(&self, dtb: RefDtb, name: &str) -> (BodyCursor, BodyCursor) {
193+
pub fn take_node_on(&self, dtb: RefDtb, name: &str) -> MultiNodeCursor {
179194
let name_bytes = name.as_bytes();
180195
let name_skip = align(name_bytes.len() + 1, BLOCK_LEN);
196+
let origin = AnyCursor::<Body>(self.0, PhantomData);
181197
let node = AnyCursor::<Body>(self.0 + 1 + name_skip, PhantomData);
182198

183199
let mut body = AnyCursor::<Body>(self.0 + 1 + name_skip, PhantomData);
184200

185201
body.escape_from(dtb);
186-
(node, body)
202+
MultiNodeCursor {
203+
start_cursor: origin,
204+
next_cursor: body,
205+
skip_cursor: node,
206+
node_count: 1,
207+
}
187208
}
188209
}
189210

src/de_mut/data.rs

Lines changed: 50 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1-
use super::{BodyCursor, Cursor};
1+
use super::cursor::MultiNodeCursor;
2+
use super::{BodyCursor, Cursor};
23
use super::{DtError, PropCursor, RefDtb, RegConfig};
34

45
use core::marker::PhantomData;
56
use serde::{de, Deserialize};
67

78
#[derive(Clone, Copy, Debug)]
89
pub(super) enum ValueCursor {
9-
Prop(BodyCursor, PropCursor),
1010
Body(BodyCursor),
11+
Prop(BodyCursor, PropCursor),
12+
Node(MultiNodeCursor),
1113
}
1214

1315
#[derive(Clone, Copy)]
@@ -206,6 +208,7 @@ impl<'de> de::Deserializer<'de> for &mut ValueDeserializer<'de> {
206208
visitor.visit_some(self)
207209
}
208210
}
211+
ValueCursor::Node(_) => visitor.visit_some(self),
209212
ValueCursor::Body(_) => visitor.visit_some(self),
210213
}
211214
}
@@ -247,25 +250,30 @@ impl<'de> de::Deserializer<'de> for &mut ValueDeserializer<'de> {
247250
V: de::Visitor<'de>,
248251
{
249252
use super::{StructAccess, StructAccessType, Temp};
250-
match self.move_on() {
251-
Cursor::Title(c) => {
252-
let (name, _) = c.split_on(self.dtb);
253-
let cursor = match self.cursor {
254-
ValueCursor::Body(cursor) => cursor,
255-
_ => unreachable!(""),
256-
};
257-
258-
let pre_len = name.as_bytes().iter().take_while(|b| **b != b'@').count();
259-
let name_bytes = &name.as_bytes()[..pre_len];
260-
let name = unsafe { core::str::from_utf8_unchecked(name_bytes) };
261-
262-
visitor.visit_seq(StructAccess {
263-
access_type: StructAccessType::Seq(name),
264-
temp: Temp::Node(cursor, cursor),
265-
de: self,
266-
})
253+
match self.cursor {
254+
ValueCursor::Node(result) => {
255+
let mut start_cursor = result.start_cursor;
256+
match start_cursor.move_on(self.dtb) {
257+
Cursor::Title(c) => {
258+
let (name, _) = c.split_on(self.dtb);
259+
260+
let pre_len = name.as_bytes().iter().take_while(|b| **b != b'@').count();
261+
let name_bytes = &name.as_bytes()[..pre_len];
262+
let name = unsafe { core::str::from_utf8_unchecked(name_bytes) };
263+
264+
let de = self;
265+
de.cursor = ValueCursor::Body(start_cursor);
266+
267+
visitor.visit_seq(StructAccess {
268+
access_type: StructAccessType::Seq(name),
269+
temp: Temp::Uninit,
270+
de,
271+
})
272+
}
273+
_ => unreachable!("seq request on a none seq cursor"),
274+
}
267275
}
268-
_ => unreachable!("seq request on a none seq cursor"),
276+
_ => unreachable!("Seq request on a not-node cursor"),
269277
}
270278
}
271279

@@ -293,14 +301,19 @@ impl<'de> de::Deserializer<'de> for &mut ValueDeserializer<'de> {
293301
V: de::Visitor<'de>,
294302
{
295303
use super::{StructAccess, StructAccessType, Temp};
296-
if let ValueCursor::Body(cursor) = self.cursor {
297-
return visitor.visit_map(StructAccess {
304+
match self.cursor {
305+
ValueCursor::Node(_) => visitor.visit_map(StructAccess {
298306
access_type: StructAccessType::Map(false),
299-
temp: Temp::Node(cursor, cursor),
307+
temp: Temp::Uninit,
300308
de: self,
301-
});
302-
};
303-
unreachable!("Prop -> map")
309+
}),
310+
ValueCursor::Body(_) => visitor.visit_map(StructAccess {
311+
access_type: StructAccessType::Map(false),
312+
temp: Temp::Uninit,
313+
de: self,
314+
}),
315+
ValueCursor::Prop(_, _) => unreachable!("Prop -> map"),
316+
}
304317
}
305318

306319
fn deserialize_struct<V>(
@@ -313,14 +326,19 @@ impl<'de> de::Deserializer<'de> for &mut ValueDeserializer<'de> {
313326
V: de::Visitor<'de>,
314327
{
315328
use super::{StructAccess, StructAccessType, Temp};
316-
if let ValueCursor::Body(cursor) = self.cursor {
317-
return visitor.visit_map(StructAccess {
329+
match self.cursor {
330+
ValueCursor::Node(_) => visitor.visit_map(StructAccess {
318331
access_type: StructAccessType::Struct(fields),
319-
temp: Temp::Node(cursor, cursor),
332+
temp: Temp::Uninit,
320333
de: self,
321-
});
322-
};
323-
unreachable!("Prop -> struct {_name} {fields:?}")
334+
}),
335+
ValueCursor::Body(_) => visitor.visit_map(StructAccess {
336+
access_type: StructAccessType::Struct(fields),
337+
temp: Temp::Uninit,
338+
de: self,
339+
}),
340+
ValueCursor::Prop(_, _) => unreachable!("Prop -> struct {_name}"),
341+
}
324342
}
325343

326344
fn deserialize_enum<V>(

src/de_mut/node.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -124,14 +124,14 @@ impl<'de> Iterator for NodeIter<'de, '_> {
124124
let dtb = self.node.dtb;
125125
if let Cursor::Title(c) = cursor.move_on(dtb) {
126126
let (name, _) = c.split_on(dtb);
127-
let (node_cursor, next) = c.take_node_on(dtb, name);
127+
let node_cursor = c.take_node_on(dtb, name);
128128
let res = Some(Self::Item {
129129
dtb,
130130
reg: self.node.reg,
131-
node: node_cursor,
131+
node: node_cursor.skip_cursor,
132132
name,
133133
});
134-
*cursor = next;
134+
*cursor = node_cursor.next_cursor;
135135
res
136136
} else {
137137
None
@@ -201,7 +201,7 @@ impl<'de> Deserialize<'de> for Node<'_> {
201201
if key == "/" {
202202
self_cursor = match value.cursor {
203203
ValueCursor::Body(cursor) => Some(cursor),
204-
ValueCursor::Prop(_, _) => {
204+
_ => {
205205
unreachable!("root of NodeSeq shouble be body cursor")
206206
}
207207
};
@@ -213,11 +213,12 @@ impl<'de> Deserialize<'de> for Node<'_> {
213213
props_start = Some(cursor);
214214
}
215215
}
216-
ValueCursor::Body(cursor) => {
216+
ValueCursor::Node(cursor) => {
217217
if nodes_start.is_none() {
218-
nodes_start = Some(cursor);
218+
nodes_start = Some(cursor.start_cursor);
219219
}
220220
}
221+
_ => unreachable!("unparsed(body) cursor"),
221222
}
222223
}
223224

src/de_mut/node_seq.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,19 +133,19 @@ impl<'de> Iterator for NodeSeqIter<'de, '_> {
133133
// 子节点名字
134134
Cursor::Title(c) => {
135135
let (full_name, _) = c.split_on(self.de.dtb);
136-
let (node, next) = c.take_node_on(self.de.dtb, full_name);
136+
let node_reuslt = c.take_node_on(self.de.dtb, full_name);
137137

138138
let (pre_name, suf_name) = full_name.split_once('@').unwrap_or((full_name, ""));
139139
if self.seq.name != pre_name {
140140
return None;
141141
}
142142

143-
self.de.cursor = ValueCursor::Body(next);
143+
self.de.cursor = ValueCursor::Body(node_reuslt.next_cursor);
144144

145145
Some(Self::Item {
146146
dtb: self.de.dtb,
147147
reg: self.de.reg,
148-
body: node,
148+
body: node_reuslt.start_cursor,
149149
at: suf_name,
150150
})
151151
}

src/de_mut/struct_access.rs

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use super::cursor::MultiNodeCursor;
12
use super::{BodyCursor, Cursor, PropCursor, ValueCursor, ValueDeserializer};
23
use crate::error::Error as DtError;
34
use serde::de;
@@ -21,8 +22,8 @@ pub struct StructAccess<'de, 'b> {
2122
/// 解析键(名字)时将确定值类型,保存 `Temp` 类型的状态。
2223
/// 根据状态分发值解析器。
2324
pub enum Temp {
24-
Node(BodyCursor, BodyCursor),
25-
Group(BodyCursor),
25+
Uninit,
26+
Nodes(MultiNodeCursor),
2627
Prop(BodyCursor, PropCursor),
2728
}
2829

@@ -46,6 +47,12 @@ impl<'de> de::MapAccess<'de> for StructAccess<'de, '_> {
4647
_ => true,
4748
}
4849
};
50+
let origin_cursor = match self.de.cursor {
51+
ValueCursor::Body(cursor) => cursor,
52+
ValueCursor::Node(result) => result.skip_cursor,
53+
_ => unreachable!("map access's cursor should always be body cursor"),
54+
};
55+
self.de.cursor = ValueCursor::Body(origin_cursor);
4956
let name = loop {
5057
let origin_cursor = match self.de.cursor {
5158
ValueCursor::Body(cursor) => cursor,
@@ -59,19 +66,19 @@ impl<'de> de::MapAccess<'de> for StructAccess<'de, '_> {
5966
let (pre_name, _) = name.split_once('@').unwrap_or((name, ""));
6067
// 子节点名字不带 @ 或正在解析 Node 类型
6168
if pre_name == name || check_contains(name) {
62-
let (node, next) = c.take_node_on(self.de.dtb, name);
63-
self.de.cursor = ValueCursor::Body(next);
69+
let take_result = c.take_node_on(self.de.dtb, name);
70+
self.de.cursor = ValueCursor::Body(take_result.next_cursor);
6471
if check_contains(name) {
65-
self.temp = Temp::Node(origin_cursor, node);
72+
self.temp = Temp::Nodes(take_result);
6673
break name;
6774
}
6875
}
6976
// @ 之前的部分是真正的名字,用这个名字搜索连续的一组
7077
else {
71-
let (group, _, next) = c.take_group_on(self.de.dtb, pre_name);
72-
self.de.cursor = ValueCursor::Body(next);
78+
let take_result = c.take_group_on(self.de.dtb, pre_name);
79+
self.de.cursor = ValueCursor::Body(take_result.next_cursor);
7380
if check_contains(pre_name) {
74-
self.temp = Temp::Group(group);
81+
self.temp = Temp::Nodes(take_result);
7582
break pre_name;
7683
}
7784
}
@@ -120,30 +127,22 @@ impl<'de> de::MapAccess<'de> for StructAccess<'de, '_> {
120127
}
121128
}
122129
match self.temp {
123-
Temp::Node(cursor, node_cursor) => {
130+
Temp::Nodes(ref result) => {
124131
// 键是独立节点名字,递归
125132
match self.access_type {
126133
StructAccessType::Map(_) => seed.deserialize(&mut ValueDeserializer {
127134
dtb: self.de.dtb,
128135
reg: self.de.reg,
129-
cursor: ValueCursor::Body(cursor),
136+
cursor: ValueCursor::Node(*result),
130137
}),
131138
StructAccessType::Struct(_) => seed.deserialize(&mut ValueDeserializer {
132139
dtb: self.de.dtb,
133140
reg: self.de.reg,
134-
cursor: ValueCursor::Body(node_cursor),
141+
cursor: ValueCursor::Node(*result),
135142
}),
136143
_ => unreachable!(),
137144
}
138145
}
139-
Temp::Group(cursor) => {
140-
// 键是组名字,构造组反序列化器
141-
seed.deserialize(&mut ValueDeserializer {
142-
dtb: self.de.dtb,
143-
reg: self.de.reg,
144-
cursor: ValueCursor::Body(cursor),
145-
})
146-
}
147146
Temp::Prop(origin_cursor, cursor) => {
148147
// 键是属性名字,构造属性反序列化器
149148
seed.deserialize(&mut ValueDeserializer {
@@ -152,6 +151,9 @@ impl<'de> de::MapAccess<'de> for StructAccess<'de, '_> {
152151
cursor: ValueCursor::Prop(origin_cursor, cursor),
153152
})
154153
}
154+
Temp::Uninit => {
155+
unreachable!("find uninited result")
156+
}
155157
}
156158
}
157159
}
@@ -168,7 +170,7 @@ impl<'de> de::SeqAccess<'de> for StructAccess<'de, '_> {
168170
// 子节点名字
169171
Cursor::Title(c) => {
170172
let (name, _) = c.split_on(self.de.dtb);
171-
let (_, next) = c.take_node_on(self.de.dtb, name);
173+
let next = c.take_node_on(self.de.dtb, name).next_cursor;
172174
let prev_cursor = match self.de.cursor {
173175
ValueCursor::Body(cursor) => cursor,
174176
_ => unreachable!(),

src/utils/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ impl<'de> Node<'de> {
5151
}
5252
return None;
5353
}
54-
return self.raw_find(path);
54+
self.raw_find(path)
5555
}
5656

5757
/// use depth-first search to traversal the tree, and exec func for each node

0 commit comments

Comments
 (0)