poke at creating Macros

- create config struct
- create config errors
- create macro struct

TODO create --config option for the file
This commit is contained in:
a-kenji 2021-03-04 15:00:23 +01:00
parent 955d38906d
commit 3e0174cc4a
6 changed files with 150 additions and 3 deletions

129
src/common/config.rs Normal file
View file

@ -0,0 +1,129 @@
//! Deserializes configuration options.
use std;
use std::collections::HashMap;
use std::error;
use std::fmt::{self, Display};
use std::fs::File;
use std::io::{self,Read};
use std::path::PathBuf;
use super::input::{keybinds,handler};
use serde::Deserialize;
/// Intermediate struct
//pub struct KeybingsFromYaml {
//}
/// Intermediate struct
//#[derive(Debug, Deserialize)]
pub struct ConfigFromYaml {
keybinds: HashMap<handler::InputMode,Vec<keybinds::Keybinds>>,
}
///// Deserialized config state
#[derive(Debug, Clone, Default, Deserialize)]
pub struct Config {
keybinds: Vec<keybinds::Keybinds>,
}
#[derive(Debug)]
pub enum ConfigError {
// from the serde documentation
// https://serde.rs/error-handling.html
// One or more variants that can be created by data structures through the
// `ser::Error` and `de::Error` traits. For example the Serialize impl for
// Mutex<T> might return an error because the mutex is poisoned, or the
// Deserialize impl for a struct may return an error because a required
// field is missing.
//Message(String),
// serde_yaml error
Serde(serde_yaml::Error),
//Eof,
// io::Error
Io(io::Error)
}
impl Config {
/// Deserializes from given path
pub fn new(path: &PathBuf) -> Result<Config,ConfigError> {
let config_deserialized: Config;
let mut config_string = String::new();
match File::open(path) {
Ok(mut file) => {
file.read_to_string(&mut config_string)?;
config_deserialized = serde_yaml::from_str(&config_string)?;
}
Err(_) => {
// TODO logging, if a file is not found
// at an expected position - should not
// panic @a-kenji
config_deserialized = Config::default();
}
}
Ok(config_deserialized)
}
}
//impl de::Error for ConfigError {
//fn custom<T: Display>(msg: T) -> Self {
//ConfigError::Message(msg.to_string())
//}
//}
impl Display for ConfigError {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
match self {
//ConfigError::Message(msg) => formatter.write_str(msg),
//ConfigError::Eof => formatter.write_str("unexpected end of input"),
//
ConfigError::Io(ref err) => write!(formatter, "Io error: {}", err),
ConfigError::Serde(ref err) => write!(formatter, "Serde error: {}", err),
/* and so forth */
}
}
}
impl std::error::Error for ConfigError {
fn description(&self) -> &str {
match *self {
//ConfigError::Message(ref err) => err,
ConfigError::Io(ref err) => err.to_string().as_str(),
ConfigError::Serde(ref err) => err.to_string().as_str(),
}
}
fn cause(&self) -> Option<&dyn error::Error> {
match *self {
// N.B. Both of these implicitly cast `err` from their concrete
// types (either `&io::Error` or `&num::ParseIntError`)
// to a trait object `&Error`. This works because both error types
// implement `Error`.
ConfigError::Io(ref err) => Some(err),
//ConfigError::Message(ref err) => Some(err),
ConfigError::Serde(ref err) => Some(err),
}
}
}
impl From<io::Error> for ConfigError {
fn from(err: io::Error) -> ConfigError {
ConfigError::Io(err)
}
}
impl From<serde_yaml::Error> for ConfigError {
fn from(err: serde_yaml::Error) -> ConfigError {
ConfigError::Serde(err)
}
}
//impl From<de::Error::Message> for ConfigError {
//fn from(err: de::Error::Message) -> ConfigError {
//ConfigError::Message(err)
//}
//}

View file

@ -1,9 +1,11 @@
//! Definition of the actions that can be bound to keys.
use super::handler;
//use super::macros;
use serde::Deserialize;
/// The four directions (left, right, up, down).
#[derive(Clone, Debug)]
#[derive(Clone, Debug, Deserialize)]
pub enum Direction {
Left,
Right,
@ -12,7 +14,7 @@ pub enum Direction {
}
/// Actions that can be bound to keys.
#[derive(Clone, Debug)]
#[derive(Clone, Debug, Deserialize)]
pub enum Action {
/// Quit Zellij.
Quit,

View file

@ -8,7 +8,7 @@ use std::collections::HashMap;
use strum::IntoEnumIterator;
use termion::event::Key;
type Keybinds = HashMap<InputMode, ModeKeybinds>;
pub type Keybinds = HashMap<InputMode, ModeKeybinds>;
type ModeKeybinds = HashMap<Key, Vec<Action>>;
/// Populates the default hashmap of keybinds.

View file

@ -0,0 +1,12 @@
//! Use a list of commands and execute them in a
//! defined predictable order.
use super::actions::Action;
use serde::Deserialize;
#[derive(Debug, Clone, Deserialize)]
pub struct Macro {
name: Option<String>,
sequence: Vec<Action>
}

View file

@ -3,3 +3,4 @@
pub mod actions;
pub mod handler;
pub mod keybinds;
pub mod macros;

View file

@ -1,3 +1,4 @@
pub mod config;
pub mod command_is_executing;
pub mod errors;
pub mod input;
@ -26,6 +27,7 @@ use wasmer::{ChainableNamedResolver, Instance, Module, Store, Value};
use wasmer_wasi::{Pipe, WasiState};
use crate::cli::CliArgs;
use crate::common::config::Config;
use crate::layout::Layout;
use command_is_executing::CommandIsExecuting;
use errors::{AppContext, ContextType, ErrorContext, PluginContext, PtyContext, ScreenContext};
@ -47,6 +49,7 @@ pub enum ApiCommand {
#[derive(Debug, Clone, Default)]
pub struct AppState {
pub input_mode: InputMode,
pub config : Config,
}
// FIXME: Make this a method on the big `Communication` struct, so that app_tx can be extracted