use self::RuleResult::{Matched, Failed};
use self::super::super::{HrxEntryData, HrxEntry, HrxPath};
use std::num::NonZeroUsize;
fn escape_default(s: &str) -> String {
s.chars().flat_map(|c| c.escape_default()).collect()
}
fn char_range_at(s: &str, pos: usize) -> (char, usize) {
let c = &s[pos..].chars().next().unwrap();
let next_pos = pos + c.len_utf8();
(*c, next_pos)
}
#[derive(Clone)]
enum RuleResult<T> {
Matched(usize, T),
Failed,
}
#[derive(PartialEq, Eq, Debug, Clone)]
pub struct ParseError {
pub line: usize,
pub column: usize,
pub offset: usize,
pub expected: ::std::collections::HashSet<&'static str>,
}
pub type ParseResult<T> = Result<T, ParseError>;
impl ::std::fmt::Display for ParseError {
fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::result::Result<(), ::std::fmt::Error> {
write!(fmt, "error at {}:{}: expected ", self.line, self.column)?;
if self.expected.len() == 0 {
write!(fmt, "EOF")?;
} else if self.expected.len() == 1 {
write!(fmt, "`{}`", escape_default(self.expected.iter().next().unwrap()))?;
} else {
let mut iter = self.expected.iter();
write!(fmt, "one of `{}`", escape_default(iter.next().unwrap()))?;
for elem in iter {
write!(fmt, ", `{}`", escape_default(elem))?;
}
}
Ok(())
}
}
impl ::std::error::Error for ParseError {
fn description(&self) -> &str {
"parse error"
}
}
fn slice_eq(input: &str, state: &mut ParseState, pos: usize, m: &'static str) -> RuleResult<()> {
# ! [inline] # ! [allow(dead_code)] let l = m.len();
if input.len() >= pos + l && &input.as_bytes()[pos..pos + l] == m.as_bytes() {
Matched(pos + l, ())
} else {
state.mark_failure(pos, m)
}
}
fn slice_eq_case_insensitive(input: &str, state: &mut ParseState, pos: usize, m: &'static str) -> RuleResult<()> {
# ! [inline] # ! [allow(dead_code)] let mut used = 0usize;
let mut input_iter = input[pos..].chars().flat_map(|x| x.to_uppercase());
for m_char_upper in m.chars().flat_map(|x| x.to_uppercase()) {
used += m_char_upper.len_utf8();
let input_char_result = input_iter.next();
if input_char_result.is_none() || input_char_result.unwrap() != m_char_upper {
return state.mark_failure(pos, m);
}
}
Matched(pos + used, ())
}
fn any_char(input: &str, state: &mut ParseState, pos: usize) -> RuleResult<()> {
# ! [inline] # ! [allow(dead_code)] if input.len() > pos {
let (_, next) = char_range_at(input, pos);
Matched(next, ())
} else {
state.mark_failure(pos, "<character>")
}
}
fn pos_to_line(input: &str, pos: usize) -> (usize, usize) {
let before = &input[..pos];
let line = before.as_bytes().iter().filter(|&&c| c == b'\n').count() + 1;
let col = before.chars().rev().take_while(|&c| c != '\n').count() + 1;
(line, col)
}
impl<'input> ParseState<'input> {
fn mark_failure(&mut self, pos: usize, expected: &'static str) -> RuleResult<()> {
if self.suppress_fail == 0 {
if pos > self.max_err_pos {
self.max_err_pos = pos;
self.expected.clear();
}
if pos == self.max_err_pos {
self.expected.insert(expected);
}
}
Failed
}
}
struct ParseState<'input> {
max_err_pos: usize,
suppress_fail: usize,
expected: ::std::collections::HashSet<&'static str>,
_phantom: ::std::marker::PhantomData<&'input ()>,
}
impl<'input> ParseState<'input> {
fn new() -> ParseState<'input> {
ParseState {
max_err_pos: 0,
suppress_fail: 0,
expected: ::std::collections::HashSet::new(),
_phantom: ::std::marker::PhantomData,
}
}
}
fn __parse_archive<'input>(__input: &'input str, __state: &mut ParseState<'input>, __pos: usize, boundary_length: NonZeroUsize)
-> RuleResult<(Option<String>, Vec<(HrxPath, HrxEntry)>, NonZeroUsize)> {# ! [ allow ( non_snake_case , unused ) ] {
let __seq_res = {
let mut __repeat_pos = __pos;
let mut __repeat_value = vec![];
loop {
let __pos = __repeat_pos;
let __step_res = __parse_entry(__input, __state, __pos, boundary_length);
match __step_res {
Matched(__newpos, __value) => {
__repeat_pos = __newpos;
__repeat_value.push(__value);
}
Failed => {
break;
}
}
}
Matched(__repeat_pos, __repeat_value)
};
match __seq_res {
Matched(__pos, ee) => {
let __seq_res = match __parse_comment(__input, __state, __pos, boundary_length) {
Matched(__newpos, __value) => Matched(__newpos, Some(__value)),
Failed => Matched(__pos, None),
};
match __seq_res {
Matched(__pos, c) => {
Matched(__pos, {
(c.map(str::to_string), ee, boundary_length)
})
}
Failed => Failed,
}
}
Failed => Failed,
}
}
}
fn __parse_entry<'input>(__input: &'input str, __state: &mut ParseState<'input>, __pos: usize, boundary_length: NonZeroUsize)
-> RuleResult<(HrxPath, HrxEntry)> {# ! [ allow ( non_snake_case , unused ) ] {
let __choice_res = {
let __seq_res = match __parse_comment(__input, __state, __pos, boundary_length) {
Matched(__newpos, __value) => Matched(__newpos, Some(__value)),
Failed => Matched(__pos, None),
};
match __seq_res {
Matched(__pos, c) => {
let __seq_res = __parse_file(__input, __state, __pos, boundary_length);
match __seq_res {
Matched(__pos, d) => {
Matched(__pos, {
(
d.0,
HrxEntry {
comment: c.map(str::to_string),
data: HrxEntryData::File { body: d.1.map(str::to_string) },
},
)
})
}
Failed => Failed,
}
}
Failed => Failed,
}
};
match __choice_res {
Matched(__pos, __value) => Matched(__pos, __value),
Failed => {
let __seq_res = match __parse_comment(__input, __state, __pos, boundary_length) {
Matched(__newpos, __value) => Matched(__newpos, Some(__value)),
Failed => Matched(__pos, None),
};
match __seq_res {
Matched(__pos, c) => {
let __seq_res = __parse_directory(__input, __state, __pos, boundary_length);
match __seq_res {
Matched(__pos, d) => {
Matched(__pos, {
(
d,
HrxEntry {
comment: c.map(str::to_string),
data: HrxEntryData::Directory,
},
)
})
}
Failed => Failed,
}
}
Failed => Failed,
}
}
}
}
}
fn __parse_comment<'input>(__input: &'input str, __state: &mut ParseState<'input>, __pos: usize, boundary_length: NonZeroUsize) -> RuleResult<&'input str> {# ! [ allow ( non_snake_case , unused ) ] {
let __seq_res = __parse_boundary(__input, __state, __pos, boundary_length);
match __seq_res {
Matched(__pos, _) => {
let __seq_res = __parse_newline(__input, __state, __pos, boundary_length);
match __seq_res {
Matched(__pos, _) => {
let __seq_res = __parse_body(__input, __state, __pos, boundary_length);
match __seq_res {
Matched(__pos, b) => {
Matched(__pos, {
b
})
}
Failed => Failed,
}
}
Failed => Failed,
}
}
Failed => Failed,
}
}
}
fn __parse_file<'input>(__input: &'input str, __state: &mut ParseState<'input>, __pos: usize, boundary_length: NonZeroUsize)
-> RuleResult<(HrxPath, Option<&'input str>)> {# ! [ allow ( non_snake_case , unused ) ] {
let __seq_res = __parse_boundary(__input, __state, __pos, boundary_length);
match __seq_res {
Matched(__pos, _) => {
let __seq_res = {
let mut __repeat_pos = __pos;
let mut __repeat_value = vec![];
loop {
let __pos = __repeat_pos;
let __step_res = slice_eq(__input, __state, __pos, " ");
match __step_res {
Matched(__newpos, __value) => {
__repeat_pos = __newpos;
__repeat_value.push(__value);
}
Failed => {
break;
}
}
}
if __repeat_value.len() >= 1 {
Matched(__repeat_pos, ())
} else {
Failed
}
};
match __seq_res {
Matched(__pos, _) => {
let __seq_res = __parse_path(__input, __state, __pos, boundary_length);
match __seq_res {
Matched(__pos, p) => {
let __seq_res = __parse_newline(__input, __state, __pos, boundary_length);
match __seq_res {
Matched(__pos, _) => {
let __seq_res = match __parse_body(__input, __state, __pos, boundary_length) {
Matched(__newpos, __value) => Matched(__newpos, Some(__value)),
Failed => Matched(__pos, None),
};
match __seq_res {
Matched(__pos, b) => {
Matched(__pos, {
(p, b)
})
}
Failed => Failed,
}
}
Failed => Failed,
}
}
Failed => Failed,
}
}
Failed => Failed,
}
}
Failed => Failed,
}
}
}
fn __parse_directory<'input>(__input: &'input str, __state: &mut ParseState<'input>, __pos: usize, boundary_length: NonZeroUsize) -> RuleResult<HrxPath> {# ! [ allow ( non_snake_case , unused ) ] {
let __seq_res = __parse_boundary(__input, __state, __pos, boundary_length);
match __seq_res {
Matched(__pos, _) => {
let __seq_res = {
let mut __repeat_pos = __pos;
let mut __repeat_value = vec![];
loop {
let __pos = __repeat_pos;
let __step_res = slice_eq(__input, __state, __pos, " ");
match __step_res {
Matched(__newpos, __value) => {
__repeat_pos = __newpos;
__repeat_value.push(__value);
}
Failed => {
break;
}
}
}
if __repeat_value.len() >= 1 {
Matched(__repeat_pos, ())
} else {
Failed
}
};
match __seq_res {
Matched(__pos, _) => {
let __seq_res = __parse_path(__input, __state, __pos, boundary_length);
match __seq_res {
Matched(__pos, p) => {
let __seq_res = slice_eq(__input, __state, __pos, "/");
match __seq_res {
Matched(__pos, _) => {
let __seq_res = {
let mut __repeat_pos = __pos;
let mut __repeat_value = vec![];
loop {
let __pos = __repeat_pos;
let __step_res = __parse_newline(__input, __state, __pos, boundary_length);
match __step_res {
Matched(__newpos, __value) => {
__repeat_pos = __newpos;
__repeat_value.push(__value);
}
Failed => {
break;
}
}
}
if __repeat_value.len() >= 1 {
Matched(__repeat_pos, ())
} else {
Failed
}
};
match __seq_res {
Matched(__pos, _) => {
Matched(__pos, {
p
})
}
Failed => Failed,
}
}
Failed => Failed,
}
}
Failed => Failed,
}
}
Failed => Failed,
}
}
Failed => Failed,
}
}
}
fn __parse_boundary<'input>(__input: &'input str, __state: &mut ParseState<'input>, __pos: usize, boundary_length: NonZeroUsize) -> RuleResult<()> {# ! [ allow ( non_snake_case , unused ) ] {
let __seq_res = slice_eq(__input, __state, __pos, "<");
match __seq_res {
Matched(__pos, _) => {
let __seq_res = {
let mut __repeat_pos = __pos;
let mut __repeat_value = vec![];
loop {
let __pos = __repeat_pos;
if __repeat_value.len() >=
{
boundary_length.get()
}
{
break;
}
let __step_res = slice_eq(__input, __state, __pos, "=");
match __step_res {
Matched(__newpos, __value) => {
__repeat_pos = __newpos;
__repeat_value.push(__value);
}
Failed => {
break;
}
}
}
if __repeat_value.len() >=
{
boundary_length.get()
}
{
Matched(__repeat_pos, ())
} else {
Failed
}
};
match __seq_res {
Matched(__pos, _) => slice_eq(__input, __state, __pos, ">"),
Failed => Failed,
}
}
Failed => Failed,
}
}
}
fn __parse_newline<'input>(__input: &'input str, __state: &mut ParseState<'input>, __pos: usize, boundary_length: NonZeroUsize) -> RuleResult<()> {# ! [ allow ( non_snake_case , unused ) ] slice_eq(__input, __state, __pos, "\n")
}
fn __parse_body<'input>(__input: &'input str, __state: &mut ParseState<'input>, __pos: usize, boundary_length: NonZeroUsize) -> RuleResult<&'input str> {# ! [ allow ( non_snake_case , unused ) ] __parse_contents(__input, __state, __pos, boundary_length)
}
fn __parse_contents<'input>(__input: &'input str, __state: &mut ParseState<'input>, __pos: usize, boundary_length: NonZeroUsize) -> RuleResult<&'input str> {# ! [ allow ( non_snake_case , unused ) ] {
let __choice_res = {
let __seq_res = {
__state.suppress_fail += 1;
let __assert_res = __parse_boundary(__input, __state, __pos, boundary_length);
__state.suppress_fail -= 1;
match __assert_res {
Failed => Matched(__pos, ()),
Matched(..) => Failed,
}
};
match __seq_res {
Matched(__pos, _) => {
let __seq_res = {
let str_start = __pos;
match {
let mut __repeat_pos = __pos;
let mut __repeat_value = vec![];
loop {
let __pos = __repeat_pos;
let __step_res = {
let __seq_res = {
__state.suppress_fail += 1;
let __assert_res = {
let __seq_res = __parse_newline(__input, __state, __pos, boundary_length);
match __seq_res {
Matched(__pos, _) => __parse_boundary(__input, __state, __pos, boundary_length),
Failed => Failed,
}
};
__state.suppress_fail -= 1;
match __assert_res {
Failed => Matched(__pos, ()),
Matched(..) => Failed,
}
};
match __seq_res {
Matched(__pos, _) => any_char(__input, __state, __pos),
Failed => Failed,
}
};
match __step_res {
Matched(__newpos, __value) => {
__repeat_pos = __newpos;
__repeat_value.push(__value);
}
Failed => {
break;
}
}
}
if __repeat_value.len() >= 1 {
Matched(__repeat_pos, ())
} else {
Failed
}
} {
Matched(__newpos, _) => Matched(__newpos, &__input[str_start..__newpos]),
Failed => Failed,
}
};
match __seq_res {
Matched(__pos, ctnt) => {
let __seq_res = __parse_newline(__input, __state, __pos, boundary_length);
match __seq_res {
Matched(__pos, _) => {
let __seq_res = {
__state.suppress_fail += 1;
let __assert_res = __parse_boundary(__input, __state, __pos, boundary_length);
__state.suppress_fail -= 1;
match __assert_res {
Matched(_, __value) => Matched(__pos, __value),
Failed => Failed,
}
};
match __seq_res {
Matched(__pos, _) => {
Matched(__pos, {
ctnt
})
}
Failed => Failed,
}
}
Failed => Failed,
}
}
Failed => Failed,
}
}
Failed => Failed,
}
};
match __choice_res {
Matched(__pos, __value) => Matched(__pos, __value),
Failed => {
let __seq_res = {
__state.suppress_fail += 1;
let __assert_res = __parse_boundary(__input, __state, __pos, boundary_length);
__state.suppress_fail -= 1;
match __assert_res {
Failed => Matched(__pos, ()),
Matched(..) => Failed,
}
};
match __seq_res {
Matched(__pos, _) => {
let __seq_res = {
let str_start = __pos;
match {
let mut __repeat_pos = __pos;
let mut __repeat_value = vec![];
loop {
let __pos = __repeat_pos;
let __step_res = any_char(__input, __state, __pos);
match __step_res {
Matched(__newpos, __value) => {
__repeat_pos = __newpos;
__repeat_value.push(__value);
}
Failed => {
break;
}
}
}
if __repeat_value.len() >= 1 {
Matched(__repeat_pos, ())
} else {
Failed
}
} {
Matched(__newpos, _) => Matched(__newpos, &__input[str_start..__newpos]),
Failed => Failed,
}
};
match __seq_res {
Matched(__pos, ctnt) => {
Matched(__pos, {
ctnt
})
}
Failed => Failed,
}
}
Failed => Failed,
}
}
}
}
}
fn __parse_path<'input>(__input: &'input str, __state: &mut ParseState<'input>, __pos: usize, boundary_length: NonZeroUsize) -> RuleResult<HrxPath> {# ! [ allow ( non_snake_case , unused ) ] {
let __seq_res = {
let str_start = __pos;
match {
let __seq_res = match __parse_path_component(__input, __state, __pos, boundary_length) {
Matched(pos, _) => Matched(pos, ()),
Failed => Failed,
};
match __seq_res {
Matched(__pos, _) => {
let mut __repeat_pos = __pos;
loop {
let __pos = __repeat_pos;
let __step_res = {
let __seq_res = slice_eq(__input, __state, __pos, "/");
match __seq_res {
Matched(__pos, _) => {
match __parse_path_component(__input, __state, __pos, boundary_length) {
Matched(pos, _) => Matched(pos, ()),
Failed => Failed,
}
}
Failed => Failed,
}
};
match __step_res {
Matched(__newpos, __value) => {
__repeat_pos = __newpos;
}
Failed => {
break;
}
}
}
Matched(__repeat_pos, ())
}
Failed => Failed,
}
} {
Matched(__newpos, _) => Matched(__newpos, &__input[str_start..__newpos]),
Failed => Failed,
}
};
match __seq_res {
Matched(__pos, p) => {
Matched(__pos, {
HrxPath(p.to_string())
})
}
Failed => Failed,
}
}
}
fn __parse_path_component<'input>(__input: &'input str, __state: &mut ParseState<'input>, __pos: usize, boundary_length: NonZeroUsize)
-> RuleResult<&'input str> {# ! [ allow ( non_snake_case , unused ) ] {
let __seq_res = {
let str_start = __pos;
match {
let mut __repeat_pos = __pos;
let mut __repeat_value = vec![];
loop {
let __pos = __repeat_pos;
let __step_res = match __parse_path_character(__input, __state, __pos, boundary_length) {
Matched(pos, _) => Matched(pos, ()),
Failed => Failed,
};
match __step_res {
Matched(__newpos, __value) => {
__repeat_pos = __newpos;
__repeat_value.push(__value);
}
Failed => {
break;
}
}
}
if __repeat_value.len() >= 1 {
Matched(__repeat_pos, ())
} else {
Failed
}
} {
Matched(__newpos, _) => Matched(__newpos, &__input[str_start..__newpos]),
Failed => Failed,
}
};
match __seq_res {
Matched(__pos, pc) => {
match {
if pc == "." || pc == ".." {
Err("Invalid '.' or '..' path component")
} else {
Ok(pc)
}
} {
Ok(res) => Matched(__pos, res),
Err(expected) => {
__state.mark_failure(__pos, expected);
Failed
}
}
}
Failed => Failed,
}
}
}
fn __parse_path_character<'input>(__input: &'input str, __state: &mut ParseState<'input>, __pos: usize, boundary_length: NonZeroUsize) -> RuleResult<char> {# ! [ allow ( non_snake_case , unused ) ] {
let __choice_res = {
__state.suppress_fail += 1;
let res = {
let __seq_res = {
let str_start = __pos;
match if __input.len() > __pos {
let (__ch, __next) = char_range_at(__input, __pos);
match __ch {
'\0'...'\u{1f}' | '\u{7f}' | '/' | ':' | '\\' => __state.mark_failure(__pos, "[^\0-\u{1f}\u{7f}/:\\]"),
_ => Matched(__next, ()),
}
} else {
__state.mark_failure(__pos, "[^\0-\u{1f}\u{7f}/:\\]")
} {
Matched(__newpos, _) => Matched(__newpos, &__input[str_start..__newpos]),
Failed => Failed,
}
};
match __seq_res {
Matched(__pos, c) => {
Matched(__pos, {
c.chars().next().unwrap()
})
}
Failed => Failed,
}
};
__state.suppress_fail -= 1;
res
};
match __choice_res {
Matched(__pos, __value) => Matched(__pos, __value),
Failed => {
__state.mark_failure(
__pos,
"Any character other than U+0000 through U+001F, U+007F DELETE, U+002F SOLIDUS, U+003A COLON, or U+005C REVERSE SOLIDUS",
);
Failed
}
}
}
}
pub fn archive<'input>(__input: &'input str, boundary_length: NonZeroUsize) -> ParseResult<(Option<String>, Vec<(HrxPath, HrxEntry)>, NonZeroUsize)> {# ! [ allow ( non_snake_case , unused ) ] let mut __state = ParseState::new();
match __parse_archive(__input, &mut __state, 0, boundary_length) {
Matched(__pos, __value) => {
if __pos == __input.len() {
return Ok(__value);
}
}
_ => {}
}
let (__line, __col) = pos_to_line(__input, __state.max_err_pos);
Err(ParseError {
line: __line,
column: __col,
offset: __state.max_err_pos,
expected: __state.expected,
})
}
pub fn entry<'input>(__input: &'input str, boundary_length: NonZeroUsize) -> ParseResult<(HrxPath, HrxEntry)> {# ! [ allow ( non_snake_case , unused ) ] let mut __state = ParseState::new();
match __parse_entry(__input, &mut __state, 0, boundary_length) {
Matched(__pos, __value) => {
if __pos == __input.len() {
return Ok(__value);
}
}
_ => {}
}
let (__line, __col) = pos_to_line(__input, __state.max_err_pos);
Err(ParseError {
line: __line,
column: __col,
offset: __state.max_err_pos,
expected: __state.expected,
})
}
pub fn comment<'input>(__input: &'input str, boundary_length: NonZeroUsize) -> ParseResult<&'input str> {# ! [ allow ( non_snake_case , unused ) ] let mut __state = ParseState::new();
match __parse_comment(__input, &mut __state, 0, boundary_length) {
Matched(__pos, __value) => {
if __pos == __input.len() {
return Ok(__value);
}
}
_ => {}
}
let (__line, __col) = pos_to_line(__input, __state.max_err_pos);
Err(ParseError {
line: __line,
column: __col,
offset: __state.max_err_pos,
expected: __state.expected,
})
}
pub fn file<'input>(__input: &'input str, boundary_length: NonZeroUsize) -> ParseResult<(HrxPath, Option<&'input str>)> {# ! [ allow ( non_snake_case , unused ) ] let mut __state = ParseState::new();
match __parse_file(__input, &mut __state, 0, boundary_length) {
Matched(__pos, __value) => {
if __pos == __input.len() {
return Ok(__value);
}
}
_ => {}
}
let (__line, __col) = pos_to_line(__input, __state.max_err_pos);
Err(ParseError {
line: __line,
column: __col,
offset: __state.max_err_pos,
expected: __state.expected,
})
}
pub fn directory<'input>(__input: &'input str, boundary_length: NonZeroUsize) -> ParseResult<HrxPath> {# ! [ allow ( non_snake_case , unused ) ] let mut __state = ParseState::new();
match __parse_directory(__input, &mut __state, 0, boundary_length) {
Matched(__pos, __value) => {
if __pos == __input.len() {
return Ok(__value);
}
}
_ => {}
}
let (__line, __col) = pos_to_line(__input, __state.max_err_pos);
Err(ParseError {
line: __line,
column: __col,
offset: __state.max_err_pos,
expected: __state.expected,
})
}
pub fn body<'input>(__input: &'input str, boundary_length: NonZeroUsize) -> ParseResult<&'input str> {# ! [ allow ( non_snake_case , unused ) ] let mut __state = ParseState::new();
match __parse_body(__input, &mut __state, 0, boundary_length) {
Matched(__pos, __value) => {
if __pos == __input.len() {
return Ok(__value);
}
}
_ => {}
}
let (__line, __col) = pos_to_line(__input, __state.max_err_pos);
Err(ParseError {
line: __line,
column: __col,
offset: __state.max_err_pos,
expected: __state.expected,
})
}
pub fn path<'input>(__input: &'input str, boundary_length: NonZeroUsize) -> ParseResult<HrxPath> {# ! [ allow ( non_snake_case , unused ) ] let mut __state = ParseState::new();
match __parse_path(__input, &mut __state, 0, boundary_length) {
Matched(__pos, __value) => {
if __pos == __input.len() {
return Ok(__value);
}
}
_ => {}
}
let (__line, __col) = pos_to_line(__input, __state.max_err_pos);
Err(ParseError {
line: __line,
column: __col,
offset: __state.max_err_pos,
expected: __state.expected,
})
}