diff options
author | Kirill Chibisov <contact@kchibisov.com> | 2020-06-05 01:10:31 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-06-05 01:10:31 +0300 |
commit | f99220f01553c6c9d36e1f4ce01c007f4d4d4cb5 (patch) | |
tree | a61843b8ffe5fc25cc3a35157bc1a4346f37d40b /alacritty_terminal/src | |
parent | 1e32e5a5154a2e765ca0b3ab8e50e4c01bbe5d18 (diff) |
Refactor Shell, Command, and Launcher to share impl
Diffstat (limited to 'alacritty_terminal/src')
-rw-r--r-- | alacritty_terminal/src/config/mod.rs | 64 | ||||
-rw-r--r-- | alacritty_terminal/src/config/window.rs | 37 | ||||
-rw-r--r-- | alacritty_terminal/src/tty/unix.rs | 12 | ||||
-rw-r--r-- | alacritty_terminal/src/tty/windows/mod.rs | 8 |
4 files changed, 59 insertions, 62 deletions
diff --git a/alacritty_terminal/src/config/mod.rs b/alacritty_terminal/src/config/mod.rs index de72d3e2..b3f13492 100644 --- a/alacritty_terminal/src/config/mod.rs +++ b/alacritty_terminal/src/config/mod.rs @@ -12,7 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::borrow::Cow; use std::collections::HashMap; use std::fmt::Display; use std::path::PathBuf; @@ -78,8 +77,8 @@ pub struct Config<T> { pub selection: Selection, /// Path to a shell program to run on startup. - #[serde(default, deserialize_with = "from_string_or_deserialize")] - pub shell: Option<Shell<'static>>, + #[serde(default, deserialize_with = "failure_default")] + pub shell: Option<Program>, /// Path where config was loaded from. #[serde(default, deserialize_with = "failure_default")] @@ -286,33 +285,30 @@ where .unwrap_or_else(|_| Percentage::new(DEFAULT_CURSOR_THICKNESS))) } -#[derive(Clone, Debug, Deserialize, PartialEq, Eq)] -pub struct Shell<'a> { - pub program: Cow<'a, str>, - - #[serde(default, deserialize_with = "failure_default")] - pub args: Vec<String>, +#[serde(untagged)] +#[derive(Deserialize, Debug, Clone, PartialEq, Eq)] +pub enum Program { + Just(String), + WithArgs { + program: String, + #[serde(default, deserialize_with = "failure_default")] + args: Vec<String>, + }, } -impl<'a> Shell<'a> { - pub fn new<S>(program: S) -> Shell<'a> - where - S: Into<Cow<'a, str>>, - { - Shell { program: program.into(), args: Vec::new() } - } - - pub fn new_with_args<S>(program: S, args: Vec<String>) -> Shell<'a> - where - S: Into<Cow<'a, str>>, - { - Shell { program: program.into(), args } +impl Program { + pub fn program(&self) -> &str { + match self { + Program::Just(program) => program, + Program::WithArgs { program, .. } => program, + } } -} -impl FromString for Option<Shell<'_>> { - fn from(input: String) -> Self { - Some(Shell::new(input)) + pub fn args(&self) -> &[String] { + match self { + Program::Just(_) => &[], + Program::WithArgs { args, .. } => args, + } } } @@ -395,19 +391,3 @@ where value => Some(T::deserialize(value).unwrap_or_else(fallback_default)), }) } - -pub fn from_string_or_deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error> -where - D: Deserializer<'de>, - T: Deserialize<'de> + FromString + Default, -{ - Ok(match Value::deserialize(deserializer)? { - Value::String(value) => T::from(value), - value => T::deserialize(value).unwrap_or_else(fallback_default), - }) -} - -// Used over From<String>, to allow implementation for foreign types. -pub trait FromString { - fn from(input: String) -> Self; -} diff --git a/alacritty_terminal/src/config/window.rs b/alacritty_terminal/src/config/window.rs index 5e934f6f..f4405396 100644 --- a/alacritty_terminal/src/config/window.rs +++ b/alacritty_terminal/src/config/window.rs @@ -1,10 +1,10 @@ use std::os::raw::c_ulong; -use serde::Deserialize; +use log::error; +use serde::{Deserialize, Deserializer}; +use serde_yaml::Value; -use crate::config::{ - failure_default, from_string_or_deserialize, option_explicit_none, Delta, FromString, -}; +use crate::config::{failure_default, option_explicit_none, Delta, LOG_TARGET_CONFIG}; use crate::index::{Column, Line}; /// Default Alacritty name, used for window title and class. @@ -42,7 +42,7 @@ pub struct WindowConfig { pub title: String, /// Window class. - #[serde(deserialize_with = "from_string_or_deserialize")] + #[serde(deserialize_with = "failure_default")] pub class: Class, /// XEmbed parent. @@ -158,8 +158,7 @@ impl Dimensions { } /// Window class hint. -#[serde(default)] -#[derive(Deserialize, Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct Class { pub instance: String, pub general: String, @@ -171,8 +170,26 @@ impl Default for Class { } } -impl FromString for Class { - fn from(value: String) -> Self { - Class { instance: value, general: DEFAULT_NAME.into() } +impl<'a> Deserialize<'a> for Class { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'a>, + { + let value = Value::deserialize(deserializer)?; + + if let Value::String(instance) = value { + return Ok(Class { instance, general: DEFAULT_NAME.into() }); + } + + match Self::deserialize(value) { + Ok(value) => Ok(value), + Err(err) => { + error!( + target: LOG_TARGET_CONFIG, + "Problem with config: {}; using class Alacritty", err + ); + Ok(Self::default()) + }, + } } } diff --git a/alacritty_terminal/src/tty/unix.rs b/alacritty_terminal/src/tty/unix.rs index 2db59519..2c2f4eee 100644 --- a/alacritty_terminal/src/tty/unix.rs +++ b/alacritty_terminal/src/tty/unix.rs @@ -14,7 +14,7 @@ // //! TTY related functionality. -use crate::config::{Config, Shell}; +use crate::config::{Config, Program}; use crate::event::OnResize; use crate::term::SizeInfo; use crate::tty::{ChildEvent, EventedPty, EventedReadWrite}; @@ -163,14 +163,14 @@ pub fn new<C>(config: &Config<C>, size: &SizeInfo, window_id: Option<usize>) -> let shell_name = pw.shell.rsplit('/').next().unwrap(); let argv = vec![String::from("-c"), format!("exec -a -{} {}", shell_name, pw.shell)]; - Shell::new_with_args("/bin/bash", argv) + Program::WithArgs { program: "/bin/bash".to_owned(), args: argv } } else { - Shell::new(pw.shell) + Program::Just(pw.shell.to_owned()) }; let shell = config.shell.as_ref().unwrap_or(&default_shell); - let mut builder = Command::new(&*shell.program); - for arg in &shell.args { + let mut builder = Command::new(&*shell.program()); + for arg in shell.args() { builder.arg(arg); } @@ -246,7 +246,7 @@ pub fn new<C>(config: &Config<C>, size: &SizeInfo, window_id: Option<usize>) -> pty.on_resize(size); pty }, - Err(err) => die!("Failed to spawn command '{}': {}", shell.program, err), + Err(err) => die!("Failed to spawn command '{}': {}", shell.program(), err), } } diff --git a/alacritty_terminal/src/tty/windows/mod.rs b/alacritty_terminal/src/tty/windows/mod.rs index 47b03d90..685e7849 100644 --- a/alacritty_terminal/src/tty/windows/mod.rs +++ b/alacritty_terminal/src/tty/windows/mod.rs @@ -18,7 +18,7 @@ use std::iter::once; use std::os::windows::ffi::OsStrExt; use std::sync::mpsc::TryRecvError; -use crate::config::{Config, Shell}; +use crate::config::{Config, Program}; use crate::event::OnResize; use crate::term::SizeInfo; use crate::tty::windows::child::ChildExitWatcher; @@ -197,11 +197,11 @@ impl OnResize for Pty { } fn cmdline<C>(config: &Config<C>) -> String { - let default_shell = Shell::new("powershell"); + let default_shell = Program::Just("powershell".to_owned()); let shell = config.shell.as_ref().unwrap_or(&default_shell); - once(shell.program.as_ref()) - .chain(shell.args.iter().map(|a| a.as_ref())) + once(shell.program().as_ref()) + .chain(shell.args().iter().map(|a| a.as_ref())) .collect::<Vec<_>>() .join(" ") } |