114 lines
3.2 KiB
Rust
114 lines
3.2 KiB
Rust
use std::fmt;
|
|
use syn::{ext::*, spanned::*, *};
|
|
|
|
macro_rules! syn_error {
|
|
($src:expr, $($fmt:expr),+) => {{
|
|
return Err(syn::Error::new($src.span(), format!($($fmt),*)));
|
|
}};
|
|
}
|
|
|
|
macro_rules! syn_assert {
|
|
($cond:expr, $src:expr, $($fmt:expr),+) => {{
|
|
if !$cond {
|
|
syn_error!($src, $($fmt),+);
|
|
}
|
|
}};
|
|
}
|
|
|
|
pub(crate) use {syn_assert, syn_error};
|
|
|
|
pub fn wrap_expr_block(expr: &Expr) -> Block {
|
|
// return the expr if it's a block, otherwise wrap it in a block
|
|
match expr {
|
|
Expr::Block(block) if block.label.is_none() => block.block.clone(),
|
|
expr => parse_quote!({ #expr }),
|
|
}
|
|
}
|
|
|
|
pub fn unwrap_expr_ident(expr: &Expr) -> Result<&Ident> {
|
|
match expr {
|
|
Expr::Path(path) => path.path.require_ident(),
|
|
_ => syn_error!(expr, "expected ident"),
|
|
}
|
|
}
|
|
|
|
pub fn unwrap_pat_ident(pat: &Pat) -> Result<Ident> {
|
|
Ok(match pat {
|
|
Pat::Ident(ident) => match ident.subpat {
|
|
Some((_, ref subpat)) => syn_error!(subpat, "unexpected subpattern"),
|
|
None => ident.ident.clone(),
|
|
},
|
|
Pat::Wild(wild) => Ident::new("_", wild.span()),
|
|
_ => syn_error!(pat, "expected ident"),
|
|
})
|
|
}
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
pub enum LuaType {
|
|
Any,
|
|
Nil,
|
|
Boolean,
|
|
Lightuserdata,
|
|
Number,
|
|
Integer,
|
|
String,
|
|
Table,
|
|
Function,
|
|
Userdata,
|
|
Thread,
|
|
Cdata,
|
|
}
|
|
|
|
impl fmt::Display for LuaType {
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
match self {
|
|
LuaType::Any => write!(f, "any"),
|
|
LuaType::Nil => write!(f, "nil"),
|
|
LuaType::Boolean => write!(f, "boolean"),
|
|
LuaType::Lightuserdata => write!(f, "lightuserdata"),
|
|
LuaType::Number => write!(f, "number"),
|
|
LuaType::Integer => write!(f, "integer"),
|
|
LuaType::String => write!(f, "string"),
|
|
LuaType::Table => write!(f, "table"),
|
|
LuaType::Function => write!(f, "function"),
|
|
LuaType::Userdata => write!(f, "userdata"),
|
|
LuaType::Thread => write!(f, "thread"),
|
|
LuaType::Cdata => write!(f, "cdata"),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl TryFrom<&Ident> for LuaType {
|
|
type Error = Error;
|
|
|
|
fn try_from(value: &Ident) -> Result<Self> {
|
|
Ok(match format!("{}", value.unraw()).as_str() {
|
|
"any" => Self::Any,
|
|
"nil" => Self::Nil,
|
|
"boolean" => Self::Boolean,
|
|
"lightuserdata" => Self::Lightuserdata,
|
|
"number" => Self::Number,
|
|
"integer" => Self::Integer,
|
|
"string" => Self::String,
|
|
"table" => Self::Table,
|
|
"function" => Self::Function,
|
|
"userdata" => Self::Userdata,
|
|
"thread" => Self::Thread,
|
|
"cdata" => Self::Cdata,
|
|
_ => syn_error!(value, "invalid lua type"),
|
|
})
|
|
}
|
|
}
|
|
|
|
impl TryFrom<&Type> for LuaType {
|
|
type Error = Error;
|
|
|
|
fn try_from(value: &Type) -> Result<Self> {
|
|
match value {
|
|
Type::Infer(_) => Ok(Self::Any),
|
|
Type::Path(path) if path.qself.is_none() => path.path.require_ident()?.try_into(),
|
|
_ => syn_error!(value, "invalid lua type"),
|
|
}
|
|
}
|
|
}
|