+ 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!(),
+ })
+ }