install-framework-core 1.0.0

[Install Framework] Core framework and basic interfaces
Documentation
// Copyright 2021 Yuri6037

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.

use std::path::Path;
use std::collections::HashMap;

use crate::command::CommandQueue;
use crate::command::InitCommand;
use crate::command::InstallCommand;
use crate::builder::InstallerBuilder;

#[derive(Clone)]
pub struct Component
{
    /// name of component
    pub name: String,

    /// version of component
    pub version: Option<String>,

    /// license text of component
    pub license: Option<String>,

    /// readme text of component
    pub readme: Option<String>
}

pub trait Installer : Send
{
    /// Executes before any other function in order to prepare the environment for subsequent component installs
    /// 
    /// # Arguments
    /// 
    /// * `commands` - the command queue to push commands into
    fn init(&mut self, commands: &mut CommandQueue<InitCommand>);

    /// Returns all components this installer is able to install
    /// 
    /// # Arguments
    /// 
    /// * `cache` - access to the cache path
    fn get_components(&mut self, cache: &Path) -> Vec<Component>;

    /// Installs a given component
    /// 
    /// # Arguments
    /// 
    /// * `component` - component name
    /// * `commands` - the command queue to push commands into
    fn install_component(&mut self, component: &str, commands: &mut CommandQueue<InstallCommand>);
}

#[derive(Clone, Copy)]
pub enum InstallMethod
{
    /// Identifies the current install mode as local to the current connected user only
    UserInstall,

    /// Identifies the current install mode as system wide (for all users)
    SystemInstall
}

/// Represents a custom post install step
pub trait PostInstall : Send
{
    /// Called after all installations have been performed (only if a PostInstall has been defined in InstallerBuilder)
    /// 
    /// # Arguments
    /// 
    /// * `cache` - access to the cache path
    /// * `content_dir` - access to the content directory of the installed application
    /// * `bin_dir` - access to the binary directory (directory which is present in PATH when one or more AddToPath rules are present)
    fn post_install(&mut self, cache: &Path, content_dir: &Path, bin_dir: &Path);
}

/// Represents a custom post uninstall step
pub trait PostUninstall : Send
{
    /// Called after all uninstallations have been performed (only if a PostInstall has been defined in InstallerBuilder)
    /// 
    /// # Arguments
    /// 
    /// * `cache` - access to the cache path
    /// * `content_dir` - access to the content directory of the installed application
    /// * `bin_dir` - access to the binary directory (directory which is present in PATH when one or more AddToPath rules are present)
    fn post_uninstall(&mut self, cache: &Path, content_dir: &Path, bin_dir: &Path);
}

/// Represents an interface
pub trait Interface
{
    type ErrorType;

    /// Opens the welcome page for this interface
    /// 
    /// # Arguments
    /// 
    /// * `installer_name` - the name of this installer
    /// * `installer_version` - the version of this installer
    /// * `installer_author` - the author or company name of this installer
    fn welcome(&mut self, installer_name: &'static str, installer_version: &'static str, installer_author: &'static str) -> Result<(), Self::ErrorType>;

    /// Returns the install method the user chose (only called if the installer supports both modes to decide which mode should be used to continue)
    /// 
    /// # Returns
    /// 
    /// an InstallMethod
    fn get_install_method(&mut self) -> Result<InstallMethod, Self::ErrorType>;

    /// Returns wether the user chose the uninstall option or the install option
    fn should_uninstall(&self) -> Result<bool, Self::ErrorType>;

    /// Runs the install procedure for this interface
    /// 
    /// # Arguments
    /// 
    /// * `install` - the installer trait
    /// * `install_dir` - the computed installation directory
    /// * `method` - the installation method
    /// * `resources` - the resources map built by InstallerBuilder
    fn run_install(&mut self, install: &mut dyn Installer, install_dir: &Path, method: InstallMethod, resources: &HashMap<&'static str, &'static [u8]>) -> Result<(), Self::ErrorType>;

    /// Runs the post-install procedure for this interface
    /// 
    /// # Arguments
    /// 
    /// * `post_install` - the custom PostInstall step
    /// * `install_dir` - the computed installation directory
    fn run_post_install(&mut self, post_install: &mut dyn PostInstall, install_dir: &Path) -> Result<(), Self::ErrorType>;

    /// Runs the uninstall procedure for this interface
    /// 
    /// # Arguments
    /// 
    /// * `install` - the installer trait
    /// * `install_dir` - the computed installation directory
    /// * `method` - the installation method
    /// * `resources` - the resources map built by InstallerBuilder
    fn run_uninstall(&mut self, install: &mut dyn Installer, install_dir: &Path, method: InstallMethod, resources: &HashMap<&'static str, &'static [u8]>) -> Result<(), Self::ErrorType>;

    /// Runs the post-uninstall procedure for this interface
    /// 
    /// # Arguments
    /// 
    /// * `post_uninstall` - the custom PostUninstall step
    /// * `install_dir` - the computed installation directory
    fn run_post_uninstall(&mut self, post_uninstall: &mut dyn PostUninstall, install_dir: &Path) -> Result<(), Self::ErrorType>;

    /// Called when an error has occured
    /// 
    /// # Arguments
    /// 
    /// * `err` - the error object
    /// 
    /// # Returns
    /// 
    /// expected program exit code for the given error object
    fn error(&mut self, err: Self::ErrorType) -> i32;

    /// Called when no error has occured and the installer is finished
    /// 
    /// # Returns
    /// 
    /// expected program exit code
    fn finish(&mut self) -> i32;
}

/// Allows an interface to be automatically constructed by the unified run system
pub trait ConstructibleInterface<'a>
{
    /// Runs the installer for the given InstallerBuilder
    /// 
    /// # Arguments
    /// 
    /// * `builder` - the builder to run
    /// 
    /// # Returns
    /// 
    /// expected program exit code
    fn run(builder: InstallerBuilder<'a>) -> i32;
}