|
21 | 21 |
|
22 | 22 | get_field/2, |
23 | 23 | get_field/3, |
| 24 | + get_field_with_stack/3, |
| 25 | + get_field_from_stack/2, |
24 | 26 | rem_field/2, |
25 | 27 | set_field/3 |
26 | 28 | ]). |
@@ -377,43 +379,56 @@ do_update_to_insert([{_, _} | Rest], Doc) -> |
377 | 379 | get_field(Props, Field) -> |
378 | 380 | get_field(Props, Field, no_validation). |
379 | 381 |
|
380 | | -get_field(Props, Field, Validator) when is_binary(Field) -> |
381 | | - {ok, Path} = mango_util:parse_field(Field), |
382 | | - get_field(Props, Path, Validator); |
383 | | -get_field(Props, [], no_validation) -> |
384 | | - Props; |
385 | | -get_field(Props, [], Validator) -> |
386 | | - case (catch Validator(Props)) of |
| 382 | +get_field(Props, Field, no_validation) -> |
| 383 | + {Value, _} = get_field_with_stack(Props, Field, []), |
| 384 | + Value; |
| 385 | +get_field(Props, Field, Validator) -> |
| 386 | + {Value, _} = get_field_with_stack(Props, Field, []), |
| 387 | + case (catch Validator(Value)) of |
387 | 388 | true -> |
388 | | - Props; |
| 389 | + Value; |
389 | 390 | _ -> |
390 | 391 | invalid_value |
391 | | - end; |
392 | | -get_field({Props}, [Name | Rest], Validator) -> |
| 392 | + end. |
| 393 | + |
| 394 | +get_field_with_stack(Props, Field, Stack) when is_binary(Field) -> |
| 395 | + {ok, Path} = mango_util:parse_field(Field), |
| 396 | + get_field_with_stack(Props, Path, Stack); |
| 397 | +get_field_with_stack(Props, [], Stack) -> |
| 398 | + {Props, Stack}; |
| 399 | +get_field_with_stack({Props}, [Name | Rest], Stack) -> |
393 | 400 | case lists:keyfind(Name, 1, Props) of |
394 | 401 | {Name, Value} -> |
395 | | - get_field(Value, Rest, Validator); |
| 402 | + get_field_with_stack(Value, Rest, [{Props} | Stack]); |
396 | 403 | false -> |
397 | | - not_found |
| 404 | + {not_found, [{Props} | Stack]} |
398 | 405 | end; |
399 | | -get_field(Values, [Name | Rest], Validator) when is_list(Values) -> |
| 406 | +get_field_with_stack(Values, [Name | Rest], Stack) when is_list(Values) -> |
400 | 407 | % Name might be an integer index into an array |
401 | 408 | try |
402 | 409 | Pos = binary_to_integer(Name), |
403 | 410 | case Pos >= 0 andalso Pos < length(Values) of |
404 | 411 | true -> |
405 | 412 | % +1 because Erlang uses 1 based list indices |
406 | 413 | Value = lists:nth(Pos + 1, Values), |
407 | | - get_field(Value, Rest, Validator); |
| 414 | + get_field_with_stack(Value, Rest, Stack); |
408 | 415 | false -> |
409 | | - bad_path |
| 416 | + {bad_path, Stack} |
410 | 417 | end |
411 | 418 | catch |
412 | 419 | error:badarg -> |
413 | | - bad_path |
| 420 | + {bad_path, Stack} |
414 | 421 | end; |
415 | | -get_field(_, [_ | _], _) -> |
416 | | - bad_path. |
| 422 | +get_field_with_stack(_, [_ | _], Stack) -> |
| 423 | + {bad_path, Stack}. |
| 424 | + |
| 425 | +get_field_from_stack([{[{<<"parent">>, N}]} | Rest], Stack) -> |
| 426 | + case length(Stack) >= N of |
| 427 | + true -> get_field(lists:nth(N, Stack), Rest); |
| 428 | + false -> not_found |
| 429 | + end; |
| 430 | +get_field_from_stack(Path, Stack) -> |
| 431 | + get_field(lists:last(Stack), Path). |
417 | 432 |
|
418 | 433 | rem_field(Props, Field) when is_binary(Field) -> |
419 | 434 | {ok, Path} = mango_util:parse_field(Field), |
|
0 commit comments