README.md (5044B)
1 # radroots_core 2 3 `radroots_core` provides the portable, deterministic value model shared by 4 Radroots domain packages: decimals, currencies, money, percentages, 5 quantities, units, and pricing. 6 7 The crate supports `no_std` environments with `alloc`. It performs no I/O, 8 starts no tasks or threads, reads no clocks or process state, and owns no 9 networking or persistence behavior. 10 11 ## Example 12 13 Checked constructors and checked pricing operations are the supported trust 14 boundary for data received from users, files, databases, or networks: 15 16 ```rust 17 use radroots_core::pricing::QuantityPriceOps; 18 use radroots_core::{Currency, Decimal, Money, Quantity, QuantityPrice, Unit}; 19 20 let price = QuantityPrice::try_new( 21 Money::try_new("6.00".parse::<Decimal>()?, Currency::USD)?, 22 Quantity::try_new(Decimal::from(2_u32), Unit::MassKg)?, 23 )?; 24 let requested = Quantity::try_new(Decimal::from(3_u32), Unit::MassKg)?; 25 let total = price.try_cost_for_rounded(&requested)?; 26 27 assert_eq!(total.amount().to_string(), "9"); 28 # Ok::<(), radroots_core::Error>(()) 29 ``` 30 31 The same program is available as the checked 32 [`pricing`](examples/checked_pricing.rs) example. 33 34 ## Public API 35 36 The crate root intentionally exports the common value types and aggregate 37 [`Error`](https://docs.rs/radroots_core/latest/radroots_core/enum.Error.html). 38 Focused errors and operations remain in these modules: 39 40 - `currency` — canonical three-letter ASCII currency codes; 41 - `decimal` — fixed-precision decimal parsing, conversion, and checked math; 42 - `money` — non-negative monetary values and currency-aware quantization; 43 - `percent` — signed percentage values and percentage calculations; 44 - `pricing` — quantity prices, discounts, and checked pricing operations; 45 - `quantity` — non-negative amounts associated with units; 46 - `unit` — unit parsing, dimensions, and deterministic conversions. 47 48 The normative responsibility and dependency boundary are defined by the 49 [`radroots_core` package charter](../../contracts/crates/release_v1/radroots_crates_release_v1.toml). 50 The reviewed pre-release surface is recorded in the 51 [`radroots_core` API baseline](../../contracts/api_baselines/radroots_core.txt). 52 53 ## Features 54 55 | Feature | Default | Effect | 56 | --- | --- | --- | 57 | `std` | yes | Implements `std::error::Error`; value behavior remains portable. | 58 | `serde` | yes | Implements canonical serialization and deserialization for public values. | 59 60 Disabling default features leaves the `no_std` + `alloc` value model. Features 61 are additive; enabling one does not select a runtime, backend, global state, or 62 side effect. 63 64 ## Invariants and untrusted input 65 66 Use `try_*`, `checked_*`, parsing, and exact-conversion APIs at trust 67 boundaries. They reject negative money or quantities, mismatched currencies or 68 units, division by zero, overflow, and lossy exact conversions as applicable. 69 Public composite values keep invariant-bearing fields private and expose only 70 checked construction and arithmetic, so invalid native state cannot be created 71 through the supported public API. 72 73 Currency and unit parsers normalize their documented textual spellings. 74 Decimal display and serialization normalize insignificant trailing zeroes. 75 Pricing quantization uses deterministic currency exponents and documents its 76 rounding strategy on the operation that performs the rounding. 77 78 The crate forbids unsafe Rust. It does not process credentials, authorize 79 actors, or provide confidentiality or authenticity. Callers must impose 80 application-specific limits before accepting unbounded collections or text; 81 this crate validates value semantics only. 82 83 ## Serialization 84 85 With `serde`, decimal numeric components are encoded as strings so JSON and 86 other number-limited formats do not introduce floating-point loss. Currencies 87 and units use their canonical string codes; aggregate values use named fields. 88 Wire compatibility is governed by the repository conformance vectors. 89 90 Deserializing a composite value re-applies the same invariants as its checked 91 constructor. Callers remain responsible for application-specific policy and 92 resource limits before committing untrusted decoded data. 93 94 ## Execution and commit semantics 95 96 Operations are synchronous and deterministic. There are no asynchronous 97 cancellation points, deadlines, retries, callbacks, or partial external side 98 effects. A successful call returns its complete value; an error returns before 99 any durable commit because the crate owns no durable state. Methods taking 100 `&mut self` document whether an error leaves the receiver unchanged. 101 102 ## Intended consumers 103 104 `radroots_core` is intended for lower-level Radroots domain crates and for 105 integrators that need the portable value model directly. Applications should 106 normally begin with the curated `radroots` crate or the advanced 107 `radroots_sdk` composition surface. 108 109 The package is pre-1.0. Its durable responsibility and package identity are 110 fixed, while API-breaking changes follow the workspace's pre-1.0 versioning 111 policy. 112 113 ## License 114 115 Licensed under either Apache-2.0 or MIT, at your option.