pub struct Resource { /* private fields */ }Expand description
A resource is just a named, cost-bearing thing: “Timber”, “Excavator”, “Legal counsel”. Cost comes from two independent parts, either of which may be absent:
purchases: one-time costs (buying materials, a machine, a licence),hourly_rate: a cost per hour a task engages it (wages, rental, fuel or wear).
An employee has only a rate, raw steel has only a purchase, a bought generator that also burns fuel has both.
Optionally a resource has a contact: whoever is responsible for it or
supplies it. If a resource is a person, the contact might be the person itself.
use planter_core::{resources::{Purchase, Resource}, money::{Money, Currency}};
let mut excavator = Resource::new("Excavator".parse().unwrap())
.at_hourly_rate(Money::from_minor_units(3_000, Currency::EUR));
excavator.add_purchase(
Purchase::builder().quantity(1).unit_price(Money::from_minor_units(10_000, Currency::EUR)).build(),
);Each priced part carries its own Money currency independently: a resource’s hourly rate
and its purchases need not agree (a truck bought in EUR might be fueled at an hourly rate
billed in USD). A resource with no rate and no purchases contributes nothing to cost.
Implementations§
Source§impl Resource
impl Resource
Sourcepub fn new(title: Title) -> Self
pub fn new(title: Title) -> Self
Creates a resource with the given title, no contact, no purchases and no rate.
The title is a validated Title; build one with "…".parse() or
Title::try_new.
§Example
use planter_core::resources::Resource;
let stimpack = Resource::new("Stimpack".parse().unwrap());
assert_eq!(stimpack.title(), "Stimpack");
assert_eq!(stimpack.purchases().count(), 0);
assert_eq!(stimpack.hourly_rate(), None);Sourcepub const fn at_hourly_rate(self, hourly_rate: Money) -> Self
pub const fn at_hourly_rate(self, hourly_rate: Money) -> Self
Sets this resource’s hourly rate and returns self. Chainable form of
Self::update_hourly_rate.
§Example
use planter_core::{resources::Resource, money::{Money, Currency}};
let drill = Resource::new("Excavator".parse().unwrap())
.at_hourly_rate(Money::from_minor_units(2_000, Currency::EUR));
assert_eq!(drill.hourly_rate(), Some(Money::from_minor_units(2_000, Currency::EUR)));Sourcepub fn with_contact(self, contact: Stakeholder) -> Self
pub fn with_contact(self, contact: Stakeholder) -> Self
Sets this resource’s contact and returns self. Chainable form of
Self::set_contact.
§Example
use planter_core::{person::Person, resources::Resource, stakeholders::Stakeholder};
let peppino = Stakeholder::individual(Person::new("Mastro", "Peppino").unwrap(), None);
let timber = Resource::new("Timber".parse().unwrap()).with_contact(peppino);
assert!(timber.contact().is_some());Sourcepub const fn contact(&self) -> Option<&Stakeholder>
pub const fn contact(&self) -> Option<&Stakeholder>
Returns this resource’s contact, if one is on record.
Sourcepub fn set_contact(&mut self, contact: Stakeholder)
pub fn set_contact(&mut self, contact: Stakeholder)
Sets this resource’s contact, replacing any previous one.
Sourcepub fn clear_contact(&mut self)
pub fn clear_contact(&mut self)
Clears this resource’s contact.
Sourcepub const fn hourly_rate(&self) -> Option<Money>
pub const fn hourly_rate(&self) -> Option<Money>
Returns the hourly rate, if set.
Sourcepub const fn update_hourly_rate(&mut self, hourly_rate: Money)
pub const fn update_hourly_rate(&mut self, hourly_rate: Money)
Sets the hourly rate.
§Example
use planter_core::{resources::Resource, money::{Money, Currency}};
let mut worker = Resource::new("Backend Engineer".parse().unwrap());
worker.update_hourly_rate(Money::from_minor_units(4_500, Currency::EUR));
assert_eq!(worker.hourly_rate(), Some(Money::from_minor_units(4_500, Currency::EUR)));Sourcepub const fn remove_hourly_rate(&mut self)
pub const fn remove_hourly_rate(&mut self)
Clears the hourly rate.
Sourcepub fn purchases(&self) -> impl Iterator<Item = &Purchase>
pub fn purchases(&self) -> impl Iterator<Item = &Purchase>
Returns the purchases recorded for this resource, in the order they were added.
Sourcepub fn add_purchase(&mut self, purchase: Purchase) -> Uuid
pub fn add_purchase(&mut self, purchase: Purchase) -> Uuid
Records a purchase against this resource, returning its Purchase::id. Adding a
purchase whose id already exists on this resource replaces it in place, without
duplicating its slot in Self::purchases.
§Example
use planter_core::{resources::{Purchase, Resource}, money::{Money, Currency}};
let mut stimpack = Resource::new("Stimpack".parse().unwrap());
stimpack.add_purchase(
Purchase::builder().quantity(40).unit_price(Money::from_minor_units(500, Currency::EUR)).build(),
);
assert_eq!(stimpack.purchases().count(), 1);Sourcepub fn rm_purchase(&mut self, purchase_id: Uuid) -> Option<Purchase>
pub fn rm_purchase(&mut self, purchase_id: Uuid) -> Option<Purchase>
Removes the purchase with the given id, returning it, or None if this resource has no
such purchase.
Sourcepub fn purchase_mut(&mut self, purchase_id: Uuid) -> Option<&mut Purchase>
pub fn purchase_mut(&mut self, purchase_id: Uuid) -> Option<&mut Purchase>
Mutable access to one of this resource’s purchases, for editing it in place. None if
this resource has no purchase with that id.
§Example
use planter_core::{resources::{Purchase, Resource}, money::{Money, Currency}};
let mut stimpack = Resource::new("Stimpack".parse().unwrap());
let purchase_id = stimpack.add_purchase(
Purchase::builder().quantity(40).unit_price(Money::from_minor_units(500, Currency::EUR)).build(),
);
stimpack.purchase_mut(purchase_id).unwrap().set_quantity(60);
assert_eq!(stimpack.purchases().next().unwrap().quantity(), 60);Sourcepub fn purchase_cost(&self) -> MultiCurrencyAmount
pub fn purchase_cost(&self) -> MultiCurrencyAmount
Returns the total of every Purchase recorded for this resource, grouped by currency.
Empty when there are no purchases.
§Example
use planter_core::resources::{Purchase, Resource};
use planter_core::money::{Currency, Money};
let mut stimpack = Resource::new("Stimpack".parse().unwrap());
stimpack.add_purchase(
Purchase::builder().quantity(40).unit_price(Money::from_minor_units(500, Currency::EUR)).build(),
);
assert_eq!(
stimpack.purchase_cost().in_currency(Currency::EUR),
Some(Money::from_minor_units(20_000, Currency::EUR)),
);Sourcepub fn usage_cost(&self, hours: u64, quantity: u32) -> Option<Money>
pub fn usage_cost(&self, hours: u64, quantity: u32) -> Option<Money>
Returns the cost this resource contributes for a task that engages quantity of it for
hours hours: hourly_rate * hours * quantity (saturating). None when the resource
has no hourly rate.
§Example
use planter_core::{resources::Resource, money::{Currency, Money}};
let mut digger = Resource::new("Excavator".parse().unwrap());
digger.update_hourly_rate(Money::from_minor_units(3_000, Currency::EUR));
assert_eq!(
digger.usage_cost(4, 1),
Some(Money::from_minor_units(12_000, Currency::EUR)),
);Trait Implementations§
impl Eq for Resource
impl StructuralPartialEq for Resource
Auto Trait Implementations§
impl Freeze for Resource
impl RefUnwindSafe for Resource
impl Send for Resource
impl Sync for Resource
impl Unpin for Resource
impl UnsafeUnpin for Resource
impl UnwindSafe for Resource
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<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