From 7623e7e692042f4da8525bb1e4ef140831fcdb6a Mon Sep 17 00:00:00 2001 From: elkowar <5300871+elkowar@users.noreply.github.com> Date: Sun, 4 Sep 2022 16:16:37 +0200 Subject: [PATCH] Improve CSS error handling by parsing GTK error output (see #446) --- Cargo.lock | 16 +-- crates/eww/src/app.rs | 41 +++++- crates/eww/src/config/eww_config.rs | 10 +- crates/eww/src/config/scss.rs | 11 +- crates/eww/src/error_handling_ctx.rs | 26 ++-- crates/eww/src/file_database.rs | 131 +++++++++++++++++++ crates/eww/src/main.rs | 1 + crates/eww/src/server.rs | 6 +- crates/eww/src/widgets/widget_definitions.rs | 5 +- crates/yuck/src/config/config.rs | 12 +- crates/yuck/src/config/file_provider.rs | 120 +---------------- crates/yuck/src/config/mod.rs | 2 - crates/yuck/src/config/test.rs | 30 ----- 13 files changed, 213 insertions(+), 198 deletions(-) create mode 100644 crates/eww/src/file_database.rs delete mode 100644 crates/yuck/src/config/test.rs diff --git a/Cargo.lock b/Cargo.lock index d4d9472..ab87125 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15,9 +15,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "0.7.18" +version = "0.7.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e" dependencies = [ "memchr", ] @@ -771,9 +771,9 @@ dependencies = [ [[package]] name = "grass" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34c6284b9a420f456146e1a10e602b82ea251f10b40854bcf04598b7121a3910" +checksum = "bc5bedc3dbd71dcdd41900e1f58e4d431fa69dd67c04ae1f86ae1a0339edd849" dependencies = [ "beef", "clap 2.34.0", @@ -1856,9 +1856,9 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.26.1" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "621609553b14bca49448b3c97e625d7187980cc2a42fd169b4c3b306dcc4a7e9" +checksum = "4ae2421f3e16b3afd4aa692d23b83d0ba42ee9b0081d5deeb7d21428d7195fb1" dependencies = [ "cfg-if", "core-foundation-sys", @@ -2012,9 +2012,9 @@ dependencies = [ [[package]] name = "ucd-trie" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89570599c4fe5585de2b388aab47e99f7fa4e9238a1399f707a02e356058141c" +checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" [[package]] name = "unescape" diff --git a/crates/eww/src/app.rs b/crates/eww/src/app.rs index fe01bac..1f2c937 100644 --- a/crates/eww/src/app.rs +++ b/crates/eww/src/app.rs @@ -9,9 +9,11 @@ use crate::{ *, }; use anyhow::anyhow; -use eww_shared_util::VarName; +use codespan_reporting::files::Files; +use eww_shared_util::{Span, VarName}; use glib::ObjectExt; use itertools::Itertools; +use once_cell::sync::Lazy; use simplexpr::dynval::DynVal; use std::{ cell::RefCell, @@ -26,6 +28,8 @@ use yuck::{ window_definition::WindowDefinition, window_geometry::{AnchorPoint, WindowGeometry}, }, + error::DiagError, + gen_diagnostic, value::Coords, }; @@ -145,9 +149,15 @@ impl App { if let Err(e) = config_result.and_then(|new_config| self.load_config(new_config)) { errors.push(e) } - let css_result = crate::config::scss::parse_scss_from_file(&self.paths.get_eww_scss_path()); - if let Err(e) = css_result.and_then(|css| self.load_css(&css)) { - errors.push(e) + match crate::config::scss::parse_scss_from_file(&self.paths.get_eww_scss_path()) { + Ok((file_id, css)) => { + if let Err(e) = self.load_css(file_id, &css) { + errors.push(anyhow!(e)); + } + } + Err(e) => { + errors.push(e); + } } sender.respond_with_error_list(errors)?; @@ -400,9 +410,26 @@ impl App { Ok(()) } - pub fn load_css(&mut self, css: &str) -> Result<()> { - self.css_provider.load_from_data(css.as_bytes())?; - Ok(()) + /// Load a given CSS string into the gtk css provider, returning a nicely formatted [`DiagError`] when GTK errors out + pub fn load_css(&mut self, file_id: usize, css: &str) -> Result<()> { + if let Err(err) = self.css_provider.load_from_data(css.as_bytes()) { + static PATTERN: Lazy = Lazy::new(|| regex::Regex::new(r"[^:]*:(\d+):(\d+)(.*)$").unwrap()); + let nice_error_option: Option<_> = try { + let captures = PATTERN.captures(&err.message())?; + let line = captures.get(1).unwrap().as_str().parse::().ok()?; + let msg = captures.get(3).unwrap().as_str(); + let db = error_handling_ctx::FILE_DATABASE.read().ok()?; + let line_range = db.line_range(file_id, line - 1).ok()?; + let span = Span(line_range.start, line_range.end - 1, file_id); + DiagError(gen_diagnostic!(msg, span)) + }; + match nice_error_option { + Some(error) => Err(anyhow!(error)), + None => Err(anyhow!("CSS error: {}", err.message())), + } + } else { + Ok(()) + } } } diff --git a/crates/eww/src/config/eww_config.rs b/crates/eww/src/config/eww_config.rs index 90a36db..b7c743c 100644 --- a/crates/eww/src/config/eww_config.rs +++ b/crates/eww/src/config/eww_config.rs @@ -3,8 +3,8 @@ use eww_shared_util::VarName; use std::collections::HashMap; use yuck::{ config::{ - file_provider::YuckFiles, script_var_definition::ScriptVarDefinition, validate::ValidationError, - widget_definition::WidgetDefinition, window_definition::WindowDefinition, Config, + script_var_definition::ScriptVarDefinition, validate::ValidationError, widget_definition::WidgetDefinition, + window_definition::WindowDefinition, Config, }, error::DiagError, format_diagnostic::ToDiagnostic, @@ -12,7 +12,7 @@ use yuck::{ use simplexpr::dynval::DynVal; -use crate::{config::inbuilt, error_handling_ctx, paths::EwwPaths, widgets::widget_definitions}; +use crate::{config::inbuilt, error_handling_ctx, file_database::FileDatabase, paths::EwwPaths, widgets::widget_definitions}; use super::script_var; @@ -20,7 +20,7 @@ use super::script_var; /// resetting and applying the global YuckFiles object in [`crate::error_handling_ctx`]. pub fn read_from_eww_paths(eww_paths: &EwwPaths) -> Result { error_handling_ctx::clear_files(); - EwwConfig::read_from_dir(&mut error_handling_ctx::YUCK_FILES.write().unwrap(), eww_paths) + EwwConfig::read_from_dir(&mut error_handling_ctx::FILE_DATABASE.write().unwrap(), eww_paths) } /// Eww configuration structure. @@ -49,7 +49,7 @@ impl Default for EwwConfig { impl EwwConfig { /// Load an [`EwwConfig`] from the config dir of the given [`crate::EwwPaths`], reading the main config file. - pub fn read_from_dir(files: &mut YuckFiles, eww_paths: &EwwPaths) -> Result { + pub fn read_from_dir(files: &mut FileDatabase, eww_paths: &EwwPaths) -> Result { let yuck_path = eww_paths.get_yuck_path(); if !yuck_path.exists() { bail!("The configuration file `{}` does not exist", yuck_path.display()); diff --git a/crates/eww/src/config/scss.rs b/crates/eww/src/config/scss.rs index 29adb08..4d08ee7 100644 --- a/crates/eww/src/config/scss.rs +++ b/crates/eww/src/config/scss.rs @@ -2,15 +2,20 @@ use std::path::Path; use anyhow::{anyhow, Context}; -use crate::util::replace_env_var_references; +use crate::{error_handling_ctx, util::replace_env_var_references}; /// read an scss file, replace all environment variable references within it and /// then parse it into css. -pub fn parse_scss_from_file(path: &Path) -> anyhow::Result { +/// Also adds the CSS to the [`crate::file_database::FileDatabase`] +pub fn parse_scss_from_file(path: &Path) -> anyhow::Result<(usize, String)> { let config_dir = path.parent().context("Given SCSS file has no parent directory?!")?; let scss_file_content = std::fs::read_to_string(path).with_context(|| format!("Given SCSS-file doesn't exist! {}", path.display()))?; let file_content = replace_env_var_references(scss_file_content); let grass_config = grass::Options::default().load_path(config_dir); - grass::from_string(file_content, &grass_config).map_err(|err| anyhow!("Encountered SCSS parsing error: {}", err)) + let css = grass::from_string(file_content, &grass_config).map_err(|err| anyhow!("SCSS parsing error: {}", err))?; + + let mut file_db = error_handling_ctx::FILE_DATABASE.write().unwrap(); + let file_id = file_db.insert_string(path.display().to_string(), css.clone())?; + Ok((file_id, css)) } diff --git a/crates/eww/src/error_handling_ctx.rs b/crates/eww/src/error_handling_ctx.rs index 2079f3d..6900f88 100644 --- a/crates/eww/src/error_handling_ctx.rs +++ b/crates/eww/src/error_handling_ctx.rs @@ -10,31 +10,23 @@ use codespan_reporting::{ use eww_shared_util::Span; use once_cell::sync::Lazy; use simplexpr::{dynval::ConversionError, eval::EvalError}; -use yuck::{ - config::{file_provider::YuckFiles, validate::ValidationError}, - error::DiagError, - format_diagnostic::ToDiagnostic, -}; +use yuck::{config::validate::ValidationError, error::DiagError, format_diagnostic::ToDiagnostic}; -pub static YUCK_FILES: Lazy>> = Lazy::new(|| Arc::new(RwLock::new(YuckFiles::new()))); +use crate::file_database::FileDatabase; + +pub static FILE_DATABASE: Lazy>> = Lazy::new(|| Arc::new(RwLock::new(FileDatabase::new()))); pub fn clear_files() { - *YUCK_FILES.write().unwrap() = YuckFiles::new(); + *FILE_DATABASE.write().unwrap() = FileDatabase::new(); } pub fn print_error(err: anyhow::Error) { match anyhow_err_to_diagnostic(&err) { Some(diag) => match stringify_diagnostic(diag) { - Ok(diag) => { - eprintln!("{}", diag); - } - Err(_) => { - log::error!("{:?}", err); - } + Ok(diag) => eprintln!("{}", diag), + Err(_) => log::error!("{:?}", err), }, - None => { - log::error!("{:?}", err); - } + None => log::error!("{:?}", err), } } @@ -69,7 +61,7 @@ pub fn stringify_diagnostic(mut diagnostic: codespan_reporting::diagnostic::Diag config.chars.note_bullet = '→'; let mut buf = Vec::new(); let mut writer = term::termcolor::Ansi::new(&mut buf); - let files = YUCK_FILES.read().unwrap(); + let files = FILE_DATABASE.read().unwrap(); term::emit(&mut writer, &config, &*files, &diagnostic)?; Ok(String::from_utf8(buf)?) } diff --git a/crates/eww/src/file_database.rs b/crates/eww/src/file_database.rs new file mode 100644 index 0000000..9d07b93 --- /dev/null +++ b/crates/eww/src/file_database.rs @@ -0,0 +1,131 @@ +use std::collections::HashMap; + +use codespan_reporting::files::Files; +use eww_shared_util::Span; +use yuck::{ + config::file_provider::{FilesError, YuckFileProvider}, + error::DiagError, + parser::ast::Ast, +}; + +#[derive(Debug, Clone, Default)] +pub struct FileDatabase { + files: HashMap, + latest_id: usize, +} + +impl FileDatabase { + pub fn new() -> Self { + Self::default() + } + + fn get_file(&self, id: usize) -> Result<&CodeFile, codespan_reporting::files::Error> { + self.files.get(&id).ok_or(codespan_reporting::files::Error::FileMissing) + } + + fn insert_code_file(&mut self, file: CodeFile) -> usize { + let file_id = self.latest_id; + self.files.insert(file_id, file); + self.latest_id += 1; + file_id + } + + pub fn insert_string(&mut self, name: String, content: String) -> Result { + let line_starts = codespan_reporting::files::line_starts(&content).collect(); + let code_file = CodeFile { name, line_starts, source_len_bytes: content.len(), source: CodeSource::Literal(content) }; + let file_id = self.insert_code_file(code_file); + Ok(file_id) + } +} + +impl YuckFileProvider for FileDatabase { + fn load_yuck_file(&mut self, path: std::path::PathBuf) -> Result<(Span, Vec), FilesError> { + let file_content = std::fs::read_to_string(&path)?; + let line_starts = codespan_reporting::files::line_starts(&file_content).collect(); + let code_file = CodeFile { + name: path.display().to_string(), + line_starts, + source_len_bytes: file_content.len(), + source: CodeSource::File(path), + }; + let file_id = self.insert_code_file(code_file); + Ok(yuck::parser::parse_toplevel(file_id, file_content)?) + } + + fn load_yuck_str(&mut self, name: String, content: String) -> Result<(Span, Vec), DiagError> { + let file_id = self.insert_string(name, content.clone())?; + yuck::parser::parse_toplevel(file_id, content) + } + + fn unload(&mut self, id: usize) { + self.files.remove(&id); + } +} + +impl<'a> Files<'a> for FileDatabase { + type FileId = usize; + type Name = &'a str; + type Source = String; + + fn name(&'a self, id: Self::FileId) -> Result { + Ok(&self.get_file(id)?.name) + } + + fn source(&'a self, id: Self::FileId) -> Result { + self.get_file(id)?.source.read_content().map_err(codespan_reporting::files::Error::Io) + } + + fn line_index(&self, id: Self::FileId, byte_index: usize) -> Result { + Ok(self.get_file(id)?.line_starts.binary_search(&byte_index).unwrap_or_else(|next_line| next_line - 1)) + } + + fn line_range( + &self, + id: Self::FileId, + line_index: usize, + ) -> Result, codespan_reporting::files::Error> { + let file = self.get_file(id)?; + let line_start = file.line_start(line_index)?; + let next_line_start = file.line_start(line_index + 1)?; + Ok(line_start..next_line_start) + } +} + +#[derive(Clone, Debug)] +struct CodeFile { + name: String, + line_starts: Vec, + source: CodeSource, + source_len_bytes: usize, +} + +impl CodeFile { + /// Return the starting byte index of the line with the specified line index. + /// Convenience method that already generates errors if necessary. + fn line_start(&self, line_index: usize) -> Result { + use std::cmp::Ordering; + + match line_index.cmp(&self.line_starts.len()) { + Ordering::Less => Ok(self.line_starts.get(line_index).cloned().expect("failed despite previous check")), + Ordering::Equal => Ok(self.source_len_bytes), + Ordering::Greater => { + Err(codespan_reporting::files::Error::LineTooLarge { given: line_index, max: self.line_starts.len() - 1 }) + } + } + } +} + +#[derive(Clone, Debug)] +enum CodeSource { + File(std::path::PathBuf), + Literal(String), +} + +impl CodeSource { + fn read_content(&self) -> std::io::Result { + match self { + CodeSource::File(path) => Ok(std::fs::read_to_string(path)?), + CodeSource::Literal(x) => Ok(x.to_string()), + } + } +} diff --git a/crates/eww/src/main.rs b/crates/eww/src/main.rs index af36111..8e51a62 100644 --- a/crates/eww/src/main.rs +++ b/crates/eww/src/main.rs @@ -26,6 +26,7 @@ mod config; mod daemon_response; mod display_backend; mod error_handling_ctx; +mod file_database; mod geometry; mod ipc_server; mod opts; diff --git a/crates/eww/src/server.rs b/crates/eww/src/server.rs index b2d7a4d..93a03ba 100644 --- a/crates/eww/src/server.rs +++ b/crates/eww/src/server.rs @@ -83,8 +83,10 @@ pub fn initialize_server(paths: EwwPaths, action: Option, should_ gtk::StyleContext::add_provider_for_screen(&screen, &app.css_provider, gtk::STYLE_PROVIDER_PRIORITY_APPLICATION); } - if let Ok(eww_css) = config::scss::parse_scss_from_file(&app.paths.get_eww_scss_path()) { - app.load_css(&eww_css)?; + if let Ok((file_id, css)) = config::scss::parse_scss_from_file(&app.paths.get_eww_scss_path()) { + if let Err(e) = app.load_css(file_id, &css) { + error_handling_ctx::print_error(e); + } } // initialize all the handlers and tasks running asyncronously diff --git a/crates/eww/src/widgets/widget_definitions.rs b/crates/eww/src/widgets/widget_definitions.rs index 1ee389e..16f1f17 100644 --- a/crates/eww/src/widgets/widget_definitions.rs +++ b/crates/eww/src/widgets/widget_definitions.rs @@ -23,6 +23,7 @@ use std::{ time::Duration, }; use yuck::{ + config::file_provider::YuckFileProvider, error::{DiagError, DiagResult}, format_diagnostic::{span_to_secondary_label, DiagnosticExt}, gen_diagnostic, @@ -868,8 +869,8 @@ fn build_gtk_literal(bargs: &mut BuilderArgs) -> Result { if !content.is_empty() { let content_widget_use: DiagResult<_> = try { let ast = { - let mut yuck_files = error_handling_ctx::YUCK_FILES.write().unwrap(); - let (span, asts) = yuck_files.load_str("".to_string(), content)?; + let mut yuck_files = error_handling_ctx::FILE_DATABASE.write().unwrap(); + let (span, asts) = yuck_files.load_yuck_str("".to_string(), content)?; if let Some(file_id) = literal_file_id.replace(Some(span.2)) { yuck_files.unload(file_id); } diff --git a/crates/yuck/src/config/config.rs b/crates/yuck/src/config/config.rs index fdbef93..6b46b79 100644 --- a/crates/yuck/src/config/config.rs +++ b/crates/yuck/src/config/config.rs @@ -8,7 +8,7 @@ use itertools::Itertools; use simplexpr::SimplExpr; use super::{ - file_provider::{FilesError, YuckFiles}, + file_provider::{FilesError, YuckFileProvider}, script_var_definition::ScriptVarDefinition, validate::ValidationError, var_definition::VarDefinition, @@ -98,7 +98,7 @@ pub struct Config { } impl Config { - fn append_toplevel(&mut self, files: &mut YuckFiles, toplevel: TopLevel) -> DiagResult<()> { + fn append_toplevel(&mut self, files: &mut impl YuckFileProvider, toplevel: TopLevel) -> DiagResult<()> { match toplevel { TopLevel::VarDefinition(x) => { if self.var_definitions.contains_key(&x.name) || self.script_vars.contains_key(&x.name) { @@ -127,7 +127,7 @@ impl Config { self.window_definitions.insert(x.name.clone(), x); } TopLevel::Include(include) => { - let (file_id, toplevels) = files.load_file(PathBuf::from(&include.path)).map_err(|err| match err { + let (file_id, toplevels) = files.load_yuck_file(PathBuf::from(&include.path)).map_err(|err| match err { FilesError::IoError(_) => DiagError(gen_diagnostic! { msg = format!("Included file `{}` not found", include.path), label = include.path_span => "Included here", @@ -142,7 +142,7 @@ impl Config { Ok(()) } - pub fn generate(files: &mut YuckFiles, elements: Vec) -> DiagResult { + pub fn generate(files: &mut impl YuckFileProvider, elements: Vec) -> DiagResult { let mut config = Self { widget_definitions: HashMap::new(), window_definitions: HashMap::new(), @@ -155,8 +155,8 @@ impl Config { Ok(config) } - pub fn generate_from_main_file(files: &mut YuckFiles, path: impl AsRef) -> DiagResult { - let (span, top_levels) = files.load_file(path.as_ref().to_path_buf()).map_err(|err| match err { + pub fn generate_from_main_file(files: &mut impl YuckFileProvider, path: impl AsRef) -> DiagResult { + let (span, top_levels) = files.load_yuck_file(path.as_ref().to_path_buf()).map_err(|err| match err { FilesError::IoError(err) => DiagError(gen_diagnostic!(err)), FilesError::DiagError(x) => x, })?; diff --git a/crates/yuck/src/config/file_provider.rs b/crates/yuck/src/config/file_provider.rs index a24097c..c62e985 100644 --- a/crates/yuck/src/config/file_provider.rs +++ b/crates/yuck/src/config/file_provider.rs @@ -17,120 +17,8 @@ pub enum FilesError { DiagError(#[from] DiagError), } -#[derive(Clone, Debug)] -pub enum YuckSource { - File(std::path::PathBuf), - Literal(String), -} - -impl YuckSource { - pub fn read_content(&self) -> std::io::Result { - match self { - YuckSource::File(path) => Ok(std::fs::read_to_string(path)?), - YuckSource::Literal(x) => Ok(x.to_string()), - } - } -} - -#[derive(Clone, Debug)] -pub struct YuckFile { - name: String, - line_starts: Vec, - source: YuckSource, - source_len_bytes: usize, -} - -impl YuckFile { - /// Return the starting byte index of the line with the specified line index. - /// Convenience method that already generates errors if necessary. - fn line_start(&self, line_index: usize) -> Result { - use std::cmp::Ordering; - - match line_index.cmp(&self.line_starts.len()) { - Ordering::Less => Ok(self.line_starts.get(line_index).cloned().expect("failed despite previous check")), - Ordering::Equal => Ok(self.source_len_bytes), - Ordering::Greater => { - Err(codespan_reporting::files::Error::LineTooLarge { given: line_index, max: self.line_starts.len() - 1 }) - } - } - } -} - -#[derive(Debug, Clone, Default)] -pub struct YuckFiles { - files: HashMap, - latest_id: usize, -} - -impl YuckFiles { - pub fn new() -> Self { - Self::default() - } -} - -impl YuckFiles { - pub fn get_file(&self, id: usize) -> Result<&YuckFile, codespan_reporting::files::Error> { - self.files.get(&id).ok_or(codespan_reporting::files::Error::FileMissing) - } - - fn insert_file(&mut self, file: YuckFile) -> usize { - let file_id = self.latest_id; - self.files.insert(file_id, file); - self.latest_id += 1; - file_id - } - - pub fn load_file(&mut self, path: std::path::PathBuf) -> Result<(Span, Vec), FilesError> { - let file_content = std::fs::read_to_string(&path)?; - let line_starts = codespan_reporting::files::line_starts(&file_content).collect(); - let yuck_file = YuckFile { - name: path.display().to_string(), - line_starts, - source_len_bytes: file_content.len(), - source: YuckSource::File(path), - }; - let file_id = self.insert_file(yuck_file); - Ok(crate::parser::parse_toplevel(file_id, file_content)?) - } - - pub fn load_str(&mut self, name: String, content: String) -> Result<(Span, Vec), DiagError> { - let line_starts = codespan_reporting::files::line_starts(&content).collect(); - let yuck_file = - YuckFile { name, line_starts, source_len_bytes: content.len(), source: YuckSource::Literal(content.to_string()) }; - let file_id = self.insert_file(yuck_file); - crate::parser::parse_toplevel(file_id, content) - } - - pub fn unload(&mut self, id: usize) { - self.files.remove(&id); - } -} - -impl<'a> Files<'a> for YuckFiles { - type FileId = usize; - type Name = &'a str; - type Source = String; - - fn name(&'a self, id: Self::FileId) -> Result { - Ok(&self.get_file(id)?.name) - } - - fn source(&'a self, id: Self::FileId) -> Result { - self.get_file(id)?.source.read_content().map_err(codespan_reporting::files::Error::Io) - } - - fn line_index(&self, id: Self::FileId, byte_index: usize) -> Result { - Ok(self.get_file(id)?.line_starts.binary_search(&byte_index).unwrap_or_else(|next_line| next_line - 1)) - } - - fn line_range( - &self, - id: Self::FileId, - line_index: usize, - ) -> Result, codespan_reporting::files::Error> { - let file = self.get_file(id)?; - let line_start = file.line_start(line_index)?; - let next_line_start = file.line_start(line_index + 1)?; - Ok(line_start..next_line_start) - } +pub trait YuckFileProvider { + fn load_yuck_file(&mut self, path: std::path::PathBuf) -> Result<(Span, Vec), FilesError>; + fn load_yuck_str(&mut self, name: String, content: String) -> Result<(Span, Vec), DiagError>; + fn unload(&mut self, id: usize); } diff --git a/crates/yuck/src/config/mod.rs b/crates/yuck/src/config/mod.rs index 56079b6..5f5070b 100644 --- a/crates/yuck/src/config/mod.rs +++ b/crates/yuck/src/config/mod.rs @@ -4,8 +4,6 @@ pub mod config; pub mod file_provider; pub mod monitor; pub mod script_var_definition; -#[cfg(test)] -mod test; pub mod validate; pub mod var_definition; pub mod widget_definition; diff --git a/crates/yuck/src/config/test.rs b/crates/yuck/src/config/test.rs deleted file mode 100644 index 1af2a61..0000000 --- a/crates/yuck/src/config/test.rs +++ /dev/null @@ -1,30 +0,0 @@ -use crate::{ - config::config::Config, - parser::{self, ast::Ast, from_ast::FromAst, lexer::Lexer}, -}; - -use super::file_provider::YuckFiles; - -#[test] -fn test_config() { - let input = r#" - (defwidget bar [arg arg2] - (foo :arg "hi")) - (defvar some_var "bla") - (defpoll stuff :interval "12s" "date") - (deflisten stuff "tail -f stuff") - (defwindow some-window - :stacking "fg" - :monitor 12 - :resizable true - :geometry (geometry :width "12%" :height "20px") - :reserve (struts :side "left" :distance "30px") - (bar :arg "bla")) - "#; - let mut files = YuckFiles::new(); - let (span, asts) = files.load_str("config.yuck".to_string(), input.to_string()).unwrap(); - let config = Config::generate(&mut files, asts); - insta::with_settings!({sort_maps => true}, { - insta::assert_ron_snapshot!(config.unwrap()); - }); -}