@@ -7,15 +7,17 @@ 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 > ,
14
13
}
15
14
16
15
impl Expression {
17
16
pub ( crate ) fn root ( root : String ) -> Self {
18
- Expression :: Identifier ( root)
17
+ Self {
18
+ root,
19
+ postfix : Vec :: new ( ) ,
20
+ }
19
21
}
20
22
}
21
23
@@ -29,6 +31,12 @@ impl FromStr for Expression {
29
31
}
30
32
}
31
33
34
+ #[ derive( Debug , Eq , PartialEq , Clone , Hash ) ]
35
+ enum Postfix {
36
+ Key ( String ) ,
37
+ Index ( isize ) ,
38
+ }
39
+
32
40
#[ derive( Debug ) ]
33
41
struct ParseError ( String ) ;
34
42
@@ -59,105 +67,83 @@ fn abs_index(index: isize, len: usize) -> Result<usize, usize> {
59
67
60
68
impl Expression {
61
69
pub ( crate ) fn get ( self , root : & Value ) -> Option < & Value > {
62
- match self {
63
- Self :: Identifier ( key) => {
64
- match root. kind {
65
- // `x` access on a table is equivalent to: map[x]
66
- ValueKind :: Table ( ref map) => map. get ( & key) ,
67
-
68
- // all other variants return None
69
- _ => 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) ?;
70
81
}
71
- }
72
-
73
- Self :: Child ( expr, key) => {
74
- match expr. get ( root) {
75
- Some ( child) => {
76
- match child. kind {
77
- // Access on a table is identical to Identifier, it just forwards
78
- ValueKind :: Table ( ref map) => map. get ( & key) ,
79
-
80
- // all other variants return None
81
- _ => None ,
82
- }
83
- }
84
-
85
- _ => 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) ?;
86
88
}
87
89
}
88
-
89
- Self :: Subscript ( expr, index) => match expr. get ( root) {
90
- Some ( child) => match child. kind {
91
- ValueKind :: Array ( ref array) => {
92
- let index = abs_index ( index, array. len ( ) ) . ok ( ) ?;
93
- array. get ( index)
94
- }
95
-
96
- _ => None ,
97
- } ,
98
-
99
- _ => None ,
100
- } ,
101
90
}
91
+ Some ( child)
102
92
}
103
93
104
94
pub ( crate ) fn get_mut_forcibly < ' a > ( & self , root : & ' a mut Value ) -> & ' a mut Value {
105
- match * self {
106
- Self :: Identifier ( ref key) => {
107
- if !matches ! ( root. kind, ValueKind :: Table ( _) ) {
108
- * root = Map :: < String , Value > :: new ( ) . into ( ) ;
109
- }
110
- let ValueKind :: Table ( ref mut map) = root. kind else {
111
- unreachable ! ( )
112
- } ;
113
-
114
- map. entry ( key. clone ( ) )
115
- . or_insert_with ( || Value :: new ( None , ValueKind :: Nil ) )
116
- }
117
-
118
- Self :: Child ( ref expr, ref key) => {
119
- let child = expr. get_mut_forcibly ( root) ;
120
-
121
- if !matches ! ( child. kind, ValueKind :: Table ( _) ) {
122
- * child = Map :: < String , Value > :: new ( ) . into ( ) ;
123
- }
124
- let ValueKind :: Table ( ref mut map) = child. kind else {
125
- unreachable ! ( )
126
- } ;
127
-
128
- map. entry ( key. clone ( ) )
129
- . or_insert_with ( || Value :: new ( None , ValueKind :: Nil ) )
130
- }
131
-
132
- Self :: Subscript ( ref expr, index) => {
133
- let child = expr. get_mut_forcibly ( root) ;
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 ( ) ;
109
+ }
110
+ let ValueKind :: Table ( ref mut map) = child. kind else {
111
+ unreachable ! ( )
112
+ } ;
134
113
135
- if !matches ! ( child. kind, ValueKind :: Array ( _) ) {
136
- * child = Vec :: < Value > :: new ( ) . into ( ) ;
114
+ child = map
115
+ . entry ( key. clone ( ) )
116
+ . or_insert_with ( || Value :: new ( None , ValueKind :: Nil ) ) ;
137
117
}
138
- let ValueKind :: Array ( ref mut array) = child. kind else {
139
- unreachable ! ( )
140
- } ;
141
-
142
- let uindex = match abs_index ( index, array. len ( ) ) {
143
- Ok ( uindex) => {
144
- if uindex >= array. len ( ) {
145
- array. resize ( uindex + 1 , Value :: new ( None , ValueKind :: Nil ) ) ;
146
- }
147
- uindex
148
- }
149
- Err ( insertion) => {
150
- array. splice (
151
- 0 ..0 ,
152
- ( 0 ..insertion) . map ( |_| Value :: new ( None , ValueKind :: Nil ) ) ,
153
- ) ;
154
- 0
118
+ Postfix :: Index ( rel_index) => {
119
+ if !matches ! ( child. kind, ValueKind :: Array ( _) ) {
120
+ * child = Vec :: < Value > :: new ( ) . into ( ) ;
155
121
}
156
- } ;
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 ) ) ;
130
+ }
131
+ uindex
132
+ }
133
+ Err ( insertion) => {
134
+ array. splice (
135
+ 0 ..0 ,
136
+ ( 0 ..insertion) . map ( |_| Value :: new ( None , ValueKind :: Nil ) ) ,
137
+ ) ;
138
+ 0
139
+ }
140
+ } ;
157
141
158
- & mut array[ uindex]
142
+ child = & mut array[ uindex] ;
143
+ }
159
144
}
160
145
}
146
+ child
161
147
}
162
148
163
149
pub ( crate ) fn set ( & self , root : & mut Value , value : Value ) {
0 commit comments