From 0a6c2e260ed2ad21a39165674d6f7dac273a259d Mon Sep 17 00:00:00 2001 From: Aster Date: Thu, 20 Jun 2024 18:01:33 +0800 Subject: [PATCH] Upgrade to pex 0.2.4 --- projects/pex-json5/Cargo.toml | 2 +- projects/pex-json5/src/parser/mod.rs | 74 +++++++++++----------------- projects/pex-json5/src/value/mod.rs | 6 +-- 3 files changed, 31 insertions(+), 51 deletions(-) diff --git a/projects/pex-json5/Cargo.toml b/projects/pex-json5/Cargo.toml index e7291ca..c5a499f 100644 --- a/projects/pex-json5/Cargo.toml +++ b/projects/pex-json5/Cargo.toml @@ -13,7 +13,7 @@ exclude = ["package.json", "tests/**"] [dependencies] serde_json = "1.0.96" index-map = "0.1.0" -pex = "0.1.0" +pex = "0.2.4" serde = "1.0.163" [dev-dependencies] diff --git a/projects/pex-json5/src/parser/mod.rs b/projects/pex-json5/src/parser/mod.rs index 538941b..eea360b 100644 --- a/projects/pex-json5/src/parser/mod.rs +++ b/projects/pex-json5/src/parser/mod.rs @@ -1,8 +1,8 @@ -use std::str::FromStr; -use pex::{ParseResult, ParseState, StopBecause}; -use pex::helpers::{decimal_string, double_quote_string, make_from_str, single_quote_string, whitespace}; +use pex::{ParseResult, ParseState, ZeroBytePattern}; +use pex::helpers::{double_quote_string, single_quote_string, whitespace}; /// An unchecked JSON5 value, need call validate before deserialize +#[derive(Debug, Clone, PartialEq)] pub enum UncheckedJson5<'i> { /// null Null, @@ -15,11 +15,7 @@ pub enum UncheckedJson5<'i> { /// +1234567890.1234567890e+1234567890 Number(&'i str), /// 0b0101010101010101 - Byte0B(&'i str), - /// 0o01234567 - Byte0O(&'i str), - /// 0x0123456789ABCDEF - Byte0X(&'i str), + Bytes(u32, &'i str), /// "string", 'string' String(&'i str), /// `[VALUE ,?]` @@ -28,32 +24,25 @@ pub enum UncheckedJson5<'i> { Object(Vec<(&'i str, UncheckedJson5<'i>)>), } -impl FromStr for UncheckedJson5 { - type Err = StopBecause; - fn from_str(s: &str) -> Result { - make_from_str(ParseState::new(s), Self::parse) - } -} - -impl UncheckedJson5 { - pub fn parse(state: ParseState) -> ParseResult { +impl<'i> UncheckedJson5<'i> { + pub fn parse(state: ParseState<'i>) -> ParseResult { let (state, value) = state.skip(ignore).match_fn(Self::parse_value)?; state.finish(value) } } -impl UncheckedJson5 { +impl<'i> UncheckedJson5<'i> { /// `[ ~ ]` #[inline] - fn parse_empty_array(state: ParseState) -> ParseResult { + fn parse_empty_array(state: ParseState<'i>) -> ParseResult { let (state, _) = state.match_char('[')?; let (state, _) = state.skip(ignore).match_char(']')?; state.finish(UncheckedJson5::Array(vec![])) } /// `[ ~ VALUE ~ (, ~ VALUE ~)* ,? ~ ]` #[inline] - fn parse_filled_array(state: ParseState) -> ParseResult { + fn parse_filled_array(state: ParseState<'i>) -> ParseResult { let (state, _) = state.match_char('[')?; let (state, value) = state.skip(ignore).match_fn(Self::parse_value)?; let mut array = vec![value]; @@ -64,46 +53,46 @@ impl UncheckedJson5 { } /// `~ , ~ VALUE` #[inline] - fn parse_array_value(state: ParseState) -> ParseResult { + fn parse_array_value(state: ParseState<'i>) -> ParseResult { let (state, _) = state.match_fn(comma)?; let (state, value) = state.skip(ignore).match_fn(Self::parse_value)?; state.skip(ignore).finish(value) } } -impl UncheckedJson5 { +impl<'i> UncheckedJson5<'i> { #[inline] - fn parse_empty_object(state: ParseState) -> ParseResult { + fn parse_empty_object(state: ParseState<'i>) -> ParseResult { let (state, _) = state.match_char('{')?; let (state, _) = state.skip(ignore).match_char('}')?; state.finish(UncheckedJson5::Object(vec![])) } #[inline] - fn parse_key_value(state: ParseState) -> ParseResult<(String, UncheckedJson5)> { + fn parse_key_value(state: ParseState<'i>) -> ParseResult<(String, Self)> { let (state, key) = state.skip(ignore).match_fn(Self::parse_key)?; let (state, _) = state.skip(ignore).match_char(':')?; let (state, value) = state.skip(ignore).match_fn(Self::parse_value)?; state.finish((key, value)) } #[inline] - fn parse_key(state: ParseState) -> ParseResult { + fn parse_key(state: ParseState<'i>) -> ParseResult { let (state, str) = state.begin_choice().or_else(double_quote_string).or_else(single_quote_string).end_choice()?; state.finish(str.to_string()) } #[inline] - fn parse_identifier(state: ParseState) -> ParseResult { + fn parse_identifier(state: ParseState<'i>) -> ParseResult { let (state, str) = state.match_str_if(|c| c.is_alphabetic(), "Identifier")?; state.finish(str.to_string()) } } -impl UncheckedJson5 { +impl<'i> UncheckedJson5<'i> { #[inline] - fn parse_value(state: ParseState) -> ParseResult { + fn parse_value(state: ParseState<'i>) -> ParseResult { state.begin_choice() .or_else(parse_string) .or_else(parse_number) - .or_else(parse_byte) + .or_else(parse_bytes) .or_else(Self::parse_empty_array) .or_else(Self::parse_filled_array) .or_else(Self::parse_empty_object) @@ -112,7 +101,7 @@ impl UncheckedJson5 { } #[inline] - fn parse_special(state: ParseState) -> ParseResult { + fn parse_special(state: ParseState<'i>) -> ParseResult { state .begin_choice() .or_else(|s| s.match_str("true").map_inner(|_| UncheckedJson5::Boolean(true))) @@ -123,13 +112,13 @@ impl UncheckedJson5 { .end_choice() } #[inline] - fn parse_nan(state: ParseState) -> ParseResult { + fn parse_nan(state: ParseState<'i>) -> ParseResult { let (state, _) = state.match_optional(|s| s.match_char('-'))?; let (state, _) = state.match_str("NaN")?; state.finish(UncheckedJson5::NAN) } #[inline] - fn parse_infinity(state: ParseState) -> ParseResult { + fn parse_infinity(state: ParseState<'i>) -> ParseResult { let (state, sign) = state.match_optional(|s| s.match_char_if(is_sign, "SIGN"))?; let neg = sign == Some('-'); let (state, _) = state.match_str("Infinity")?; @@ -138,30 +127,23 @@ impl UncheckedJson5 { } #[inline] -fn parse_number(state: ParseState) -> ParseResult { +fn parse_number<'i>(state: ParseState<'i>) -> ParseResult> { todo!() } #[inline] -fn parse_string(state: ParseState) -> ParseResult { +fn parse_string<'i>(state: ParseState<'i>) -> ParseResult> { let (state, str) = state.begin_choice().or_else(double_quote_string).or_else(single_quote_string).end_choice()?; - state.finish(UncheckedJson5::String(str.to_string())) + state.finish(UncheckedJson5::String(str)) } #[inline] -fn parse_byte(state: ParseState) -> ParseResult { - let (state, _) = state.match_char('0')?; - let (state, base) = state.match_char_if(|c| c == 'b' || c == 'o' || c == 'x', "BASE")?; - let (state, json5) = match base { - 'x' => state.match_str_if(|c| c.is_digit(16), "HEX").map_inner(|s| UncheckedJson5::Byte0X(s.to_string()))?, - 'o' => state.match_str_if(|c| c.is_digit(08), "OCT").map_inner(|s| UncheckedJson5::Byte0O(s.to_string()))?, - 'b' => state.match_str_if(|c| c.is_digit(02), "BIN").map_inner(|s| UncheckedJson5::Byte0B(s.to_string()))?, - _ => StopBecause::must_be("one of x, o, b", state.start_offset)?, - }; - state.finish(json5) +fn parse_bytes(state: ParseState) -> ParseResult { + let bytes = ZeroBytePattern::new(&[("0x", 16), ("0o", 8), ("0b", 2)]); + let (state, byte) = bytes.match_pattern(state)?; + state.finish(UncheckedJson5::Bytes(byte.0, byte.1)) } - fn ignore(state: ParseState) -> ParseResult<()> { let (state, _) = state.match_fn(whitespace)?; state.finish(()) diff --git a/projects/pex-json5/src/value/mod.rs b/projects/pex-json5/src/value/mod.rs index 1341c27..b476ea5 100644 --- a/projects/pex-json5/src/value/mod.rs +++ b/projects/pex-json5/src/value/mod.rs @@ -1,7 +1,7 @@ use serde_json::Error; use crate::UncheckedJson5; -impl UncheckedJson5 { +impl<'i> UncheckedJson5<'i> { pub fn validate(&self) -> Vec { let mut errors = Vec::new(); match self { @@ -10,9 +10,7 @@ impl UncheckedJson5 { UncheckedJson5::NAN => {} UncheckedJson5::Infinity(_) => {} UncheckedJson5::Number(_) => {} - UncheckedJson5::Byte0B(_) => {} - UncheckedJson5::Byte0O(_) => {} - UncheckedJson5::Byte0X(_) => {} + UncheckedJson5::Bytes(_, _) => {} UncheckedJson5::String(_) => {} UncheckedJson5::Array(_) => {} UncheckedJson5::Object(_) => {}