Skip to main content

Project

Struct Project 

Source
pub struct Project { /* private fields */ }
Expand description

Represents a project with a name and a list of resources.

Implementations§

Source§

impl Project

Source

pub fn builder() -> ProjectBuilder

Create an instance of Project using the builder syntax

Source§

impl Project

Source

pub fn new(name: impl Into<String>) -> Self

Creates a new project with the given name.

§Arguments
  • name - The name of the project.
§Returns

A new Project instance.

§Example
use planter_core::project::Project;

let project = Project::new("World domination");
assert_eq!(project.name(), "World domination");
Source

pub fn name(&self) -> &str

Returns the name of the project.

§Example
use planter_core::project::Project;

let project = Project::new("World domination");
assert_eq!(project.name(), "World domination");
Source

pub fn description(&self) -> Option<&str>

Returns the description of the project.

§Example
use planter_core::project::Project;

let project = Project::new("World domination");
assert_eq!(project.description(), None);
Source

pub fn add_task(&mut self, task: Task) -> Uuid

Adds a task to the project and returns its stable Uuid.

§Arguments
  • task - The task to add to the project.
§Returns

The stable Uuid assigned to the task.

§Example
use planter_core::{project::Project, task::Task};

let mut project = Project::new("World domination");
let id = project.add_task(Task::new("Become world leader"));
assert_eq!(project.tasks().count(), 1);
Source

pub fn add_sibling_before(&mut self, task: Task, sibling_id: Uuid) -> Uuid

Inserts a new task as a sibling right before sibling_id in the task order. If the sibling has a parent, the new task becomes a child of the same parent.

§Example
use planter_core::{project::Project, task::Task};

let mut project = Project::new("World domination");
let a = project.add_task(Task::new("Build an army"));
let b = project.add_task(Task::new("Train troops"));
let c = project.add_sibling_before(Task::new("Gather allies"), b);

let ids: Vec<_> = project.tasks().map(|t| t.id()).collect();
assert_eq!(ids, vec![a, c, b]);
Source

pub fn add_sibling_after(&mut self, task: Task, sibling_id: Uuid) -> Uuid

Inserts a new task as a sibling right after sibling_id in the task order. If the sibling has a parent, the new task becomes a child of the same parent.

§Example
use planter_core::{project::Project, task::Task};

let mut project = Project::new("World domination");
let a = project.add_task(Task::new("Build an army"));
let b = project.add_task(Task::new("Train troops"));
let c = project.add_sibling_after(Task::new("Gather allies"), a);

let ids: Vec<_> = project.tasks().map(|t| t.id()).collect();
assert_eq!(ids, vec![a, c, b]);
Source

pub fn rm_task(&mut self, id: Uuid) -> Result<Task>

Deletes a task and all references to it from the project.

§Arguments
  • id - The Uuid of the task to remove.
§Errors

Returns an error if the task doesn’t exist.

§Example
use planter_core::{project::Project, task::Task};

let mut project = Project::new("World domination");
let id = project.add_task(Task::new("Become world leader"));
assert_eq!(project.tasks().count(), 1);
assert!(project.rm_task(id).is_ok());
assert_eq!(project.tasks().count(), 0);
Source

pub fn task(&self, id: Uuid) -> Option<&Task>

Gets a reference to the task with the given Uuid.

§Example
use planter_core::{project::Project, task::Task};

let mut project = Project::new("World domination");
let id = project.add_task(Task::new("Become world leader"));
assert_eq!(project.task(id).unwrap().name(), "Become world leader");
Source

pub fn task_mut(&mut self, id: Uuid) -> Option<&mut Task>

Gets a mutable reference to the task with the given Uuid.

§Example
use planter_core::{project::Project, task::Task};

let mut project = Project::new("World domination");
let id = project.add_task(Task::new("Become world leader"));
let task = project.task_mut(id).unwrap();
assert_eq!(task.name(), "Become world leader");

