Add utilities to enum

This commit is contained in:
Jeong YunWon 2023-05-16 23:06:17 +09:00
parent 3bdf8a940a
commit 2c9d66f9f7
8 changed files with 30 additions and 15 deletions

View file

@ -11,3 +11,15 @@ pub enum ConversionFlag {
/// Converts by calling `repr(<value>)`. /// Converts by calling `repr(<value>)`.
Repr = b'r' as i8, Repr = b'r' as i8,
} }
impl ConversionFlag {
pub fn to_byte(&self) -> Option<u8> {
match self {
Self::None => None,
flag => Some(*flag as u8),
}
}
pub fn to_char(&self) -> Option<char> {
Some(self.to_byte()? as char)
}
}

View file

@ -1,7 +1,7 @@
//! Control in the different modes by which a source file can be parsed. //! Control in the different modes by which a source file can be parsed.
/// The mode argument specifies in what way code must be parsed. /// The mode argument specifies in what way code must be parsed.
#[derive(Clone, Copy)] #[derive(Clone, Copy, Hash, PartialEq, Eq)]
pub enum Mode { pub enum Mode {
/// The code consists of a sequence of statements. /// The code consists of a sequence of statements.
Module, Module,

View file

@ -9,6 +9,7 @@ license = "MIT"
[dependencies] [dependencies]
hexf-parse = "0.2.1" hexf-parse = "0.2.1"
is-macro.workspace = true
lexical-parse-float = { version = "0.8.0", features = ["format"] } lexical-parse-float = { version = "0.8.0", features = ["format"] }
num-traits = { workspace = true } num-traits = { workspace = true }
unic-ucd-category = "0.9" unic-ucd-category = "0.9"

View file

@ -1,4 +1,4 @@
#[derive(Debug, PartialEq, Eq, Copy, Clone)] #[derive(Debug, PartialEq, Eq, Copy, Clone, Hash, is_macro::Is)]
pub enum Quote { pub enum Quote {
Single, Single,
Double, Double,

View file

@ -1,4 +1,4 @@
#[derive(Debug, PartialEq, Clone, Copy)] #[derive(Debug, PartialEq, Eq, Clone, Copy, is_macro::Is, Hash)]
pub enum Case { pub enum Case {
Lower, Lower,
Upper, Upper,

View file

@ -40,4 +40,4 @@ rustc-hash = "1.1.0"
serde = { version = "1.0.133", optional = true, default-features = false, features = ["derive"] } serde = { version = "1.0.133", optional = true, default-features = false, features = ["derive"] }
[dev-dependencies] [dev-dependencies]
insta = { workspace = true } insta = { workspace = true }

View file

@ -156,13 +156,13 @@ impl<'a> StringParser<'a> {
'v' => '\x0b', 'v' => '\x0b',
o @ '0'..='7' => self.parse_octet(o), o @ '0'..='7' => self.parse_octet(o),
'x' => self.parse_unicode_literal(2)?, 'x' => self.parse_unicode_literal(2)?,
'u' if !self.kind.is_bytes() => self.parse_unicode_literal(4)?, 'u' if !self.kind.is_any_bytes() => self.parse_unicode_literal(4)?,
'U' if !self.kind.is_bytes() => self.parse_unicode_literal(8)?, 'U' if !self.kind.is_any_bytes() => self.parse_unicode_literal(8)?,
'N' if !self.kind.is_bytes() => self.parse_unicode_name()?, 'N' if !self.kind.is_any_bytes() => self.parse_unicode_name()?,
// Special cases where the escape sequence is not a single character // Special cases where the escape sequence is not a single character
'\n' => return Ok("".to_string()), '\n' => return Ok("".to_string()),
c => { c => {
if self.kind.is_bytes() && !c.is_ascii() { if self.kind.is_any_bytes() && !c.is_ascii() {
return Err(LexicalError { return Err(LexicalError {
error: LexicalErrorType::OtherError( error: LexicalErrorType::OtherError(
"bytes can only contain ASCII literal characters".to_owned(), "bytes can only contain ASCII literal characters".to_owned(),
@ -578,9 +578,9 @@ impl<'a> StringParser<'a> {
} }
fn parse(&mut self) -> Result<Vec<Expr>, LexicalError> { fn parse(&mut self) -> Result<Vec<Expr>, LexicalError> {
if self.kind.is_fstring() { if self.kind.is_any_fstring() {
self.parse_fstring(0) self.parse_fstring(0)
} else if self.kind.is_bytes() { } else if self.kind.is_any_bytes() {
self.parse_bytes().map(|expr| vec![expr]) self.parse_bytes().map(|expr| vec![expr])
} else { } else {
self.parse_string().map(|expr| vec![expr]) self.parse_string().map(|expr| vec![expr])
@ -611,10 +611,12 @@ pub(crate) fn parse_strings(
let initial_start = values[0].0; let initial_start = values[0].0;
let last_end = values.last().unwrap().2; let last_end = values.last().unwrap().2;
let initial_kind = (values[0].1 .1 == StringKind::Unicode).then(|| "u".to_owned()); let initial_kind = (values[0].1 .1 == StringKind::Unicode).then(|| "u".to_owned());
let has_fstring = values.iter().any(|(_, (_, kind, ..), _)| kind.is_fstring()); let has_fstring = values
.iter()
.any(|(_, (_, kind, ..), _)| kind.is_any_fstring());
let num_bytes = values let num_bytes = values
.iter() .iter()
.filter(|(_, (_, kind, ..), _)| kind.is_bytes()) .filter(|(_, (_, kind, ..), _)| kind.is_any_bytes())
.count(); .count();
let has_bytes = num_bytes > 0; let has_bytes = num_bytes > 0;

View file

@ -327,7 +327,7 @@ impl fmt::Display for Tok {
/// section of the Python reference. /// section of the Python reference.
/// ///
/// [String and Bytes literals]: https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals /// [String and Bytes literals]: https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals
#[derive(PartialEq, Eq, Debug, Clone)] #[derive(PartialEq, Eq, Debug, Clone, Hash, Copy)] // TODO: is_macro::Is
pub enum StringKind { pub enum StringKind {
/// A normal string literal with no prefix. /// A normal string literal with no prefix.
String, String,
@ -398,14 +398,14 @@ impl StringKind {
/// Returns true if the string is an f-string, i,e one of /// Returns true if the string is an f-string, i,e one of
/// [`StringKind::FString`] or [`StringKind::RawFString`]. /// [`StringKind::FString`] or [`StringKind::RawFString`].
pub fn is_fstring(&self) -> bool { pub fn is_any_fstring(&self) -> bool {
use StringKind::{FString, RawFString}; use StringKind::{FString, RawFString};
matches!(self, FString | RawFString) matches!(self, FString | RawFString)
} }
/// Returns true if the string is a byte string, i,e one of /// Returns true if the string is a byte string, i,e one of
/// [`StringKind::Bytes`] or [`StringKind::RawBytes`]. /// [`StringKind::Bytes`] or [`StringKind::RawBytes`].
pub fn is_bytes(&self) -> bool { pub fn is_any_bytes(&self) -> bool {
use StringKind::{Bytes, RawBytes}; use StringKind::{Bytes, RawBytes};
matches!(self, Bytes | RawBytes) matches!(self, Bytes | RawBytes)
} }