normal atom stream ok

master
Avril 4 years ago
parent 0c97a5fcc8
commit 7b00455385
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -15,8 +15,20 @@ pub enum ParseErrorKind
CannotCombine(char, char),
BadTail(char, String),
NotUnique(char),
ModeSet,
}
impl error::Error for ParseErrorKind{}
impl fmt::Display for ParseErrorKind
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
Ok(())
}
}
impl From<(String, ParseErrorKind)> for Error
{
#[inline] fn from((froms, fromk): (String, ParseErrorKind)) -> Self
@ -25,6 +37,33 @@ impl From<(String, ParseErrorKind)> for Error
}
}
#[derive(Debug)]
#[non_exhaustive]
pub enum ConstructError
{
AlreadyExists(String),
Resolve(resolve::Error),
}
impl error::Error for ConstructError
{
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
Some(match self {
Self::Resolve(res) => res,
_=> return None,
})
}
}
impl fmt::Display for ConstructError
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
match self {
_ => write!(f, "unknown error"),
}
}
}
#[derive(Debug)]
#[non_exhaustive]
@ -34,12 +73,21 @@ pub enum Error {
Unknown,
AtomInternal,
}
impl error::Error for Error{}
impl error::Error for Error
{
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
Some(match &self {
Error::Parse(_, parse) => parse,
_=> return None,
})
}
}
impl fmt::Display for Error
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
match self {
Error::AtomInternal => unreachable!("This should've been handled."),
_ => write!(f, "unknown error"),
}
}
@ -53,3 +101,12 @@ impl<T> From<tokio::sync::mpsc::error::SendError<T>> for Error
Self::AtomInternal
}
}
impl From<resolve::Error> for ConstructError
{
#[inline] fn from(from: resolve::Error) -> Self
{
Self::Resolve(from)
}
}