task.edit_name("Become world's biggest loser");
assert_eq!(task.name(), "Become world's biggest loser")
Source

pub fn tasks(&self) -> impl Iterator<Item = &Task>

Returns the tasks of the project in insertion order.

§Example
use planter_core::{project::Project, task::Task};

let mut project = Project::new("World domination");
project.add_task(Task::new("Become world leader"));
assert_eq!(project.tasks().count(), 1);
Source

pub fn tasks_mut(&mut self) -> impl Iterator<Item = &mut Task>

Returns a mutable iterator over the tasks.

§Example
use planter_core::{project::Project, task::Task};

let mut project = Project::new("World domination");
project.add_task(Task::new("Become world leader"));
assert_eq!(project.tasks_mut().count(), 1);
Source

pub fn add_time_relationship( &mut self, predecessor: Uuid, successor: Uuid, kind: TimeRelationship, ) -> Result<()>

Adds a relationship between tasks, where one is the predecessor and the other a successor.

§Arguments
  • predecessor - The Uuid of the predecessor task.
  • successor - The Uuid of the successor task.
  • kind - The type of relationship.
§Errors

Returns an error if either task doesn’t exist, if the relationship would create a cycle, or if the relationship already exists.

§Example
use planter_core::{project::{Project, TimeRelationship}, task::Task};

let mut project = Project::new("World domination");
let pred = project.add_task(Task::new("Get rich"));
let succ = project.add_task(Task::new("Become world leader"));
project.add_time_relationship(pred, succ, TimeRelationship::default());

assert_eq!(project.successors(pred).next().unwrap().name(), "Become world leader")
Source

pub fn rm_time_relationship( &mut self, predecessor: Uuid, successor: Uuid, ) -> Result<()>

Removes a relationship between tasks.

§Arguments
  • predecessor - The Uuid of the predecessor task.
  • successor - The Uuid of the successor task.
§Errors

Returns an error if no relationship exists between the tasks.

§Example
use planter_core::{project::{Project, TimeRelationship}, task::Task};

let mut project = Project::new("World domination");
let pred = project.add_task(Task::new("Get rich"));
let succ = project.add_task(Task::new("Become world leader"));
project.add_time_relationship(pred, succ, TimeRelationship::default());
project.rm_time_relationship(pred, succ).unwrap();

assert_eq!(project.successors(pred).count(), 0);
Source

pub fn successors(&self, id: Uuid) -> impl Iterator<Item = &Task>

Gets the successors of a given task.

§Example
use planter_core::{project::{Project, TimeRelationship}, task::Task};

let mut project = Project::new("World domination");
let pred = project.add_task(Task::new("Get rich"));
let succ = project.add_task(Task::new("Become world leader"));
project.add_time_relationship(pred, succ, TimeRelationship::default());

assert_eq!(project.successors(pred).next().unwrap().name(), "Become world leader")
Source

pub fn successors_ids(&self, id: Uuid) -> impl Iterator<Item = Uuid>

Gets the Uuids of all successors for a given task.

§Example
use planter_core::{project::{Project, TimeRelationship}, task::Task};

let mut project = Project::new("World domination");
let pred = project.add_task(Task::new("Get rich"));
let succ = project.add_task(Task::new("Become world leader"));
project.add_time_relationship(pred, succ, TimeRelationship::default());

assert_eq!(project.successors_ids(pred).next().unwrap(), succ)
Source

pub fn predecessors(&self, id: Uuid) -> impl Iterator<Item = &Task>

Gets the predecessors of a given task.

§Example
use planter_core::{project::{Project, TimeRelationship}, task::Task};

let mut project = Project::new("World domination");
let pred = project.add_task(Task::new("Get rich"));
let succ = project.add_task(Task::new("Become world leader"));
project.add_time_relationship(pred, succ, TimeRelationship::default());

