Skip to main content

decimal_scaled/types/traits/
decimal.rs

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