@ -10,10 +10,10 @@ use std::{
iter,
};
use eyre::eyre;
use config::op::Password;
use config::op::{self, Password};
use error::ParseErrorKind;
#[derive(Debug)]
#[derive(Debug, Hash, PartialEq, Eq)]
enum IsSigning
{
No,
@ -30,18 +30,17 @@ impl Default for IsSigning
}
}
#[derive(Debug)]
#[derive(Debug, Hash, PartialEq, Eq)]
enum KeyKind
{
Autodetect,
RsaPublic,
Autodetect(IsSigning),
RsaPublic(IsSigning),
RsaPrivate(IsSigning), // is signing key?
Aes,
}
#[derive(Debug)]
enum TranslationMode
{
#[derive(Debug, Hash, PartialEq, Eq)]
enum TranslationMode {
Autodetect,
Encrypt,
Decrypt,
@ -57,20 +56,35 @@ impl Default for TranslationMode
}
#[derive(Debug)]
#[derive(Debug, Hash, PartialEq, Eq)]
enum Atom
{
Key(KeyKind, String, Password),
NonSpecific,
FileAuto(String),
FileSpecific(String, String, TranslationMode),
//TODO:
SetMode(config::op::Mode),
}
impl Atom
{
pub fn hash_into(&self, map: &mut smallmap::Map<u64, ()>) -> bool
{
use std::hash::{Hash,Hasher,};
let hasher = std::collections::hash_map::DefaultHasher::new();
self.hash(&mut hasher);
let vl = hasher.finish();
if map.contains_key(&vl) {
true
} else {
map.insert(hasher.finish(),());
false
}
}
}
#[instrument]
pub async fn parse<I: IntoIterator<Item=String> + std::fmt::Debug>(args: I) -> Result<!/* TODO: What type do we make for this? */, eyre::Report>
pub async fn parse<I: IntoIterator<Item=String> + std::fmt::Debug>(args: I) -> Result<config::Operation, eyre::Report>
{
let (mut tx, mut rx) = mpsc::channel(1);
@ -89,13 +103,50 @@ pub async fn parse<I: IntoIterator<Item=String> + std::fmt::Debug>(args: I) -> R
"--stat" => todo!(),
_ => {
let handler = tokio::spawn(async move {
//TODO: What container type do we make for this?
let mut output = op::Normal::default();
let mut had = smallmap::Map::new();
while let Some(atom) = rx.recv().await {
debug!("[Normal] recv atom: {:?}", atom);
// Construct `Normal` with atoms
if Atom::hash_into(&atom, &mut had) {
return Err(error::ConstructError::AlreadyExists(format!("TODO: {:?}", atom)));
}
match atom {
Atom::NonSpecific => output.in_place = true,
Atom::SetMode(mode) => output.mode = Some(mode),
Atom::FileAuto(file) => output.files.push((file, None, None)),
Atom::FileSpecific(finput, foutput, mode) => {
let mode = match mode {
TranslationMode::Autodetect => resolve::find_file_mode(&finput).await?,
TranslationMode::Encrypt => op::Mode::Encrypt,
TranslationMode::Decrypt => op::Mode::Decrypt,
};
output.files.push((finput, Some(foutput), Some(mode)));
},
Atom::Key(kind, string, password) => {
let (kind, sign) = match kind {
KeyKind::Autodetect(s) => (resolve::find_key_mode(&string).await?, s),
KeyKind::RsaPrivate(s) => (config::KeyKind::RsaPrivate, s),
KeyKind::RsaPublic(s) => (config::KeyKind::RsaPublic, s),
KeyKind::Aes => (config::KeyKind::Aes, Default::default()),
};
if sign != IsSigning::No && kind == config::KeyKind::Aes {
warn!("Key was detected to not be RSA, option to sign is set and ignored.");
} else {
output.sign.push((string.clone(), password.clone()));
}
match kind {
config::KeyKind::Aes => output.aes.push((string, password)),
config::KeyKind::RsaPublic => output.rsa.push((string, password)),
config::KeyKind::RsaPrivate => output.rsa.push((string, password))
}
},
}
}
todo!()
});
Ok(config::Operation::Normal(output))
}.instrument(tracing::info_span!("handler")));
match parse_normal(std::iter::once(arg)
.chain(args.map(Into::into)), &mut tx).await
{
@ -119,12 +170,11 @@ pub async fn parse<I: IntoIterator<Item=String> + std::fmt::Debug>(args: I) -> R
.wrap_err_with(|| eyre!("Failed to construct operation from arguments"))
.with_note(|| "In constructing of operation from spec");
},
Ok(result) => {
Ok(operation) => {
//TODO: Validate operation here?
Ok(operation)
},
}
todo!()
}
async fn parse_normal<I: IntoIterator<Item=String>>(args: I, atoms: &mut mpsc::Sender<Atom>) -> Result<(), error::Error>
@ -132,7 +182,7 @@ async fn parse_normal<I: IntoIterator<Item=String>>(args: I, atoms: &mut mpsc::S
let mut args = args.into_iter();
let mut reading=true;
let mut mode_set=false;
while let Some(arg) = args.next()
{
@ -146,7 +196,27 @@ async fn parse_normal<I: IntoIterator<Item=String>>(args: I, atoms: &mut mpsc::S
}
if reading && arg.starts_with("-") {
let mut opt = arg.chars().skip(1);
macro_rules! check_mode_set
{
() => {
if mode_set {
return Err((arg, error::ParseErrorKind::ModeSet).into());
} else {
mode_set=true;
}
}
}
match opt.next() {
Some('a') => check_mode_set!(),
Some('e') => {
check_mode_set!();
atoms.send(Atom::SetMode(config::op::Mode::Encrypt)).await?;
},
Some('d') => {
check_mode_set!();
atoms.send(Atom::SetMode(config::op::Mode::Decrypt)).await?;
},
Some('i') => match opt.next() {
None => atoms.send(Atom::NonSpecific).await?,
Some(r) => return Err((ParseErrorKind::BadTail('i', iter::once(r).chain(opt).collect()), arg).swap().into()),
@ -238,8 +308,8 @@ async fn parse_normal<I: IntoIterator<Item=String>>(args: I, atoms: &mut mpsc::S
}
let kind = match kind {
KeySpec::Autodetect => KeyKind::Autodetect,
KeySpec::RsaPublic => KeyKind::RsaPublic,
KeySpec::Autodetect => KeyKind::Autodetect(signing),
KeySpec::RsaPublic => KeyKind::RsaPublic(signing),
KeySpec::RsaPrivate => KeyKind::RsaPrivate(signing),
KeySpec::Aes => KeyKind::Aes,
};

@ -6,28 +6,19 @@ pub mod op {
/// The crypt mode
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
pub enum Mode {
/// Detect based on file-type
Autodetect,
Encrypt,
Decrypt,
}
impl Default for Mode
{
#[inline]
fn default() -> Self
{
Mode::Autodetect
}
}
#[derive(Debug, Clone,PartialEq, Eq, Default)]
pub struct Normal {
pub rsa: Vec<(String, Password)>,
pub sign: Vec<(String, Password)>,
pub aes: Vec<(String, Password)>,
pub mode: Mode,
pub files: Vec<(String, Option<String>)>,
pub in_place: bool,
pub mode: Option<Mode>,// `None` is autodetect mode per file
pub files: Vec<(String, Option<String>, Option<Mode> /* `None` is use global*/)>,
}
#[derive(Debug, Clone,PartialEq, Eq)]
@ -92,3 +83,11 @@ pub enum Operation
KeyInfo(Vec<(String, op::Password)>),
Help,
}
#[derive(Debug, Clone,PartialEq, Eq)]
pub enum KeyKind
{
RsaPublic,
RsaPrivate,
Aes,
}

@ -15,6 +15,7 @@ use color_eyre::{
};
use lazy_static::lazy_static;
use serde::{Serialize, Deserialize};
use tracing_futures::Instrument;
pub const CURRENT_VERSION: version::Version = version::Version::new(0,0,0,version::Tag::Prerelease);
@ -22,6 +23,7 @@ mod ext;
use ext::*;
mod version;
mod config;
mod resolve;
mod args;
/*/// Dispatch params operations that can be handled at top level (i.e. `Help`)

@ -0,0 +1,37 @@
//! Used for resolving autodetects
use super::*;
use std::{
path::{
Path,
},
error,
fmt,
};
pub async fn find_file_mode<P: AsRef<Path>>(path: P) -> Result<config::op::Mode, Error>
{
//TODO: we need to calculate mode here
todo!()
}
pub async fn find_key_mode<P: AsRef<Path>>(path: P) -> Result<config::KeyKind, Error>
{
//TODO: we need to calculate mode here
todo!()
}
#[derive(Debug)]
#[non_exhaustive]
pub enum Error
{
}
impl error::Error for Error{}
impl fmt::Display for Error
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
Ok(())
}
}
Loading…
Cancel
Save