#[derive(Debug, Clone, PartialEq)]
pub enum Stmt {
Load { module: String, names: Vec<String> },
Assign { target: String, value: Expr },
FuncDef {
name: String,
params: Vec<Param>,
body: Vec<Stmt>,
},
Return(Expr),
Expr(Expr),
Comment(String),
Blank,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Param {
pub name: String,
pub default: Option<Expr>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum Expr {
String(String),
Bool(bool),
Int(i64),
None,
Ident(String),
List(Vec<Expr>),
Tuple(Vec<Expr>),
Dict(Vec<DictEntry>),
Call {
func: Box<Expr>,
args: Vec<Expr>,
kwargs: Vec<(String, Expr)>,
},
Attr { value: Box<Expr>, attr: String },
Raw(String),
Commented { comment: String, expr: Box<Expr> },
}
#[derive(Debug, Clone, PartialEq)]
pub struct DictEntry {
pub key: Expr,
pub value: Expr,
}
impl Expr {
pub fn string(s: impl Into<String>) -> Self {
Expr::String(s.into())
}
pub fn bool(b: bool) -> Self {
Expr::Bool(b)
}
pub fn ident(s: impl Into<String>) -> Self {
Expr::Ident(s.into())
}
pub fn call(func: impl Into<String>, args: Vec<Expr>) -> Self {
Expr::Call {
func: Box::new(Expr::Ident(func.into())),
args,
kwargs: vec![],
}
}
pub fn call_kwargs(
func: impl Into<String>,
args: Vec<Expr>,
kwargs: Vec<(impl Into<String>, Expr)>,
) -> Self {
Expr::Call {
func: Box::new(Expr::Ident(func.into())),
args,
kwargs: kwargs.into_iter().map(|(k, v)| (k.into(), v)).collect(),
}
}
pub fn method(
self,
method: impl Into<String>,
args: Vec<Expr>,
kwargs: Vec<(impl Into<String>, Expr)>,
) -> Self {
Expr::Call {
func: Box::new(Expr::Attr {
value: Box::new(self),
attr: method.into(),
}),
args,
kwargs: kwargs.into_iter().map(|(k, v)| (k.into(), v)).collect(),
}
}
pub fn attr(self, attr: impl Into<String>) -> Self {
Expr::Attr {
value: Box::new(self),
attr: attr.into(),
}
}
pub fn list(items: Vec<Expr>) -> Self {
Expr::List(items)
}
pub fn tuple(items: Vec<Expr>) -> Self {
Expr::Tuple(items)
}
pub fn dict(entries: Vec<DictEntry>) -> Self {
Expr::Dict(entries)
}
pub fn raw(s: impl Into<String>) -> Self {
Expr::Raw(s.into())
}
pub fn allow(self) -> Self {
self.method("allow", vec![], Vec::<(&str, Expr)>::new())
}
pub fn deny(self) -> Self {
self.method("deny", vec![], Vec::<(&str, Expr)>::new())
}
pub fn ask(self) -> Self {
self.method("ask", vec![], Vec::<(&str, Expr)>::new())
}
pub fn sandbox(self, sb: Expr) -> Self {
self.method("sandbox", vec![sb], Vec::<(&str, Expr)>::new())
}
pub fn recurse(self) -> Self {
self.method("recurse", vec![], Vec::<(&str, Expr)>::new())
}
pub fn child(self, name: impl Into<String>) -> Self {
self.method(
"child",
vec![Expr::string(name)],
Vec::<(&str, Expr)>::new(),
)
}
pub fn allow_kwargs(self, kwargs: Vec<(impl Into<String>, Expr)>) -> Self {
self.method("allow", vec![], kwargs)
}
pub fn commented(comment: impl Into<String>, expr: Expr) -> Self {
Expr::Commented {
comment: comment.into(),
expr: Box::new(expr),
}
}
}
impl DictEntry {
pub fn new(key: Expr, value: Expr) -> Self {
Self { key, value }
}
}
impl Stmt {
pub fn load(module: impl Into<String>, names: &[&str]) -> Self {
Stmt::Load {
module: module.into(),
names: names.iter().map(|s| (*s).to_owned()).collect(),
}
}
pub fn assign(target: impl Into<String>, value: Expr) -> Self {
Stmt::Assign {
target: target.into(),
value,
}
}
pub fn def(name: impl Into<String>, body: Vec<Stmt>) -> Self {
Stmt::FuncDef {
name: name.into(),
params: vec![],
body,
}
}
pub fn comment(text: impl Into<String>) -> Self {
Stmt::Comment(text.into())
}
}
impl From<bool> for Expr {
fn from(b: bool) -> Self {
Expr::Bool(b)
}
}
impl From<&str> for Expr {
fn from(s: &str) -> Self {
Expr::String(s.to_owned())
}
}
impl From<i64> for Expr {
fn from(n: i64) -> Self {
Expr::Int(n)
}
}