1
0
Fork 0
forked from wry/wry

config: split toml parser crate

This commit is contained in:
kossLAN 2026-05-29 18:42:50 -04:00
parent e3f122e903
commit b5b690d9cf
No known key found for this signature in database
68 changed files with 309 additions and 270 deletions

14
Cargo.lock generated
View file

@ -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]]

View file

@ -57,6 +57,7 @@ members = [
"pango",
"libinput",
"toml-config",
"toml-parser",
"algorithms",
"toml-spec",
"wire-to-xml",

View file

@ -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"

View file

@ -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::{

View file

@ -1,7 +1,7 @@
use {
crate::{
config::error::SpannedError,
toml::{
jay_toml::{
toml_parser::{ErrorHandler, ParserError},
toml_span::{Span, Spanned},
},

View file

@ -1,5 +1,5 @@
use {
crate::toml::toml_span::Span,
jay_toml::toml_span::Span,
bstr::ByteSlice,
error_reporter::Report,
std::{

View file

@ -1,7 +1,7 @@
use {
crate::{
config::context::Context,
toml::{
jay_toml::{
toml_span::{Span, Spanned, SpannedExt},
toml_value::Value,
},

View file

@ -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<P> = Result<<P as Parser>::Value, Spanned<<P as Parser>::Error>>;
pub trait Parser {
type Value;
type Error: From<UnexpectedDataType>;
const EXPECTED: &'static [DataType];
fn parse_string(&mut self, span: Span, string: &str) -> ParseResult<Self> {
let _ = string;
expected(self, span, DataType::String)
}
fn parse_integer(&mut self, span: Span, integer: i64) -> ParseResult<Self> {
let _ = integer;
expected(self, span, DataType::Integer)
}
fn parse_float(&mut self, span: Span, float: f64) -> ParseResult<Self> {
let _ = float;
expected(self, span, DataType::Float)
}
fn parse_bool(&mut self, span: Span, bool: bool) -> ParseResult<Self> {
let _ = bool;
expected(self, span, DataType::Boolean)
}
fn parse_array(&mut self, span: Span, array: &[Spanned<Value>]) -> ParseResult<Self> {
let _ = array;
expected(self, span, DataType::Array)
}
fn parse_table(
&mut self,
span: Span,
table: &IndexMap<Spanned<String>, Spanned<Value>>,
) -> ParseResult<Self> {
let _ = table;
expected(self, span, DataType::Table)
}
}
fn expected<P: Parser + ?Sized>(_p: &P, span: Span, actual: DataType) -> ParseResult<P> {
Err(P::Error::from(UnexpectedDataType(P::EXPECTED, actual)).spanned(span))
}

View file

@ -1,7 +1,7 @@
use {
crate::{
config::parser::{DataType, ParseResult, Parser, UnexpectedDataType},
toml::toml_span::Span,
jay_toml::toml_span::Span,
},
thiserror::Error,
};

View file

@ -26,7 +26,7 @@ use {
},
spanned::SpannedErrorExt,
},
toml::{
jay_toml::{
toml_span::{DespanExt, Span, Spanned, SpannedExt},
toml_value::Value,
},

View file

@ -7,7 +7,7 @@ use {
parser::{DataType, ParseResult, Parser, UnexpectedDataType},
parsers::action::ActionParser,
},
toml::{
jay_toml::{
toml_span::{Span, Spanned, SpannedExt},
toml_value::Value,
},

View file

@ -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,
},

View file

@ -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,
},

View file

@ -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,
},

View file

@ -11,7 +11,7 @@ use {
},
spanned::SpannedErrorExt,
},
toml::{
jay_toml::{
toml_span::{DespanExt, Span, Spanned},
toml_value::Value,
},

View file

@ -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},

View file

@ -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,
},

View file

@ -44,7 +44,7 @@ use {
},
spanned::SpannedErrorExt,
},
toml::{
jay_toml::{
toml_span::{DespanExt, Span, Spanned},
toml_value::Value,
},

View file

@ -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,
},

View file

@ -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,
},

View file

@ -1,7 +1,7 @@
use {
crate::{
config::parser::{DataType, ParseResult, Parser, UnexpectedDataType},
toml::{
jay_toml::{
toml_span::{Span, Spanned, SpannedExt},
toml_value::Value,
},

View file

@ -10,7 +10,7 @@ use {
gfx_api::GfxApiParser,
},
},
toml::{
jay_toml::{
toml_span::{DespanExt, Span, Spanned},
toml_value::Value,
},

View file

@ -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,
},

View file

@ -4,7 +4,7 @@ use {
parser::{DataType, ParseResult, Parser, UnexpectedDataType},
parsers::{StringParser, StringParserError},
},
toml::{
jay_toml::{
toml_span::{Span, Spanned},
toml_value::Value,
},

View file

@ -10,7 +10,7 @@ use {
env::{EnvParser, EnvParserError},
},
},
toml::{
jay_toml::{
toml_span::{Span, Spanned, SpannedExt},
toml_value::Value,
},

View file

@ -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,

View file

@ -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,
},

View file

@ -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,
},

View file

@ -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,

View file

@ -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,

View file

@ -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,
},

View file

@ -12,7 +12,7 @@ use {
output_match::OutputMatchParser,
},
},
toml::{
jay_toml::{
toml_span::{DespanExt, Span, Spanned, SpannedExt},
toml_value::Value,
},

View file

@ -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,
},

View file

@ -8,7 +8,7 @@ use {
parsers::shortcuts::{ComplexShortcutsParser, ShortcutsParser, ShortcutsParserError},
spanned::SpannedErrorExt,
},
toml::{
jay_toml::{
toml_span::{DespanExt, Span, Spanned},
toml_value::Value,
},

View file

@ -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,
},

View file

@ -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,
},

View file

@ -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,

View file

@ -6,7 +6,7 @@ use {
keycodes::KEYCODES,
parser::{DataType, ParseResult, Parser, UnexpectedDataType},
},
toml::{
jay_toml::{
toml_span::{Span, Spanned, SpannedExt},
toml_value::Value,
},

View file

@ -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,
},

View file

@ -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,

View file

@ -13,7 +13,7 @@ use {
vrr::VrrParser,
},
},
toml::{
jay_toml::{
toml_span::{DespanExt, Span, Spanned, SpannedExt},
toml_value::Value,
},

View file

@ -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,
},

View file

@ -6,7 +6,7 @@ use {
extractor::{Extractor, ExtractorError, s32},
parser::{DataType, ParseResult, Parser, UnexpectedDataType},
},
toml::{
jay_toml::{
toml_span::{Span, Spanned},
toml_value::Value,
},

View file

@ -13,7 +13,7 @@ use {
},
spanned::SpannedErrorExt,
},
toml::{
jay_toml::{
toml_span::{Span, Spanned, SpannedExt},
toml_value::Value,
},

View file

@ -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,
},

View file

@ -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,
},

