* feat: add Azure Policy alias normalization/denormalization
Add normalizer and denormalizer for ARM JSON resources, enabling Azure
Policy alias short names to become direct paths into a flat structure.
- Normalizer: flattens properties wrappers, lowercases keys, resolves
per-alias versioned ARM paths, handles sub-resource array flattening,
element-level field remaps, and array base renames
- Denormalizer: reverses all transformations with casing restoration
- AliasRegistry: loads production alias catalogs and data policy manifests
- Types: serde deserialization for ARM provider alias formats
- YAML test suite: 13 test files covering normalize, denormalize, round-trip,
data-plane, edge cases, malformed input, sub-resources, and registry API
- Benchmark suite for normalization performance
* feat: add FFI and C# bindings for alias normalization
- FFI: alias_registry.rs with C-compatible API for loading catalogs,
normalizing resources, and denormalizing back to ARM JSON
- C#: AliasRegistry wrapper class with NativeMethods P/Invoke bindings
and integration tests
- Updated Cargo.lock files for new serde_json dependency
* feat: add Azure Policy builtins with YAML test suite
Implement ARM template functions for Azure Policy evaluation:
Builtins:
- String: indexOf, lastIndexOf, trim, format, split, startsWith, endsWith,
padLeft, concat, replace, toLower, toUpper, substring, guid, uniqueString
- DateTime: dateTimeAdd, dateTimeFromEpoch, dateTimeToEpoch, addDays
- Collection: intersection, union, take, skip, first, last, min, max,
range, items, tryGet, tryIndexFromEnd, empty, array, createObject
- Encoding: base64, base64ToString, base64ToJson, uri, uriComponent,
uriComponentToString, dataUri, dataUriToString
- Numeric: int, float, intDiv, intMod
- Misc: json, join, bool, string, coalesce, if, getParameter, resolveField
- Logic: logicAll, logicAny
Key implementation details:
- Unicode case-insensitive search via ICU4X case folding with single-pass
fold_with_char_map() for indexOf/lastIndexOf
- .NET composite formatting (System.String.Format) with alignment, standard
and custom datetime format specifiers, numeric format specifiers
- DateTime round-trip preserves input shape (Z vs +00:00, T vs space,
fractional seconds) when no explicit output format is supplied
- Zero-cost as_str() helper borrows directly from Value::String(Rc<str>)
- BTreeSet<&Value> in array union avoids redundant cloning
Test suite:
- 53 YAML test files exercising all builtins via direct BUILTINS registry
- Coverage for edge cases: empty inputs, Unicode, fractional seconds,
invalid alignment, unknown format specifiers, RFC3339 offset shapes
Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
* fix: address PR review comments
- Fix percent_encode to only uppercase hex digits, not entire string
- Remove guid/uniqueString (unsupported); delete custom SHA-1 impl
- Replace unwrap_or(0) with proper error in format placeholder parsing
- Hoist CaseMapper into static CaseMapperBorrowed for zero per-call overhead
- Pre-allocate Vec in range() with_capacity
- Update bindings/ffi and bindings/ruby Cargo.lock
- Fix uri_component test expectations for correct case preservation
Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
* fix: address second round of PR review comments
- float(): return Undefined when as_f64() fails instead of leaking
the original non-f64 representation
- createObject(): reject odd number of arguments with an error
(ARM-template parity)
- format(): error on unknown numeric format specifiers instead of
silently passing through (matches .NET FormatException behavior)
- format(): cap alignment width at 10,000 to prevent DoS from
user-controlled format strings like {0,1000000000}
- Add YAML test cases for all new error behaviors
Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
* fix: address third round of PR review comments
- percent_decode: reject incomplete % escapes (e.g. "%", "%2") instead
of treating them as literal characters
- parse_iso8601_duration: reject leftover digits without a unit designator
at T boundary and end-of-input (e.g. "P1", "P1T2H")
- yaml_to_value: panic on unsupported YAML numeric representations instead
of silently mapping to Null
- Revert unused src/languages/mod.rs changes (module is defined inline in
lib.rs)
Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
* fix: add missing edge-case tests and fix empty-delimiter panic
- fn_split: return input as single-element array for empty string
delimiter instead of panicking (Rust's str::split("") panics)
- format: add test for F3 higher precision ({0:F3} + 1.23456 → 1.235)
- format: add test for N2 float with thousands separator
- format: add test for negative index error ({-1})
- split: add test for empty-string delimiter
- uri: add tests for query string and fragment in relative URI
- createObject: add test for non-string (numeric) keys
Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
* fix: address fourth round of PR review comments
- Add MAX_VARIADIC_ARGS (64) constant for variadic builtin arity
instead of registering with 0 (logic_all, logic_any, min, max,
format, intersection, union, coalesce, createObject); set
dateTimeAdd to exact arity 3
- Switch indexOf/lastIndexOf to UTF-16 code-unit indices to match
.NET String.IndexOf semantics (track ch.len_utf16() in
fold_with_char_map, use encode_utf16().count() for empty-needle
lastIndexOf)
- Use DateTime::<Utc>::from_timestamp for explicit timezone type
- Remove stale docs/azure-policy/casing.md link from module doc
- Fix misleading comment in want_error test branch (code bails on
Undefined, not accepts it)
Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
---------
Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
- Disable default features in dependencies
- Use anyhow::Error::msg to map errors. Note: anyhow will itself be removed later.
- lazy_static/spin_no_std used in no_std environments
- ensure_no_std binary is built to target thumbv7m-none-eabi to ensure that
there are no std dependencies. thumbv7m-none-eabi target has no std support.
- The opa-no-std feature enables only those Regorus features that work with no_std.
- Enable tests with no_std
- Update sizes of regorus binary in README.md
- Ensure that regorus example can be built with only std
- Ensure that regorus example can be built with no_std
Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
* `arc` feature to make engine usable from multiple threads.
`arc` is turned on by default. When enabled, std::sync::Arc
will be used instead of std::rc::Rc. The former makes regorus
types like Engine, Value, ast nodes etc Send, allowing for
usability from multiple threads.
Arc would add a performance overhead though since the reference
counting will now become atomic.
Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
* Make engine and related types Debug
Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
* Input, Data as json. Evaluate bool queries.
Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
---------
Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
- Separate out public, unstable and internal APIs.
- Cleanup README.md and include it as the crate documentation.
Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>