strong_type/
lib.rs

1#![no_std]
2
3#[cfg(feature = "alloc")]
4extern crate alloc;
5
6// Re-export String for convenience in no_std + alloc environments
7#[cfg(feature = "alloc")]
8pub use alloc::string::String;
9
10use core::fmt::Debug;
11
12/// Derive macro to create strong types in Rust.
13pub use strong_type_derive::StrongType;
14
15/// Trait for strong types to obtain the associated underlying type and primitive type.
16pub trait StrongType: Debug + PartialEq + PartialOrd + Clone {
17    type UnderlyingType;
18    type PrimitiveType;
19}
20
21/// Internal module for operator delegation to reduce binary size.
22///
23/// This module provides generic helper functions that are shared across all strong types
24/// wrapping the same primitive type, reducing monomorphization cost.
25#[doc(hidden)]
26pub mod delegation {
27    use core::ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Neg, Not, Rem, Shl, Shr, Sub};
28
29    /// Trait for accessing the underlying primitive value of a strong type.
30    /// This trait is automatically implemented by the StrongType derive macro.
31    pub trait StrongTypeOps: Sized {
32        type Primitive: Copy;
33
34        /// Extract the primitive value from the strong type
35        fn to_primitive(self) -> Self::Primitive;
36
37        /// Create a strong type from a primitive value
38        fn from_primitive(val: Self::Primitive) -> Self;
39    }
40
41    // ============================================================================
42    // Binary Operators - Shared across all strong types per primitive
43    // ============================================================================
44
45    /// Shared add implementation - monomorphized once per primitive type
46    #[inline(never)]
47    pub fn delegate_add<T>(lhs: T, rhs: T) -> T
48    where
49        T: StrongTypeOps,
50        T::Primitive: Add<Output = T::Primitive>,
51    {
52        T::from_primitive(lhs.to_primitive() + rhs.to_primitive())
53    }
54
55    /// Shared sub implementation - monomorphized once per primitive type
56    #[inline(never)]
57    pub fn delegate_sub<T>(lhs: T, rhs: T) -> T
58    where
59        T: StrongTypeOps,
60        T::Primitive: Sub<Output = T::Primitive>,
61    {
62        T::from_primitive(lhs.to_primitive() - rhs.to_primitive())
63    }
64
65    /// Shared mul implementation - monomorphized once per primitive type
66    #[inline(never)]
67    pub fn delegate_mul<T>(lhs: T, rhs: T) -> T
68    where
69        T: StrongTypeOps,
70        T::Primitive: Mul<Output = T::Primitive>,
71    {
72        T::from_primitive(lhs.to_primitive() * rhs.to_primitive())
73    }
74
75    /// Shared div implementation - monomorphized once per primitive type
76    #[inline(never)]
77    pub fn delegate_div<T>(lhs: T, rhs: T) -> T
78    where
79        T: StrongTypeOps,
80        T::Primitive: Div<Output = T::Primitive>,
81    {
82        T::from_primitive(lhs.to_primitive() / rhs.to_primitive())
83    }
84
85    /// Shared rem implementation - monomorphized once per primitive type
86    #[inline(never)]
87    pub fn delegate_rem<T>(lhs: T, rhs: T) -> T
88    where
89        T: StrongTypeOps,
90        T::Primitive: Rem<Output = T::Primitive>,
91    {
92        T::from_primitive(lhs.to_primitive() % rhs.to_primitive())
93    }
94
95    /// Shared bitand implementation - monomorphized once per primitive type
96    #[inline(never)]
97    pub fn delegate_bitand<T>(lhs: T, rhs: T) -> T
98    where
99        T: StrongTypeOps,
100        T::Primitive: BitAnd<Output = T::Primitive>,
101    {
102        T::from_primitive(lhs.to_primitive() & rhs.to_primitive())
103    }
104
105    /// Shared bitor implementation - monomorphized once per primitive type
106    #[inline(never)]
107    pub fn delegate_bitor<T>(lhs: T, rhs: T) -> T
108    where
109        T: StrongTypeOps,
110        T::Primitive: BitOr<Output = T::Primitive>,
111    {
112        T::from_primitive(lhs.to_primitive() | rhs.to_primitive())
113    }
114
115    /// Shared bitxor implementation - monomorphized once per primitive type
116    #[inline(never)]
117    pub fn delegate_bitxor<T>(lhs: T, rhs: T) -> T
118    where
119        T: StrongTypeOps,
120        T::Primitive: BitXor<Output = T::Primitive>,
121    {
122        T::from_primitive(lhs.to_primitive() ^ rhs.to_primitive())
123    }
124
125    // ============================================================================
126    // Unary Operators
127    // ============================================================================
128
129    /// Shared neg implementation - monomorphized once per primitive type
130    #[inline(never)]
131    pub fn delegate_neg<T>(val: T) -> T
132    where
133        T: StrongTypeOps,
134        T::Primitive: Neg<Output = T::Primitive>,
135    {
136        T::from_primitive(-val.to_primitive())
137    }
138
139    /// Shared not implementation - monomorphized once per primitive type
140    #[inline(never)]
141    pub fn delegate_not<T>(val: T) -> T
142    where
143        T: StrongTypeOps,
144        T::Primitive: Not<Output = T::Primitive>,
145    {
146        T::from_primitive(!val.to_primitive())
147    }
148
149    // ============================================================================
150    // Bit Shift Operators
151    // ============================================================================
152
153    /// Shared shl implementation - monomorphized once per primitive type
154    #[inline(never)]
155    pub fn delegate_shl<T, Rhs>(lhs: T, rhs: Rhs) -> T
156    where
157        T: StrongTypeOps,
158        T::Primitive: Shl<Rhs, Output = T::Primitive>,
159        Rhs: Copy,
160    {
161        T::from_primitive(lhs.to_primitive() << rhs)
162    }
163
164    /// Shared shr implementation - monomorphized once per primitive type
165    #[inline(never)]
166    pub fn delegate_shr<T, Rhs>(lhs: T, rhs: Rhs) -> T
167    where
168        T: StrongTypeOps,
169        T::Primitive: Shr<Rhs, Output = T::Primitive>,
170        Rhs: Copy,
171    {
172        T::from_primitive(lhs.to_primitive() >> rhs)
173    }
174
175    // ============================================================================
176    // Scalar Operations
177    // ============================================================================
178
179    /// Shared scalar mul implementation
180    #[inline(never)]
181    pub fn delegate_scalar_mul<T>(lhs: T, rhs: T::Primitive) -> T
182    where
183        T: StrongTypeOps,
184        T::Primitive: Mul<Output = T::Primitive>,
185    {
186        T::from_primitive(lhs.to_primitive() * rhs)
187    }
188
189    /// Shared scalar div implementation
190    #[inline(never)]
191    pub fn delegate_scalar_div<T>(lhs: T, rhs: T::Primitive) -> T
192    where
193        T: StrongTypeOps,
194        T::Primitive: Div<Output = T::Primitive>,
195    {
196        T::from_primitive(lhs.to_primitive() / rhs)
197    }
198
199    /// Shared scalar rem implementation
200    #[inline(never)]
201    pub fn delegate_scalar_rem<T>(lhs: T, rhs: T::Primitive) -> T
202    where
203        T: StrongTypeOps,
204        T::Primitive: Rem<Output = T::Primitive>,
205    {
206        T::from_primitive(lhs.to_primitive() % rhs)
207    }
208}