use std::vec;
use syn::{punctuated::Punctuated, token, PathSegment};
use typst::syntax::ast::Params;
use crate::literal_string;
pub fn typst_scope_to_rust(scope: &typst::eval::Scope) -> syn::Item {
let functions = scope
.iter()
.map(|(name, value)| {
if let Ok(value) = value.clone().cast::<typst::eval::Func>() {
typst_func_to_rust(name.as_str(), value)
} else {
todo!()
}
})
.collect::<Vec<_>>();
syn::Item::Mod(syn::ItemMod {
attrs: Vec::new(),
vis: syn::Visibility::Public(token::Pub::default()),
unsafety: None,
mod_token: token::Mod::default(),
ident: syn::Ident::new("test", proc_macro2::Span::call_site()),
content: Some((token::Brace::default(), functions)),
semi: None,
})
}
fn typst_params_to_syn<'a>(params: Params<'a>) -> impl Iterator<Item = syn::FnArg> + 'a {
dbg!(params.children().collect::<Vec<_>>());
params.children().map(|child| {
if let typst::syntax::ast::Param::Pos(typst::syntax::ast::Pattern::Normal(
typst::syntax::ast::Expr::Ident(param),
)) = child
{
syn::FnArg::Typed(syn::PatType {
attrs: Vec::new(),
pat: Box::new(syn::Pat::Ident(syn::PatIdent {
attrs: Vec::new(),
by_ref: None,
mutability: None,
ident: syn::Ident::new(param.as_str(), proc_macro2::Span::call_site()),
subpat: None,
})),
colon_token: token::Colon::default(),
ty: Box::new(syn::Type::Path(syn::TypePath {
qself: None,
path: syn::Path {
leading_colon: None,
segments: Punctuated::from_iter(
vec![
syn::PathSegment {
ident: syn::Ident::new("typst", proc_macro2::Span::call_site()),
arguments: syn::PathArguments::None,
},
syn::PathSegment {
ident: syn::Ident::new("eval", proc_macro2::Span::call_site()),
arguments: syn::PathArguments::None,
},
syn::PathSegment {
ident: syn::Ident::new("Value", proc_macro2::Span::call_site()),
arguments: syn::PathArguments::None,
},
]
.into_iter(),
),
},
})),
})
} else {
dbg!(child);
todo!()
}
})
}
fn typst_op_to_syn(operation: typst::syntax::ast::BinOp) -> syn::BinOp {
match operation {
typst::syntax::ast::BinOp::Add => syn::BinOp::Add(token::Plus::default()),
_ => todo!(),
}
}
fn typst_expr_to_syn(expression: typst::syntax::ast::Expr) -> syn::Expr {
match expression {
typst::syntax::ast::Expr::Binary(binary) => syn::Expr::Call(syn::ExprCall {
attrs: Vec::new(),
func: Box::new(syn::Expr::Path(syn::ExprPath {
attrs: Vec::new(),
qself: None,
path: syn::Path {
leading_colon: None,
segments: Punctuated::from_iter(
vec![
syn::PathSegment {
ident: syn::Ident::new("typst", proc_macro2::Span::call_site()),
arguments: syn::PathArguments::None,
},
syn::PathSegment {
ident: syn::Ident::new("eval", proc_macro2::Span::call_site()),
arguments: syn::PathArguments::None,
},
syn::PathSegment {
ident: syn::Ident::new("ops", proc_macro2::Span::call_site()),
arguments: syn::PathArguments::None,
},
syn::PathSegment {
ident: syn::Ident::new(
match binary.op() {
typst::syntax::ast::BinOp::Add => "add",
_ => todo!(),
},
proc_macro2::Span::call_site(),
),
arguments: syn::PathArguments::None,
},
]
.into_iter(),
),
},
})),
paren_token: token::Paren::default(),
args: Punctuated::from_iter(
vec![
typst_expr_to_syn(binary.lhs()),
typst_expr_to_syn(binary.rhs()),
]
.into_iter(),
),
}),
// syn::Expr::Binary(syn::ExprBinary {
// attrs: Vec::new(),
// left: Box::new(typst_expr_to_syn(binary.lhs())),
// op: typst_op_to_syn(binary.op()),
// right: Box::new(typst_expr_to_syn(binary.rhs())),
// }),
typst::syntax::ast::Expr::Ident(ident) => syn::Expr::Path(syn::ExprPath {
attrs: Vec::new(),
qself: None,
path: syn::Path {
leading_colon: None,
segments: Punctuated::from_iter(
Some(syn::PathSegment {
ident: syn::Ident::new(ident.as_str(), proc_macro2::Span::call_site()),
arguments: syn::PathArguments::None,
})
.into_iter(),
),
},
}),
_ => {
dbg!(expression);
todo!()
}
}
}
pub fn typst_func_to_rust(name: &str, func: typst::eval::Func) -> syn::Item {
syn::Item::Fn(match func.repr {
typst::eval::FuncRepr::Closure(closure) => {
let closure_ast = closure.node.cast::<typst::syntax::ast::Closure>().unwrap();
dbg!(typst_params_to_syn(closure_ast.params()).collect::<Vec<_>>());
syn::ItemFn {
attrs: Vec::new(),
vis: syn::Visibility::Public(token::Pub::default()),
sig: syn::Signature {
constness: None,
asyncness: None,
unsafety: None,
abi: None,
fn_token: token::Fn::default(),
ident: syn::Ident::new(name, proc_macro2::Span::call_site()),
generics: syn::Generics::default(),
paren_token: token::Paren::default(),
inputs: Punctuated::from_iter(typst_params_to_syn(closure_ast.params())),
variadic: None,
output: syn::ReturnType::Type(
token::RArrow::default(),
Box::new(syn::Type::Path(syn::TypePath {
qself: None,
path: syn::Path {
leading_colon: None,
segments: Punctuated::from_iter(
vec![
syn::PathSegment {
ident: syn::Ident::new(
"typst",
proc_macro2::Span::call_site(),
),
arguments: syn::PathArguments::None,
},
syn::PathSegment {
ident: syn::Ident::new(
"diag",
proc_macro2::Span::call_site(),
),
arguments: syn::PathArguments::None,
},
syn::PathSegment {
ident: syn::Ident::new(
"StrResult",
proc_macro2::Span::call_site(),
),
arguments: syn::PathArguments::AngleBracketed(
syn::AngleBracketedGenericArguments {
colon2_token: None,
lt_token: token::Lt::default(),
args: Punctuated::from_iter(
Some(syn::GenericArgument::Type(
syn::Type::Path(syn::TypePath {
qself: None,
path: syn::Path {
leading_colon: None,
segments: Punctuated::from_iter(
vec![
syn::PathSegment {
ident: syn::Ident::new(
"typst",
proc_macro2::Span::call_site(),
),
arguments: syn::PathArguments::None,
},
syn::PathSegment {
ident: syn::Ident::new(
"eval",
proc_macro2::Span::call_site(),
),
arguments: syn::PathArguments::None,
},syn::PathSegment {
ident: syn::Ident::new(
"Value",
proc_macro2::Span::call_site(),
),
arguments: syn::PathArguments::None,
}].into_iter(),
),
},
}),
))
.into_iter(),
),
gt_token: token::Gt::default(),
},
),
},
]
.into_iter(),
),
},
})),
),
},
block: Box::new(syn::Block {
brace_token: token::Brace::default(),
stmts: vec![syn::Stmt::Expr(typst_expr_to_syn(closure_ast.body()), None)],
}),
}
}
_ => todo!(),
})
}