@@ -10,10 +10,16 @@ use crate::dscerror::DscError;
10
10
use crate :: functions:: FunctionDispatcher ;
11
11
use crate :: parser:: functions:: Function ;
12
12
13
+ #[ derive( Clone ) ]
14
+ pub enum Accessor {
15
+ Member ( String ) ,
16
+ Index ( Value ) ,
17
+ }
18
+
13
19
#[ derive( Clone ) ]
14
20
pub struct Expression {
15
21
function : Function ,
16
- member_access : Option < Vec < String > > ,
22
+ accessors : Vec < Accessor > ,
17
23
}
18
24
19
25
impl Expression {
@@ -32,57 +38,110 @@ impl Expression {
32
38
let Some ( function) = expression. child_by_field_name ( "function" ) else {
33
39
return Err ( DscError :: Parser ( "Function node not found" . to_string ( ) ) ) ;
34
40
} ;
41
+ debug ! ( "Parsing function '{:?}'" , function) ;
35
42
let function = Function :: new ( statement_bytes, & function) ?;
36
- let member_access = if let Some ( members) = expression. child_by_field_name ( "members" ) {
37
- if members. is_error ( ) {
38
- return Err ( DscError :: Parser ( "Error parsing dot-notation" . to_string ( ) ) ) ;
43
+ let mut accessors = Vec :: < Accessor > :: new ( ) ;
44
+ if let Some ( accessor) = expression. child_by_field_name ( "accessor" ) {
45
+ debug ! ( "Parsing accessor '{:?}'" , accessor) ;
46
+ if accessor. is_error ( ) {
47
+ return Err ( DscError :: Parser ( "Error parsing accessor" . to_string ( ) ) ) ;
39
48
}
40
- let mut result = vec ! [ ] ;
41
- let mut cursor = members. walk ( ) ;
42
- for member in members. named_children ( & mut cursor) {
43
- if member. is_error ( ) {
44
- return Err ( DscError :: Parser ( "Error parsing dot-notation member" . to_string ( ) ) ) ;
49
+ let mut cursor = accessor. walk ( ) ;
50
+ for accessor in accessor. named_children ( & mut cursor) {
51
+ if accessor. is_error ( ) {
52
+ return Err ( DscError :: Parser ( "Error parsing accessor" . to_string ( ) ) ) ;
45
53
}
46
- let value = member. utf8_text ( statement_bytes) ?;
47
- result. push ( value. to_string ( ) ) ;
54
+ let accessor_kind = accessor. kind ( ) ;
55
+ let value = match accessor_kind {
56
+ "memberAccess" => {
57
+ debug ! ( "Parsing member accessor '{:?}'" , accessor) ;
58
+ let Some ( member_name) = accessor. child_by_field_name ( "name" ) else {
59
+ return Err ( DscError :: Parser ( "Member name not found" . to_string ( ) ) ) ;
60
+ } ;
61
+ let member = member_name. utf8_text ( statement_bytes) ?;
62
+ Accessor :: Member ( member. to_string ( ) )
63
+ } ,
64
+ "index" => {
65
+ debug ! ( "Parsing index accessor '{:?}'" , accessor) ;
66
+ let Some ( index_value) = accessor. child_by_field_name ( "indexValue" ) else {
67
+ return Err ( DscError :: Parser ( "Index value not found" . to_string ( ) ) ) ;
68
+ } ;
69
+ match index_value. kind ( ) {
70
+ "number" => {
71
+ let value = index_value. utf8_text ( statement_bytes) ?;
72
+ let value = serde_json:: from_str ( value) ?;
73
+ Accessor :: Index ( value)
74
+ } ,
75
+ "expression" => {
76
+ return Err ( DscError :: Parser ( "Expression index not supported" . to_string ( ) ) ) ;
77
+ } ,
78
+ _ => {
79
+ return Err ( DscError :: Parser ( format ! ( "Invalid accessor kind: '{:?}'" , accessor_kind) ) ) ;
80
+ } ,
81
+ }
82
+ } ,
83
+ _ => {
84
+ return Err ( DscError :: Parser ( format ! ( "Invalid accessor kind: '{:?}'" , accessor_kind) ) ) ;
85
+ } ,
86
+ } ;
87
+ accessors. push ( value) ;
48
88
}
49
- Some ( result)
50
89
}
51
- else {
52
- None
53
- } ;
90
+
54
91
Ok ( Expression {
55
92
function,
56
- member_access ,
93
+ accessors ,
57
94
} )
58
95
}
59
96
60
97
/// Invoke the expression.
61
98
///
99
+ /// # Arguments
100
+ ///
101
+ /// * `function_dispatcher` - The function dispatcher to use.
102
+ /// * `context` - The context to use.
103
+ ///
104
+ /// # Returns
105
+ ///
106
+ /// The result of the expression.
107
+ ///
62
108
/// # Errors
63
109
///
64
110
/// This function will return an error if the expression fails to execute.
65
111
pub fn invoke ( & self , function_dispatcher : & FunctionDispatcher , context : & Context ) -> Result < Value , DscError > {
66
112
let result = self . function . invoke ( function_dispatcher, context) ?;
67
113
trace ! ( "Function result: '{:?}'" , result) ;
68
- if let Some ( member_access) = & self . member_access {
69
- debug ! ( "Evaluating member access '{:?}'" , member_access) ;
70
- if !result. is_object ( ) {
71
- return Err ( DscError :: Parser ( "Member access on non-object value" . to_string ( ) ) ) ;
72
- }
73
-
114
+ if self . accessors . len ( ) > 0 {
115
+ debug ! ( "Evaluating accessors" ) ;
74
116
let mut value = result;
75
- for member in member_access {
76
- if !value. is_object ( ) {
77
- return Err ( DscError :: Parser ( format ! ( "Member access '{member}' on non-object value" ) ) ) ;
78
- }
79
-
80
- if let Some ( object) = value. as_object ( ) {
81
- if !object. contains_key ( member) {
82
- return Err ( DscError :: Parser ( format ! ( "Member '{member}' not found" ) ) ) ;
83
- }
84
-
85
- value = object[ member] . clone ( ) ;
117
+ for accessor in & self . accessors {
118
+ match accessor {
119
+ Accessor :: Member ( member) => {
120
+ if !value. is_object ( ) {
121
+ return Err ( DscError :: Parser ( "Member access on non-object value" . to_string ( ) ) ) ;
122
+ }
123
+ if let Some ( object) = value. as_object ( ) {
124
+ if !object. contains_key ( member) {
125
+ return Err ( DscError :: Parser ( format ! ( "Member '{:?}' not found" , member) ) ) ;
126
+ }
127
+ value = object[ member] . clone ( ) ;
128
+ }
129
+ } ,
130
+ Accessor :: Index ( index) => {
131
+ if !value. is_array ( ) {
132
+ return Err ( DscError :: Parser ( "Index access on non-array value" . to_string ( ) ) ) ;
133
+ }
134
+ if let Some ( array) = value. as_array ( ) {
135
+ if !index. is_number ( ) {
136
+ return Err ( DscError :: Parser ( "Index is not a number" . to_string ( ) ) ) ;
137
+ }
138
+ let index = index. as_u64 ( ) . unwrap ( ) as usize ;
139
+ if index >= array. len ( ) {
140
+ return Err ( DscError :: Parser ( "Index out of bounds" . to_string ( ) ) ) ;
141
+ }
142
+ value = array[ index] . clone ( ) ;
143
+ }
144
+ } ,
86
145
}
87
146
}
88
147
0 commit comments