Skip to content

Commit d2eb042

Browse files
committed
feat: add Node NodeIter PropIter
Signed-off-by: Woshiluo Luo <woshiluo.luo@outlook.com>
1 parent b06b580 commit d2eb042

File tree

5 files changed

+320
-45
lines changed

5 files changed

+320
-45
lines changed

src/de_mut/cursor.rs

Lines changed: 57 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ impl Type for Title {}
2626
impl Type for Group {}
2727
impl Type for Prop {}
2828

29+
pub enum MoveResult {
30+
In,
31+
Out,
32+
Others,
33+
}
34+
2935
impl<T: Type> AnyCursor<T> {
3036
/// 移动 `n` 格。
3137
pub fn step_n(&mut self, len: usize) {
@@ -71,39 +77,53 @@ impl BodyCursor {
7177
}
7278
todo!()
7379
}
80+
/// 移动指针至下一块
81+
pub fn move_next(&mut self, dtb: RefDtb) -> MoveResult {
82+
use StructureBlock as B;
83+
let structure = &dtb.borrow().structure;
84+
match structure[self.0] {
85+
// 下陷一级
86+
B::NODE_BEGIN => {
87+
self.0 += 1;
88+
self.skip_str_on(dtb);
89+
MoveResult::In
90+
}
91+
// 上浮一级
92+
B::NODE_END => {
93+
self.0 += 1;
94+
MoveResult::Out
95+
}
96+
// 属性项
97+
B::PROP => {
98+
if let [_, len_data, _, ..] = &structure[self.0..] {
99+
self.0 += 3 + align(len_data.as_usize(), BLOCK_LEN);
100+
} else {
101+
todo!()
102+
}
103+
MoveResult::Others
104+
}
105+
// 空白项
106+
B::NOP => {
107+
self.0 += 1;
108+
MoveResult::Others
109+
}
110+
_ => todo!(),
111+
}
112+
}
74113

75114
/// 离开当前子树。
76115
pub fn escape_from(&mut self, dtb: RefDtb) {
77-
use StructureBlock as B;
78-
let structure = &dtb.borrow().structure;
79116
let mut level = 1;
80117
loop {
81-
match structure[self.0] {
82-
// 下陷一级
83-
B::NODE_BEGIN => {
84-
self.0 += 1;
85-
self.skip_str_on(dtb);
86-
level += 1;
87-
}
88-
// 上浮一级
89-
B::NODE_END => {
90-
self.0 += 1;
118+
match self.move_next(dtb) {
119+
MoveResult::In => level += 1,
120+
MoveResult::Out => {
91121
if level == 1 {
92122
break;
93123
}
94124
level -= 1;
95125
}
96-
// 属性项
97-
B::PROP => {
98-
if let [_, len_data, _, ..] = &structure[self.0..] {
99-
self.0 += 3 + align(len_data.as_usize(), BLOCK_LEN);
100-
} else {
101-
todo!()
102-
}
103-
}
104-
// 空白项
105-
B::NOP => self.0 += 1,
106-
_ => todo!(),
126+
_ => {}
107127
}
108128
}
109129
}
@@ -131,7 +151,7 @@ impl TitleCursor {
131151
/// 生成组光标。
132152
pub fn take_group_on(&self, dtb: RefDtb, name: &str) -> (GroupCursor, usize, BodyCursor) {
133153
let name_bytes = name.as_bytes();
134-
let name_skip = align(name_bytes.len(), BLOCK_LEN);
154+
let name_skip = align(name_bytes.len() + 1, BLOCK_LEN);
135155
let group = AnyCursor::<Group>(self.0, PhantomData);
136156

137157
let mut body = AnyCursor::<Body>(self.0 + 1 + name_skip, PhantomData);
@@ -160,6 +180,18 @@ impl TitleCursor {
160180
}
161181
(group, len, body)
162182
}
183+
184+
/// 生成节点光标。
185+
pub fn take_node_on(&self, dtb: RefDtb, name: &str) -> (BodyCursor, BodyCursor) {
186+
let name_bytes = name.as_bytes();
187+
let name_skip = align(name_bytes.len() + 1, BLOCK_LEN);
188+
let node = AnyCursor::<Body>(self.0 + 1 + name_skip, PhantomData);
189+
190+
let mut body = AnyCursor::<Body>(self.0 + 1 + name_skip, PhantomData);
191+
192+
body.escape_from(dtb);
193+
(node, body)
194+
}
163195
}
164196

165197
impl GroupCursor {
@@ -281,6 +313,7 @@ impl PropCursor {
281313
}
282314
}
283315

316+
#[derive(Debug)]
284317
pub(super) enum Cursor {
285318
Title(TitleCursor),
286319
Prop(PropCursor),

src/de_mut/mod.rs

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use serde::de;
77
mod cursor;
88
mod data;
99
mod group;
10+
mod node;
1011
mod node_seq;
1112
mod reg;
1213
mod str_seq;
@@ -15,12 +16,13 @@ mod structs;
1516

1617
pub use structs::{Dtb, DtbPtr};
1718
pub mod buildin {
18-
pub use super::{node_seq::NodeSeq, reg::Reg, str_seq::StrSeq};
19+
pub use super::{node::Node, node_seq::NodeSeq, reg::Reg, str_seq::StrSeq};
1920
}
2021

2122
use cursor::{BodyCursor, Cursor, GroupCursor, PropCursor};
2223
use data::BorrowedValueDeserializer;
2324
use group::GroupDeserializer;
25+
// use node::NodeDeserializer;
2426
use r#struct::StructDeserializer;
2527
use reg::RegConfig;
2628
use structs::{RefDtb, StructureBlock, BLOCK_LEN};
@@ -64,7 +66,7 @@ struct StructAccess<'de, 'b> {
6466
/// 解析键(名字)时将确定值类型,保存 `Temp` 类型的状态。
6567
/// 根据状态分发值解析器。
6668
enum Temp {
67-
Node,
69+
Node(BodyCursor),
6870
Group(GroupCursor, usize, usize),
6971
Prop(PropCursor),
7072
}
@@ -80,17 +82,17 @@ impl<'de, 'b> de::MapAccess<'de> for StructAccess<'de, 'b> {
8082
match self.de.move_next() {
8183
// 子节点名字
8284
Cursor::Title(c) => {
83-
let (name, sub) = c.split_on(self.de.dtb);
85+
let (name, _) = c.split_on(self.de.dtb);
8486

8587
let pre_len = name.as_bytes().iter().take_while(|b| **b != b'@').count();
8688
// 子节点名字不带 @
8789
if pre_len == name.as_bytes().len() {
88-
self.de.cursor = sub;
90+
let (node, next) = c.take_node_on(self.de.dtb, name);
91+
self.de.cursor = next;
8992
if self.fields.contains(&name) {
90-
self.temp = Temp::Node;
93+
self.temp = Temp::Node(node);
9194
break name;
9295
}
93-
self.de.escape();
9496
}
9597
// @ 之前的部分是真正的名字,用这个名字搜索连续的一组
9698
else {
@@ -138,12 +140,13 @@ impl<'de, 'b> de::MapAccess<'de> for StructAccess<'de, 'b> {
138140
V: de::DeserializeSeed<'de>,
139141
{
140142
match self.temp {
141-
Temp::Node => {
143+
Temp::Node(cursor) => {
142144
// 键是独立节点名字,递归
143-
let mut child = self.de.clone();
144-
let res = seed.deserialize(&mut child)?;
145-
self.de.cursor = child.cursor;
146-
Ok(res)
145+
seed.deserialize(&mut StructDeserializer {
146+
dtb: self.de.dtb,
147+
cursor,
148+
reg: self.de.reg,
149+
})
147150
}
148151
Temp::Group(cursor, len_item, len_name) => {
149152
// 键是组名字,构造组反序列化器

0 commit comments

Comments
 (0)