View file

@ -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,
},

View file

@ -7,7 +7,7 @@ use {
parser::{DataType, ParseResult, Parser, UnexpectedDataType},
parsers::color::ColorParser,
},
toml::{
jay_toml::{
toml_span::{DespanExt, Span, Spanned},
toml_value::Value,
},

View file

@ -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,

View file

@ -7,7 +7,7 @@ use {
parser::{DataType, ParseResult, Parser, UnexpectedDataType},
parsers::exec::ExecParserError,
},
toml::{
jay_toml::{
toml_span::{DespanExt, Span, Spanned},
toml_value::Value,
},

View file

@ -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,
},

View file

@ -11,7 +11,7 @@ use {
window_type::{WindowTypeParser, WindowTypeParserError},
},
},
toml::{
jay_toml::{
toml_span::{DespanExt, Span, Spanned},
toml_value::Value,
},

View file

@ -12,7 +12,7 @@ use {
},
spanned::SpannedErrorExt,
},
toml::{
jay_toml::{
toml_span::{DespanExt, Span, Spanned},
toml_value::Value,
},

View file

@ -1,7 +1,7 @@
use {
crate::{
config::parser::{DataType, ParseResult, Parser, UnexpectedDataType},
toml::{
jay_toml::{
toml_span::{Span, Spanned, SpannedExt},
toml_value::Value,
},

View file

@ -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,

View file

@ -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,
},

View file

@ -1,63 +1 @@
use crate::{
config::parser::{ParseResult, Parser},
toml::{toml_span::Spanned, toml_value::Value},
};
impl Spanned<&Value> {
pub fn parse<P: Parser>(&self, parser: &mut P) -> ParseResult<P> {
self.value.parse(self.span, parser)
}
pub fn parse_map<P: Parser, E>(
&self,
parser: &mut P,
) -> Result<<P as Parser>::Value, Spanned<E>>
where
<P as Parser>::Error: Into<E>,
{
self.parse(parser).map_spanned_err(|e| e.into())
}
}
impl Spanned<Value> {
pub fn parse<P: Parser>(&self, parser: &mut P) -> ParseResult<P> {
self.as_ref().parse(parser)
}
pub fn parse_map<P: Parser, E>(
&self,
parser: &mut P,
) -> Result<<P as Parser>::Value, Spanned<E>>
where
<P as Parser>::Error: Into<E>,
{
self.as_ref().parse_map(parser)
}
}
pub trait SpannedErrorExt {
type T;
type E;
fn map_spanned_err<U, F>(self, f: F) -> Result<Self::T, Spanned<U>>
where
F: FnOnce(Self::E) -> U;
}
impl<T, E> SpannedErrorExt for Result<T, Spanned<E>> {
type T = T;
type E = E;
fn map_spanned_err<U, F>(self, f: F) -> Result<Self::T, Spanned<U>>
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;

View file

@ -8,7 +8,8 @@
mod config;
mod rules;
mod shortcuts;
mod toml;
pub(crate) use jay_toml;
use {
crate::{

16
toml-parser/Cargo.toml Normal file
View file

@ -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"

View file

@ -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;

View file

@ -0,0 +1,64 @@
use crate::{
toml_span::Spanned,
toml_value::Value,
value_parser::{ParseResult, Parser},
};
impl Spanned<&Value> {
pub fn parse<P: Parser>(&self, parser: &mut P) -> ParseResult<P> {
self.value.parse(self.span, parser)
}
pub fn parse_map<P: Parser, E>(
&self,
parser: &mut P,
) -> Result<<P as Parser>::Value, Spanned<E>>
where
<P as Parser>::Error: Into<E>,
{
self.parse(parser).map_spanned_err(|e| e.into())
}
}
impl Spanned<Value> {
pub fn parse<P: Parser>(&self, parser: &mut P) -> ParseResult<P> {
self.as_ref().parse(parser)
}
pub fn parse_map<P: Parser, E>(
&self,
parser: &mut P,
) -> Result<<P as Parser>::Value, Spanned<E>>
where
<P as Parser>::Error: Into<E>,
{
self.as_ref().parse_map(parser)
}
}
pub trait SpannedErrorExt {
type T;
type E;
fn map_spanned_err<U, F>(self, f: F) -> Result<Self::T, Spanned<U>>
where
F: FnOnce(Self::E) -> U;
}
impl<T, E> SpannedErrorExt for Result<T, Spanned<E>> {
type T = T;
type E = E;
fn map_spanned_err<U, F>(self, f: F) -> Result<Self::T, Spanned<U>>
where
F: FnOnce(Self::E) -> U,
{
match self {
Ok(v) => Ok(v),
Err(e) => Err(Spanned {
span: e.span,
value: f(e.value),
}),
}
}
}

View file

@ -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<Value> {
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<ParserError>) {
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::<Infallible>,
}
FormatError(prev, None),
);
}
}
struct FormatError(Span, Option<ParserError>);
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)
}
}