assert_eq!(project.predecessors(succ).next().unwrap().name(), "Get rich")
Source

pub fn predecessors_ids(&self, id: Uuid) -> impl Iterator<Item = Uuid>

Gets the Uuids of all predecessors for a given task.

§Example
use planter_core::{project::{Project, TimeRelationship}, task::Task};

let mut project = Project::new("World domination");
let pred = project.add_task(Task::new("Get rich"));
let succ = project.add_task(Task::new("Become world leader"));
project.add_time_relationship(pred, succ, TimeRelationship::default());

assert_eq!(project.predecessors_ids(succ).next().unwrap(), pred)
Source

pub fn update_relationships( &mut self, task_id: Uuid, ids: &[Uuid], dir: RelDir, kind: TimeRelationship, ) -> Result<()>

Sets the predecessors or successors of a task to exactly the given set of tasks.

§Arguments
  • task_id - The Uuid of the task whose relationships need updating.
  • ids - The tasks to set as predecessors or successors.
  • dir - Whether to update predecessors or successors.
  • kind - The type of time relationship.
§Errors

Returns an error if:

  • Any task doesn’t exist.
  • The update would create a cycle.
§Example
use planter_core::{project::{Project, RelDir, TimeRelationship}, task::Task};

let mut project = Project::new("World domination");
let id0 = project.add_task(Task::new("Become world leader"));
let id1 = project.add_task(Task::new("Get rich"));
let id2 = project.add_task(Task::new("Be evil"));

project.update_relationships(id2, &[id0, id1], RelDir::Predecessors, TimeRelationship::FinishToStart).unwrap();
assert_eq!(project.predecessors(id2).count(), 2);
Source

pub fn move_task_after(&mut self, id: Uuid, after_id: Uuid)

Moves id right after after_id in the global task order, affecting display order.

§Example
use planter_core::{project::Project, task::Task};

let mut project = Project::new("World domination");
let a = project.add_task(Task::new("Build an army"));
let b = project.add_task(Task::new("Train troops"));
let c = project.add_task(Task::new("Gather allies"));
project.move_task_after(c, a);

let ids: Vec<_> = project.tasks().map(|t| t.id()).collect();
assert_eq!(ids, vec![a, c, b]);
Source

pub fn add_subtask(&mut self, parent_id: Uuid, child_id: Uuid) -> Result<()>

Adds a subtask to a given task, marking the child as a component of the parent. The parent task is completed when all children are completed.

§Arguments
  • parent_id - The Uuid of the parent task.
  • child_id - The Uuid of the child subtask.
§Errors

Returns an error if either task doesn’t exist.

§Example
use planter_core::{project::Project, task::Task};

let mut project = Project::new("World domination");
let parent = project.add_task(Task::new("Build a house"));
let child1 = project.add_task(Task::new("Lay foundations"));
let child2 = project.add_task(Task::new("Build roof"));

project.add_subtask(parent, child1).unwrap();
project.add_subtask(parent, child2).unwrap();
assert_eq!(project.subtasks(parent).count(), 2);
Source

pub fn remove_subtask(&mut self, child_id: Uuid) -> Result<()>

Removes a subtask relationship, promoting the child back to a top-level task.

§Errors

Returns an error if the task is not a subtask.

§Example
use planter_core::{project::Project, task::Task};

let mut project = Project::new("World domination");
let army = project.add_task(Task::new("Build an army"));
let supplies = project.add_task(Task::new("Gather supplies"));
project.add_subtask(army, supplies).unwrap();
assert!(project.task_parent(supplies).is_some());

project.remove_subtask(supplies).unwrap();
assert!(project.task_parent(supplies).is_none());
Source

pub fn task_parent(&self, child_id: Uuid) -> Option<Uuid>

Returns the parent Uuid of a subtask, or None if the task is at root level.

§Example
use planter_core::{project::Project, task::Task};

