datalogic-rs 4.0.21

A fast, type-safe Rust implementation of JSONLogic for evaluating logical rules as JSON. Perfect for business rules engines and dynamic filtering in Rust applications.
Documentation
[
  "# Sort operator tests",
  {
    "description": "Sort array in ascending order (default)",
    "rule": { "sort": [{"val": "array"}] },
    "data": { "array": [3, 1, 4, 2, 5] },
    "result": [1, 2, 3, 4, 5]
  },
  {
    "description": "Sort array in descending order",
    "rule": { "sort": [{"val": "array"}, false] },
    "data": { "array": [3, 1, 4, 2, 5] },
    "result": [5, 4, 3, 2, 1]
  },
  {
    "description": "Sort array with asc parameter",
    "rule": { "sort": [{"val": "array"}, true] },
    "data": { "array": [3, 1, 4, 2, 5] },
    "result": [1, 2, 3, 4, 5]
  },
  {
    "description": "Sort array with explicit ascending parameter",
    "rule": { "sort": [{"val": "array"}, true] },
    "data": { "array": [3, 1, 4, 2, 5] },
    "result": [1, 2, 3, 4, 5]
  },
  {
    "description": "Sort array with explicit descending parameter",
    "rule": { "sort": [{"val": "array"}, false] },
    "data": { "array": [3, 1, 4, 2, 5] },
    "result": [5, 4, 3, 2, 1]
  },
  "# Already sorted arrays",
  {
    "description": "Sort already ascending sorted array",
    "rule": { "sort": [{"val": "array"}] },
    "data": { "array": [1, 2, 3, 4, 5] },
    "result": [1, 2, 3, 4, 5]
  },
  {
    "description": "Sort already descending sorted array to ascending",
    "rule": { "sort": [{"val": "array"}] },
    "data": { "array": [5, 4, 3, 2, 1] },
    "result": [1, 2, 3, 4, 5]
  },
  "# Edge cases",
  {
    "description": "Sort empty array returns empty array",
    "rule": { "sort": [{"val": "emptyArray"}] },
    "data": { "emptyArray": [] },
    "result": []
  },
  {
    "description": "Sort single item array returns same array",
    "rule": { "sort": [{"val": "singleItem"}] },
    "data": { "singleItem": [42] },
    "result": [42]
  },
  {
    "description": "Sort array with repeated items maintains duplicates",
    "rule": { "sort": [{"val": "repeatedItems"}] },
    "data": { "repeatedItems": [3, 1, 3, 2, 1] },
    "result": [1, 1, 2, 3, 3]
  },
  "# String sorting",
  {
    "description": "Sort string array alphabetically",
    "rule": { "sort": [{"val": "strings"}] },
    "data": { "strings": ["banana", "apple", "cherry", "date"] },
    "result": ["apple", "banana", "cherry", "date"]
  },
  {
    "description": "Sort mixed case strings (case-sensitive by default)",
    "rule": { "sort": [{"val": "mixedCase"}] },
    "data": { "mixedCase": ["banana", "Apple", "cherry", "Date"] },
    "result": ["Apple", "Date", "banana", "cherry"]
  },
  "# Mixed types and special cases",
  {
    "description": "Sort array with mixed number types",
    "rule": { "sort": [{"val": "mixedNumbers"}] },
    "data": { "mixedNumbers": [3.14, 1, 2.5, 2, 5] },
    "result": [1, 2, 2.5, 3.14, 5]
  },
  {
    "description": "Sort with numbers as strings",
    "rule": { "sort": [{"val": "numbersAsStrings"}] },
    "data": { "numbersAsStrings": ["10", "2", "1", "20"] },
    "result": ["1", "10", "2", "20"]
  },
  {
    "description": "Sort with mixed types follows type order",
    "rule": { "sort": [{"val": "mixedTypes"}] },
    "data": { "mixedTypes": [true, "banana", 42, null, false, "apple"] },
    "result": [null, false, true, 42, "apple", "banana"]
  },
  "# Field extraction - Simple field",
  {
    "description": "Sort objects by a simple field (ascending)",
    "rule": { "sort": [{"val": "people"}, true, {"val": "age"}] },
    "data": { 
      "people": [
        {"name": "Alice", "age": 30},
        {"name": "Bob", "age": 25},
        {"name": "Charlie", "age": 35}
      ]
    },
    "result": [
      {"name": "Bob", "age": 25},
      {"name": "Alice", "age": 30},
      {"name": "Charlie", "age": 35}
    ]
  },
  {
    "description": "Sort objects by a simple field (descending)",
    "rule": { "sort": [{"val": "people"}, false, {"val": "age"}] },
    "data": { 
      "people": [
        {"name": "Alice", "age": 30},
        {"name": "Bob", "age": 25},
        {"name": "Charlie", "age": 35}
      ]
    },
    "result": [
      {"name": "Charlie", "age": 35},
      {"name": "Alice", "age": 30},
      {"name": "Bob", "age": 25}
    ]
  },
  {
    "description": "Sort objects by a string field",
    "rule": { "sort": [{"val": "people"}, true, {"val": "name"}] },
    "data": { 
      "people": [
        {"name": "Charlie", "age": 35},
        {"name": "Alice", "age": 30},
        {"name": "Bob", "age": 25}
      ]
    },
    "result": [
      {"name": "Alice", "age": 30},
      {"name": "Bob", "age": 25},
      {"name": "Charlie", "age": 35}
    ]
  },
  "# Field extraction - Nested fields",
  {
    "description": "Sort objects by a nested field",
    "rule": { "sort": [{"val": "companies"}, true, {"val": ["address", "city"]}] },
    "data": { 
      "companies": [
        {"name": "Acme Corp", "address": {"city": "New York", "zip": "10001"}},
        {"name": "Globex", "address": {"city": "Boston", "zip": "02108"}},
        {"name": "Initech", "address": {"city": "Austin", "zip": "73301"}}
      ]
    },
    "result": [
      {"name": "Initech", "address": {"city": "Austin", "zip": "73301"}},
      {"name": "Globex", "address": {"city": "Boston", "zip": "02108"}},
      {"name": "Acme Corp", "address": {"city": "New York", "zip": "10001"}}
    ]
  },
  {
    "description": "Sort objects by a deeply nested field",
    "rule": { "sort": [{"val": "companies"}, true, {"val": ["metrics", "finance", "revenue"]}] },
    "data": { 
      "companies": [
        {"name": "Acme Corp", "metrics": {"finance": {"revenue": 1000000, "profit": 250000}}},
        {"name": "Globex", "metrics": {"finance": {"revenue": 2500000, "profit": 1000000}}},
        {"name": "Initech", "metrics": {"finance": {"revenue": 500000, "profit": 100000}}}
      ]
    },
    "result": [
      {"name": "Initech", "metrics": {"finance": {"revenue": 500000, "profit": 100000}}},
      {"name": "Acme Corp", "metrics": {"finance": {"revenue": 1000000, "profit": 250000}}},
      {"name": "Globex", "metrics": {"finance": {"revenue": 2500000, "profit": 1000000}}}
    ]
  },
  "# Field extraction - Complex expressions",
  {
    "description": "Sort objects by a calculated field (total price)",
    "rule": { "sort": [{"val": "products"}, true, {"+": [{"val": "price"}, {"val": "tax"}]}] },
    "data": { 
      "products": [
        {"name": "Laptop", "price": 1000, "tax": 100},
        {"name": "Phone", "price": 500, "tax": 50},
        {"name": "Tablet", "price": 300, "tax": 30}
      ]
    },
    "result": [
      {"name": "Tablet", "price": 300, "tax": 30},
      {"name": "Phone", "price": 500, "tax": 50},
      {"name": "Laptop", "price": 1000, "tax": 100}
    ]
  },
  {
    "description": "Sort by the length of a field",
    "rule": { "sort": [{"val": "strings"}, true, {"length": {"val": []}}] },
    "data": { 
      "strings": ["elephant", "cat", "hippopotamus", "dog"]
    },
    "result": ["cat", "dog", "elephant", "hippopotamus"]
  },
  {
    "description": "Sort array of objects by field with missing values",
    "rule": { "sort": [{"val": "data"}, true, {"val": "value"}] },
    "data": { 
      "data": [
        {"id": 1, "value": 10},
        {"id": 2},
        {"id": 3, "value": 5},
        {"id": 4, "value": null}
      ]
    },
    "result": [
      {"id": 2},
      {"id": 4, "value": null},
      {"id": 3, "value": 5},
      {"id": 1, "value": 10}
    ]
  },
  "# Error handling",
  {
    "description": "Sort missing variable returns null",
    "rule": { "sort": [{"val": "missing"}] },
    "data": {},
    "result": null
  },
  {
    "description": "Sort operator with null argument throws error",
    "rule": { "sort": null },
    "data": {},
    "error": { "type": "Invalid Arguments" }
  },
  {
    "description": "Sort operator with numeric argument throws error",
    "rule": { "sort": 123 },
    "data": {},
    "error": { "type": "Invalid Arguments" }
  },
  {
    "description": "Sort operator with boolean argument throws error",
    "rule": { "sort": true },
    "data": {},
    "error": { "type": "Invalid Arguments" }
  },
  {
    "description": "Sort with invalid direction parameter defaults to ascending",
    "rule": { "sort": [{"val": "array"}, "invalid"] },
    "data": { "array": [3, 1, 4, 2, 5] },
    "result": [1, 2, 3, 4, 5]
  },
  "# Complex usage",
  {
    "description": "Sort result of filtered array",
    "rule": { "sort": [{ "filter": [{"val": "array"}, {">=": [{"val": []}, 3]}] }] },
    "data": { "array": [3, 1, 4, 2, 5] },
    "result": [3, 4, 5]
  },
  {
    "description": "Map operation on sorted array",
    "rule": { "map": [{ "sort": [{"val": "array"}] }, { "*": [{"val": []}, 2] }] },
    "data": { "array": [3, 1, 4, 2, 5] },
    "result": [2, 4, 6, 8, 10]
  }
]