thot-local 0.10.0-intermediate

Local functionality for Thot data management and analysis software.
Documentation
use crate::common::scripts_file_of;
use crate::result::Result;
use crate::system::settings::user_settings::UserSettings;
use cluFlock::FlockLock;
use serde::{Deserialize, Serialize};
use settings_manager::list_setting::ListSetting;
use settings_manager::local_settings::{LocalSettings, LockSettingsFile};
use settings_manager::result::{
    Error as SettingsError, LocalSettingsError, Result as SettingsResult,
};
use settings_manager::settings::Settings;
use settings_manager::system_settings::SystemSettings;
use settings_manager::types::Priority as SettingsPriority;
use std::fs::File;
use std::path::{Path, PathBuf};
use thot_core::project::Script;
use thot_core::types::{ResourceId, ResourcePath};

// **************
// *** Script ***
// **************

pub struct LocalScript;

impl LocalScript {
    /// Creates a new [`Script`] with the `creator` field matching the current active creator.
    pub fn new(path: ResourcePath) -> Result<Script> {
        let settings = UserSettings::load()?;
        let creator = settings.active_user;

        let mut script = Script::new(path)?;
        script.creator = creator;
        Ok(script)
    }
}

// ***************
// *** Scripts ***
// ***************

/// Project scripts.
#[derive(Serialize, Deserialize, Debug, Default)]
pub struct Scripts {
    #[serde(skip)]
    _file_lock: Option<FlockLock<File>>,

    #[serde(skip)]
    _base_path: Option<PathBuf>,

    pub scripts: Vec<Script>,
}

impl Scripts {
    pub fn new() -> Self {
        Scripts {
            _file_lock: None,
            _base_path: None,

            scripts: Vec::new(),
        }
    }

    /// Gets a [`Script`] by its [`ResourceId`] if it is registered,
    /// otherwise returns `None`.
    pub fn get(&self, rid: &ResourceId) -> Option<&Script> {
        for script in &self.scripts {
            if &script.rid == rid {
                return Some(script);
            }
        }

        None
    }

    /// Returns whether a script with the given id is registered.
    pub fn contains(&self, rid: &ResourceId) -> bool {
        self.get(rid).is_some()
    }

    /// Returns whether a script with the given path is registered.
    pub fn contains_path(&self, path: &ResourcePath) -> bool {
        self.by_path(path).is_some()
    }

    /// Gets a script by its path if it is registered.
    pub fn by_path(&self, path: &ResourcePath) -> Option<&Script> {
        for script in &self.scripts {
            if &script.path == path {
                return Some(&script);
            }
        }

        None
    }
}

impl Settings for Scripts {
    fn store_lock(&mut self, lock: FlockLock<File>) {
        self._file_lock = Some(lock);
    }

    fn controls_file(&self) -> bool {
        self._file_lock.is_some()
    }

    fn priority(&self) -> SettingsPriority {
        SettingsPriority::Project
    }
}

impl LocalSettings for Scripts {
    fn rel_path() -> SettingsResult<PathBuf> {
        Ok(scripts_file_of(Path::new("")))
    }

    fn base_path(&self) -> SettingsResult<PathBuf> {
        self._base_path
            .clone()
            .ok_or(SettingsError::LocalSettingsError(
                LocalSettingsError::PathNotSet,
            ))
    }

    fn set_base_path(&mut self, path: PathBuf) -> SettingsResult {
        self._base_path = Some(path);
        Ok(())
    }
}

impl ListSetting for Scripts {
    type Item = Script;

    fn items(&mut self) -> &mut Vec<Script> {
        &mut self.scripts
    }
}

impl LockSettingsFile for Scripts {}

#[cfg(test)]
#[path = "./script_test.rs"]
mod script_test;