@@ -46,9 +46,9 @@ module Output = struct
46
46
47
47
let lift2 (f : 'a -> 'b -> 'c ) (mx : ('a, string) result )
48
48
(my : ('b, string) result ) : ('c, string) result =
49
- match mx with
50
- | Ok x -> ( match my with Ok y -> Ok (f x y) | Error err -> Error err )
51
- | Error err -> Error err
49
+ match (mx, my) with
50
+ | Ok x , Ok y -> Ok (f x y)
51
+ | Error err , _ | _ , Error err -> Error err
52
52
53
53
let collect (xs : ('a list, string) result list ) : ('a list, string) result =
54
54
List. fold_right (lift2 ( @ )) xs empty
@@ -173,16 +173,58 @@ let index (value : int) (json : Json.t) =
173
173
match json with
174
174
| `List list when List. length list > value ->
175
175
Output. return (Json. index value json)
176
- | `List list -> Error (make_acessing_to_missing_item value ( List. length list ))
176
+ | `List _ -> Output. return `Null
177
177
| _ -> Error (make_error (" [" ^ string_of_int value ^ " ]" ) json)
178
178
179
+ let slice (start : int option ) (end_ : int option ) (json : Json.t ) =
180
+ let start =
181
+ match (json, start) with
182
+ | `String s , Some start when start > String. length s -> String. length s
183
+ | `String s , Some start when start < 0 -> start + String. length s
184
+ | `List l , Some start when start > List. length l -> List. length l
185
+ | `List l , Some start when start < 0 -> start + List. length l
186
+ | (`String _ | `List _ ), Some start -> start
187
+ | (`String _ | `List _ ), None -> 0
188
+ | _ -> assert false
189
+ in
190
+ let end_ =
191
+ match (json, end_) with
192
+ | `String s , None -> String. length s
193
+ | `String s , Some end_ when end_ > String. length s -> String. length s
194
+ | `String s , Some end_ when end_ < 0 -> end_ + String. length s
195
+ | `List l , None -> List. length l
196
+ | `List l , Some end_ when end_ > List. length l -> List. length l
197
+ | `List l , Some end_ when end_ < 0 -> end_ + List. length l
198
+ | (`String _ | `List _ ), Some end_ -> end_
199
+ | _ -> assert false
200
+ in
201
+ match json with
202
+ | `String _s when end_ < start -> Output. return (`String " " )
203
+ | `String s -> Output. return (`String (String. sub s start (end_ - start)))
204
+ | `List _l when end_ < start -> Output. return (`List [] )
205
+ | `List l ->
206
+ let sliced =
207
+ List. fold_left
208
+ (fun (acc , i ) x ->
209
+ if i > = start && i < end_ then (x :: acc, i + 1 ) else (acc, i + 1 ))
210
+ ([] , 0 ) l
211
+ |> fst |> List. rev
212
+ in
213
+ Output. return (`List sliced)
214
+ | _ ->
215
+ Error
216
+ (make_error
217
+ (" [" ^ string_of_int start ^ " :" ^ string_of_int end_ ^ " ]" )
218
+ json)
219
+
179
220
let rec compile expression json : (Json.t list, string) result =
180
221
match expression with
181
222
| Identity -> Output. return json
182
223
| Empty -> empty
183
224
| Keys -> keys json
184
225
| Key (key , opt ) -> member key opt json
185
226
| Index idx -> index idx json
227
+ | Slice (start , end_ ) -> slice start end_ json
186
228
| Head -> head json
187
229
| Tail -> tail json
188
230
| Length -> length json
0 commit comments