Skip to main content

Resource

Struct Resource 

Source
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

Source

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);
Source

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)));
Source

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());
Source

pub const fn id(&self) -> Uuid

Returns the stable identifier of this resource.

Source

pub fn title(&self) -> &str

Returns this resource’s title.

Source

pub fn set_title(&mut self, title: Title)

Retitles this resource.

Source

pub const fn contact(&self) -> Option<&Stakeholder>

Returns this resource’s contact, if one is on record.

Source

pub fn set_contact(&mut self, contact: Stakeholder)

Sets this resource’s contact, replacing any previous one.

Source

pub fn clear_contact(&mut self)

Clears this resource’s contact.

Source

pub const fn hourly_rate(&self) -> Option<Money>

Returns the hourly rate, if set.

Source

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)));
Source

pub const fn remove_hourly_rate(&mut self)

Clears the hourly rate.

Source

pub fn purchases(&self) -> impl Iterator<Item = &Purchase>

Returns the purchases recorded for this resource, in the order they were added.

Source

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);
Source

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.

Source

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);
Source

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)),
);
Source

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§

Source§

impl Clone for Resource

Source§

fn clone(&self) -> Resource

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Resource

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Eq for Resource

Source§

impl PartialEq for Resource

Source§

fn eq(&self, other: &Resource) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for Resource

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.