diff --git a/zellij-utils/src/input/config.rs b/zellij-utils/src/input/config.rs index 0339d4dce8..941efa1d99 100644 --- a/zellij-utils/src/input/config.rs +++ b/zellij-utils/src/input/config.rs @@ -45,9 +45,8 @@ pub enum ConfigError { IoPath(io::Error, PathBuf), // Internal Deserialization Error FromUtf8(std::string::FromUtf8Error), - // Missing the tab section in the layout. - Layout(LayoutMissingTabSectionError), - LayoutPartAndTab(LayoutPartAndTabError), + // Naming a part in a tab is unsupported + LayoutNameInTab(LayoutNameInTabError), } impl Default for Config { @@ -139,70 +138,32 @@ impl Config { // TODO: Split errors up into separate modules #[derive(Debug, Clone)] -pub struct LayoutMissingTabSectionError; -#[derive(Debug, Clone)] -pub struct LayoutPartAndTabError; - -impl fmt::Display for LayoutMissingTabSectionError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!( - f, - "MissingTabSectionError: -There needs to be exactly one `tabs` section specified in the layout file, for example: ---- -direction: Horizontal -parts: - - direction: Vertical - - direction: Vertical - tabs: - - direction: Vertical - - direction: Vertical - - direction: Vertical -" - ) - } -} - -impl std::error::Error for LayoutMissingTabSectionError { - fn description(&self) -> &str { - "One tab must be specified per Layout." - } -} +pub struct LayoutNameInTabError; -impl fmt::Display for LayoutPartAndTabError { +impl fmt::Display for LayoutNameInTabError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, - "LayoutPartAndTabError: -The `tabs` and `parts` section should not be specified on the same level in the layout file, for example: + "LayoutNameInTabError: +The `parts` inside the `tabs` can't be named. For example: --- -direction: Horizontal -parts: - - direction: Vertical - - direction: Vertical tabs: - direction: Vertical - - direction: Vertical - - direction: Vertical - -should rather be specified as: ---- -direction: Horizontal -parts: - - direction: Vertical - - direction: Vertical - tabs: - - direction: Vertical + name: main + parts: - direction: Vertical + name: section # <== The part section can't be named. - direction: Vertical + - direction: Vertical + name: test " ) } } -impl std::error::Error for LayoutPartAndTabError { +impl std::error::Error for LayoutNameInTabError { fn description(&self) -> &str { - "The `tabs` and parts section should not be specified on the same level." + "The `parts` inside the `tabs` can't be named." } } @@ -215,10 +176,7 @@ impl Display for ConfigError { } ConfigError::Serde(ref err) => write!(formatter, "Deserialization error: {}", err), ConfigError::FromUtf8(ref err) => write!(formatter, "FromUtf8Error: {}", err), - ConfigError::Layout(ref err) => { - write!(formatter, "There was an error in the layout file, {}", err) - } - ConfigError::LayoutPartAndTab(ref err) => { + ConfigError::LayoutNameInTab(ref err) => { write!(formatter, "There was an error in the layout file, {}", err) } } @@ -232,8 +190,7 @@ impl std::error::Error for ConfigError { ConfigError::IoPath(ref err, _) => Some(err), ConfigError::Serde(ref err) => Some(err), ConfigError::FromUtf8(ref err) => Some(err), - ConfigError::Layout(ref err) => Some(err), - ConfigError::LayoutPartAndTab(ref err) => Some(err), + ConfigError::LayoutNameInTab(ref err) => Some(err), } } } @@ -256,15 +213,9 @@ impl From for ConfigError { } } -impl From for ConfigError { - fn from(err: LayoutMissingTabSectionError) -> ConfigError { - ConfigError::Layout(err) - } -} - -impl From for ConfigError { - fn from(err: LayoutPartAndTabError) -> ConfigError { - ConfigError::LayoutPartAndTab(err) +impl From for ConfigError { + fn from(err: LayoutNameInTabError) -> ConfigError { + ConfigError::LayoutNameInTab(err) } } diff --git a/zellij-utils/src/input/layout.rs b/zellij-utils/src/input/layout.rs index 98fdb0d12b..9dc8cd47b1 100644 --- a/zellij-utils/src/input/layout.rs +++ b/zellij-utils/src/input/layout.rs @@ -9,7 +9,10 @@ // If plugins should be able to depend on the layout system // then [`zellij-utils`] could be a proper place. use crate::{ - input::{command::RunCommand, config::ConfigError}, + input::{ + command::RunCommand, + config::{ConfigError, LayoutNameInTabError}, + }, pane_size::{Dimension, PaneGeom}, setup, }; @@ -106,7 +109,12 @@ impl LayoutFromYaml { let layout: Option = serde_yaml::from_str(&layout)?; match layout { - Some(layout) => Ok(layout), + Some(layout) => { + for tab in layout.tabs.clone() { + tab.check()?; + } + Ok(layout) + } None => Ok(LayoutFromYaml::default()), } } @@ -220,6 +228,7 @@ impl LayoutTemplate { #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] #[serde(crate = "self::serde")] pub struct TabLayout { + #[serde(default)] pub direction: Direction, #[serde(default)] pub borderless: bool, @@ -231,6 +240,18 @@ pub struct TabLayout { pub name: String, } +impl TabLayout { + fn check(&self) -> Result { + for part in self.parts.iter() { + part.check()?; + if !part.name.is_empty() { + return Err(ConfigError::LayoutNameInTab(LayoutNameInTabError)); + } + } + Ok(self.clone()) + } +} + impl Layout { pub fn total_terminal_panes(&self) -> usize { let mut total_panes = 0; @@ -467,6 +488,12 @@ impl Default for LayoutFromYaml { } } +impl Default for Direction { + fn default() -> Self { + Direction::Horizontal + } +} + // The unit test location. #[cfg(test)] #[path = "./unit/layout_test.rs"]