Skip to content
mod.rs 3.43 KiB
Newer Older
Luker's avatar
Luker committed
/*
Luker's avatar
Luker committed
 * Copyright (c) 2021-2022, Luca Fulchir <luker@fenrirproject.org>
Luker's avatar
Luker committed
 *
 * This file is part of dfim.
 *
 * dfim is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * dfim is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with dfim.  If not, see <https://www.gnu.org/licenses/>.
 */

pub mod exec;
pub mod fs;
pub mod gpt;

use fs::btrfs;
Luker's avatar
Luker committed
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, PartialEq)]
Luker's avatar
Luker committed
#[serde(deny_unknown_fields)]
pub enum Target {
Luker's avatar
Luker committed
    Dummy,
Luker's avatar
Luker committed
    Exec(exec::Exec),
Luker's avatar
Luker committed
    GPT(gpt::GPT),
    BTRFS(btrfs::BTRFS),
}

#[derive(::serde::Deserialize, ::serde::Serialize, Clone)]
Luker's avatar
Luker committed
#[serde(deny_unknown_fields)]
pub enum TargetId {
    Id(String),
    Inline(Target),
}
Luker's avatar
Luker committed
impl TargetId {
    pub fn id(&self) -> &str {
        match &self {
            TargetId::Id(name) => name,
            TargetId::Inline(target) => target.id(),
        }
    }
}

Luker's avatar
Luker committed
pub trait TargetCommon {
    fn id(&self) -> &str;
Luker's avatar
Luker committed
    fn targets(&self) -> Vec<String>;
Luker's avatar
Luker committed
}

impl TargetCommon for Target {
    fn id(&self) -> &str {
Luker's avatar
Luker committed
        match &self {
Luker's avatar
Luker committed
            Target::Dummy => "dummy",
Luker's avatar
Luker committed
            Target::Exec(e) => e.id(),
Luker's avatar
Luker committed
            Target::GPT(g) => g.id(),
            Target::BTRFS(b) => b.id(),
        }
    }
Luker's avatar
Luker committed
    fn targets(&self) -> Vec<String> {
        match &self {
Luker's avatar
Luker committed
            Target::Dummy => Vec::new(),
Luker's avatar
Luker committed
            Target::Exec(e) => e.targets(),
Luker's avatar
Luker committed
            Target::GPT(g) => g.targets(),
            Target::BTRFS(b) => b.targets(),
        }
    }
Luker's avatar
Luker committed
}

impl super::CfgVerify for Target {
    fn standardize(&mut self) {
        match self {
Luker's avatar
Luker committed
            Target::Dummy => {}
            Target::Exec(e) => e.standardize(),
            Target::GPT(g) => g.standardize(),
            Target::BTRFS(b) => b.standardize(),
        }
    }
    fn check_consistency(
        &self,
        logger: &slog::Logger,
    ) -> Result<(), super::errors::ConfigError> {
Luker's avatar
Luker committed
        if let Target::Dummy = *self {
        } else {
            if self.id() == "dummy" {
                ::slog::error!(
                    logger,
                    "target name \"dummy\" is reserved, don't use it"
                );
                return Err(super::errors::ConfigError::Consistency(
                    "used dummy as target name".to_owned(),
                ));
            }
            let id_re = ::regex::Regex::new(r"^[\w\d_-]+$").unwrap();
            if !id_re.is_match(self.id()) {
                ::slog::error!(
                    logger,
                    "target name \"{}\" is invalid: must not contain \
                     whitespace, only letters,numbers, and -_",
                    self.id()
                );
                return Err(super::errors::ConfigError::Consistency(
                    "Invalid target name".to_owned(),
                ));
            }
        }
        match &self {
Luker's avatar
Luker committed
            Target::Dummy => {}
            Target::Exec(e) => e.check_consistency(logger)?,
            Target::GPT(g) => g.check_consistency(logger)?,
            Target::BTRFS(b) => b.check_consistency(logger)?,
        }
        Ok(())
    }
}