diff --git a/Cargo.lock b/Cargo.lock index ec0be875..0074f993 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1065,6 +1065,17 @@ dependencies = [ "uapi", ] +[[package]] +name = "jay-toml" +version = "0.1.0" +dependencies = [ + "bstr", + "indexmap", + "serde_json", + "thiserror", + "walkdir", +] + [[package]] name = "jay-toml-config" version = "0.12.0" @@ -1075,15 +1086,14 @@ dependencies = [ "indexmap", "jay-config", "jay-config-schema", + "jay-toml", "kbvm", "log", "phf", "run-on-drop", - "serde_json", "simplelog", "thiserror", "uapi", - "walkdir", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index b3c24f84..1e4e89b9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,6 +57,7 @@ members = [ "pango", "libinput", "toml-config", + "toml-parser", "algorithms", "toml-spec", "wire-to-xml", diff --git a/toml-config/Cargo.toml b/toml-config/Cargo.toml index 2752a640..734cf415 100644 --- a/toml-config/Cargo.toml +++ b/toml-config/Cargo.toml @@ -9,6 +9,7 @@ repository = "https://github.com/mahkoh/jay" [dependencies] jay-config = { version = "1.10.0", path = "../jay-config" } jay-config-schema = { version = "0.1.0", path = "../jay-config-schema" } +jay-toml = { version = "0.1.0", path = "../toml-parser" } log = "0.4.14" thiserror = "2.0.11" error_reporter = "1.0.0" @@ -22,5 +23,3 @@ kbvm = "0.1.6" [dev-dependencies] simplelog = { version = "0.12.2", features = ["test"] } -serde_json = "1.0.114" -walkdir = "2.5.0" diff --git a/toml-config/src/config.rs b/toml-config/src/config.rs index 31e43c14..6b82768b 100644 --- a/toml-config/src/config.rs +++ b/toml-config/src/config.rs @@ -5,7 +5,6 @@ mod keycodes; mod parser; mod parsers; mod spanned; -mod value; use { crate::{ @@ -15,7 +14,6 @@ use { config::{ConfigParser, ConfigParserError}, }, }, - toml::{self}, }, ahash::AHashMap, std::{ @@ -23,7 +21,7 @@ use { error::Error, }, thiserror::Error, - toml::toml_parser, + jay_toml::toml_parser, }; pub use jay_config_schema::{ diff --git a/toml-config/src/config/context.rs b/toml-config/src/config/context.rs index 5ffb015c..710fa481 100644 --- a/toml-config/src/config/context.rs +++ b/toml-config/src/config/context.rs @@ -1,7 +1,7 @@ use { crate::{ config::error::SpannedError, - toml::{ + jay_toml::{ toml_parser::{ErrorHandler, ParserError}, toml_span::{Span, Spanned}, }, diff --git a/toml-config/src/config/error.rs b/toml-config/src/config/error.rs index 4c615179..2374ab05 100644 --- a/toml-config/src/config/error.rs +++ b/toml-config/src/config/error.rs @@ -1,5 +1,5 @@ use { - crate::toml::toml_span::Span, + jay_toml::toml_span::Span, bstr::ByteSlice, error_reporter::Report, std::{ diff --git a/toml-config/src/config/extractor.rs b/toml-config/src/config/extractor.rs index 09e5d29c..57d91d74 100644 --- a/toml-config/src/config/extractor.rs +++ b/toml-config/src/config/extractor.rs @@ -1,7 +1,7 @@ use { crate::{ config::context::Context, - toml::{ + jay_toml::{ toml_span::{Span, Spanned, SpannedExt}, toml_value::Value, }, diff --git a/toml-config/src/config/parser.rs b/toml-config/src/config/parser.rs index 53bc3e91..19733c41 100644 --- a/toml-config/src/config/parser.rs +++ b/toml-config/src/config/parser.rs @@ -1,118 +1,3 @@ -use { - crate::toml::{ - toml_span::{Span, Spanned, SpannedExt}, - toml_value::Value, - }, - indexmap::IndexMap, - std::{ - error::Error, - fmt::{self, Display, Formatter}, - }, +pub use jay_toml::value_parser::{ + DataType, ParseResult, Parser, UnexpectedDataType, }; - -#[derive(Copy, Clone, Debug)] -pub enum DataType { - String, - Integer, - Float, - Boolean, - Array, - Table, -} - -impl Display for DataType { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - let s = match self { - DataType::String => "a string", - DataType::Integer => "an integer", - DataType::Float => "a float", - DataType::Boolean => "a bool", - DataType::Array => "an array", - DataType::Table => "a table", - }; - f.write_str(s) - } -} - -pub struct DataTypes(&'static [DataType]); - -impl Display for DataTypes { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - let d = self.0; - match d.len() { - 0 => Ok(()), - 1 => d[0].fmt(f), - 2 => write!(f, "{} or {}", d[0], d[1]), - _ => { - let mut first = true; - #[expect(clippy::needless_range_loop)] - for i in 0..d.len() - 1 { - if !first { - f.write_str(", ")?; - } - first = false; - d[i].fmt(f)?; - } - write!(f, ", or {}", d[d.len() - 1]) - } - } - } -} - -#[derive(Debug)] -pub struct UnexpectedDataType(&'static [DataType], DataType); - -impl Display for UnexpectedDataType { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - write!(f, "Expected {} but found {}", DataTypes(self.0), self.1) - } -} - -impl Error for UnexpectedDataType {} - -pub type ParseResult

= Result<

::Value, Spanned<

::Error>>; - -pub trait Parser { - type Value; - type Error: From; - - const EXPECTED: &'static [DataType]; - - fn parse_string(&mut self, span: Span, string: &str) -> ParseResult { - let _ = string; - expected(self, span, DataType::String) - } - - fn parse_integer(&mut self, span: Span, integer: i64) -> ParseResult { - let _ = integer; - expected(self, span, DataType::Integer) - } - - fn parse_float(&mut self, span: Span, float: f64) -> ParseResult { - let _ = float; - expected(self, span, DataType::Float) - } - - fn parse_bool(&mut self, span: Span, bool: bool) -> ParseResult { - let _ = bool; - expected(self, span, DataType::Boolean) - } - - fn parse_array(&mut self, span: Span, array: &[Spanned]) -> ParseResult { - let _ = array; - expected(self, span, DataType::Array) - } - - fn parse_table( - &mut self, - span: Span, - table: &IndexMap, Spanned>, - ) -> ParseResult { - let _ = table; - expected(self, span, DataType::Table) - } -} - -fn expected(_p: &P, span: Span, actual: DataType) -> ParseResult

{ - Err(P::Error::from(UnexpectedDataType(P::EXPECTED, actual)).spanned(span)) -} diff --git a/toml-config/src/config/parsers.rs b/toml-config/src/config/parsers.rs index f540a8e5..5bea6371 100644 --- a/toml-config/src/config/parsers.rs +++ b/toml-config/src/config/parsers.rs @@ -1,7 +1,7 @@ use { crate::{ config::parser::{DataType, ParseResult, Parser, UnexpectedDataType}, - toml::toml_span::Span, + jay_toml::toml_span::Span, }, thiserror::Error, }; diff --git a/toml-config/src/config/parsers/action.rs b/toml-config/src/config/parsers/action.rs index 4c5cadab..951cc929 100644 --- a/toml-config/src/config/parsers/action.rs +++ b/toml-config/src/config/parsers/action.rs @@ -26,7 +26,7 @@ use { }, spanned::SpannedErrorExt, }, - toml::{ + jay_toml::{ toml_span::{DespanExt, Span, Spanned, SpannedExt}, toml_value::Value, }, diff --git a/toml-config/src/config/parsers/actions.rs b/toml-config/src/config/parsers/actions.rs index 0743b5e7..3958dfa4 100644 --- a/toml-config/src/config/parsers/actions.rs +++ b/toml-config/src/config/parsers/actions.rs @@ -7,7 +7,7 @@ use { parser::{DataType, ParseResult, Parser, UnexpectedDataType}, parsers::action::ActionParser, }, - toml::{ + jay_toml::{ toml_span::{Span, Spanned, SpannedExt}, toml_value::Value, }, diff --git a/toml-config/src/config/parsers/animations.rs b/toml-config/src/config/parsers/animations.rs index cc5cb439..9af8a497 100644 --- a/toml-config/src/config/parsers/animations.rs +++ b/toml-config/src/config/parsers/animations.rs @@ -6,7 +6,7 @@ use { extractor::{Extractor, ExtractorError, bol, n32, opt, recover, str, val}, parser::{DataType, ParseResult, Parser, UnexpectedDataType}, }, - toml::{ + jay_toml::{ toml_span::{DespanExt, Span, Spanned, SpannedExt}, toml_value::Value, }, diff --git a/toml-config/src/config/parsers/clean_logs_older_than.rs b/toml-config/src/config/parsers/clean_logs_older_than.rs index 0c3bb4a7..c81324f3 100644 --- a/toml-config/src/config/parsers/clean_logs_older_than.rs +++ b/toml-config/src/config/parsers/clean_logs_older_than.rs @@ -5,7 +5,7 @@ use { extractor::{Extractor, ExtractorError, fltorint, opt}, parser::{DataType, ParseResult, Parser, UnexpectedDataType}, }, - toml::{ + jay_toml::{ toml_span::{DespanExt, Span, Spanned, SpannedExt}, toml_value::Value, }, diff --git a/toml-config/src/config/parsers/client_match.rs b/toml-config/src/config/parsers/client_match.rs index 2941bad7..1d8050c2 100644 --- a/toml-config/src/config/parsers/client_match.rs +++ b/toml-config/src/config/parsers/client_match.rs @@ -6,7 +6,7 @@ use { extractor::{Extractor, ExtractorError, arr, bol, n32, opt, s32, str, val}, parser::{DataType, ParseResult, Parser, UnexpectedDataType}, }, - toml::{ + jay_toml::{ toml_span::{DespanExt, Span, Spanned}, toml_value::Value, }, diff --git a/toml-config/src/config/parsers/client_rule.rs b/toml-config/src/config/parsers/client_rule.rs index 50bf7f0d..239b1a75 100644 --- a/toml-config/src/config/parsers/client_rule.rs +++ b/toml-config/src/config/parsers/client_rule.rs @@ -11,7 +11,7 @@ use { }, spanned::SpannedErrorExt, }, - toml::{ + jay_toml::{ toml_span::{DespanExt, Span, Spanned}, toml_value::Value, }, diff --git a/toml-config/src/config/parsers/color.rs b/toml-config/src/config/parsers/color.rs index 25073b20..96edb5ab 100644 --- a/toml-config/src/config/parsers/color.rs +++ b/toml-config/src/config/parsers/color.rs @@ -4,7 +4,7 @@ use { extractor::ExtractorError, parser::{DataType, ParseResult, Parser, UnexpectedDataType}, }, - toml::toml_span::{Span, SpannedExt}, + jay_toml::toml_span::{Span, SpannedExt}, }, jay_config::theme::Color, std::{num::ParseIntError, ops::Range}, diff --git a/toml-config/src/config/parsers/color_management.rs b/toml-config/src/config/parsers/color_management.rs index fc49bb5a..1857a376 100644 --- a/toml-config/src/config/parsers/color_management.rs +++ b/toml-config/src/config/parsers/color_management.rs @@ -6,7 +6,7 @@ use { extractor::{Extractor, ExtractorError, bol, opt}, parser::{DataType, ParseResult, Parser, UnexpectedDataType}, }, - toml::{ + jay_toml::{ toml_span::{DespanExt, Span, Spanned}, toml_value::Value, }, diff --git a/toml-config/src/config/parsers/config.rs b/toml-config/src/config/parsers/config.rs index 5b96e27c..0932a410 100644 --- a/toml-config/src/config/parsers/config.rs +++ b/toml-config/src/config/parsers/config.rs @@ -44,7 +44,7 @@ use { }, spanned::SpannedErrorExt, }, - toml::{ + jay_toml::{ toml_span::{DespanExt, Span, Spanned}, toml_value::Value, }, diff --git a/toml-config/src/config/parsers/connector.rs b/toml-config/src/config/parsers/connector.rs index c1618221..5545a4b7 100644 --- a/toml-config/src/config/parsers/connector.rs +++ b/toml-config/src/config/parsers/connector.rs @@ -7,7 +7,7 @@ use { parser::{DataType, ParseResult, Parser, UnexpectedDataType}, parsers::connector_match::{ConnectorMatchParser, ConnectorMatchParserError}, }, - toml::{ + jay_toml::{ toml_span::{DespanExt, Span, Spanned}, toml_value::Value, }, diff --git a/toml-config/src/config/parsers/connector_match.rs b/toml-config/src/config/parsers/connector_match.rs index b9eb4e9b..ac8d8c83 100644 --- a/toml-config/src/config/parsers/connector_match.rs +++ b/toml-config/src/config/parsers/connector_match.rs @@ -6,7 +6,7 @@ use { extractor::{Extractor, ExtractorError, opt, str}, parser::{DataType, ParseResult, Parser, UnexpectedDataType}, }, - toml::{ + jay_toml::{ toml_span::{Span, Spanned}, toml_value::Value, }, diff --git a/toml-config/src/config/parsers/content_type.rs b/toml-config/src/config/parsers/content_type.rs index c7038bbf..c0af74b1 100644 --- a/toml-config/src/config/parsers/content_type.rs +++ b/toml-config/src/config/parsers/content_type.rs @@ -1,7 +1,7 @@ use { crate::{ config::parser::{DataType, ParseResult, Parser, UnexpectedDataType}, - toml::{ + jay_toml::{ toml_span::{Span, Spanned, SpannedExt}, toml_value::Value, }, diff --git a/toml-config/src/config/parsers/drm_device.rs b/toml-config/src/config/parsers/drm_device.rs index d2030adf..6de886b4 100644 --- a/toml-config/src/config/parsers/drm_device.rs +++ b/toml-config/src/config/parsers/drm_device.rs @@ -10,7 +10,7 @@ use { gfx_api::GfxApiParser, }, }, - toml::{ + jay_toml::{ toml_span::{DespanExt, Span, Spanned}, toml_value::Value, }, diff --git a/toml-config/src/config/parsers/drm_device_match.rs b/toml-config/src/config/parsers/drm_device_match.rs index 3b0aeac7..7d50b67f 100644 --- a/toml-config/src/config/parsers/drm_device_match.rs +++ b/toml-config/src/config/parsers/drm_device_match.rs @@ -6,7 +6,7 @@ use { extractor::{Extractor, ExtractorError, n32, opt, recover, str}, parser::{DataType, ParseResult, Parser, UnexpectedDataType}, }, - toml::{ + jay_toml::{ toml_span::{DespanExt, Span, Spanned}, toml_value::Value, }, diff --git a/toml-config/src/config/parsers/env.rs b/toml-config/src/config/parsers/env.rs index a2a0f9ae..4c80e917 100644 --- a/toml-config/src/config/parsers/env.rs +++ b/toml-config/src/config/parsers/env.rs @@ -4,7 +4,7 @@ use { parser::{DataType, ParseResult, Parser, UnexpectedDataType}, parsers::{StringParser, StringParserError}, }, - toml::{ + jay_toml::{ toml_span::{Span, Spanned}, toml_value::Value, }, diff --git a/toml-config/src/config/parsers/exec.rs b/toml-config/src/config/parsers/exec.rs index aee577ac..09473de3 100644 --- a/toml-config/src/config/parsers/exec.rs +++ b/toml-config/src/config/parsers/exec.rs @@ -10,7 +10,7 @@ use { env::{EnvParser, EnvParserError}, }, }, - toml::{ + jay_toml::{ toml_span::{Span, Spanned, SpannedExt}, toml_value::Value, }, diff --git a/toml-config/src/config/parsers/fallback_output_mode.rs b/toml-config/src/config/parsers/fallback_output_mode.rs index 3918a5db..91381b38 100644 --- a/toml-config/src/config/parsers/fallback_output_mode.rs +++ b/toml-config/src/config/parsers/fallback_output_mode.rs @@ -1,7 +1,7 @@ use { crate::{ config::parser::{DataType, ParseResult, Parser, UnexpectedDataType}, - toml::toml_span::{Span, SpannedExt}, + jay_toml::toml_span::{Span, SpannedExt}, }, jay_config::input::FallbackOutputMode, thiserror::Error, diff --git a/toml-config/src/config/parsers/float.rs b/toml-config/src/config/parsers/float.rs index e31c981e..f09c1189 100644 --- a/toml-config/src/config/parsers/float.rs +++ b/toml-config/src/config/parsers/float.rs @@ -6,7 +6,7 @@ use { extractor::{Extractor, ExtractorError, bol, opt, recover}, parser::{DataType, ParseResult, Parser, UnexpectedDataType}, }, - toml::{ + jay_toml::{ toml_span::{DespanExt, Span, Spanned}, toml_value::Value, }, diff --git a/toml-config/src/config/parsers/focus_history.rs b/toml-config/src/config/parsers/focus_history.rs index 04c84a5d..15340512 100644 --- a/toml-config/src/config/parsers/focus_history.rs +++ b/toml-config/src/config/parsers/focus_history.rs @@ -6,7 +6,7 @@ use { extractor::{Extractor, ExtractorError, bol, opt, recover}, parser::{DataType, ParseResult, Parser, UnexpectedDataType}, }, - toml::{ + jay_toml::{ toml_span::{DespanExt, Span, Spanned}, toml_value::Value, }, diff --git a/toml-config/src/config/parsers/format.rs b/toml-config/src/config/parsers/format.rs index 7755b555..d9aaf31d 100644 --- a/toml-config/src/config/parsers/format.rs +++ b/toml-config/src/config/parsers/format.rs @@ -1,7 +1,7 @@ use { crate::{ config::parser::{DataType, ParseResult, Parser, UnexpectedDataType}, - toml::toml_span::{Span, SpannedExt}, + jay_toml::toml_span::{Span, SpannedExt}, }, jay_config::video::Format, thiserror::Error, diff --git a/toml-config/src/config/parsers/gfx_api.rs b/toml-config/src/config/parsers/gfx_api.rs index 69bb6740..b7e75122 100644 --- a/toml-config/src/config/parsers/gfx_api.rs +++ b/toml-config/src/config/parsers/gfx_api.rs @@ -1,7 +1,7 @@ use { crate::{ config::parser::{DataType, ParseResult, Parser, UnexpectedDataType}, - toml::toml_span::{Span, SpannedExt}, + jay_toml::toml_span::{Span, SpannedExt}, }, jay_config::video::GfxApi, thiserror::Error, diff --git a/toml-config/src/config/parsers/idle.rs b/toml-config/src/config/parsers/idle.rs index 5da15f8b..16bb128a 100644 --- a/toml-config/src/config/parsers/idle.rs +++ b/toml-config/src/config/parsers/idle.rs @@ -5,7 +5,7 @@ use { extractor::{Extractor, ExtractorError, bol, n64, opt, recover, val}, parser::{DataType, ParseResult, Parser, UnexpectedDataType}, }, - toml::{ + jay_toml::{ toml_span::{DespanExt, Span, Spanned}, toml_value::Value, }, diff --git a/toml-config/src/config/parsers/input.rs b/toml-config/src/config/parsers/input.rs index 2b4115a3..e810b638 100644 --- a/toml-config/src/config/parsers/input.rs +++ b/toml-config/src/config/parsers/input.rs @@ -12,7 +12,7 @@ use { output_match::OutputMatchParser, }, }, - toml::{ + jay_toml::{ toml_span::{DespanExt, Span, Spanned, SpannedExt}, toml_value::Value, }, diff --git a/toml-config/src/config/parsers/input_match.rs b/toml-config/src/config/parsers/input_match.rs index 0d534cea..9a0998df 100644 --- a/toml-config/src/config/parsers/input_match.rs +++ b/toml-config/src/config/parsers/input_match.rs @@ -6,7 +6,7 @@ use { extractor::{Extractor, ExtractorError, bol, opt, str}, parser::{DataType, ParseResult, Parser, UnexpectedDataType}, }, - toml::{ + jay_toml::{ toml_span::{DespanExt, Span, Spanned}, toml_value::Value, }, diff --git a/toml-config/src/config/parsers/input_mode.rs b/toml-config/src/config/parsers/input_mode.rs index 035e9c47..fa053912 100644 --- a/toml-config/src/config/parsers/input_mode.rs +++ b/toml-config/src/config/parsers/input_mode.rs @@ -8,7 +8,7 @@ use { parsers::shortcuts::{ComplexShortcutsParser, ShortcutsParser, ShortcutsParserError}, spanned::SpannedErrorExt, }, - toml::{ + jay_toml::{ toml_span::{DespanExt, Span, Spanned}, toml_value::Value, }, diff --git a/toml-config/src/config/parsers/keymap.rs b/toml-config/src/config/parsers/keymap.rs index ea4afc66..16276b92 100644 --- a/toml-config/src/config/parsers/keymap.rs +++ b/toml-config/src/config/parsers/keymap.rs @@ -6,7 +6,7 @@ use { extractor::{Extractor, ExtractorError, opt, str, val}, parser::{DataType, ParseResult, Parser, UnexpectedDataType}, }, - toml::{ + jay_toml::{ toml_span::{DespanExt, Span, Spanned, SpannedExt}, toml_value::Value, }, diff --git a/toml-config/src/config/parsers/libei.rs b/toml-config/src/config/parsers/libei.rs index 47fd825f..9be10fc0 100644 --- a/toml-config/src/config/parsers/libei.rs +++ b/toml-config/src/config/parsers/libei.rs @@ -6,7 +6,7 @@ use { extractor::{Extractor, ExtractorError, bol, opt, recover}, parser::{DataType, ParseResult, Parser, UnexpectedDataType}, }, - toml::{ + jay_toml::{ toml_span::{DespanExt, Span, Spanned}, toml_value::Value, }, diff --git a/toml-config/src/config/parsers/log_level.rs b/toml-config/src/config/parsers/log_level.rs index 73209d1b..5c23030e 100644 --- a/toml-config/src/config/parsers/log_level.rs +++ b/toml-config/src/config/parsers/log_level.rs @@ -1,7 +1,7 @@ use { crate::{ config::parser::{DataType, ParseResult, Parser, UnexpectedDataType}, - toml::toml_span::{Span, SpannedExt}, + jay_toml::toml_span::{Span, SpannedExt}, }, jay_config::logging::LogLevel, thiserror::Error, diff --git a/toml-config/src/config/parsers/mark_id.rs b/toml-config/src/config/parsers/mark_id.rs index e3dc0688..cb6ece68 100644 --- a/toml-config/src/config/parsers/mark_id.rs +++ b/toml-config/src/config/parsers/mark_id.rs @@ -6,7 +6,7 @@ use { keycodes::KEYCODES, parser::{DataType, ParseResult, Parser, UnexpectedDataType}, }, - toml::{ + jay_toml::{ toml_span::{Span, Spanned, SpannedExt}, toml_value::Value, }, diff --git a/toml-config/src/config/parsers/mode.rs b/toml-config/src/config/parsers/mode.rs index 5a64d9ae..31c108e2 100644 --- a/toml-config/src/config/parsers/mode.rs +++ b/toml-config/src/config/parsers/mode.rs @@ -6,7 +6,7 @@ use { extractor::{Extractor, ExtractorError, fltorint, opt, s32}, parser::{DataType, ParseResult, Parser, UnexpectedDataType}, }, - toml::{ + jay_toml::{ toml_span::{DespanExt, Span, Spanned}, toml_value::Value, }, diff --git a/toml-config/src/config/parsers/modified_keysym.rs b/toml-config/src/config/parsers/modified_keysym.rs index 102a1c22..a693557a 100644 --- a/toml-config/src/config/parsers/modified_keysym.rs +++ b/toml-config/src/config/parsers/modified_keysym.rs @@ -1,7 +1,7 @@ use { crate::{ config::parser::{DataType, ParseResult, Parser, UnexpectedDataType}, - toml::toml_span::{Span, SpannedExt}, + jay_toml::toml_span::{Span, SpannedExt}, }, jay_config::keyboard::{ ModifiedKeySym, diff --git a/toml-config/src/config/parsers/output.rs b/toml-config/src/config/parsers/output.rs index 120bfe25..0ecfef9f 100644 --- a/toml-config/src/config/parsers/output.rs +++ b/toml-config/src/config/parsers/output.rs @@ -13,7 +13,7 @@ use { vrr::VrrParser, }, }, - toml::{ + jay_toml::{ toml_span::{DespanExt, Span, Spanned, SpannedExt}, toml_value::Value, }, diff --git a/toml-config/src/config/parsers/output_match.rs b/toml-config/src/config/parsers/output_match.rs index 4af292f2..4af59515 100644 --- a/toml-config/src/config/parsers/output_match.rs +++ b/toml-config/src/config/parsers/output_match.rs @@ -6,7 +6,7 @@ use { extractor::{Extractor, ExtractorError, opt, str}, parser::{DataType, ParseResult, Parser, UnexpectedDataType}, }, - toml::{ + jay_toml::{ toml_span::{DespanExt, Span, Spanned}, toml_value::Value, }, diff --git a/toml-config/src/config/parsers/repeat_rate.rs b/toml-config/src/config/parsers/repeat_rate.rs index 4374d853..f6658299 100644 --- a/toml-config/src/config/parsers/repeat_rate.rs +++ b/toml-config/src/config/parsers/repeat_rate.rs @@ -6,7 +6,7 @@ use { extractor::{Extractor, ExtractorError, s32}, parser::{DataType, ParseResult, Parser, UnexpectedDataType}, }, - toml::{ + jay_toml::{ toml_span::{Span, Spanned}, toml_value::Value, }, diff --git a/toml-config/src/config/parsers/shortcuts.rs b/toml-config/src/config/parsers/shortcuts.rs index 46e71813..540d8e96 100644 --- a/toml-config/src/config/parsers/shortcuts.rs +++ b/toml-config/src/config/parsers/shortcuts.rs @@ -13,7 +13,7 @@ use { }, spanned::SpannedErrorExt, }, - toml::{ + jay_toml::{ toml_span::{Span, Spanned, SpannedExt}, toml_value::Value, }, diff --git a/toml-config/src/config/parsers/simple_im.rs b/toml-config/src/config/parsers/simple_im.rs index b4c08095..f1a69f61 100644 --- a/toml-config/src/config/parsers/simple_im.rs +++ b/toml-config/src/config/parsers/simple_im.rs @@ -6,7 +6,7 @@ use { extractor::{Extractor, ExtractorError, bol, opt, recover}, parser::{DataType, ParseResult, Parser, UnexpectedDataType}, }, - toml::{ + jay_toml::{ toml_span::{DespanExt, Span, Spanned}, toml_value::Value, }, diff --git a/toml-config/src/config/parsers/status.rs b/toml-config/src/config/parsers/status.rs index 77e3aa72..77cf08f1 100644 --- a/toml-config/src/config/parsers/status.rs +++ b/toml-config/src/config/parsers/status.rs @@ -7,7 +7,7 @@ use { parser::{DataType, ParseResult, Parser, UnexpectedDataType}, parsers::exec::{ExecParser, ExecParserError}, }, - toml::{ + jay_toml::{ toml_span::{Span, Spanned, SpannedExt}, toml_value::Value, }, diff --git a/toml-config/src/config/parsers/tearing.rs b/toml-config/src/config/parsers/tearing.rs index 7e6061bc..7e0c96bb 100644 --- a/toml-config/src/config/parsers/tearing.rs +++ b/toml-config/src/config/parsers/tearing.rs @@ -6,7 +6,7 @@ use { extractor::{Extractor, ExtractorError, opt, val}, parser::{DataType, ParseResult, Parser, UnexpectedDataType}, }, - toml::{ + jay_toml::{ toml_span::{Span, Spanned, SpannedExt}, toml_value::Value, }, diff --git a/toml-config/src/config/parsers/theme.rs b/toml-config/src/config/parsers/theme.rs index c67fa744..4a2e05c0 100644 --- a/toml-config/src/config/parsers/theme.rs +++ b/toml-config/src/config/parsers/theme.rs @@ -7,7 +7,7 @@ use { parser::{DataType, ParseResult, Parser, UnexpectedDataType}, parsers::color::ColorParser, }, - toml::{ + jay_toml::{ toml_span::{DespanExt, Span, Spanned}, toml_value::Value, }, diff --git a/toml-config/src/config/parsers/tile_state.rs b/toml-config/src/config/parsers/tile_state.rs index de9d30eb..0634c840 100644 --- a/toml-config/src/config/parsers/tile_state.rs +++ b/toml-config/src/config/parsers/tile_state.rs @@ -1,7 +1,7 @@ use { crate::{ config::parser::{DataType, ParseResult, Parser, UnexpectedDataType}, - toml::toml_span::{Span, SpannedExt}, + jay_toml::toml_span::{Span, SpannedExt}, }, jay_config::window::TileState, thiserror::Error, diff --git a/toml-config/src/config/parsers/ui_drag.rs b/toml-config/src/config/parsers/ui_drag.rs index aff14805..6749b4ed 100644 --- a/toml-config/src/config/parsers/ui_drag.rs +++ b/toml-config/src/config/parsers/ui_drag.rs @@ -7,7 +7,7 @@ use { parser::{DataType, ParseResult, Parser, UnexpectedDataType}, parsers::exec::ExecParserError, }, - toml::{ + jay_toml::{ toml_span::{DespanExt, Span, Spanned}, toml_value::Value, }, diff --git a/toml-config/src/config/parsers/vrr.rs b/toml-config/src/config/parsers/vrr.rs index f2f2322a..224225c8 100644 --- a/toml-config/src/config/parsers/vrr.rs +++ b/toml-config/src/config/parsers/vrr.rs @@ -6,7 +6,7 @@ use { extractor::{Extractor, ExtractorError, opt, val}, parser::{DataType, ParseResult, Parser, UnexpectedDataType}, }, - toml::{ + jay_toml::{ toml_span::{Span, Spanned, SpannedExt}, toml_value::Value, }, diff --git a/toml-config/src/config/parsers/window_match.rs b/toml-config/src/config/parsers/window_match.rs index a2c11305..d6a911d6 100644 --- a/toml-config/src/config/parsers/window_match.rs +++ b/toml-config/src/config/parsers/window_match.rs @@ -11,7 +11,7 @@ use { window_type::{WindowTypeParser, WindowTypeParserError}, }, }, - toml::{ + jay_toml::{ toml_span::{DespanExt, Span, Spanned}, toml_value::Value, }, diff --git a/toml-config/src/config/parsers/window_rule.rs b/toml-config/src/config/parsers/window_rule.rs index 5311641c..b25b632a 100644 --- a/toml-config/src/config/parsers/window_rule.rs +++ b/toml-config/src/config/parsers/window_rule.rs @@ -12,7 +12,7 @@ use { }, spanned::SpannedErrorExt, }, - toml::{ + jay_toml::{ toml_span::{DespanExt, Span, Spanned}, toml_value::Value, }, diff --git a/toml-config/src/config/parsers/window_type.rs b/toml-config/src/config/parsers/window_type.rs index 388fe317..39363069 100644 --- a/toml-config/src/config/parsers/window_type.rs +++ b/toml-config/src/config/parsers/window_type.rs @@ -1,7 +1,7 @@ use { crate::{ config::parser::{DataType, ParseResult, Parser, UnexpectedDataType}, - toml::{ + jay_toml::{ toml_span::{Span, Spanned, SpannedExt}, toml_value::Value, }, diff --git a/toml-config/src/config/parsers/workspace_display_order.rs b/toml-config/src/config/parsers/workspace_display_order.rs index 749cff2d..2b69c0ac 100644 --- a/toml-config/src/config/parsers/workspace_display_order.rs +++ b/toml-config/src/config/parsers/workspace_display_order.rs @@ -1,7 +1,7 @@ use { crate::{ config::parser::{DataType, ParseResult, Parser, UnexpectedDataType}, - toml::toml_span::{Span, SpannedExt}, + jay_toml::toml_span::{Span, SpannedExt}, }, jay_config::workspace::WorkspaceDisplayOrder, thiserror::Error, diff --git a/toml-config/src/config/parsers/xwayland.rs b/toml-config/src/config/parsers/xwayland.rs index c6420334..9998dd5d 100644 --- a/toml-config/src/config/parsers/xwayland.rs +++ b/toml-config/src/config/parsers/xwayland.rs @@ -6,7 +6,7 @@ use { extractor::{Extractor, ExtractorError, bol, opt, recover, val}, parser::{DataType, ParseResult, Parser, UnexpectedDataType}, }, - toml::{ + jay_toml::{ toml_span::{DespanExt, Span, Spanned, SpannedExt}, toml_value::Value, }, diff --git a/toml-config/src/config/spanned.rs b/toml-config/src/config/spanned.rs index a88282c7..bb4db6ef 100644 --- a/toml-config/src/config/spanned.rs +++ b/toml-config/src/config/spanned.rs @@ -1,63 +1 @@ -use crate::{ - config::parser::{ParseResult, Parser}, - toml::{toml_span::Spanned, toml_value::Value}, -}; - -impl Spanned<&Value> { - pub fn parse(&self, parser: &mut P) -> ParseResult

{ - self.value.parse(self.span, parser) - } - - pub fn parse_map( - &self, - parser: &mut P, - ) -> Result<

::Value, Spanned> - where -

::Error: Into, - { - self.parse(parser).map_spanned_err(|e| e.into()) - } -} - -impl Spanned { - pub fn parse(&self, parser: &mut P) -> ParseResult

{ - self.as_ref().parse(parser) - } - - pub fn parse_map( - &self, - parser: &mut P, - ) -> Result<

::Value, Spanned> - where -

::Error: Into, - { - self.as_ref().parse_map(parser) - } -} - -pub trait SpannedErrorExt { - type T; - type E; - - fn map_spanned_err(self, f: F) -> Result> - where - F: FnOnce(Self::E) -> U; -} - -impl SpannedErrorExt for Result> { - type T = T; - type E = E; - - fn map_spanned_err(self, f: F) -> Result> - where - F: FnOnce(Self::E) -> U, - { - match self { - Ok(v) => Ok(v), - Err(e) => Err(Spanned { - span: e.span, - value: f(e.value), - }), - } - } -} +pub use jay_toml::SpannedErrorExt; diff --git a/toml-config/src/lib.rs b/toml-config/src/lib.rs index 67586416..86b411fe 100644 --- a/toml-config/src/lib.rs +++ b/toml-config/src/lib.rs @@ -8,7 +8,8 @@ mod config; mod rules; mod shortcuts; -mod toml; + +pub(crate) use jay_toml; use { crate::{ diff --git a/toml-parser/Cargo.toml b/toml-parser/Cargo.toml new file mode 100644 index 00000000..e8f98acc --- /dev/null +++ b/toml-parser/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "jay-toml" +version = "0.1.0" +edition = "2024" +license = "GPL-3.0-only" +description = "Internal TOML parser used by Jay" +repository = "https://github.com/mahkoh/jay" + +[dependencies] +bstr = { version = "1.9.1", default-features = false } +indexmap = "2.2.5" +thiserror = "2.0.11" + +[dev-dependencies] +serde_json = "1.0.114" +walkdir = "2.5.0" diff --git a/toml-config/src/toml.rs b/toml-parser/src/lib.rs similarity index 51% rename from toml-config/src/toml.rs rename to toml-parser/src/lib.rs index 8c2ce876..045b62d1 100644 --- a/toml-config/src/toml.rs +++ b/toml-parser/src/lib.rs @@ -1,6 +1,11 @@ +mod spanned_ext; #[cfg(test)] mod tests; mod toml_lexer; pub mod toml_parser; pub mod toml_span; pub mod toml_value; +mod value_ext; +pub mod value_parser; + +pub use spanned_ext::SpannedErrorExt; diff --git a/toml-parser/src/spanned_ext.rs b/toml-parser/src/spanned_ext.rs new file mode 100644 index 00000000..40886a0a --- /dev/null +++ b/toml-parser/src/spanned_ext.rs @@ -0,0 +1,64 @@ +use crate::{ + toml_span::Spanned, + toml_value::Value, + value_parser::{ParseResult, Parser}, +}; + +impl Spanned<&Value> { + pub fn parse(&self, parser: &mut P) -> ParseResult

{ + self.value.parse(self.span, parser) + } + + pub fn parse_map( + &self, + parser: &mut P, + ) -> Result<

::Value, Spanned> + where +

::Error: Into, + { + self.parse(parser).map_spanned_err(|e| e.into()) + } +} + +impl Spanned { + pub fn parse(&self, parser: &mut P) -> ParseResult

{ + self.as_ref().parse(parser) + } + + pub fn parse_map( + &self, + parser: &mut P, + ) -> Result<

::Value, Spanned> + where +

::Error: Into, + { + self.as_ref().parse_map(parser) + } +} + +pub trait SpannedErrorExt { + type T; + type E; + + fn map_spanned_err(self, f: F) -> Result> + where + F: FnOnce(Self::E) -> U; +} + +impl SpannedErrorExt for Result> { + type T = T; + type E = E; + + fn map_spanned_err(self, f: F) -> Result> + where + F: FnOnce(Self::E) -> U, + { + match self { + Ok(v) => Ok(v), + Err(e) => Err(Spanned { + span: e.span, + value: f(e.value), + }), + } + } +} diff --git a/toml-config/src/toml/tests.rs b/toml-parser/src/tests.rs similarity index 77% rename from toml-config/src/toml/tests.rs rename to toml-parser/src/tests.rs index 0cb76e36..4f62d112 100644 --- a/toml-config/src/toml/tests.rs +++ b/toml-parser/src/tests.rs @@ -1,15 +1,11 @@ use { crate::{ - config::error::SpannedError, - toml::{ - toml_parser::{ErrorHandler, ParserError, parse}, - toml_span::{Span, Spanned, SpannedExt}, - toml_value::Value, - }, + toml_parser::{ErrorHandler, ParserError, parse}, + toml_span::{Span, Spanned, SpannedExt}, + toml_value::Value, }, bstr::{BStr, ByteSlice}, std::{ - convert::Infallible, os::unix::ffi::OsStrExt, panic::{AssertUnwindSafe, catch_unwind}, str::FromStr, @@ -21,7 +17,15 @@ use { fn test() { let mut have_failures = false; let mut num = 0; - for path in WalkDir::new("./toml-test/tests/valid") { + let tests = std::path::Path::new(concat!( + env!("CARGO_MANIFEST_DIR"), + "/../toml-config/toml-test/tests/valid" + )); + if !tests.exists() { + eprintln!("skipping TOML conformance tests because fixtures are not present"); + return; + } + for path in WalkDir::new(tests) { let path = path.unwrap(); if let Some(prefix) = path.path().as_os_str().as_bytes().strip_suffix(b".toml") { num += 1; @@ -45,11 +49,11 @@ fn run_test(prefix: &BStr) -> bool { let json: serde_json::Value = serde_json::from_str(&json).unwrap(); let json_as_toml = json_to_value(json); - let toml = match parse(toml.as_bytes(), &NoErrorHandler(prefix, &toml)) { + let toml = match parse(toml.as_bytes(), &NoErrorHandler(prefix)) { Ok(t) => t, Err(e) => { eprintln!("toml could not be parsed in test {}", prefix); - NoErrorHandler(prefix, &toml).handle(e); + NoErrorHandler(prefix).handle(e); return true; } }; @@ -95,18 +99,14 @@ fn json_to_value(json: serde_json::Value) -> Spanned { val.spanned(span) } -struct NoErrorHandler<'a>(&'a BStr, &'a [u8]); +struct NoErrorHandler<'a>(&'a BStr); impl<'a> ErrorHandler for NoErrorHandler<'a> { fn handle(&self, err: Spanned) { eprintln!( "{}: An error occurred during validation: {}", self.0, - SpannedError { - input: self.1.into(), - span: err.span, - cause: Some(err.value), - } + FormatError(err.span, Some(err.value)), ); } @@ -114,20 +114,23 @@ impl<'a> ErrorHandler for NoErrorHandler<'a> { eprintln!( "{}: Redefinition: {}", self.0, - SpannedError { - input: self.1.into(), - span: err.span, - cause: Some(err.value), - } + FormatError(err.span, Some(err.value)), ); eprintln!( "{}: Previous: {}", self.0, - SpannedError { - input: self.1.into(), - span: prev, - cause: None::, - } + FormatError(prev, None), ); } } + +struct FormatError(Span, Option); + +impl std::fmt::Display for FormatError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(cause) = &self.1 { + write!(f, "{cause}: ")?; + } + write!(f, "span {}..{}", self.0.lo, self.0.hi) + } +} diff --git a/toml-config/src/toml/toml_lexer.rs b/toml-parser/src/toml_lexer.rs similarity index 99% rename from toml-config/src/toml/toml_lexer.rs rename to toml-parser/src/toml_lexer.rs index 7e3d90b8..d59d5f43 100644 --- a/toml-config/src/toml/toml_lexer.rs +++ b/toml-parser/src/toml_lexer.rs @@ -1,4 +1,4 @@ -use crate::toml::toml_span::{Span, Spanned, SpannedExt}; +use crate::toml_span::{Span, Spanned, SpannedExt}; #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum Token<'a> { diff --git a/toml-config/src/toml/toml_parser.rs b/toml-parser/src/toml_parser.rs similarity index 99% rename from toml-config/src/toml/toml_parser.rs rename to toml-parser/src/toml_parser.rs index 0ce75eba..5020d425 100644 --- a/toml-config/src/toml/toml_parser.rs +++ b/toml-parser/src/toml_parser.rs @@ -1,5 +1,5 @@ use { - crate::toml::{ + crate::{ toml_lexer::{Lexer, Token}, toml_span::{Span, Spanned, SpannedExt}, toml_value::Value, diff --git a/toml-config/src/toml/toml_span.rs b/toml-parser/src/toml_span.rs similarity index 100% rename from toml-config/src/toml/toml_span.rs rename to toml-parser/src/toml_span.rs diff --git a/toml-config/src/toml/toml_value.rs b/toml-parser/src/toml_value.rs similarity index 97% rename from toml-config/src/toml/toml_value.rs rename to toml-parser/src/toml_value.rs index c93f942e..af290efc 100644 --- a/toml-config/src/toml/toml_value.rs +++ b/toml-parser/src/toml_value.rs @@ -1,5 +1,5 @@ use { - crate::toml::toml_span::Spanned, + crate::toml_span::Spanned, indexmap::IndexMap, std::{ cmp::Ordering, diff --git a/toml-config/src/config/value.rs b/toml-parser/src/value_ext.rs similarity index 85% rename from toml-config/src/config/value.rs rename to toml-parser/src/value_ext.rs index 0a80b0c6..db061de5 100644 --- a/toml-config/src/config/value.rs +++ b/toml-parser/src/value_ext.rs @@ -1,6 +1,7 @@ use crate::{ - config::parser::{ParseResult, Parser}, - toml::{toml_span::Span, toml_value::Value}, + toml_span::Span, + toml_value::Value, + value_parser::{ParseResult, Parser}, }; impl Value { diff --git a/toml-parser/src/value_parser.rs b/toml-parser/src/value_parser.rs new file mode 100644 index 00000000..a7003db8 --- /dev/null +++ b/toml-parser/src/value_parser.rs @@ -0,0 +1,118 @@ +use { + crate::{ + toml_span::{Span, Spanned, SpannedExt}, + toml_value::Value, + }, + indexmap::IndexMap, + std::{ + error::Error, + fmt::{self, Display, Formatter}, + }, +}; + +#[derive(Copy, Clone, Debug)] +pub enum DataType { + String, + Integer, + Float, + Boolean, + Array, + Table, +} + +impl Display for DataType { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + let s = match self { + DataType::String => "a string", + DataType::Integer => "an integer", + DataType::Float => "a float", + DataType::Boolean => "a bool", + DataType::Array => "an array", + DataType::Table => "a table", + }; + f.write_str(s) + } +} + +pub struct DataTypes(&'static [DataType]); + +impl Display for DataTypes { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + let d = self.0; + match d.len() { + 0 => Ok(()), + 1 => d[0].fmt(f), + 2 => write!(f, "{} or {}", d[0], d[1]), + _ => { + let mut first = true; + #[expect(clippy::needless_range_loop)] + for i in 0..d.len() - 1 { + if !first { + f.write_str(", ")?; + } + first = false; + d[i].fmt(f)?; + } + write!(f, ", or {}", d[d.len() - 1]) + } + } + } +} + +#[derive(Debug)] +pub struct UnexpectedDataType(&'static [DataType], DataType); + +impl Display for UnexpectedDataType { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!(f, "Expected {} but found {}", DataTypes(self.0), self.1) + } +} + +impl Error for UnexpectedDataType {} + +pub type ParseResult

= Result<

::Value, Spanned<

::Error>>; + +pub trait Parser { + type Value; + type Error: From; + + const EXPECTED: &'static [DataType]; + + fn parse_string(&mut self, span: Span, string: &str) -> ParseResult { + let _ = string; + expected(self, span, DataType::String) + } + + fn parse_integer(&mut self, span: Span, integer: i64) -> ParseResult { + let _ = integer; + expected(self, span, DataType::Integer) + } + + fn parse_float(&mut self, span: Span, float: f64) -> ParseResult { + let _ = float; + expected(self, span, DataType::Float) + } + + fn parse_bool(&mut self, span: Span, bool: bool) -> ParseResult { + let _ = bool; + expected(self, span, DataType::Boolean) + } + + fn parse_array(&mut self, span: Span, array: &[Spanned]) -> ParseResult { + let _ = array; + expected(self, span, DataType::Array) + } + + fn parse_table( + &mut self, + span: Span, + table: &IndexMap, Spanned>, + ) -> ParseResult { + let _ = table; + expected(self, span, DataType::Table) + } +} + +fn expected(_p: &P, span: Span, actual: DataType) -> ParseResult

{ + Err(P::Error::from(UnexpectedDataType(P::EXPECTED, actual)).spanned(span)) +}