nuts_tool/cli/
container.rs

1// MIT License
2//
3// Copyright (c) 2023,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
23pub mod aquire;
24pub mod attach;
25pub mod change;
26pub mod create;
27pub mod delete;
28pub mod info;
29pub mod list;
30pub mod read;
31pub mod release;
32pub mod write;
33
34use anyhow::Result;
35use clap::builder::PossibleValue;
36use clap::{Args, Subcommand, ValueEnum};
37use nuts_container::Cipher;
38use std::ops::Deref;
39
40use crate::cli::container::aquire::ContainerAquireArgs;
41use crate::cli::container::attach::ContainerAttachArgs;
42use crate::cli::container::change::ContainerChangeArgs;
43use crate::cli::container::create::ContainerCreateArgs;
44use crate::cli::container::delete::ContainerDeleteArgs;
45use crate::cli::container::info::ContainerInfoArgs;
46use crate::cli::container::list::ContainerListArgs;
47use crate::cli::container::read::ContainerReadArgs;
48use crate::cli::container::release::ContainerReleaseArgs;
49use crate::cli::container::write::ContainerWriteArgs;
50
51const AES128_GCM: &str = "aes128-gcm";
52const AES192_GCM: &str = "aes192-gcm";
53const AES256_GCM: &str = "aes256-gcm";
54const AES128_CTR: &str = "aes128-ctr";
55const AES192_CTR: &str = "aes192-ctr";
56const AES256_CTR: &str = "aes256-ctr";
57const NONE: &str = "none";
58
59#[derive(Clone, Debug)]
60pub struct CliCipher(Cipher);
61
62impl PartialEq<Cipher> for CliCipher {
63    fn eq(&self, other: &Cipher) -> bool {
64        self.0 == *other
65    }
66}
67
68impl Deref for CliCipher {
69    type Target = Cipher;
70
71    fn deref(&self) -> &Cipher {
72        &self.0
73    }
74}
75
76impl ValueEnum for CliCipher {
77    fn value_variants<'a>() -> &'a [Self] {
78        &[
79            CliCipher(Cipher::Aes128Gcm),
80            CliCipher(Cipher::Aes192Gcm),
81            CliCipher(Cipher::Aes256Gcm),
82            CliCipher(Cipher::Aes192Ctr),
83            CliCipher(Cipher::Aes256Ctr),
84            CliCipher(Cipher::Aes128Ctr),
85            CliCipher(Cipher::None),
86        ]
87    }
88
89    fn to_possible_value(&self) -> Option<PossibleValue> {
90        let value = match self.0 {
91            Cipher::None => NONE,
92            Cipher::Aes128Ctr => AES128_CTR,
93            Cipher::Aes192Ctr => AES192_CTR,
94            Cipher::Aes256Ctr => AES256_CTR,
95            Cipher::Aes128Gcm => AES128_GCM,
96            Cipher::Aes192Gcm => AES192_GCM,
97            Cipher::Aes256Gcm => AES256_GCM,
98        };
99
100        Some(PossibleValue::new(value))
101    }
102}
103
104#[derive(Debug, Args)]
105#[clap(args_conflicts_with_subcommands = true, subcommand_required = true)]
106pub struct ContainerArgs {
107    #[clap(subcommand)]
108    command: Option<ContainerCommand>,
109}
110
111impl ContainerArgs {
112    pub fn run(&self) -> Result<()> {
113        self.command
114            .as_ref()
115            .map_or(Ok(()), |command| command.run())
116    }
117}
118
119#[derive(Debug, Subcommand)]
120pub enum ContainerCommand {
121    /// Aquires a new block in a container
122    Aquire(ContainerAquireArgs),
123
124    /// Attaches a plugin to a nuts-container
125    Attach(ContainerAttachArgs),
126
127    /// Modifies the container
128    Change(ContainerChangeArgs),
129
130    /// Creates a nuts-container
131    Create(ContainerCreateArgs),
132
133    /// Removes a container again
134    Delete(ContainerDeleteArgs),
135
136    /// Prints general information about the container
137    Info(ContainerInfoArgs),
138
139    /// Lists all available container
140    List(ContainerListArgs),
141
142    /// Reads a block from the container
143    Read(ContainerReadArgs),
144
145    /// Releases a block again
146    Release(ContainerReleaseArgs),
147
148    /// Writes a block into the container
149    Write(ContainerWriteArgs),
150}
151
152impl ContainerCommand {
153    pub fn run(&self) -> Result<()> {
154        match self {
155            Self::Aquire(args) => args.run(),
156            Self::Attach(args) => args.run(),
157            Self::Change(args) => args.run(),
158            Self::Create(args) => args.run(),
159            Self::Delete(args) => args.run(),
160            Self::Info(args) => args.run(),
161            Self::List(args) => args.run(),
162            Self::Read(args) => args.run(),
163            Self::Release(args) => args.run(),
164            Self::Write(args) => args.run(),
165        }
166    }
167}