Skip to content

Commit

Permalink
fmt + cli fix
Browse files Browse the repository at this point in the history
  • Loading branch information
AtomicGamer9523 committed Nov 11, 2023
1 parent a5e4720 commit 27a15eb
Show file tree
Hide file tree
Showing 16 changed files with 1,396 additions and 1,379 deletions.
156 changes: 78 additions & 78 deletions libs/macros-core/ffi/mod.rs
Original file line number Diff line number Diff line change
@@ -1,78 +1,78 @@
use crate::TokenStream;

/// Simplifies the creation of FFI functions
///
/// # Example
/// ```rust,ignore,no_run
/// #[macros::ffi(type = "system")]
/// pub fn Java_Main_greet<'a>(
/// mut env: JNIEnv<'a>, _class: JClass<'a>, input: JString<'a>
/// ) -> jstring {
/// // First, we have to get the string out of Java. Check out the `strings`
/// // module for more info on how this works.
/// let input: String = env.get_string(&input).expect("Couldn't get java string!").into();
///
/// // Then we have to create a new Java string to return. Again, more info
/// // in the `strings` module.
/// let output = env.new_string(
/// format!("Hello, {}!", input)
/// ).expect("Couldn't create java string!");
///
/// // Finally, extract the raw pointer to return.
/// output.into_raw()
/// }
/// ```
pub fn ffi<T: Into<TokenStream>>(cfg: T, input: T) -> TokenStream {
let res = parse_func(input.into()).to_string();
let settings = parse_settings(cfg.into());
let res = res.replace("__FFI_RAW_MODIFIERS__", &settings.0);
let res = res.replace("__FFI_EXTERN_MODIFIER__", &settings.1);
match syn::parse_str::<TokenStream>(&res) {
Ok(res) => res,
Err(err) => err.to_compile_error(),
}
}

/// parses the function it should be attached to
fn parse_func(item: TokenStream) -> TokenStream {
let input = match syn::parse2::<syn::ItemFn>(item) {
Ok(input) => input,
Err(err) => {
return err.to_compile_error();
}
};
let ret = &input.sig.output;
let inputs = &input.sig.inputs;
let name = &input.sig.ident;
let generics = &input.sig.generics;
let body = &input.block;
let attrs = &input.attrs;
let vis = &input.vis;
let result = quote::quote! {
#(#attrs)*
#[no_mangle]
#vis __FFI_RAW_MODIFIERS__ extern __FFI_EXTERN_MODIFIER__ fn #name #generics(#inputs) #ret {
#body
}
};
result
}

/// parses the settings (can be none, const, unsafe or both)
fn parse_settings(attr: TokenStream) -> (String, String) {
let modifiers_str = attr.to_string();
let mut res = String::new();
if modifiers_str.contains("const") {
res.push_str("const ");
}
if modifiers_str.contains("unsafe") {
res.push_str("unsafe ");
}
let t = if modifiers_str.contains("type=") {
let type_str = modifiers_str.split("type=").collect::<Vec<&str>>()[1];
type_str.split(' ').collect::<Vec<&str>>()[0]
} else {
"C"
};
(res, format!("\"{}\"",t))
}
use crate::TokenStream;

/// Simplifies the creation of FFI functions
///
/// # Example
/// ```rust,ignore,no_run
/// #[macros::ffi(type = "system")]
/// pub fn Java_Main_greet<'a>(
/// mut env: JNIEnv<'a>, _class: JClass<'a>, input: JString<'a>
/// ) -> jstring {
/// // First, we have to get the string out of Java. Check out the `strings`
/// // module for more info on how this works.
/// let input: String = env.get_string(&input).expect("Couldn't get java string!").into();
///
/// // Then we have to create a new Java string to return. Again, more info
/// // in the `strings` module.
/// let output = env.new_string(
/// format!("Hello, {}!", input)
/// ).expect("Couldn't create java string!");
///
/// // Finally, extract the raw pointer to return.
/// output.into_raw()
/// }
/// ```
pub fn ffi<T: Into<TokenStream>>(cfg: T, input: T) -> TokenStream {
let res = parse_func(input.into()).to_string();
let settings = parse_settings(cfg.into());
let res = res.replace("__FFI_RAW_MODIFIERS__", &settings.0);
let res = res.replace("__FFI_EXTERN_MODIFIER__", &settings.1);
match syn::parse_str::<TokenStream>(&res) {
Ok(res) => res,
Err(err) => err.to_compile_error(),
}
}

