pub struct Project { /* private fields */ }Expand description
Represents a project with a name and a list of resources.
Implementations§
Source§impl Project
impl Project
Sourcepub fn builder() -> ProjectBuilder
pub fn builder() -> ProjectBuilder
Create an instance of Project using the builder syntax
Source§impl Project
impl Project
Sourcepub fn name(&self) -> &str
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");Sourcepub fn description(&self) -> Option<&str>
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);Sourcepub fn add_task(&mut self, task: Task) -> Uuid
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);Sourcepub fn add_sibling_before(&mut self, task: Task, sibling_id: Uuid) -> Uuid
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]);Sourcepub fn add_sibling_after(&mut self, task: Task, sibling_id: Uuid) -> Uuid
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]);Sourcepub fn rm_task(&mut self, id: Uuid) -> Result<Task>
pub fn rm_task(&mut self, id: Uuid) -> Result<Task>
Deletes a task and all references to it from the project.
§Arguments
id- TheUuidof 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);Sourcepub fn task_mut(&mut self, id: Uuid) -> Option<&mut Task>
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")Sourcepub fn tasks(&self) -> impl Iterator<Item = &Task>
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);Sourcepub fn tasks_mut(&mut self) -> impl Iterator<Item = &mut Task>
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);Sourcepub fn add_time_relationship(
&mut self,
predecessor: Uuid,
successor: Uuid,
kind: TimeRelationship,
) -> Result<()>
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- TheUuidof the predecessor task.successor- TheUuidof 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")Sourcepub fn rm_time_relationship(
&mut self,
predecessor: Uuid,
successor: Uuid,
) -> Result<()>
pub fn rm_time_relationship( &mut self, predecessor: Uuid, successor: Uuid, ) -> Result<()>
Removes a relationship between tasks.
§Arguments
§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);Sourcepub fn successors(&self, id: Uuid) -> impl Iterator<Item = &Task>
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")Sourcepub fn successors_ids(&self, id: Uuid) -> impl Iterator<Item = Uuid>
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)Sourcepub fn predecessors(&self, id: Uuid) -> impl Iterator<Item = &Task>
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")Sourcepub fn predecessors_ids(&self, id: Uuid) -> impl Iterator<Item = Uuid>
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)Sourcepub fn update_relationships(
&mut self,
task_id: Uuid,
ids: &[Uuid],
dir: RelDir,
kind: TimeRelationship,
) -> Result<()>
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- TheUuidof 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);Sourcepub fn move_task_after(&mut self, id: Uuid, after_id: Uuid)
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]);Sourcepub fn add_subtask(&mut self, parent_id: Uuid, child_id: Uuid) -> Result<()>
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
§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);Sourcepub fn remove_subtask(&mut self, child_id: Uuid) -> Result<()>
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());Sourcepub fn task_parent(&self, child_id: Uuid) -> Option<Uuid>
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));Sourcepub fn subtasks(&self, parent_id: Uuid) -> impl Iterator<Item = Uuid> + '_
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);Sourcepub fn sync_parent_dates(&mut self, parent_id: Uuid) -> Result<()>
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));Sourcepub const fn start_date(&self) -> Option<DateTime<Utc>>
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));Sourcepub fn add_resource(&mut self, resource: Resource)
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);Sourcepub fn resource(&self, index: usize) -> Option<&Resource>
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());Sourcepub fn rm_resource(&mut self, index: usize) -> Option<Resource>
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());Sourcepub fn resource_mut(&mut self, index: usize) -> Option<&mut Resource>
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");
}
}Sourcepub fn resources(&self) -> &[Resource]
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);Sourcepub fn res_into_consumable(
&mut self,
resource_index: usize,
) -> Result<(), ResourceConversionError>
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 aConsumable
§Errors
ResourceConversionError::ResourceNotFound- If a resource with the specified index does not exist.ResourceConversionError::ConversionNotPossible- When trying to convert a resource that’s not aMaterial.
§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());Sourcepub fn res_into_nonconsumable(
&mut self,
resource_index: usize,
) -> Result<(), ResourceConversionError>
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 aNonConsumable
§Errors
ResourceConversionError::ResourceNotFound- If a resource with the specified index does not exist.ResourceConversionError::ConversionNotPossible- When trying to convert a resource that’s not aMaterial.
§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());Sourcepub fn add_stakeholder(&mut self, stakeholder: Stakeholder)
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);Sourcepub fn stakeholders(&self) -> &[Stakeholder]
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);Sourcepub fn rm_stakeholder(&mut self, index: usize) -> Option<Stakeholder>
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§
Auto Trait Implementations§
impl Freeze for Project
impl RefUnwindSafe for Project
impl Send for Project
impl Sync for Project
impl Unpin for Project
impl UnsafeUnpin for Project
impl UnwindSafe for Project
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> 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