feat(custom_layout): add yaml file support

This commit adds support for loading custom layouts from yaml files, and
also moves the custom layout loading and validating logic into the
komorebi-core crate.

re #50
This commit is contained in:
LGUG2Z
2021-10-18 14:46:23 -07:00
parent 5d6351f48d
commit 6981d778a9
5 changed files with 65 additions and 14 deletions

34
Cargo.lock generated
View File

@@ -286,6 +286,12 @@ dependencies = [
"winapi 0.3.9",
]
[[package]]
name = "dtoa"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0"
[[package]]
name = "either"
version = "1.6.1"
@@ -544,6 +550,7 @@ dependencies = [
"color-eyre",
"serde",
"serde_json",
"serde_yaml",
"strum",
]
@@ -584,6 +591,12 @@ version = "0.2.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6"
[[package]]
name = "linked-hash-map"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
[[package]]
name = "lock_api"
version = "0.4.5"
@@ -1111,6 +1124,18 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_yaml"
version = "0.8.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8c608a35705a5d3cdc9fbe403147647ff34b921f8e833e49306df898f9b20af"
dependencies = [
"dtoa",
"indexmap",
"serde",
"yaml-rust",
]
[[package]]
name = "sharded-slab"
version = "0.1.4"
@@ -1525,3 +1550,12 @@ dependencies = [
"winapi 0.2.8",
"winapi-build",
]
[[package]]
name = "yaml-rust"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
dependencies = [
"linked-hash-map",
]

View File

@@ -12,4 +12,5 @@ clap = "3.0.0-beta.4"
color-eyre = "0.5"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
serde_yaml = "0.8"
strum = { version = "0.21", features = ["derive"] }

View File

@@ -1,6 +1,11 @@
use std::collections::HashMap;
use std::fs::File;
use std::io::BufReader;
use std::ops::Deref;
use std::path::PathBuf;
use color_eyre::eyre::anyhow;
use color_eyre::Result;
use serde::Deserialize;
use serde::Serialize;
@@ -18,6 +23,28 @@ impl Deref for CustomLayout {
}
impl CustomLayout {
pub fn from_path_buf(path: PathBuf) -> Result<Self> {
let invalid_filetype = anyhow!("custom layouts must be json or yaml files");
let layout: Self = match path.extension() {
Some(extension) => {
if extension == "yaml" || extension == "yml" {
serde_yaml::from_reader(BufReader::new(File::open(path)?))?
} else if extension == "json" {
serde_json::from_reader(BufReader::new(File::open(path)?))?
} else {
return Err(invalid_filetype);
}
}
None => return Err(invalid_filetype),
};
if !layout.is_valid() {
return Err(anyhow!("the layout file provided was invalid"));
}
Ok(layout)
}
#[must_use]
pub fn column_with_idx(&self, idx: usize) -> (usize, Option<&Column>) {
let column_idx = self.column_for_container_idx(idx);

View File

@@ -1,6 +1,4 @@
use std::collections::VecDeque;
use std::fs::File;
use std::io::BufReader;
use std::io::ErrorKind;
use std::num::NonZeroUsize;
use std::path::PathBuf;
@@ -1059,11 +1057,8 @@ impl WindowManager {
#[tracing::instrument(skip(self))]
pub fn change_workspace_custom_layout(&mut self, path: PathBuf) -> Result<()> {
tracing::info!("changing layout");
let layout: CustomLayout = serde_json::from_reader(BufReader::new(File::open(path)?))?;
if !layout.is_valid() {
return Err(anyhow!("the layout file provided was invalid"));
}
let layout = CustomLayout::from_path_buf(path)?;
let workspace = self.focused_workspace_mut()?;
match workspace.layout() {
@@ -1182,13 +1177,7 @@ impl WindowManager {
path: PathBuf,
) -> Result<()> {
tracing::info!("setting workspace layout");
let file = File::open(path)?;
let reader = BufReader::new(file);
let layout: CustomLayout = serde_json::from_reader(reader)?;
if !layout.is_valid() {
return Err(anyhow!("the layout file provided was invalid"));
}
let layout = CustomLayout::from_path_buf(path)?;
let invisible_borders = self.invisible_borders;
let offset = self.work_area_offset;
let focused_monitor_idx = self.focused_monitor_idx();

View File

@@ -299,7 +299,7 @@ struct Load {
#[derive(Clap, AhkFunction)]
struct LoadLayout {
/// File from which the custom layout definition should be loaded
/// JSON or YAML file from which the custom layout definition should be loaded
path: String,
}