feat: make factory lib

This commit is contained in:
Kristofers Solo 2025-11-10 09:07:05 +02:00
parent bfa93c095a
commit f42080c90a
Signed by: kristoferssolo
GPG Key ID: 74FF8144483D82C8
11 changed files with 97 additions and 56 deletions

View File

@ -1,12 +1,14 @@
[workspace]
resolver = "2"
members = ["aes", "cipher-core", "cli", "des"]
members = ["aes", "cipher-core", "cipher-factory", "cli", "des"]
[workspace.dependencies]
aes = { path = "aes" }
color-eyre = "0.6"
cipher-core = { path = "cipher-core" }
cipher-factory = { path = "cipher-factory" }
claims = "0.8"
clap = { version = "4.5", features = ["derive"] }
des = { path = "des" }
rand = "0.9"
rstest = "0.26"

17
cipher-factory/Cargo.toml Normal file
View File

@ -0,0 +1,17 @@
[package]
name = "cipher-factory"
version = "0.1.0"
edition = "2024"
[dependencies]
aes.workspace = true
cipher-core.workspace = true
clap = { workspace = true, optional = true }
des.workspace = true
[features]
default = []
clap = ["dep:clap"]
[lints]
workspace = true

View File

@ -0,0 +1,30 @@
use cipher_core::{BlockCipher, InputBlock};
use des::Des;
use std::fmt::Display;
#[cfg_attr(feature = "clap", derive(clap::ValueEnum))]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Algorithm {
Des,
Aes,
}
impl Algorithm {
#[must_use]
pub fn get_cipher(&self, key: &impl InputBlock) -> impl BlockCipher {
match self {
Self::Des => Des::from_key(key.as_bytes()),
Self::Aes => todo!("Must implement AES first"),
}
}
}
impl Display for Algorithm {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let s = match self {
Self::Des => "Des",
Self::Aes => "Aes",
};
f.write_str(s)
}
}

View File

@ -0,0 +1,5 @@
mod algorithm;
mod operation;
mod output;
pub use {algorithm::Algorithm, operation::OperationChoice, output::OutputFormat};

View File

@ -0,0 +1,6 @@
#[cfg_attr(feature = "clap", derive(clap::ValueEnum))]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum OperationChoice {
Encrypt,
Decrypt,
}

View File

@ -0,0 +1,27 @@
use cipher_core::Output;
#[cfg_attr(feature = "clap", derive(clap::ValueEnum))]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum OutputFormat {
/// Binary output
Binary,
/// Octal output
Octal,
/// Decimal output
#[default]
Hex,
/// Text output (ASCII)
Text,
}
impl OutputFormat {
#[must_use]
pub fn to_string(&self, value: &Output) -> String {
match self {
Self::Binary => format!("{value:064b}"),
Self::Octal => format!("{value:022o}"),
Self::Hex => format!("{value:016X}"),
Self::Text => format!("{value}"),
}
}
}

View File

@ -7,7 +7,8 @@ edition = "2024"
[dependencies]
aes.workspace = true
cipher-core.workspace = true
clap = { version = "4.5", features = ["derive"] }
cipher-factory = { workspace = true, features = ["clap"] }
clap.workspace = true
color-eyre.workspace = true
des.workspace = true
thiserror.workspace = true

View File

@ -1,5 +1,5 @@
use crate::output::OutputFormat;
use clap::{Parser, ValueEnum};
use cipher_factory::{Algorithm, OperationChoice, OutputFormat};
use clap::Parser;
use des::Block64;
use std::str::FromStr;
@ -12,7 +12,7 @@ pub struct Args {
/// Encryption algorithm
#[arg(short, long)]
pub algorithm: AlgorithmChoice,
pub algorithm: Algorithm,
/// Key used for encryption/decryption. Can be a string or a path to a file
#[arg(short, long, value_parser = Block64::from_str, required = true)]
@ -26,15 +26,3 @@ pub struct Args {
#[arg(short = 'f', long)]
pub output_format: Option<OutputFormat>,
}
#[derive(Debug, Clone, Copy, ValueEnum)]
pub enum AlgorithmChoice {
Des,
Aes,
}
#[derive(Debug, Clone, Copy, ValueEnum)]
pub enum OperationChoice {
Encrypt,
Decrypt,
}

View File

@ -1,13 +0,0 @@
use crate::args::AlgorithmChoice;
use cipher_core::{BlockCipher, InputBlock};
use des::Des;
impl AlgorithmChoice {
#[must_use]
pub fn get_cipher(&self, key: &impl InputBlock) -> impl BlockCipher {
match self {
Self::Des => Des::from_key(key.as_bytes()),
Self::Aes => todo!("Must implement AES first"),
}
}
}

View File

@ -1,12 +1,8 @@
mod args;
mod cipher;
mod output;
use crate::{
args::{Args, OperationChoice},
output::OutputFormat,
};
use crate::args::Args;
use cipher_core::BlockCipher;
use cipher_factory::OperationChoice;
use clap::Parser;
fn main() -> color_eyre::Result<()> {
@ -28,12 +24,8 @@ fn main() -> color_eyre::Result<()> {
OperationChoice::Decrypt => {
let cipher = algorithm.get_cipher(&key);
let plaintext = cipher.decrypt(&text.to_be_bytes())?;
match output_format.unwrap_or_default() {
OutputFormat::Binary => println!("{plaintext:064b}"),
OutputFormat::Octal => println!("{plaintext:022o}"),
OutputFormat::Hex => println!("{plaintext:016X}"),
OutputFormat::Text => println!("{plaintext}"),
}
let output = output_format.unwrap_or_default().to_string(&plaintext);
println!("{output}");
}
}
Ok(())

View File

@ -1,14 +0,0 @@
use clap::ValueEnum;
#[derive(Debug, Clone, Default, ValueEnum)]
pub enum OutputFormat {
/// Binary output
Binary,
/// Octal output
Octal,
/// Decimal output
#[default]
Hex,
/// Text output (ASCII)
Text,
}