Skip to content

Commit 2860513

Browse files
committed
impl std::str::FromStr for compile::Mode
1 parent 4f9a71f commit 2860513

File tree

5 files changed

+40
-22
lines changed

5 files changed

+40
-22
lines changed

compiler/src/compile.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,35 @@ pub enum Mode {
109109
Single,
110110
}
111111

112+
impl std::str::FromStr for Mode {
113+
type Err = ModeParseError;
114+
fn from_str(s: &str) -> Result<Self, ModeParseError> {
115+
match s {
116+
"exec" => Ok(Mode::Exec),
117+
"eval" => Ok(Mode::Eval),
118+
"single" => Ok(Mode::Single),
119+
_ => Err(ModeParseError { _priv: () }),
120+
}
121+
}
122+
}
123+
124+
#[derive(Debug)]
125+
pub struct ModeParseError {
126+
_priv: (),
127+
}
128+
129+
impl std::fmt::Display for ModeParseError {
130+
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
131+
write!(f, r#"mode should be "exec", "eval", or "single""#)
132+
}
133+
}
134+
135+
#[derive(Clone, Copy)]
136+
enum EvalContext {
137+
Statement,
138+
Expression,
139+
}
140+
112141
pub(crate) type Label = usize;
113142

114143
impl<O> Default for Compiler<O>

derive/src/compile_bytecode.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -169,15 +169,13 @@ impl PyCompileInput {
169169
for meta in &self.metas {
170170
if let Meta::NameValue(name_value) = meta {
171171
if name_value.ident == "mode" {
172-
mode = Some(match &name_value.lit {
173-
Lit::Str(s) => match s.value().as_str() {
174-
"exec" => compile::Mode::Exec,
175-
"eval" => compile::Mode::Eval,
176-
"single" => compile::Mode::Single,
177-
_ => bail_span!(s, "mode must be exec, eval, or single"),
172+
match &name_value.lit {
173+
Lit::Str(s) => match s.value().parse() {
174+
Ok(mode_val) => mode = Some(mode_val),
175+
Err(e) => bail_span!(s, "{}", e),
178176
},
179177
_ => bail_span!(name_value.lit, "mode must be a string"),
180-
})
178+
}
181179
} else if name_value.ident == "module_name" {
182180
module_name = Some(match &name_value.lit {
183181
Lit::Str(s) => s.value(),

vm/src/builtins.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ use crate::obj::objtype::{self, PyClassRef};
2121
#[cfg(feature = "rustpython-compiler")]
2222
use rustpython_compiler::compile;
2323

24-
use crate::eval::get_compile_mode;
2524
use crate::function::{single_or_tuple_any, Args, KwArgs, OptionalArg, PyFuncArgs};
2625
use crate::pyobject::{
2726
Either, IdProtocol, IntoPyObject, ItemProtocol, PyIterable, PyObjectRef, PyResult, PyValue,
@@ -125,7 +124,9 @@ fn builtin_compile(args: CompileArgs, vm: &VirtualMachine) -> PyResult<PyCodeRef
125124
Either::B(bytes) => str::from_utf8(&bytes).unwrap().to_string(),
126125
};
127126

128-
let mode = get_compile_mode(vm, &args.mode.value)?;
127+
let mode = args.mode.as_str().parse().map_err(|_| {
128+
vm.new_value_error("compile() mode must be 'exec', 'eval' or 'single'".to_owned())
129+
})?;
129130

130131
vm.compile(&source, mode, args.filename.value.to_string())
131132
.map_err(|err| vm.new_syntax_error(&err))

vm/src/eval.rs

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,6 @@ pub fn eval(vm: &VirtualMachine, source: &str, scope: Scope, source_path: &str)
1313
}
1414
}
1515

16-
pub fn get_compile_mode(vm: &VirtualMachine, mode: &str) -> PyResult<compile::Mode> {
17-
match mode {
18-
"exec" => Ok(compile::Mode::Exec),
19-
"eval" => Ok(compile::Mode::Eval),
20-
"single" => Ok(compile::Mode::Single),
21-
_ => {
22-
Err(vm.new_value_error("compile() mode must be 'exec', 'eval' or 'single'".to_string()))
23-
}
24-
}
25-
}
26-
2716
#[cfg(test)]
2817
mod tests {
2918
use super::eval;

vm/src/stdlib/symtable.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use crate::eval::get_compile_mode;
21
use crate::obj::objstr::PyStringRef;
32
use crate::obj::objtype::PyClassRef;
43
use crate::pyobject::{PyClassImpl, PyObjectRef, PyRef, PyResult, PyValue};
@@ -28,7 +27,9 @@ fn symtable_symtable(
2827
mode: PyStringRef,
2928
vm: &VirtualMachine,
3029
) -> PyResult<PySymbolTableRef> {
31-
let mode = get_compile_mode(vm, &mode.value)?;
30+
let mode = mode.as_str().parse().map_err(|_| {
31+
vm.new_value_error("symtable() arg 3 must be 'exec' or 'eval' or 'single'".to_owned())
32+
})?;
3233
let symtable =
3334
source_to_symtable(&source.value, mode).map_err(|err| vm.new_syntax_error(&err))?;
3435

0 commit comments

Comments
 (0)