@@ -7,10 +7,18 @@ use crate::value::{Value, ValueKind};
7
7
mod parser;
8
8
9
9
#[ derive( Debug , Eq , PartialEq , Clone , Hash ) ]
10
- pub ( crate ) enum Expression {
11
- Identifier ( String ) ,
12
- Child ( Box < Self > , String ) ,
13
- Subscript ( Box < Self > , isize ) ,
10
+ pub ( crate ) struct Expression {
11
+ root : String ,
12
+ postfix : Vec < Postfix > ,
13
+ }
14
+
15
+ impl Expression {
16
+ pub ( crate ) fn root ( root : String ) -> Self {
17
+ Self {
18
+ root,
19
+ postfix : Vec :: new ( ) ,
20
+ }
21
+ }
14
22
}
15
23
16
24
impl FromStr for Expression {
@@ -23,6 +31,12 @@ impl FromStr for Expression {
23
31
}
24
32
}
25
33
34
+ #[ derive( Debug , Eq , PartialEq , Clone , Hash ) ]
35
+ enum Postfix {
36
+ Key ( String ) ,
37
+ Index ( isize ) ,
38
+ }
39
+
26
40
#[ derive( Debug ) ]
27
41
struct ParseError ( String ) ;
28
42
@@ -53,186 +67,97 @@ fn abs_index(index: isize, len: usize) -> Result<usize, usize> {
53
67
54
68
impl Expression {
55
69
pub ( crate ) fn get ( self , root : & Value ) -> Option < & Value > {
56
- match self {
57
- Self :: Identifier ( id) => {
58
- match root. kind {
59
- // `x` access on a table is equivalent to: map[x]
60
- ValueKind :: Table ( ref map) => map. get ( & id) ,
61
-
62
- // all other variants return None
63
- _ => None ,
70
+ let ValueKind :: Table ( map) = & root. kind else {
71
+ return None ;
72
+ } ;
73
+ let mut child = map. get ( & self . root ) ?;
74
+ for postfix in & self . postfix {
75
+ match postfix {
76
+ Postfix :: Key ( key) => {
77
+ let ValueKind :: Table ( map) = & child. kind else {
78
+ return None ;
79
+ } ;
80
+ child = map. get ( key) ?;
64
81
}
65
- }
66
-
67
- Self :: Child ( expr, key) => {
68
- match expr. get ( root) {
69
- Some ( value) => {
70
- match value. kind {
71
- // Access on a table is identical to Identifier, it just forwards
72
- ValueKind :: Table ( ref map) => map. get ( & key) ,
73
-
74
- // all other variants return None
75
- _ => None ,
76
- }
77
- }
78
-
79
- _ => None ,
82
+ Postfix :: Index ( rel_index) => {
83
+ let ValueKind :: Array ( array) = & child. kind else {
84
+ return None ;
85
+ } ;
86
+ let index = abs_index ( * rel_index, array. len ( ) ) . ok ( ) ?;
87
+ child = array. get ( index) ?;
80
88
}
81
89
}
82
-
83
- Self :: Subscript ( expr, index) => match expr. get ( root) {
84
- Some ( value) => match value. kind {
85
- ValueKind :: Array ( ref array) => {
86
- let index = abs_index ( index, array. len ( ) ) . ok ( ) ?;
87
- array. get ( index)
88
- }
89
-
90
- _ => None ,
91
- } ,
92
-
93
- _ => None ,
94
- } ,
95
90
}
91
+ Some ( child)
96
92
}
97
93
98
- pub ( crate ) fn get_mut_forcibly < ' a > ( & self , root : & ' a mut Value ) -> Option < & ' a mut Value > {
99
- match * self {
100
- Self :: Identifier ( ref id) => match root. kind {
101
- ValueKind :: Table ( ref mut map) => Some (
102
- map. entry ( id. clone ( ) )
103
- . or_insert_with ( || Value :: new ( None , ValueKind :: Nil ) ) ,
104
- ) ,
105
-
106
- _ => None ,
107
- } ,
108
-
109
- Self :: Child ( ref expr, ref key) => match expr. get_mut_forcibly ( root) {
110
- Some ( value) => {
111
- if let ValueKind :: Table ( ref mut map) = value. kind {
112
- Some (
113
- map. entry ( key. clone ( ) )
114
- . or_insert_with ( || Value :: new ( None , ValueKind :: Nil ) ) ,
115
- )
116
- } else {
117
- * value = Map :: < String , Value > :: new ( ) . into ( ) ;
118
-
119
- if let ValueKind :: Table ( ref mut map) = value. kind {
120
- Some (
121
- map. entry ( key. clone ( ) )
122
- . or_insert_with ( || Value :: new ( None , ValueKind :: Nil ) ) ,
123
- )
124
- } else {
125
- unreachable ! ( ) ;
126
- }
94
+ pub ( crate ) fn get_mut_forcibly < ' a > ( & self , root : & ' a mut Value ) -> & ' a mut Value {
95
+ if !matches ! ( root. kind, ValueKind :: Table ( _) ) {
96
+ * root = Map :: < String , Value > :: new ( ) . into ( ) ;
97
+ }
98
+ let ValueKind :: Table ( map) = & mut root. kind else {
99
+ unreachable ! ( )
100
+ } ;
101
+ let mut child = map
102
+ . entry ( self . root . clone ( ) )
103
+ . or_insert_with ( || Value :: new ( None , ValueKind :: Nil ) ) ;
104
+ for postfix in & self . postfix {
105
+ match postfix {
106
+ Postfix :: Key ( key) => {
107
+ if !matches ! ( child. kind, ValueKind :: Table ( _) ) {
108
+ * child = Map :: < String , Value > :: new ( ) . into ( ) ;
127
109
}
128
- }
129
-
130
- _ => None ,
131
- } ,
110
+ let ValueKind :: Table ( ref mut map) = child. kind else {
111
+ unreachable ! ( )
112
+ } ;
132
113
133
- Self :: Subscript ( ref expr, index) => match expr. get_mut_forcibly ( root) {
134
- Some ( value) => {
135
- match value. kind {
136
- ValueKind :: Array ( _) => ( ) ,
137
- _ => * value = Vec :: < Value > :: new ( ) . into ( ) ,
114
+ child = map
115
+ . entry ( key. clone ( ) )
116
+ . or_insert_with ( || Value :: new ( None , ValueKind :: Nil ) ) ;
117
+ }
118
+ Postfix :: Index ( rel_index) => {
119
+ if !matches ! ( child. kind, ValueKind :: Array ( _) ) {
120
+ * child = Vec :: < Value > :: new ( ) . into ( ) ;
138
121
}
139
-
140
- match value. kind {
141
- ValueKind :: Array ( ref mut array) => {
142
- let index = abs_index ( index, array. len ( ) ) . ok ( ) ?;
143
-
144
- if index >= array. len ( ) {
145
- array. resize ( index + 1 , Value :: new ( None , ValueKind :: Nil ) ) ;
122
+ let ValueKind :: Array ( ref mut array) = child. kind else {
123
+ unreachable ! ( )
124
+ } ;
125
+
126
+ let uindex = match abs_index ( * rel_index, array. len ( ) ) {
127
+ Ok ( uindex) => {
128
+ if uindex >= array. len ( ) {
129
+ array. resize ( uindex + 1 , Value :: new ( None , ValueKind :: Nil ) ) ;
146
130
}
147
-
148
- Some ( & mut array[ index] )
131
+ uindex
132
+ }
133
+ Err ( insertion) => {
134
+ array. splice (
135
+ 0 ..0 ,
136
+ ( 0 ..insertion) . map ( |_| Value :: new ( None , ValueKind :: Nil ) ) ,
137
+ ) ;
138
+ 0
149
139
}
140
+ } ;
150
141
151
- _ => None ,
152
- }
142
+ child = & mut array[ uindex] ;
153
143
}
154
- _ => None ,
155
- } ,
144
+ }
156
145
}
146
+ child
157
147
}
158
148
159
149
pub ( crate ) fn set ( & self , root : & mut Value , value : Value ) {
160
- match * self {
161
- Self :: Identifier ( ref id) => {
162
- // Ensure that root is a table
163
- match root. kind {
164
- ValueKind :: Table ( _) => { }
165
-
166
- _ => {
167
- * root = Map :: < String , Value > :: new ( ) . into ( ) ;
168
- }
169
- }
170
-
171
- match value. kind {
172
- ValueKind :: Table ( ref incoming_map) => {
173
- // Pull out another table
174
- let target = if let ValueKind :: Table ( ref mut map) = root. kind {
175
- map. entry ( id. clone ( ) )
176
- . or_insert_with ( || Map :: < String , Value > :: new ( ) . into ( ) )
177
- } else {
178
- unreachable ! ( ) ;
179
- } ;
180
-
181
- // Continue the deep merge
182
- for ( key, val) in incoming_map {
183
- Self :: Identifier ( key. clone ( ) ) . set ( target, val. clone ( ) ) ;
184
- }
185
- }
186
-
187
- _ => {
188
- if let ValueKind :: Table ( ref mut map) = root. kind {
189
- // Just do a simple set
190
- if let Some ( existing) = map. get_mut ( id) {
191
- * existing = value;
192
- } else {
193
- map. insert ( id. clone ( ) , value) ;
194
- }
195
- }
196
- }
197
- }
198
- }
199
-
200
- Self :: Child ( ref expr, ref key) => {
201
- if let Some ( parent) = expr. get_mut_forcibly ( root) {
202
- if !matches ! ( parent. kind, ValueKind :: Table ( _) ) {
203
- // Didn't find a table. Oh well. Make a table and do this anyway
204
- * parent = Map :: < String , Value > :: new ( ) . into ( ) ;
205
- }
206
- Self :: Identifier ( key. clone ( ) ) . set ( parent, value) ;
150
+ let parent = self . get_mut_forcibly ( root) ;
151
+ match value. kind {
152
+ ValueKind :: Table ( ref incoming_map) => {
153
+ // Continue the deep merge
154
+ for ( key, val) in incoming_map {
155
+ Self :: root ( key. clone ( ) ) . set ( parent, val. clone ( ) ) ;
207
156
}
208
157
}
209
158
210
- Self :: Subscript ( ref expr, index) => {
211
- if let Some ( parent) = expr. get_mut_forcibly ( root) {
212
- if !matches ! ( parent. kind, ValueKind :: Array ( _) ) {
213
- * parent = Vec :: < Value > :: new ( ) . into ( ) ;
214
- }
215
-
216
- if let ValueKind :: Array ( ref mut array) = parent. kind {
217
- let uindex = match abs_index ( index, array. len ( ) ) {
218
- Ok ( uindex) => {
219
- if uindex >= array. len ( ) {
220
- array. resize ( uindex + 1 , Value :: new ( None , ValueKind :: Nil ) ) ;
221
- }
222
- uindex
223
- }
224
- Err ( insertion) => {
225
- array. splice (
226
- 0 ..0 ,
227
- ( 0 ..insertion) . map ( |_| Value :: new ( None , ValueKind :: Nil ) ) ,
228
- ) ;
229
- 0
230
- }
231
- } ;
232
-
233
- array[ uindex] = value;
234
- }
235
- }
159
+ _ => {
160
+ * parent = value;
236
161
}
237
162
}
238
163
}
0 commit comments