pub struct BookedCost {
pub per_unit: Decimal,
pub total: Decimal,
}Expand description
Payload of CostNumber::PerUnitFromTotal.
Carries both the per-unit value derived at booking time and the
original {{ total }} cost so residual math can use the exact
total (avoiding the division-then-multiplication precision loss
that hits the rust_decimal 28-digit ceiling on long ledgers).
Fields§
§per_unit: DecimalPer-unit cost, derived as total / |units| during booking.
Used by lot tracking, display (Python-compat post-booking
per-unit form), and validation reads that want a per-unit
value.
total: DecimalOriginal total as written. Used by residual calculation to avoid the division-then-multiplication precision loss that would otherwise leak into balance checks.
Implementations§
Source§impl BookedCost
impl BookedCost
Sourcepub fn new(per_unit: Decimal, total: Decimal, units: Decimal) -> Self
pub fn new(per_unit: Decimal, total: Decimal, units: Decimal) -> Self
Construct from booking with a precision invariant check.
In debug builds, asserts that per_unit * |units| ≈ total to
the limits of rust_decimal precision (tolerance:
max(1e-20, |total| * 1e-24), derived from the booker’s
total / |units| divisor truncating at 28 significant digits;
see the private check_invariant helper for the exact
computation). Callers are the booker (which derives
per_unit = total / |units|) and the plugin / FFI ingress
bridges (which must validate consistency before constructing).
§Panics
In debug builds: if the invariant fails. Release builds skip
the check (but trust-boundary callers should use
Self::try_new for runtime validation in release too).
Sourcepub fn try_new(
per_unit: Decimal,
total: Decimal,
units: Decimal,
) -> Result<Self, BookedCostInvariantError>
pub fn try_new( per_unit: Decimal, total: Decimal, units: Decimal, ) -> Result<Self, BookedCostInvariantError>
Try to construct, returning a typed error if the consistency invariant fails. Use this at trust boundaries (FFI input, plugin egress) where the caller may have supplied inconsistent values and you want to reject rather than panic in debug or accept silently in release.
§Errors
Returns BookedCostInvariantError when:
units == 0(the post-booking shape is structurally undefined for zero units; callers should sendPerUnitorTotalinstead).per_unit * |units|differs fromtotalby more thanmax(1e-20, |total| * 1e-24).
Trait Implementations§
Source§impl Archive for BookedCost
impl Archive for BookedCost
Source§type Archived = ArchivedBookedCost
type Archived = ArchivedBookedCost
Source§type Resolver = BookedCostResolver
type Resolver = BookedCostResolver
Source§fn resolve(&self, resolver: Self::Resolver, out: Place<Self::Archived>)
fn resolve(&self, resolver: Self::Resolver, out: Place<Self::Archived>)
Source§const COPY_OPTIMIZATION: CopyOptimization<Self> = _
const COPY_OPTIMIZATION: CopyOptimization<Self> = _
serialize. Read moreSource§impl Clone for BookedCost
impl Clone for BookedCost
Source§fn clone(&self) -> BookedCost
fn clone(&self) -> BookedCost
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreimpl Copy for BookedCost
Source§impl Debug for BookedCost
impl Debug for BookedCost
Source§impl<'de> Deserialize<'de> for BookedCost
impl<'de> Deserialize<'de> for BookedCost
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl<__D: Fallible + ?Sized> Deserialize<BookedCost, __D> for Archived<BookedCost>where
AsDecimal: ArchiveWith<Decimal> + DeserializeWith<<AsDecimal as ArchiveWith<Decimal>>::Archived, Decimal, __D>,
impl<__D: Fallible + ?Sized> Deserialize<BookedCost, __D> for Archived<BookedCost>where
AsDecimal: ArchiveWith<Decimal> + DeserializeWith<<AsDecimal as ArchiveWith<Decimal>>::Archived, Decimal, __D>,
Source§fn deserialize(
&self,
deserializer: &mut __D,
) -> Result<BookedCost, <__D as Fallible>::Error>
fn deserialize( &self, deserializer: &mut __D, ) -> Result<BookedCost, <__D as Fallible>::Error>
impl Eq for BookedCost
Source§impl Hash for BookedCost
impl Hash for BookedCost
Source§impl PartialEq for BookedCost
impl PartialEq for BookedCost
Source§fn eq(&self, other: &BookedCost) -> bool
fn eq(&self, other: &BookedCost) -> bool
self and other values to be equal, and is used by ==.Source§impl Serialize for BookedCost
impl Serialize for BookedCost
Source§impl ShiftSpans for BookedCost
impl ShiftSpans for BookedCost
impl StructuralPartialEq for BookedCost
Auto Trait Implementations§
impl Freeze for BookedCost
impl RefUnwindSafe for BookedCost
impl Send for BookedCost
impl Sync for BookedCost
impl Unpin for BookedCost
impl UnsafeUnpin for BookedCost
impl UnwindSafe for BookedCost
Blanket Implementations§
Source§impl<T> ArchivePointee for T
impl<T> ArchivePointee for T
Source§type ArchivedMetadata = ()
type ArchivedMetadata = ()
Source§fn pointer_metadata(
_: &<T as ArchivePointee>::ArchivedMetadata,
) -> <T as Pointee>::Metadata
fn pointer_metadata( _: &<T as ArchivePointee>::ArchivedMetadata, ) -> <T as Pointee>::Metadata
Source§impl<T> ArchiveUnsized for Twhere
T: Archive,
impl<T> ArchiveUnsized for Twhere
T: Archive,
Source§type Archived = <T as Archive>::Archived
type Archived = <T as Archive>::Archived
Archive, it may be
unsized. Read moreSource§fn archived_metadata(
&self,
) -> <<T as ArchiveUnsized>::Archived as ArchivePointee>::ArchivedMetadata
fn archived_metadata( &self, ) -> <<T as ArchiveUnsized>::Archived as ArchivePointee>::ArchivedMetadata
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<T> LayoutRaw for T
impl<T> LayoutRaw for T
Source§fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>
fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>
Source§impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
Source§unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool
unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool
Source§fn resolve_niched(out: Place<NichedOption<T, N1>>)
fn resolve_niched(out: Place<NichedOption<T, N1>>)
out indicating that a T is niched.