Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 96a9b46

Browse files
authored
fix: rewrite of compile module
1 parent c189f18 commit 96a9b46

20 files changed

Lines changed: 1795 additions & 1904 deletions

File tree

core/src/compile/address.rs

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
use std::collections::VecDeque;
2+
3+
use crate::schema::FieldRef;
4+
5+
/// A struct to hold the parsed components of the location of a node in a compiled tree.
6+
///
7+
/// An address of a node in the `Content` tree is an array of string names of child nodes, as
8+
/// declared by the node's [`Compile`](super::Compile) implementation.
9+
#[derive(Debug, Default, Clone, Eq, PartialEq, Hash, Ord, PartialOrd)]
10+
pub struct Address(VecDeque<String>);
11+
12+
impl std::fmt::Display for Address {
13+
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
14+
let mut chunks = self.iter();
15+
write!(f, "{}", chunks.next().unwrap_or("{top-level}"))?;
16+
for chunk in chunks {
17+
write!(f, ".{}", chunk)?;
18+
}
19+
Ok(())
20+
}
21+
}
22+
23+
impl Address {
24+
#[inline]
25+
pub fn new_root() -> Self {
26+
Self(VecDeque::new())
27+
}
28+
29+
#[inline]
30+
pub fn is_root(&self) -> bool {
31+
self.0.is_empty()
32+
}
33+
34+
pub fn root(&self) -> Self {
35+
self.iter().map(|node| node.to_string()).take(1).collect()
36+
}
37+
38+
#[inline]
39+
pub fn iter(&self) -> impl DoubleEndedIterator<Item = &str> {
40+
self.0.iter().map(|value| value.as_str())
41+
}
42+
43+
#[inline]
44+
pub fn deeper(&mut self) -> Option<String> {
45+
self.0.pop_front()
46+
}
47+
48+
#[inline]
49+
pub fn shallower(&mut self) -> Option<String> {
50+
self.0.pop_back()
51+
}
52+
53+
#[inline]
54+
pub fn into_shallower(mut self) -> Self {
55+
self.shallower().unwrap();
56+
self
57+
}
58+
59+
#[inline]
60+
pub fn within(&mut self, scope: &str) -> &mut Self {
61+
self.0.push_front(scope.to_string());
62+
self
63+
}
64+
65+
#[inline]
66+
pub fn len(&self) -> usize {
67+
self.0.len()
68+
}
69+
70+
#[inline]
71+
pub fn is_empty(&self) -> bool {
72+
self.0.is_empty()
73+
}
74+
75+
#[inline]
76+
pub fn into_within(mut self, scope: &str) -> Self {
77+
self.within(scope);
78+
self
79+
}
80+
81+
#[inline]
82+
pub fn at(&mut self, attribute: &str) -> &mut Self {
83+
self.0.push_back(attribute.to_string());
84+
self
85+
}
86+
87+
#[inline]
88+
pub fn into_at(mut self, attribute: &str) -> Self {
89+
self.at(attribute);
90+
self
91+
}
92+
93+
pub fn as_local_to(&self, root: &Self) -> Option<Self> {
94+
if root.0.len() > self.0.len() {
95+
None
96+
} else {
97+
Some(
98+
self.iter()
99+
.zip(root.iter())
100+
.skip_while(|(left, right)| left == right)
101+
.map(|(left, _)| left.to_string())
102+
.collect(),
103+
)
104+
}
105+
}
106+
107+
pub fn as_in(&self, other: &Self) -> Option<Self> {
108+
let mut out = self.clone();
109+
for level in other.iter() {
110+
if *level != out.deeper()? {
111+
return None;
112+
}
113+
}
114+
Some(out)
115+
}
116+
117+
pub fn concat(&self, other: &Self) -> Self {
118+
let mut out = self.clone();
119+
out.extend(other.clone().into_iter());
120+
out
121+
}
122+
123+
pub fn relativize(&self, with: &Self) -> (Self, Self) {
124+
let root = self.common_root(with);
125+
let relative = self.as_in(&root).unwrap();
126+
(root, relative)
127+
}
128+
129+
pub fn common_root(&self, other: &Self) -> Self {
130+
self.iter()
131+
.zip(other.iter())
132+
.take_while(|(left, right)| left == right)
133+
.map(|(left, _)| left.to_string())
134+
.collect()
135+
}
136+
}
137+
138+
impl std::iter::FromIterator<String> for Address {
139+
#[inline]
140+
fn from_iter<I: IntoIterator<Item = String>>(iter: I) -> Self {
141+
Self(iter.into_iter().collect())
142+
}
143+
}
144+
145+
impl std::iter::Extend<String> for Address {
146+
#[inline]
147+
fn extend<T: IntoIterator<Item = String>>(&mut self, iter: T) {
148+
self.0.extend(iter)
149+
}
150+
}
151+
152+
impl std::iter::IntoIterator for Address {
153+
type Item = String;
154+
155+
type IntoIter = std::collections::vec_deque::IntoIter<String>;
156+
157+
#[inline]
158+
fn into_iter(self) -> Self::IntoIter {
159+
self.0.into_iter()
160+
}
161+
}
162+
163+
impl From<FieldRef> for Address {
164+
#[inline]
165+
fn from(field: FieldRef) -> Self {
166+
field.into_iter().collect()
167+
}
168+
}

0 commit comments

Comments
 (0)