/// parses the function it should be attached to
fn parse_func(item: TokenStream) -> TokenStream {
let input = match syn::parse2::<syn::ItemFn>(item) {
Ok(input) => input,
Err(err) => {
return err.to_compile_error();
}
};
let ret = &input.sig.output;
let inputs = &input.sig.inputs;
let name = &input.sig.ident;
let generics = &input.sig.generics;
let body = &input.block;
let attrs = &input.attrs;
let vis = &input.vis;
let result = quote::quote! {
#(#attrs)*
#[no_mangle]
#vis __FFI_RAW_MODIFIERS__ extern __FFI_EXTERN_MODIFIER__ fn #name #generics(#inputs) #ret {
#body
}
};
result
}

/// parses the settings (can be none, const, unsafe or both)
fn parse_settings(attr: TokenStream) -> (String, String) {
let modifiers_str = attr.to_string();
let mut res = String::new();
if modifiers_str.contains("const") {
res.push_str("const ");
}
if modifiers_str.contains("unsafe") {
res.push_str("unsafe ");
}
let t = if modifiers_str.contains("type=") {
let type_str = modifiers_str.split("type=").collect::<Vec<&str>>()[1];
type_str.split(' ').collect::<Vec<&str>>()[0]
} else {
"C"
};
(res, format!("\"{}\"", t))
}
22 changes: 11 additions & 11 deletions libs/macros-core/lib.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
//! A collection of core functionality for the macros.
#![warn(missing_docs, unused, clippy::all)]

use proc_macro2::TokenStream;

mod mass_impl;
mod ffi;

pub use mass_impl::mass_impl;
pub use ffi::ffi;
//! A collection of core functionality for the macros.
#![warn(missing_docs, unused, clippy::all)]

use proc_macro2::TokenStream;

mod ffi;
mod mass_impl;

pub use ffi::ffi;
pub use mass_impl::mass_impl;
93 changes: 46 additions & 47 deletions libs/macros-core/mass_impl/args.rs
Original file line number Diff line number Diff line change
@@ -1,47 +1,46 @@
//! Argument parsing for the `mass_impl` macro.
pub use super::variants::TypeVariant;

/// The configuration for the `mass_impl` macro.
pub struct MassImplMacroConfig {
/// The type variants to implement the trait for.
pub type_variants: Vec<TypeVariant>,
}

impl std::fmt::Debug for MassImplMacroConfig {
/// Formats a `TypeVariant`
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("MassImplMacroConfig")
.field("type_variants", &self.type_variants)
.field("number_of_passthroughs", &self.number_of_passthroughs())
.finish()
}
}

impl MassImplMacroConfig {
/// Returns the number of passthroughs for this type variant.
pub fn number_of_passthroughs(&self) -> i32 {
let mut i = 1;
for variant in &self.type_variants {
i *= variant.number_of_passthroughs();
}
i
}
}

// parses this:
// $SELF = @R @M Vec2D,
// $OTHER = @R @M Vec2D
//
impl syn::parse::Parse for MassImplMacroConfig {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
let mut type_variants = Vec::new();
let vars = syn::punctuated::Punctuated::<TypeVariant, syn::Token![,]>::parse_terminated(input)?;
for var in vars {
type_variants.push(var);
}
Ok(MassImplMacroConfig {
type_variants,
})
}
}
//! Argument parsing for the `mass_impl` macro.
pub use super::variants::TypeVariant;

