@@ -14,6 +14,7 @@ use crate::parser::functions::Function;
14
14
pub enum Accessor {
15
15
Member ( String ) ,
16
16
Index ( Value ) ,
17
+ IndexExpression ( Expression ) ,
17
18
}
18
19
19
20
#[ derive( Clone ) ]
@@ -73,7 +74,8 @@ impl Expression {
73
74
Accessor :: Index ( value)
74
75
} ,
75
76
"expression" => {
76
- return Err ( DscError :: Parser ( "Expression index not supported" . to_string ( ) ) ) ;
77
+ let expression = Expression :: new ( statement_bytes, & index_value) ?;
78
+ Accessor :: IndexExpression ( expression)
77
79
} ,
78
80
_ => {
79
81
return Err ( DscError :: Parser ( format ! ( "Invalid accessor kind: '{accessor_kind}'" ) ) ) ;
@@ -118,6 +120,7 @@ impl Expression {
118
120
debug ! ( "Evaluating accessors" ) ;
119
121
let mut value = result;
120
122
for accessor in & self . accessors {
123
+ let mut index = Value :: Null ;
121
124
match accessor {
122
125
Accessor :: Member ( member) => {
123
126
if let Some ( object) = value. as_object ( ) {
@@ -129,20 +132,31 @@ impl Expression {
129
132
return Err ( DscError :: Parser ( "Member access on non-object value" . to_string ( ) ) ) ;
130
133
}
131
134
} ,
132
- Accessor :: Index ( index) => {
133
- if let Some ( array) = value. as_array ( ) {
134
- let Some ( index) = index. as_u64 ( ) else {
135
- return Err ( DscError :: Parser ( "Index is not a valid number" . to_string ( ) ) ) ;
136
- } ;
137
- let index = usize:: try_from ( index) ?;
138
- if index >= array. len ( ) {
139
- return Err ( DscError :: Parser ( "Index out of bounds" . to_string ( ) ) ) ;
140
- }
141
- value = array[ index] . clone ( ) ;
142
- } else {
143
- return Err ( DscError :: Parser ( "Index access on non-array value" . to_string ( ) ) ) ;
144
- }
135
+ Accessor :: Index ( index_value) => {
136
+ index = index_value. clone ( ) ;
145
137
} ,
138
+ Accessor :: IndexExpression ( expression) => {
139
+ index = expression. invoke ( function_dispatcher, context) ?;
140
+ trace ! ( "Expression result: '{:?}'" , index) ;
141
+ } ,
142
+ }
143
+
144
+ if index. is_number ( ) {
145
+ if let Some ( array) = value. as_array ( ) {
146
+ let Some ( index) = index. as_u64 ( ) else {
147
+ return Err ( DscError :: Parser ( "Index is not a valid number" . to_string ( ) ) ) ;
148
+ } ;
149
+ let index = usize:: try_from ( index) ?;
150
+ if index >= array. len ( ) {
151
+ return Err ( DscError :: Parser ( "Index out of bounds" . to_string ( ) ) ) ;
152
+ }
153
+ value = array[ index] . clone ( ) ;
154
+ } else {
155
+ return Err ( DscError :: Parser ( "Index access on non-array value" . to_string ( ) ) ) ;
156
+ }
157
+ }
158
+ else if !index. is_null ( ) {
159
+ return Err ( DscError :: Parser ( "Invalid index type" . to_string ( ) ) ) ;
146
160
}
147
161
}
148
162
0 commit comments