nuts_tool/config/
container.rs

1// MIT License
2//
3// Copyright (c) 2024 Robin Doer
4//
5// Permission is hereby granted, free of charge, to any person obtaining a copy
6// of this software and associated documentation files (the "Software"), to
7// deal in the Software without restriction, including without limitation the
8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9// sell copies of the Software, and to permit persons to whom the Software is
10// furnished to do so, subject to the following conditions:
11//
12// The above copyright notice and this permission notice shall be included in
13// all copies or substantial portions of the Software.
14//
15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21// IN THE SOFTWARE.
22
23use anyhow::Result;
24use log::debug;
25use nuts_tool_api::tool_dir;
26use serde::{Deserialize, Serialize};
27use std::collections::HashMap;
28use std::fs;
29use std::path::PathBuf;
30
31use crate::config::load_path;
32
33#[derive(Debug, Deserialize, Serialize)]
34struct Inner {
35    plugin: String,
36}
37
38#[derive(Debug, Deserialize, Serialize)]
39pub struct ContainerConfig {
40    #[serde(flatten)]
41    container: HashMap<String, Inner>,
42}
43
44impl ContainerConfig {
45    pub fn config() -> Result<PathBuf> {
46        Ok(tool_dir()?.join("container"))
47    }
48
49    pub fn load() -> Result<ContainerConfig> {
50        let path = Self::config()?;
51
52        match load_path(&path)? {
53            Some(s) => Ok(toml::from_str(&s)?),
54            None => Ok(ContainerConfig {
55                container: HashMap::new(),
56            }),
57        }
58    }
59
60    pub fn list_container(&self) -> Vec<&str> {
61        let mut vec: Vec<&str> = self.container.keys().map(|s| s.as_str()).collect();
62
63        vec.sort();
64
65        vec
66    }
67
68    pub fn get_plugin(&self, name: &str) -> Option<&str> {
69        self.container.get(name).map(|inner| inner.plugin.as_str())
70    }
71
72    pub fn add_plugin(&mut self, name: &str, plugin: &str, force: bool) -> bool {
73        if self.container.contains_key(name) && !force {
74            return false;
75        }
76
77        self.container.insert(
78            name.to_string(),
79            Inner {
80                plugin: plugin.to_string(),
81            },
82        );
83
84        true
85    }
86
87    pub fn remove_plugin(&mut self, name: &str) -> bool {
88        self.container.remove(name).is_some()
89    }
90
91    pub fn save(&self) -> Result<()> {
92        let path = Self::config()?;
93        let toml = toml::to_string(self)?;
94
95        debug!("{}: dump {} bytes", path.display(), toml.as_bytes().len());
96
97        fs::write(path, toml)?;
98
99        Ok(())
100    }
101}