/// The configuration for the `mass_impl` macro.
pub struct MassImplMacroConfig {
/// The type variants to implement the trait for.
pub type_variants: Vec<TypeVariant>,
}

impl std::fmt::Debug for MassImplMacroConfig {
/// Formats a `TypeVariant`
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("MassImplMacroConfig")
.field("type_variants", &self.type_variants)
.field("number_of_passthroughs", &self.number_of_passthroughs())
.finish()
}
}

impl MassImplMacroConfig {
/// Returns the number of passthroughs for this type variant.
pub fn number_of_passthroughs(&self) -> i32 {
let mut i = 1;
for variant in &self.type_variants {
i *= variant.number_of_passthroughs();
}
i
}
}

// parses this:
// $SELF = @R @M Vec2D,
// $OTHER = @R @M Vec2D
//
impl syn::parse::Parse for MassImplMacroConfig {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
let mut type_variants = Vec::new();
let vars =
syn::punctuated::Punctuated::<TypeVariant, syn::Token![,]>::parse_terminated(input)?;
for var in vars {
type_variants.push(var);
}
Ok(MassImplMacroConfig { type_variants })
}
}
92 changes: 45 additions & 47 deletions libs/macros-core/mass_impl/mod.rs
Original file line number Diff line number Diff line change
@@ -1,47 +1,45 @@
use crate::TokenStream;

mod variants;
mod args;

/// A macro for implementing a trait for a list of types.
pub fn mass_impl<T: Into<TokenStream>>(cfg: T, input: T) -> TokenStream {
let cfg: TokenStream = cfg.into();
let input: TokenStream = input.into();
let config = match syn::parse2::<args::MassImplMacroConfig>(cfg) {
Ok(config) => config,
Err(err) => {
return err.to_compile_error();
}
};
let mut results = vec![input.to_string()];

for tv in &config.type_variants {
let mut temp_results = Vec::new();
if tv.allow_owned {
for r in &results {
let new = r.replace(&tv.alias.to_string(), &tv.ty.to_string());
temp_results.push(new);
}
}
if tv.allow_ref {
for r in &results {
let new = r.replace(&tv.alias.to_string(), &format!("&{}", tv.ty));
temp_results.push(new);
}
}
if tv.allow_mut {
for r in &results {
let new = r.replace(&tv.alias.to_string(), &format!("&mut {}", tv.ty));
temp_results.push(new);
}
}
results = temp_results;
}
let single_str = results.join("\n");
match syn::parse_str::<TokenStream>(&single_str) {
Ok(ts) => ts,
Err(err) => {
err.to_compile_error()
}
}
}
use crate::TokenStream;

mod args;
mod variants;

/// A macro for implementing a trait for a list of types.
pub fn mass_impl<T: Into<TokenStream>>(cfg: T, input: T) -> TokenStream {
let cfg: TokenStream = cfg.into();
let input: TokenStream = input.into();
let config = match syn::parse2::<args::MassImplMacroConfig>(cfg) {
Ok(config) => config,
Err(err) => {
return err.to_compile_error();
}
};
let mut results = vec![input.to_string()];

for tv in &config.type_variants {
let mut temp_results = Vec::new();
if tv.allow_owned {
for r in &results {
let new = r.replace(&tv.alias.to_string(), &tv.ty.to_string());
temp_results.push(new);
}
}
if tv.allow_ref {
for r in &results {
let new = r.replace(&tv.alias.to_string(), &format!("&{}", tv.ty));
temp_results.push(new);
}
}
if tv.allow_mut {
for r in &results {
let new = r.replace(&tv.alias.to_string(), &format!("&mut {}", tv.ty));
temp_results.push(new);
}
}
results = temp_results;
}
let single_str = results.join("\n");
match syn::parse_str::<TokenStream>(&single_str) {
Ok(ts) => ts,
Err(err) => err.to_compile_error(),
}
}
Loading

0 comments on commit 27a15eb

Please sign in to comment.