Skip to content

Commit

Permalink
change str impl to use unquote_string
Browse files Browse the repository at this point in the history
  • Loading branch information
quinchs committed Feb 7, 2024
1 parent 75da459 commit 4e98310
Showing 1 changed file with 54 additions and 88 deletions.
142 changes: 54 additions & 88 deletions src/prompt/variable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ use anyhow::Context as _;

use colorful::Colorful;
use bigdecimal::BigDecimal;
use combine::stream::Range;

Check warning on line 11 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / test-bin-installable (ubuntu-latest)

unused import: `combine::stream::Range`

Check warning on line 11 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / test (ubuntu-20.04, nightly)

unused import: `combine::stream::Range`

Check warning on line 11 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / musl-test (ubuntu-latest, nightly)

unused import: `combine::stream::Range`

Check warning on line 11 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / musl-test (ubuntu-latest, nightly)

unused import: `combine::stream::Range`

Check warning on line 11 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, nightly)

unused import: `combine::stream::Range`

Check warning on line 11 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / portable-install-tests (ubuntu-20.04)

unused import: `combine::stream::Range`

Check warning on line 11 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / portable-install-tests (ubuntu-20.04)

unused import: `combine::stream::Range`

Check warning on line 11 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / portable-tests-macos (portable_project)

unused import: `combine::stream::Range`

Check warning on line 11 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / portable-tests-macos (portable_project)

unused import: `combine::stream::Range`

Check warning on line 11 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / portable-tests-macos (portable_project_dir)

unused import: `combine::stream::Range`

Check warning on line 11 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / portable-tests-macos (portable_project_dir)

unused import: `combine::stream::Range`

Check warning on line 11 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / portable-tests-macos (portable_smoke)

unused import: `combine::stream::Range`

Check warning on line 11 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / portable-tests-macos (portable_smoke)

unused import: `combine::stream::Range`

Check warning on line 11 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / portable-tests-macos (portable_shared)

unused import: `combine::stream::Range`

Check warning on line 11 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / portable-tests-macos (portable_shared)

unused import: `combine::stream::Range`

Check warning on line 11 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / test (macos-latest, nightly)

unused import: `combine::stream::Range`
use edgedb_protocol::value::Value;
use edgedb_protocol::model;
use edgeql_parser::helpers::unquote_string;
use nom::combinator::{map_opt, recognize, value, verify, map, map_res};

Check warning on line 15 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / test-bin-installable (ubuntu-latest)

unused imports: `map_opt`, `verify`

Check warning on line 15 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / test (ubuntu-20.04, nightly)

unused imports: `map_opt`, `verify`

Check warning on line 15 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / musl-test (ubuntu-latest, nightly)

unused imports: `map_opt`, `verify`

Check warning on line 15 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / musl-test (ubuntu-latest, nightly)

unused imports: `map_opt`, `verify`

Check warning on line 15 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, nightly)

unused imports: `map_opt`, `verify`

Check warning on line 15 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / portable-install-tests (ubuntu-20.04)

unused imports: `map_opt`, `verify`

Check warning on line 15 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / portable-install-tests (ubuntu-20.04)

unused imports: `map_opt`, `verify`

Check warning on line 15 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / portable-tests-macos (portable_project)

unused imports: `map_opt`, `verify`

Check warning on line 15 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / portable-tests-macos (portable_project)

unused imports: `map_opt`, `verify`

Check warning on line 15 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / portable-tests-macos (portable_project_dir)

unused imports: `map_opt`, `verify`

Check warning on line 15 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / portable-tests-macos (portable_project_dir)

unused imports: `map_opt`, `verify`

Check warning on line 15 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / portable-tests-macos (portable_smoke)

unused imports: `map_opt`, `verify`

Check warning on line 15 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / portable-tests-macos (portable_smoke)

unused imports: `map_opt`, `verify`

Check warning on line 15 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / portable-tests-macos (portable_shared)

unused imports: `map_opt`, `verify`

Check warning on line 15 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / portable-tests-macos (portable_shared)