let mut project = Project::new("World domination");
let army = project.add_task(Task::new("Build an army"));
let supplies = project.add_task(Task::new("Gather supplies"));

assert!(project.task_parent(supplies).is_none());

project.add_subtask(army, supplies).unwrap();
assert_eq!(project.task_parent(supplies), Some(army));
Source

pub fn subtasks(&self, parent_id: Uuid) -> impl Iterator<Item = Uuid> + '_

Gets the Uuids of all subtasks of the given task.

§Example
use planter_core::{project::Project, task::Task};

let mut project = Project::new("World domination");
let parent = project.add_task(Task::new("Build a house"));
let child = project.add_task(Task::new("Lay foundations"));
assert_eq!(project.subtasks(parent).count(), 0);

project.add_subtask(parent, child).unwrap();
assert_eq!(project.subtasks(parent).count(), 1);
Source

pub fn sync_parent_dates(&mut self, parent_id: Uuid) -> Result<()>

Expands the parent’s start/finish dates to encompass all children. Only ever expands outward — never contracts. Has no effect if no child has start/finish dates.

§Errors

Returns an error if the parent task doesn’t exist.

§Example
use chrono::Utc;
use planter_core::{project::Project, task::Task};

let mut project = Project::new("World domination");
let army = project.add_task(Task::new("Build an army"));
let supplies = project.add_task(Task::new("Gather supplies"));
project.add_subtask(army, supplies).unwrap();

let now = Utc::now();
project.task_mut(supplies).unwrap().edit_start(now).unwrap();
project.sync_parent_dates(army).unwrap();

assert_eq!(project.task(army).unwrap().start(), Some(now));
Source

pub const fn start_date(&self) -> Option<DateTime<Utc>>

Returns the start date of the project.

§Example
use planter_core::project::Project;
use chrono::Utc;

let start_date = Utc::now();
let project = Project::builder().name("World domination").start_date(start_date).build();
assert_eq!(project.start_date(), Some(start_date));
Source

pub fn add_resource(&mut self, resource: Resource)

Adds a resource to the project.

§Arguments
  • resource - The resource to add to the project.
§Example
use planter_core::{resources::Resource, project::Project, person::Person};

let mut project = Project::new("World domination");
project.add_resource(Resource::Personnel {
    person: Person::new("Sebastiano", "Giordano").unwrap(),
    hourly_rate: None,
});
assert_eq!(project.resources().len(), 1);
Source

pub fn resource(&self, index: usize) -> Option<&Resource>

Get a reference to a resource used in the project.

§Example
use planter_core::{resources::Resource, project::Project, person::Person};

let mut project = Project::new("World domination");
project.add_resource(Resource::Personnel {
    person: Person::new("Sebastiano", "Giordano").unwrap(),
    hourly_rate: None,
});

assert!(project.resource(0).is_some());
Source

pub fn rm_resource(&mut self, index: usize) -> Option<Resource>

Remove a resource from the project.

§Example
use planter_core::{resources::Resource, project::Project, person::Person};

let mut project = Project::new("World domination");
project.add_resource(Resource::Personnel {
    person: Person::new("Sebastiano", "Giordano").unwrap(),
    hourly_rate: None,
});

assert!(project.resource(0).is_some());
project.rm_resource(0);
assert!(project.resource(0).is_none());
assert!(project.rm_resource(0).is_none());
Source

pub fn resource_mut(&mut self, index: usize) -> Option<&mut Resource>

Get a mutable reference to a resource used in the project.

§Example
use planter_core::{resources::Resource, project::Project, person::Person};

let mut project = Project::new("World domination");
project.add_resource(Resource::Personnel {
    person: Person::new("Sebastiano", "Giordano").unwrap(),
    hourly_rate: None,
});

let resource = project.resource_mut(0).unwrap();
match resource {
  Resource::Material(_) => panic!(),
  Resource::Personnel {
    person,
    ..
  } => {
    person.update_first_name("Alessandro");
    assert_eq!(person.first_name(), "Alessandro");
  }
}
Source

