mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-16 23:08:05 +08:00
Initial implementation of node graph based on structs
This commit is contained in:
committed by
Keavon Chambers
parent
58c1a9db03
commit
01bbe5dced
47
node-graph/proc-macro/Cargo.lock
generated
Normal file
47
node-graph/proc-macro/Cargo.lock
generated
Normal file
@@ -0,0 +1,47 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "graph-proc-macros"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f71489ff30030d2ae598524f61326b902466f72a0fb1a8564c001cc63425bcc7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
15
node-graph/proc-macro/Cargo.toml
Normal file
15
node-graph/proc-macro/Cargo.toml
Normal file
@@ -0,0 +1,15 @@
|
||||
[package]
|
||||
name = "graph-proc-macros"
|
||||
version = "0.1.0"
|
||||
authors = ["Graphite Authors <contact@graphite.design>"]
|
||||
edition = "2018"
|
||||
publish = false
|
||||
|
||||
[lib]
|
||||
path = "src/lib.rs"
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
proc-macro2 = "1.0.26"
|
||||
syn = { version = "1.0.68", features = ["full"] }
|
||||
quote = "1.0.9"
|
||||
76
node-graph/proc-macro/src/lib.rs
Normal file
76
node-graph/proc-macro/src/lib.rs
Normal file
@@ -0,0 +1,76 @@
|
||||
use proc_macro::TokenStream;
|
||||
use quote::{quote, ToTokens};
|
||||
use syn::punctuated::Punctuated;
|
||||
use syn::{parse_macro_input, FnArg, ItemFn, Pat, Type};
|
||||
|
||||
fn extract_type(a: FnArg) -> Box<Type> {
|
||||
match a {
|
||||
FnArg::Typed(p) => p.ty, // notice `ty` instead of `pat`
|
||||
_ => panic!("Not supported on types with `self`!"),
|
||||
}
|
||||
}
|
||||
|
||||
fn extract_arg_types(fn_args: Punctuated<FnArg, syn::token::Comma>) -> Vec<Box<Type>> {
|
||||
return fn_args.into_iter().map(extract_type).collect::<Vec<_>>();
|
||||
}
|
||||
|
||||
fn extract_arg_idents(fn_args: Punctuated<FnArg, syn::token::Comma>) -> Vec<Box<Pat>> {
|
||||
return fn_args.into_iter().map(extract_arg_pat).collect::<Vec<_>>();
|
||||
}
|
||||
|
||||
fn extract_arg_pat(a: FnArg) -> Box<Pat> {
|
||||
match a {
|
||||
FnArg::Typed(p) => p.pat,
|
||||
_ => panic!("Not supported on types with `self`!"),
|
||||
}
|
||||
}
|
||||
|
||||
#[proc_macro_attribute] // 2
|
||||
pub fn to_node(_attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
let string = item.to_string();
|
||||
let item2 = item.clone();
|
||||
let parsed = parse_macro_input!(item2 as ItemFn); // 3
|
||||
//item.extend(generate_to_string(parsed, string)); // 4
|
||||
//item
|
||||
generate_to_string(parsed, string)
|
||||
}
|
||||
|
||||
fn generate_to_string(parsed: ItemFn, string: String) -> TokenStream {
|
||||
let whole_function = parsed.clone();
|
||||
//let fn_body = parsed.block; // function body
|
||||
let sig = parsed.sig; // function signature
|
||||
//let vis = parsed.vis; // visibility, pub or not
|
||||
let generics = sig.generics;
|
||||
let fn_args = sig.inputs; // comma separated args
|
||||
let fn_return_type = sig.output; // return type
|
||||
let fn_name = sig.ident; // function name/identifier
|
||||
let idents = extract_arg_idents(fn_args.clone());
|
||||
let types = extract_arg_types(fn_args);
|
||||
let types = types.iter().map(|t| t.to_token_stream()).collect::<Vec<_>>();
|
||||
let idents = idents.iter().map(|t| t.to_token_stream()).collect::<Vec<_>>();
|
||||
|
||||
let node_fn_name = syn::Ident::new(&(fn_name.to_string() + "_node"), proc_macro2::Span::call_site()); // function name/identifier
|
||||
let return_type_string = fn_return_type.to_token_stream().to_string().replace("->","");
|
||||
let arg_type_string = types.iter().map(|t|t.to_string()).collect::<Vec<_>>().join(", ");
|
||||
let error = format!("called {} with the wrong type", fn_name.to_string());
|
||||
|
||||
let x = quote! {
|
||||
//#whole_function
|
||||
fn #node_fn_name #generics() -> Node {
|
||||
Node { func: Box::new(move |x| {
|
||||
let args = x.downcast::<(#(#types,)*)>().expect(#error);
|
||||
let (#(#idents,)*) = *args;
|
||||
#whole_function
|
||||
|
||||
Box::new(#fn_name(#(#idents,)*))
|
||||
}),
|
||||
code: #string.to_string(),
|
||||
return_type: #return_type_string.trim().to_string(),
|
||||
args: format!("({})",#arg_type_string.trim()),
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
//panic!("{}\n{:?}", x.to_string(), x);
|
||||
x.into()
|
||||
}
|
||||
Reference in New Issue
Block a user