unused imports: `map_opt`, `verify`

Check warning on line 15 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / test (macos-latest, nightly)

unused imports: `map_opt`, `verify`
use nom::bytes::complete::{is_not, tag, take, take_while, take_while_m_n};

Check warning on line 16 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / test-bin-installable (ubuntu-latest)

unused imports: `is_not`, `take`

Check warning on line 16 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / test (ubuntu-20.04, nightly)

unused imports: `is_not`, `take`

Check warning on line 16 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / musl-test (ubuntu-latest, nightly)

unused imports: `is_not`, `take`

Check warning on line 16 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / musl-test (ubuntu-latest, nightly)

unused imports: `is_not`, `take`

Check warning on line 16 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, nightly)

unused imports: `is_not`, `take`

Check warning on line 16 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / portable-install-tests (ubuntu-20.04)

unused imports: `is_not`, `take`

Check warning on line 16 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / portable-install-tests (ubuntu-20.04)

unused imports: `is_not`, `take`

Check warning on line 16 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / portable-tests-macos (portable_project)

unused imports: `is_not`, `take`

Check warning on line 16 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / portable-tests-macos (portable_project)

unused imports: `is_not`, `take`

Check warning on line 16 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / portable-tests-macos (portable_project_dir)

unused imports: `is_not`, `take`

Check warning on line 16 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / portable-tests-macos (portable_project_dir)

unused imports: `is_not`, `take`

Check warning on line 16 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / portable-tests-macos (portable_smoke)

unused imports: `is_not`, `take`

Check warning on line 16 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / portable-tests-macos (portable_smoke)

unused imports: `is_not`, `take`

Check warning on line 16 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / portable-tests-macos (portable_shared)

unused imports: `is_not`, `take`

Check warning on line 16 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / portable-tests-macos (portable_shared)

unused imports: `is_not`, `take`

Check warning on line 16 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / test (macos-latest, nightly)

unused imports: `is_not`, `take`
use nom::character::complete::{char, i16, i32, i64, multispace0};
Expand All @@ -19,7 +21,7 @@ use nom::Err::{Error, Failure, Incomplete};
use nom::error::{context, ContextError, ErrorKind, FromExternalError, ParseError};
use nom::multi::{fold_many0, separated_list0};

Check warning on line 22 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / test-bin-installable (ubuntu-latest)

unused import: `fold_many0`

Check warning on line 22 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / test (ubuntu-20.04, nightly)

unused import: `fold_many0`

Check warning on line 22 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / musl-test (ubuntu-latest, nightly)

unused import: `fold_many0`

Check warning on line 22 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / musl-test (ubuntu-latest, nightly)

unused import: `fold_many0`

Check warning on line 22 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, nightly)

unused import: `fold_many0`

Check warning on line 22 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / portable-install-tests (ubuntu-20.04)

unused import: `fold_many0`

Check warning on line 22 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / portable-install-tests (ubuntu-20.04)

unused import: `fold_many0`

Check warning on line 22 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / portable-tests-macos (portable_project)

unused import: `fold_many0`

Check warning on line 22 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / portable-tests-macos (portable_project)

unused import: `fold_many0`

Check warning on line 22 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / portable-tests-macos (portable_project_dir)

unused import: `fold_many0`

Check warning on line 22 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / portable-tests-macos (portable_project_dir)

unused import: `fold_many0`

Check warning on line 22 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / portable-tests-macos (portable_smoke)

unused import: `fold_many0`

Check warning on line 22 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / portable-tests-macos (portable_smoke)

unused import: `fold_many0`

Check warning on line 22 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / portable-tests-macos (portable_shared)

unused import: `fold_many0`

Check warning on line 22 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / portable-tests-macos (portable_shared)

unused import: `fold_many0`

Check warning on line 22 in src/prompt/variable.rs

View workflow job for this annotation

GitHub Actions / test (macos-latest, nightly)

