tatuin-providers 0.6.1

Providers lib of the Tatuin project
Documentation
// SPDX-License-Identifier: MIT

use crate::obsidian::internal_links_renderer::InternalLinksTransformer;

use super::{description::Description, fs, project::Project, state::State};
use std::{
    any::Any,
    path::{Path, PathBuf},
};
use tatuin_core::{
    RichString,
    project::Project as ProjectTrait,
    task::{DateTimeUtc, PatchPolicy, Priority, State as TaskState, Task as TaskTrait},
    task_patch::DatePatchItem,
};

#[derive(Debug, Clone, Default)]
pub struct Task {
    pub vault_path: PathBuf,
    pub provider: String,

    pub name: String,
    pub file_path: PathBuf,
    pub start_pos: usize,
    pub end_pos: usize,
    pub state: State,
    pub description: Option<Description>,
    pub due: Option<DateTimeUtc>,
    pub scheduled: Option<DateTimeUtc>,
    pub completed_at: Option<DateTimeUtc>,
    pub priority: Priority,
    pub tags: Vec<String>,
}

impl PartialEq for Task {
    fn eq(&self, o: &Self) -> bool {
        self.start_pos == o.start_pos
            && self.end_pos == o.end_pos
            && self.state == o.state
            && self.name == o.name
            && self.description == o.description
            && self.due == o.due
            && self.scheduled == o.scheduled
            && self.priority == o.priority
            && self.tags == o.tags
    }
}

impl Eq for Task {}

impl Task {
    pub fn set_vault_path(&mut self, p: &Path) {
        self.vault_path = p.to_path_buf();
    }

    pub fn set_provider(&mut self, p: String) {
        self.provider = p;
    }
}

impl TaskTrait for Task {
    fn id(&self) -> String {
        sha256::digest(format!(
            "{:?}:{}:{}:{}:{}",
            self.file_path, self.start_pos, self.end_pos, self.state, self.name
        ))
    }

    fn name(&self) -> RichString {
        RichString::new(&self.name).with_transformer(Box::new(
            InternalLinksTransformer::new(&self.vault_path).with_remove_tags(),
        ))
    }

    fn description(&self) -> Option<RichString> {
        self.description.clone().map(|d| {
            RichString::new(&d.text).with_transformer(Box::new(InternalLinksTransformer::new(&self.vault_path)))
        })
    }

    fn state(&self) -> TaskState {
        self.state.into()
    }

    fn place(&self) -> String {
        format!(
            "{}:{}",
            fs::strip_root_str(&self.vault_path, &self.file_path),
            self.start_pos,
        )
    }

    fn due(&self) -> Option<DateTimeUtc> {
        self.due
    }

    fn scheduled(&self) -> Option<DateTimeUtc> {
        self.scheduled
    }

    fn completed_at(&self) -> Option<DateTimeUtc> {
        self.completed_at
    }

    fn provider(&self) -> String {
        self.provider.to_string()
    }

    fn project(&self) -> Option<Box<dyn ProjectTrait>> {
        Some(Box::new(Project::new(
            &self.provider,
            &self.vault_path,
            &self.file_path,
        )))
    }

    fn priority(&self) -> Priority {
        self.priority
    }

    fn url(&self) -> String {
        fs::obsidian_url(&self.vault_path, &self.file_path)
    }

    fn labels(&self) -> Vec<String> {
        self.tags.clone()
    }

    fn const_patch_policy(&self) -> PatchPolicy {
        PatchPolicy {
            is_editable: true,
            is_removable: true,
            available_states: vec![TaskState::Uncompleted, TaskState::Completed, TaskState::InProgress],
            available_priorities: Priority::values(),
            available_due_items: DatePatchItem::values(),
            available_scheduled_items: DatePatchItem::values(),
        }
    }

    fn as_any(&self) -> &dyn Any {
        self
    }

    fn clone_boxed(&self) -> Box<dyn TaskTrait> {
        Box::new(self.clone())
    }
}