This macro transforms an expression like: mylistExpr.sortBy(e, -math.abs(e)) into something equivalent to: cel.bind( @__sortBy_input__, myListExpr, @__sortBy_input__.@sortByAssociatedKeys( @__sortBy_input__.map(e, -math.abs(e) ) )
| 430 | // ) |
| 431 | // ) |
| 432 | Macro ListSortByMacro() { |
| 433 | absl::StatusOr<Macro> sortby_macro = Macro::Receiver( |
| 434 | "sortBy", 2, |
| 435 | [](MacroExprFactory& factory, Expr& target, |
| 436 | absl::Span<Expr> args) -> absl::optional<Expr> { |
| 437 | if (!target.has_ident_expr() && !target.has_select_expr() && |
| 438 | !target.has_list_expr() && !target.has_comprehension_expr() && |
| 439 | !target.has_call_expr()) { |
| 440 | return factory.ReportErrorAt( |
| 441 | target, |
| 442 | "sortBy can only be applied to a list, identifier, " |
| 443 | "comprehension, call or select expression"); |
| 444 | } |
| 445 | |
| 446 | auto sortby_input_ident = factory.NewIdent("@__sortBy_input__"); |
| 447 | auto sortby_input_expr = std::move(target); |
| 448 | auto key_ident = std::move(args[0]); |
| 449 | auto key_expr = std::move(args[1]); |
| 450 | |
| 451 | // Build the map expression: |
| 452 | // map_compr := @__sortBy_input__.map(key_ident, key_expr) |
| 453 | auto map_compr = |
| 454 | MakeMapComprehension(factory, factory.Copy(sortby_input_ident), |
| 455 | std::move(key_ident), std::move(key_expr)); |
| 456 | if (!map_compr.has_value()) { |
| 457 | return absl::nullopt; |
| 458 | } |
| 459 | |
| 460 | // Build the call expression: |
| 461 | // call_expr := @__sortBy_input__.@sortByAssociatedKeys(map_compr) |
| 462 | std::vector<Expr> call_args; |
| 463 | call_args.push_back(std::move(*map_compr)); |
| 464 | auto call_expr = factory.NewMemberCall("@sortByAssociatedKeys", |
| 465 | std::move(sortby_input_ident), |
| 466 | absl::MakeSpan(call_args)); |
| 467 | |
| 468 | // Build the returned bind expression: |
| 469 | // cel.bind(@__sortBy_input__, target, call_expr) |
| 470 | auto var_ident = factory.NewIdent("@__sortBy_input__"); |
| 471 | auto var_expr = std::move(sortby_input_expr); |
| 472 | auto bind_compr = |
| 473 | MakeBindComprehension(factory, std::move(var_ident), |
| 474 | std::move(var_expr), std::move(call_expr)); |
| 475 | return bind_compr; |
| 476 | }); |
| 477 | return *sortby_macro; |
| 478 | } |
| 479 | |
| 480 | absl::StatusOr<Value> ListSort( |
| 481 | const ListValue& list, |
no test coverage detected