unused import: `fold_many0`
use nom::number::complete::{double, float, recognize_float_parts};
use nom::sequence::{delimited, preceded, terminated};
use nom::sequence::{delimited, preceded, terminated, tuple};
use num_bigint::ToBigInt;
use rustyline::completion::Completer;
use rustyline::error::ReadlineError;
Expand Down Expand Up @@ -131,106 +133,70 @@ fn quoted_str(input: &str) -> IResult<&str, String, ParsingError> {
fn single_quoted_str(input: &str) -> IResult<&str, String, ParsingError> {
context(
"single_quote_str",
|s| quoted_str_parser(s, '\'', "\'\\")
|s| quoted_str_parser(s, '\'')
)(input)
}

fn double_quoted_str(input: &str) -> IResult<&str, String, ParsingError> {
context(
"double_quote_str",
|s| quoted_str_parser(s, '\"', "\"\\")
|s| quoted_str_parser(s, '\"')
)(input)
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum StringFragment<'a> {
Literal(&'a str),
EscapedChar(char),
EscapedWS,
}

// heavily based on https://github.com/rust-bakery/nom/blob/main/examples/string.rs
fn quoted_str_parser<'a>(input: &'a str, quote: char, esc: &str) -> IResult<&'a str, String, ParsingError> {
fn quoted_str_parser<'a>(input: &'a str, quote: char) -> IResult<&'a str, String, ParsingError> {
context(
"quoted_string",
delimited(
char(quote),
fold_many0(
alt((
map(
verify(is_not(esc), |s: &str| !s.is_empty()),
StringFragment::Literal
),
map(
preceded(
char('\\'),
alt((
map_opt(
map_res(
preceded(
char('u'),
verify(
take(4usize),
|s: &str| s.chars().all(|c| c.is_ascii_hexdigit())
)
),
move |hex| u32::from_str_radix(hex, 16).context("Failed to parse hex digit")
),
std::char::from_u32
),
map_res(
map_res(
preceded(
char('x'),
verify(
take(2usize),
|s: &str| s.chars().all(|c| c.is_ascii_hexdigit())
)
),
move |hex| u8::from_str_radix(hex, 16).context("Invalid hex digit")
),
|digit| {
if digit > 0x7F || digit == 0 {
return Err(
format!(
"invalid string literal: \
invalid escape sequence '\\x{:x}' \
(only non-null ascii allowed)", digit)
);
}

Ok(digit as char)
}
),
value('\n', char('n')),
value('\r', char('r')),
value('\t', char('t')),
value('\u{08}', char('b')),
value('\u{0C}', char('f')),
value('\\', char('\\')),
value('/', char('/')),
value('"', char('"')),
value('\'', char('\'')),
))
),
StringFragment::EscapedChar
),
value(
StringFragment::EscapedWS,
preceded(char('\\'), nom::character::streaming::multispace1)
),
map_res(
recognize(
tuple((
char(quote),
move |str: &'a str| {
let mut pos = 0;

if str.is_empty() {
return Err(Error(ParsingError::Incomplete));
}

if str.len() == 1 && str.chars().nth(0).unwrap() != quote {
return Err(Error(ParsingError::Mistake {
kind: None,
description: "Missing end quote on string".to_string()
}))
}

let chars = str.char_indices();

let mut prev = None;

for (i, c) in chars {
if prev == None {
prev = Some(c);
continue;
}

if c == quote {
// is it escaped?
if prev.unwrap() == '\\' {
prev = Some(c);
continue;
}

// not escaped, its the end of the quoted string
pos = i;
break;
}

prev = Some(c)
}

// slice out the actual string part, and the remainder based on the 'pos'
Ok((&str[pos..], &str[..pos]))
},
char(quote),
)),
String::new,
|mut string, fragment| {
match fragment {
StringFragment::Literal(s) => string.push_str(s),
StringFragment::EscapedChar(c) => string.push(c),
StringFragment::EscapedWS => {}
}
string
}
),
char(quote),
|s| unquote_string(s).map(|v| v.into()).context("Failed to unquote string")
)
)(input)
}
Expand Down

0 comments on commit 4e98310

Please sign in to comment.