View file

@ -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> {

View file

@ -1,5 +1,5 @@
use {
crate::toml::{
crate::{
toml_lexer::{Lexer, Token},
toml_span::{Span, Spanned, SpannedExt},
toml_value::Value,

View file

@ -1,5 +1,5 @@
use {
crate::toml::toml_span::Spanned,
crate::toml_span::Spanned,
indexmap::IndexMap,
std::{
cmp::Ordering,

View file

@ -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 {

View file

@ -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<P> = Result<<P as Parser>::Value, Spanned<<P as Parser>::Error>>;
pub trait Parser {
type Value;
type Error: From<UnexpectedDataType>;
const EXPECTED: &'static [DataType];
fn parse_string(&mut self, span: Span, string: &str) -> ParseResult<Self> {
let _ = string;
expected(self, span, DataType::String)
}
fn parse_integer(&mut self, span: Span, integer: i64) -> ParseResult<Self> {
let _ = integer;
expected(self, span, DataType::Integer)
}
fn parse_float(&mut self, span: Span, float: f64) -> ParseResult<Self> {
let _ = float;
expected(self, span, DataType::Float)
}
fn parse_bool(&mut self, span: Span, bool: bool) -> ParseResult<Self> {
let _ = bool;
expected(self, span, DataType::Boolean)
}
fn parse_array(&mut self, span: Span, array: &[Spanned<Value>]) -> ParseResult<Self> {
let _ = array;
expected(self, span, DataType::Array)
}
fn parse_table(
&mut self,
span: Span,
table: &IndexMap<Spanned<String>, Spanned<Value>>,
) -> ParseResult<Self> {
let _ = table;
expected(self, span, DataType::Table)
}
}
fn expected<P: Parser + ?Sized>(_p: &P, span: Span, actual: DataType) -> ParseResult<P> {
Err(P::Error::from(UnexpectedDataType(P::EXPECTED, actual)).spanned(span))
}