Skip to main content

decimal_scaled/types/traits/
decimal.rs

1//! The [`Decimal`] trait — width-generic marker that requires the
2//! full surface (arithmetic + conversion + transcendentals + constants).
3//!
4//! `Decimal` itself has no methods; the surface lives on four
5//! narrower traits and `Decimal` is a supertrait union:
6//!
7//! - [`DecimalArithmetic`] — operators, sign, integer-style division,
8//!   pow / checked / wrapping / saturating / overflowing, plus the
9//!   foundational type info (`Storage`, `SCALE`, `MAX_SCALE`, `ZERO`,
10//!   `ONE`, `MAX`, `MIN`, `multiplier()`) and reductions (`sum`,
11//!   `product`).
12//! - [`DecimalConvert`] — `from_bits` / `to_bits` / `scale`, the
13//!   integer bridges (`from_i32`, `to_int`, `to_int_with`), and the
14//!   `std`-gated f64 / f32 bridge (`from_f64`, `from_f64_with`,
15//!   `to_f64`, `to_f32`).
16//! - [`DecimalTranscendental`] — the four-variant matrix on every
17//!   transcendental + roots (`_strict` / `_strict_with(mode)` /
18//!   `_approx(g)` / `_approx_with(g, mode)`).
19//! - [`DecimalConstants`] — `pi` / `tau` / `half_pi` / `quarter_pi` /
20//!   `golden` / `e` plus their `_with(mode)` siblings.
21//!
22//! Implemented automatically by a blanket impl, so any type that
23//! impls all four halves is `Decimal` for free. Every shipped width
24//! (`D9`, `D18`, `D38`, `D57`, `D76`, `D115`, `D153`, `D230`, `D307`,
25//! `D462`, `D616`, `D924`, `D1232`) already satisfies the bound via
26//! the per-tier macros (`decl_decimal_basics!` for arithmetic +
27//! convert, `decl_decimal_consts!` for constants,
28//! `decl_decimal_transcendental_impl!` for the transcendental
29//! surface).
30//!
31//! # Usage
32//!
33//! ```ignore
34//! use decimal_scaled::Decimal;
35//!
36//! // Pulls in the full surface — arithmetic, conversion,
37//! // transcendentals, and constants.
38//! fn radius_to_area<T: Decimal>(r: T) -> T {
39//!     T::pi() * r * r
40//! }
41//! ```
42//!
43//! When you only need a slice of the surface, target the narrower
44//! trait directly to keep bounds tight:
45//!
46//! ```ignore
47//! use decimal_scaled::DecimalArithmetic;
48//!
49//! fn dot<T: DecimalArithmetic + Copy>(a: &[T], b: &[T]) -> T {
50//!     a.iter().zip(b).map(|(x, y)| (*x) * (*y))
51//!         .fold(T::ZERO, |acc, p| acc + p)
52//! }
53//! ```
54//!
55//! # Out of scope on `Decimal` (and all four sub-traits)
56//!
57//! - **Rescale** (`rescale<TARGET>` / `rescale_with`) takes a
58//!   `const`-generic target `SCALE` parameter; const-generic trait
59//!   methods aren't stable. Use the inherent method on the concrete
60//!   type.
61//! - **`from_int`** takes a different source integer per width;
62//!   [`DecimalConvert::from_i32`] is the width-generic constructor.
63//! - **Joint kernels** (`sin_cos`, `sinh_cosh`) exist only on the
64//!   wide tiers; reach for them on the concrete type.
65
66pub use crate::types::traits::arithmetic::DecimalArithmetic;
67pub use crate::types::traits::convert::DecimalConvert;
68
69/// Marker supertrait combining the four halves of the decimal API
70/// surface ([`DecimalArithmetic`], [`DecimalConvert`],
71/// [`crate::DecimalTranscendental`], [`crate::DecimalConstants`]).
72///
73/// Implemented automatically for any type that implements all four;
74/// see the module-level documentation for usage.
75pub trait Decimal:
76    DecimalArithmetic
77    + DecimalConvert
78    + crate::types::traits::transcendental::DecimalTranscendental
79    + crate::types::consts::DecimalConstants
80{
81}
82
83impl<T> Decimal for T where
84    T: DecimalArithmetic
85        + DecimalConvert
86        + crate::types::traits::transcendental::DecimalTranscendental
87        + crate::types::consts::DecimalConstants
88{
89}