There are so many caveats, but the most simple adding function can now be automatically expressed in Rust!
OVEFU3K2T36H3EMYOIF6U7AYWMJIV5IJYRL56F3PWRCG7EGEZMQAC GKBSBSDY5XLAT7SDKAVFQI3PHFUHKHTJGGXZH5XWG2E45U7BSU5QC 2N3KOCP74PCK2ETO5PCWBDR5PA57DDNT2KR4JLBPZPQPA56SAR4QC CQEA2ZDITRMPXKCO5T346QH7JJOOGOPRC66F3MG6VEMEQGLYYUZAC YKL5NCLHVHFQMBIWC6HW4NFPPYK5DR6XTCKJ5VBHNLVP2RO3H24AC HEIF2O2ELHA3M7K77CK7AHBZ4656AUS3QW5M4E2DUY7ECOLVWKIAC Q3IYM4WFHTO2IQLR2ZJ52FIE7U4RYIHQHXTPCK2HENSPVI7CPUZAC I3NG5A4WXPELEOY3KFQKYBZVKA56VPGLI5R7O7TDCZTQAA7EROTQC GYTRFADRDO4SYXV6V3PEPGGFIRDHQH5YBTKEJCWFAIZ5CX4P46NAC BA5Y6VSEHJQBOYBS6R6FE6IZDRNAPNIN5ITJXWK7L46RJVHNI7JAC BSJYWOYSJRERQ45AD7RN3364RYQ5P3IM76S67262VLFZPFO3B5JQC ZRGSUUICJKNHKVH2JZHHOKSSIQXNWCNLJX2ICSX524AG2XJKD3VAC 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!(),})}
token, AngleBracketedGenericArguments, ExprLit, ExprTuple, GenericArgument,GenericParam, Generics, Ident, Item, ItemFn, ItemMod, ItemUse, Lit, LitStr, PathArguments,PathSegment, ReturnType, Signature, Stmt, TraitBound, TraitBoundModifier, TypeImplTrait,TypeParam, TypeParamBound, TypePath, UseGroup, UseName, UsePath, UseTree, Visibility,
token, AngleBracketedGenericArguments, ExprLit, ExprTuple, GenericArgument, GenericParam,Generics, Ident, Item, ItemFn, ItemMod, ItemUse, Lit, LitStr, PathArguments, PathSegment,ReturnType, Signature, Stmt, TraitBound, TraitBoundModifier, TypeImplTrait, TypeParam,TypeParamBound, TypePath, UseGroup, UseName, UsePath, UseTree, Visibility,
dbg!(typst_ast.scope(), typst_ast.clone().content());let xilem_expressions = typst_to_xilem(typst_ast.content());let function = xilem_to_function(&fs_path_to_module_ident(&file), xilem_expressions);
// let xilem_expressions = typst_to_xilem(typst_ast.content());// let function = xilem_to_function(&fs_path_to_module_ident(&file), xilem_expressions);let function = scope::typst_scope_to_rust(typst_ast.scope());