Skip to content

Commit

Permalink
Upgrade to pex 0.2.4
Browse files Browse the repository at this point in the history
  • Loading branch information
oovm committed Jun 20, 2024
1 parent bb1877f commit 0a6c2e2
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 51 deletions.
2 changes: 1 addition & 1 deletion projects/pex-json5/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
74 changes: 28 additions & 46 deletions projects/pex-json5/src/parser/mod.rs
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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 ,?]`
Expand All @@ -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<Self, StopBecause> {
make_from_str(ParseState::new(s), Self::parse)
}
}

impl UncheckedJson5 {
pub fn parse(state: ParseState) -> ParseResult<UncheckedJson5> {
impl<'i> UncheckedJson5<'i> {
pub fn parse(state: ParseState<'i>) -> ParseResult<Self> {
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<UncheckedJson5> {
fn parse_empty_array(state: ParseState<'i>) -> ParseResult<Self> {
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<UncheckedJson5> {
fn parse_filled_array(state: ParseState<'i>) -> ParseResult<Self> {
let (state, _) = state.match_char('[')?;
let (state, value) = state.skip(ignore).match_fn(Self::parse_value)?;
let mut array = vec![value];
Expand All @@ -64,46 +53,46 @@ impl UncheckedJson5 {
}
/// `~ , ~ VALUE`
#[inline]
fn parse_array_value(state: ParseState) -> ParseResult<UncheckedJson5> {
fn parse_array_value(state: ParseState<'i>) -> ParseResult<Self> {
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<UncheckedJson5> {
fn parse_empty_object(state: ParseState<'i>) -> ParseResult<Self> {
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<String> {
fn parse_key(state: ParseState<'i>) -> ParseResult<String> {
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<String> {
fn parse_identifier(state: ParseState<'i>) -> ParseResult<String> {
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<UncheckedJson5> {
fn parse_value(state: ParseState<'i>) -> ParseResult<Self> {
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)
Expand All @@ -112,7 +101,7 @@ impl UncheckedJson5 {
}

#[inline]
fn parse_special(state: ParseState) -> ParseResult<UncheckedJson5> {
fn parse_special(state: ParseState<'i>) -> ParseResult<Self> {
state
.begin_choice()
.or_else(|s| s.match_str("true").map_inner(|_| UncheckedJson5::Boolean(true)))
Expand All @@ -123,13 +112,13 @@ impl UncheckedJson5 {
.end_choice()
}
#[inline]
fn parse_nan(state: ParseState) -> ParseResult<UncheckedJson5> {
fn parse_nan(state: ParseState<'i>) -> ParseResult<Self> {
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<UncheckedJson5> {
fn parse_infinity(state: ParseState<'i>) -> ParseResult<Self> {
let (state, sign) = state.match_optional(|s| s.match_char_if(is_sign, "SIGN"))?;
let neg = sign == Some('-');
let (state, _) = state.match_str("Infinity")?;
Expand All @@ -138,30 +127,23 @@ impl UncheckedJson5 {
}

#[inline]
fn parse_number(state: ParseState) -> ParseResult<UncheckedJson5> {
fn parse_number<'i>(state: ParseState<'i>) -> ParseResult<UncheckedJson5<'i>> {
todo!()
}

#[inline]
fn parse_string(state: ParseState) -> ParseResult<UncheckedJson5> {
fn parse_string<'i>(state: ParseState<'i>) -> ParseResult<UncheckedJson5<'i>> {
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<UncheckedJson5> {
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<UncheckedJson5> {
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(())
Expand Down
6 changes: 2 additions & 4 deletions projects/pex-json5/src/value/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use serde_json::Error;
use crate::UncheckedJson5;

impl UncheckedJson5 {
impl<'i> UncheckedJson5<'i> {
pub fn validate(&self) -> Vec<Error> {
let mut errors = Vec::new();
match self {
Expand All @@ -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(_) => {}
Expand Down

0 comments on commit 0a6c2e2

Please sign in to comment.