pub enum Total {
Exact(EstimatedUsd),
AtLeast {
floor: EstimatedUsd,
unpriced: Vec<UnpricedLine>,
},
}Expand description
A report’s total, which is a lower bound whenever anything is unpriced (COST-4).
Two variants rather than a struct with a flag, and that is the upgrade over the
Python’s Total(priced, unpriced=()): there a consumer could read .priced and
never look at .is_lower_bound, so the honesty rule depended on the caller
checking. Here the floor is inside Total::AtLeast, beside the reasons, so
reaching it means seeing them. A plain sum cannot express “everything we could
price, plus a build AWS will not tell us the price of”, and the natural way to
force it to — dropping the unpriced line — is exactly the lie this module exists
not to tell.
Variants§
Exact(EstimatedUsd)
Every line item was priced, so this is the whole estimate.
AtLeast
At least this much, plus line items with no published rate.
Fields
floor: EstimatedUsdThe sum of the priced lines. Not the total — the total is unknowable.
unpriced: Vec<UnpricedLine>The lines that could not be priced, in report order.
Non-empty by construction: Total::of answers Total::Exact when
there is nothing to name, so an AtLeast with an empty list — a lower
bound that will not say what it is missing — is not a value this type
holds.
Implementations§
Source§impl Total
impl Total
Sourcepub fn of<'a>(
amounts: impl IntoIterator<Item = (CostPhase, &'a Amount)>,
) -> Total
pub fn of<'a>( amounts: impl IntoIterator<Item = (CostPhase, &'a Amount)>, ) -> Total
The total over a report’s amounts, each labelled with the phase it came from.
The one place a total is computed, so COST-4 holds for every consumer rather
than for the ones that remembered. An unpriced amount routes the whole answer
to Total::AtLeast; it is never skipped and never summed as zero.
Takes (phase, amount) rather than a bare amount so the phase cannot go
missing on the way in: the rendered total names phases, and a Total built
without them could only fall back to printing reasons.
Sourcepub fn floor(&self) -> EstimatedUsd
pub fn floor(&self) -> EstimatedUsd
Everything that could be priced.
Named floor rather than total on purpose: for Total::AtLeast it is a
lower bound, and a consumer reading a field called total would have no
reason to check which variant it came from.
Sourcepub fn is_lower_bound(&self) -> bool
pub fn is_lower_bound(&self) -> bool
True when line items with no published rate are missing from the floor.
Sourcepub fn unpriced_lines(&self) -> &[UnpricedLine]
pub fn unpriced_lines(&self) -> &[UnpricedLine]
The lines that could not be priced. Empty for Total::Exact.
Sourcepub fn unpriced_reasons(&self) -> Vec<String>
pub fn unpriced_reasons(&self) -> Vec<String>
The reasons the unpriced lines could not be priced, in report order. Empty for
Total::Exact.
Kept beside Total::unpriced_lines because the reason is what a consumer
surfacing the why wants, while the rendered total names phases.
Sourcepub fn unpriced_phase_names(&self) -> Vec<&'static str>
pub fn unpriced_phase_names(&self) -> Vec<&'static str>
The distinct phase names of the unpriced lines, sorted — what the rendered total names.
Sorted and deduplicated to match cost.py:342’s
", ".join(sorted({item.phase.value for item in self.unpriced})): two unpriced
lines in one phase name it once, and the order does not depend on report order.
Trait Implementations§
Source§impl Display for Total
“at least” is the whole point, so it leads.
impl Display for Total
“at least” is the whole point, so it leads.
The parenthetical names phases, not reasons, which is cost.py:343 verbatim. A
reason is a sentence explaining what AWS does not publish, and joining several of
them turns a one-line total into a paragraph the two clients cannot both print.
impl Eq for Total
impl StructuralPartialEq for Total
Auto Trait Implementations§
impl Freeze for Total
impl RefUnwindSafe for Total
impl Send for Total
impl Sync for Total
impl Unpin for Total
impl UnsafeUnpin for Total
impl UnwindSafe for Total
Blanket Implementations§
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,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more