pub fn resources(&self) -> &[Resource]

Returns a reference to the list of resources associated with the project.

§Example
use planter_core::{resources::{Resource, Material, NonConsumable}, project::Project};

let mut project = Project::new("World domination");
project.add_resource(Resource::Material(Material::NonConsumable(
   NonConsumable::new("Crowbar"),
)));
assert_eq!(project.resources().len(), 1);
Source

pub fn res_into_consumable( &mut self, resource_index: usize, ) -> Result<(), ResourceConversionError>

Converts a resource into a Consumable, if that’s possible.

§Arguments
  • resource_index - The index of a Material, that’s not a Consumable
§Errors
  • ResourceConversionError::ResourceNotFound - If a resource with the specified index does not exist.
  • ResourceConversionError::ConversionNotPossible - When trying to convert a resource that’s not a Material.
§Example
use planter_core::{resources::{Resource, Material, NonConsumable}, project::Project};

let mut project = Project::new("World domination");
project.add_resource(Resource::Material(Material::NonConsumable(
   NonConsumable::new("Crowbar"),
)));
assert!(project.res_into_consumable(0).is_ok());
Source

pub fn res_into_nonconsumable( &mut self, resource_index: usize, ) -> Result<(), ResourceConversionError>

Converts a resource into a NonConsumable, if that’s possible.

§Arguments
  • resource_index - The index of a Material, that’s not a NonConsumable
§Errors
  • ResourceConversionError::ResourceNotFound - If a resource with the specified index does not exist.
  • ResourceConversionError::ConversionNotPossible - When trying to convert a resource that’s not a Material.
§Example
use planter_core::{resources::{Resource, Material, Consumable}, project::Project};

let mut project = Project::new("World domination");
project.add_resource(Resource::Material(Material::Consumable(
   Consumable::new("Stimpack"),
)));
assert!(project.res_into_nonconsumable(0).is_ok());
Source

pub fn add_stakeholder(&mut self, stakeholder: Stakeholder)

Adds a stakeholder to the project.

§Arguments
  • stakeholder - The stakeholder to add to the project.
§Example
use planter_core::{stakeholders::Stakeholder, project::Project, person::Person};

let mut project = Project::new("World domination");
let person = Person::new("Margherita", "Hack").unwrap();
project.add_stakeholder(Stakeholder::Individual {
  person,
  description: None,
});
assert_eq!(project.stakeholders().len(), 1);
Source

pub fn stakeholders(&self) -> &[Stakeholder]

Returns a reference to the list of stakeholders associated with the project.

§Example
use planter_core::{stakeholders::Stakeholder, project::Project, person::Person};

let mut project = Project::new("World domination");
let person = Person::new("Margherita", "Hack").unwrap();
project.add_stakeholder(Stakeholder::Individual {
  person,
  description: None,
});
assert_eq!(project.stakeholders().len(), 1);
Source

pub fn rm_stakeholder(&mut self, index: usize) -> Option<Stakeholder>

Removes a stakeholder from the project by index.

§Arguments
  • index - The index of the stakeholder to remove.
§Returns

The removed stakeholder, or None if the index is out of bounds.

§Example
use planter_core::{stakeholders::Stakeholder, project::Project, person::Person};

let mut project = Project::new("World domination");
let person = Person::new("Margherita", "Hack").unwrap();
project.add_stakeholder(Stakeholder::Individual { person, description: None });
assert_eq!(project.stakeholders().len(), 1);
let removed = project.rm_stakeholder(0);
assert!(removed.is_some());
assert_eq!(project.stakeholders().len(), 0);

Trait Implementations§

Source§

impl Debug for Project

Source§

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

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

impl Default for Project

Source§

fn default() -> Project

Returns the “default value” for a type. Read more

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> 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, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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.