Tweak Mode.

- Add `use Mode::*` to avoid all the qualifiers.
- Reorder the variants. The existing order makes no particular sense,
  which has bugged me for some time. I've chosen an order that makes
  sense to me.
This commit is contained in:
Nicholas Nethercote 2023-12-07 11:18:09 +11:00
parent adc46e5c08
commit 0a401b624b

View File

@ -4,6 +4,8 @@
use std::ops::Range; use std::ops::Range;
use std::str::Chars; use std::str::Chars;
use Mode::*;
#[cfg(test)] #[cfg(test)]
mod tests; mod tests;
@ -85,15 +87,14 @@ where
F: FnMut(Range<usize>, Result<char, EscapeError>), F: FnMut(Range<usize>, Result<char, EscapeError>),
{ {
match mode { match mode {
Mode::Char | Mode::Byte => { Char | Byte => {
let mut chars = src.chars(); let mut chars = src.chars();
let res = unescape_char_or_byte(&mut chars, mode); let res = unescape_char_or_byte(&mut chars, mode);
callback(0..(src.len() - chars.as_str().len()), res); callback(0..(src.len() - chars.as_str().len()), res);
} }
Mode::Str | Mode::ByteStr => unescape_str_common(src, mode, callback), Str | ByteStr => unescape_str_common(src, mode, callback),
RawStr | RawByteStr => unescape_raw_str_or_raw_byte_str(src, mode, callback),
Mode::RawStr | Mode::RawByteStr => unescape_raw_str_or_raw_byte_str(src, mode, callback), CStr | RawCStr => unreachable!(),
Mode::CStr | Mode::RawCStr => unreachable!(),
} }
} }
@ -119,36 +120,44 @@ pub fn unescape_c_string<F>(src: &str, mode: Mode, callback: &mut F)
where where
F: FnMut(Range<usize>, Result<CStrUnit, EscapeError>), F: FnMut(Range<usize>, Result<CStrUnit, EscapeError>),
{ {
if mode == Mode::RawCStr { match mode {
unescape_raw_str_or_raw_byte_str(src, mode, &mut |r, result| { CStr => {
callback(r, result.map(CStrUnit::Char)) unescape_str_common(src, mode, callback);
}); }
} else { RawCStr => {
unescape_str_common(src, mode, callback); unescape_raw_str_or_raw_byte_str(src, mode, &mut |r, result| {
callback(r, result.map(CStrUnit::Char))
});
}
Char | Byte | Str | RawStr | ByteStr | RawByteStr => unreachable!(),
} }
} }
/// Takes a contents of a char literal (without quotes), and returns an /// Takes a contents of a char literal (without quotes), and returns an
/// unescaped char or an error. /// unescaped char or an error.
pub fn unescape_char(src: &str) -> Result<char, EscapeError> { pub fn unescape_char(src: &str) -> Result<char, EscapeError> {
unescape_char_or_byte(&mut src.chars(), Mode::Char) unescape_char_or_byte(&mut src.chars(), Char)
} }
/// Takes a contents of a byte literal (without quotes), and returns an /// Takes a contents of a byte literal (without quotes), and returns an
/// unescaped byte or an error. /// unescaped byte or an error.
pub fn unescape_byte(src: &str) -> Result<u8, EscapeError> { pub fn unescape_byte(src: &str) -> Result<u8, EscapeError> {
unescape_char_or_byte(&mut src.chars(), Mode::Byte).map(byte_from_char) unescape_char_or_byte(&mut src.chars(), Byte).map(byte_from_char)
} }
/// What kind of literal do we parse. /// What kind of literal do we parse.
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub enum Mode { pub enum Mode {
Char, Char,
Str,
Byte, Byte,
ByteStr,
Str,
RawStr, RawStr,
ByteStr,
RawByteStr, RawByteStr,
CStr, CStr,
RawCStr, RawCStr,
} }
@ -156,47 +165,42 @@ pub enum Mode {
impl Mode { impl Mode {
pub fn in_double_quotes(self) -> bool { pub fn in_double_quotes(self) -> bool {
match self { match self {
Mode::Str Str | RawStr | ByteStr | RawByteStr | CStr | RawCStr => true,
| Mode::ByteStr Char | Byte => false,
| Mode::RawStr
| Mode::RawByteStr
| Mode::CStr
| Mode::RawCStr => true,
Mode::Char | Mode::Byte => false,
} }
} }
/// Non-byte literals should have `\xXX` escapes that are within the ASCII range. /// Non-byte literals should have `\xXX` escapes that are within the ASCII range.
fn ascii_escapes_should_be_ascii(self) -> bool { fn ascii_escapes_should_be_ascii(self) -> bool {
match self { match self {
Mode::Char | Mode::Str => true, Char | Str => true,
Mode::Byte | Mode::ByteStr | Mode::CStr => false, Byte | ByteStr | CStr => false,
Mode::RawStr | Mode::RawByteStr | Mode::RawCStr => unreachable!(), RawStr | RawByteStr | RawCStr => unreachable!(),
} }
} }
/// Whether characters within the literal must be within the ASCII range /// Whether characters within the literal must be within the ASCII range.
#[inline] #[inline]
fn chars_should_be_ascii(self) -> bool { fn chars_should_be_ascii(self) -> bool {
match self { match self {
Mode::Byte | Mode::ByteStr | Mode::RawByteStr => true, Byte | ByteStr | RawByteStr => true,
Mode::Char | Mode::Str | Mode::RawStr | Mode::CStr | Mode::RawCStr => false, Char | Str | RawStr | CStr | RawCStr => false,
} }
} }
/// Byte literals do not allow unicode escape. /// Byte literals do not allow unicode escape.
fn is_unicode_escape_disallowed(self) -> bool { fn is_unicode_escape_disallowed(self) -> bool {
match self { match self {
Mode::Byte | Mode::ByteStr | Mode::RawByteStr => true, Byte | ByteStr | RawByteStr => true,
Mode::Char | Mode::Str | Mode::RawStr | Mode::CStr | Mode::RawCStr => false, Char | Str | RawStr | CStr | RawCStr => false,
} }
} }
pub fn prefix_noraw(self) -> &'static str { pub fn prefix_noraw(self) -> &'static str {
match self { match self {
Mode::Byte | Mode::ByteStr | Mode::RawByteStr => "b", Char | Str | RawStr => "",
Mode::CStr | Mode::RawCStr => "c", Byte | ByteStr | RawByteStr => "b",
Mode::Char | Mode::Str | Mode::RawStr => "", CStr | RawCStr => "c",
} }
} }
} }
@ -411,7 +415,7 @@ where
#[inline] #[inline]
pub fn byte_from_char(c: char) -> u8 { pub fn byte_from_char(c: char) -> u8 {
let res = c as u32; let res = c as u32;
debug_assert!(res <= u8::MAX as u32, "guaranteed because of Mode::ByteStr"); debug_assert!(res <= u8::MAX as u32, "guaranteed because of ByteStr");
res as u8 res as u8
} }