Compare commits
2 Commits
366efd8331
...
5514fbb67e
Author | SHA1 | Date |
---|---|---|
Benedikt Peetz | 5514fbb67e | |
Benedikt Peetz | 475e7edadf |
|
@ -22,6 +22,10 @@
|
||||||
name = "trixy"
|
name = "trixy"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
license = "LGPL-3.0-or-later"
|
||||||
|
repository = "https://git.nerdcult.net/trinitrix/trixy"
|
||||||
|
categories = ["config", "compilers", "development-tools::ffi"]
|
||||||
|
keywords = ["ffi", "c-ffi", "api"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = { version = "4.5.4", features = ["derive"], optional = true }
|
clap = { version = "4.5.4", features = ["derive"], optional = true }
|
||||||
|
|
6
cog.toml
6
cog.toml
|
@ -25,8 +25,8 @@ ignore_merge_commits = false
|
||||||
[commit_types]
|
[commit_types]
|
||||||
|
|
||||||
pre_bump_hooks = [
|
pre_bump_hooks = [
|
||||||
"licensur -p -i", # update the license header in each file
|
"./scripts/renew_copyright_header.sh", # update the license header in each file
|
||||||
"nix build", # verify the project builds
|
"nix flake check", # verify the project builds
|
||||||
"nix fmt", # format
|
"nix fmt", # format
|
||||||
"cargo set-version {{version}}", # bump version in Cargo.toml
|
"cargo set-version {{version}}", # bump version in Cargo.toml
|
||||||
]
|
]
|
||||||
|
@ -43,4 +43,4 @@ path = "NEWS.md"
|
||||||
remote = "git.nerdcult.net"
|
remote = "git.nerdcult.net"
|
||||||
repository = "trixy"
|
repository = "trixy"
|
||||||
owner = "trinitrix"
|
owner = "trinitrix"
|
||||||
authors = [{ signature = "Soispha", username = "soispha" }]
|
authors = [{ signature = "Benedikt Peetz", username = "soispha" }]
|
||||||
|
|
24
flake.lock
24
flake.lock
|
@ -7,11 +7,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1711407199,
|
"lastModified": 1714755562,
|
||||||
"narHash": "sha256-A/nB4j3JHL51ztlMQdfKw6y8tUJJzai3bLsZUEEaBxY=",
|
"narHash": "sha256-jJ0xVJ27aQ3mLV8xqy064smZs96fJL84bccbKpZ+JcY=",
|
||||||
"owner": "ipetkov",
|
"owner": "ipetkov",
|
||||||
"repo": "crane",
|
"repo": "crane",
|
||||||
"rev": "7e468a455506f2e65550e08dfd45092f0857a009",
|
"rev": "234eee4fa47c3860700d757ae94e43cf81b03dfd",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -152,11 +152,11 @@
|
||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1711370797,
|
"lastModified": 1714656196,
|
||||||
"narHash": "sha256-2xu0jVSjuKhN97dqc4bVtvEH52Rwh6+uyI1XCnzoUyI=",
|
"narHash": "sha256-kjQkA98lMcsom6Gbhw8SYzmwrSo+2nruiTcTZp5jK7o=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "c726225724e681b3626acc941c6f95d2b0602087",
|
"rev": "94035b482d181af0a0f8f77823a790b256b7c3cc",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -188,11 +188,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1711419061,
|
"lastModified": 1714702555,
|
||||||
"narHash": "sha256-+5M/czgYGqs/jKmi8bvYC+JUYboUKNTfkRiesXopeXQ=",
|
"narHash": "sha256-/NoUbE5S5xpK1FU3nlHhQ/tL126+JcisXdzy3Ng4pDU=",
|
||||||
"owner": "oxalica",
|
"owner": "oxalica",
|
||||||
"repo": "rust-overlay",
|
"repo": "rust-overlay",
|
||||||
"rev": "4c11d2f698ff1149f76b69e72852d5d75f492d0c",
|
"rev": "7f0e3ef7b7fbed78e12e5100851175d28af4b7c6",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -256,11 +256,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1710781103,
|
"lastModified": 1714058656,
|
||||||
"narHash": "sha256-nehQK/XTFxfa6rYKtbi8M1w+IU1v5twYhiyA4dg1vpg=",
|
"narHash": "sha256-Qv4RBm4LKuO4fNOfx9wl40W2rBbv5u5m+whxRYUMiaA=",
|
||||||
"owner": "numtide",
|
"owner": "numtide",
|
||||||
"repo": "treefmt-nix",
|
"repo": "treefmt-nix",
|
||||||
"rev": "7ee5aaac63c30d3c97a8c56efe89f3b2aa9ae564",
|
"rev": "c6aaf729f34a36c445618580a9f95a48f5e4e03f",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
|
@ -200,6 +200,7 @@
|
||||||
|
|
||||||
formatter = treefmtEval.config.build.wrapper;
|
formatter = treefmtEval.config.build.wrapper;
|
||||||
checks = {
|
checks = {
|
||||||
|
build = craneBuild;
|
||||||
formatting = treefmtEval.config.build.check self;
|
formatting = treefmtEval.config.build.check self;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
https://reuse.software/faq/
|
||||||
|
gcc -fanalyzer -> https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html
|
||||||
|
-> https://gcc.gnu.org/onlinedocs/gcc/Static-Analyzer-Options.html
|
|
@ -1,125 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2023 - 2024:
|
|
||||||
* The Trinitrix Project <soispha@vhack.eu, antifallobst@systemausfall.org>
|
|
||||||
* SPDX-License-Identifier: LGPL-3.0-or-later
|
|
||||||
*
|
|
||||||
* This file is part of the Trixy crate for Trinitrix.
|
|
||||||
*
|
|
||||||
* Trixy is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the Lesser GNU General Public License as
|
|
||||||
* published by the Free Software Foundation, either version 3 of
|
|
||||||
* the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* and the Lesser GNU General Public License along with this program.
|
|
||||||
* If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
use convert_case::{Case, Casing};
|
|
||||||
use proc_macro2::TokenStream as TokenStream2;
|
|
||||||
use quote::{format_ident, quote, ToTokens};
|
|
||||||
use syn::{punctuated::Punctuated, Ident, Token, Type};
|
|
||||||
|
|
||||||
use crate::{command_enum_parsing::Field, DataCommandEnum};
|
|
||||||
|
|
||||||
use super::get_input_type_of_bare_fn_field;
|
|
||||||
|
|
||||||
pub fn command_enum(input: &DataCommandEnum) -> TokenStream2 {
|
|
||||||
let (fields, namespace_enums): (TokenStream2, TokenStream2) =
|
|
||||||
turn_fields_to_enum(&input.fields);
|
|
||||||
|
|
||||||
quote! {
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum Command {
|
|
||||||
#fields
|
|
||||||
}
|
|
||||||
#namespace_enums
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn turn_fields_to_enum(fields: &Punctuated<Field, Token![,]>) -> (TokenStream2, TokenStream2) {
|
|
||||||
let output: Vec<_> = fields
|
|
||||||
.iter()
|
|
||||||
.map(|field| turn_struct_field_to_enum(field))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let mut fields_output: TokenStream2 = Default::default();
|
|
||||||
let mut namespace_enums_output: TokenStream2 = Default::default();
|
|
||||||
|
|
||||||
for (fields, namespace_enum) in output {
|
|
||||||
fields_output.extend(fields.to_token_stream());
|
|
||||||
namespace_enums_output.extend(namespace_enum.to_token_stream());
|
|
||||||
}
|
|
||||||
|
|
||||||
(fields_output, namespace_enums_output)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn turn_struct_field_to_enum(field: &Field) -> (TokenStream2, TokenStream2) {
|
|
||||||
match field {
|
|
||||||
Field::Function(fun_field) => {
|
|
||||||
let field_name = format_ident!(
|
|
||||||
"{}",
|
|
||||||
fun_field
|
|
||||||
.name
|
|
||||||
.to_string()
|
|
||||||
.from_case(Case::Snake)
|
|
||||||
.to_case(Case::Pascal)
|
|
||||||
);
|
|
||||||
|
|
||||||
let input_type: Option<Type> = get_input_type_of_bare_fn_field(fun_field);
|
|
||||||
|
|
||||||
match input_type {
|
|
||||||
Some(input_type) => (
|
|
||||||
quote! {
|
|
||||||
#field_name(#input_type),
|
|
||||||
},
|
|
||||||
quote! {},
|
|
||||||
),
|
|
||||||
None => (
|
|
||||||
quote! {
|
|
||||||
#field_name,
|
|
||||||
},
|
|
||||||
quote! {},
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Field::Namespace(namespace) => {
|
|
||||||
let (namespace_output_fields, namespace_output_namespace_enums) =
|
|
||||||
turn_fields_to_enum(&namespace.fields);
|
|
||||||
let namespace_name: Ident = format_ident!(
|
|
||||||
"{}",
|
|
||||||
namespace
|
|
||||||
.path
|
|
||||||
.iter()
|
|
||||||
.map(|name| name.to_string())
|
|
||||||
.collect::<String>()
|
|
||||||
);
|
|
||||||
|
|
||||||
let new_namespace_name: Ident = format_ident!(
|
|
||||||
"{}",
|
|
||||||
namespace_name
|
|
||||||
.to_string()
|
|
||||||
.from_case(Case::Snake)
|
|
||||||
.to_case(Case::Pascal)
|
|
||||||
);
|
|
||||||
|
|
||||||
(
|
|
||||||
quote! {
|
|
||||||
#new_namespace_name(#new_namespace_name),
|
|
||||||
},
|
|
||||||
quote! {
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum #new_namespace_name {
|
|
||||||
#namespace_output_fields
|
|
||||||
}
|
|
||||||
#namespace_output_namespace_enums
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2023 - 2024:
|
|
||||||
* The Trinitrix Project <soispha@vhack.eu, antifallobst@systemausfall.org>
|
|
||||||
* SPDX-License-Identifier: LGPL-3.0-or-later
|
|
||||||
*
|
|
||||||
* This file is part of the Trixy crate for Trinitrix.
|
|
||||||
*
|
|
||||||
* Trixy is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the Lesser GNU General Public License as
|
|
||||||
* published by the Free Software Foundation, either version 3 of
|
|
||||||
* the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* and the Lesser GNU General Public License along with this program.
|
|
||||||
* If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
use proc_macro2::TokenStream as TokenStream2;
|
|
||||||
use quote::quote;
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
generate::lua_wrapper::{
|
|
||||||
lua_functions_to_globals::generate_add_lua_functions_to_globals,
|
|
||||||
rust_wrapper_functions::generate_rust_wrapper_functions,
|
|
||||||
},
|
|
||||||
DataCommandEnum,
|
|
||||||
};
|
|
||||||
|
|
||||||
mod lua_functions_to_globals;
|
|
||||||
mod rust_wrapper_functions;
|
|
||||||
|
|
||||||
pub fn lua_wrapper(input: &DataCommandEnum) -> TokenStream2 {
|
|
||||||
let add_lua_functions_to_globals = generate_add_lua_functions_to_globals(input);
|
|
||||||
let rust_wrapper_functions = generate_rust_wrapper_functions(None, input);
|
|
||||||
quote! {
|
|
||||||
#add_lua_functions_to_globals
|
|
||||||
#rust_wrapper_functions
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,78 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2023 - 2024:
|
|
||||||
* The Trinitrix Project <soispha@vhack.eu, antifallobst@systemausfall.org>
|
|
||||||
* SPDX-License-Identifier: LGPL-3.0-or-later
|
|
||||||
*
|
|
||||||
* This file is part of the Trixy crate for Trinitrix.
|
|
||||||
*
|
|
||||||
* Trixy is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the Lesser GNU General Public License as
|
|
||||||
* published by the Free Software Foundation, either version 3 of
|
|
||||||
* the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* and the Lesser GNU General Public License along with this program.
|
|
||||||
* If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
mod command_enum;
|
|
||||||
mod lua_wrapper;
|
|
||||||
|
|
||||||
pub use command_enum::command_enum;
|
|
||||||
pub use lua_wrapper::lua_wrapper;
|
|
||||||
use syn::{ReturnType, Type, TypeBareFn};
|
|
||||||
|
|
||||||
use crate::command_enum_parsing::FunctionDeclaration;
|
|
||||||
|
|
||||||
pub fn get_bare_fn_input_type(function: &TypeBareFn) -> Option<Type> {
|
|
||||||
if function.inputs.len() == 1 {
|
|
||||||
Some(
|
|
||||||
function
|
|
||||||
.inputs
|
|
||||||
.first()
|
|
||||||
.expect("Only one element exists, we checked the length above")
|
|
||||||
.ty
|
|
||||||
.clone(),
|
|
||||||
)
|
|
||||||
} else if function.inputs.len() == 0 {
|
|
||||||
// No inputs, so we can't return a type
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
unreachable!(
|
|
||||||
"The Function can only take one or zero arguments.
|
|
||||||
Use a tuple `(arg1, arg2)` if you want more"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_input_type_of_bare_fn_field(field: &FunctionDeclaration) -> Option<Type> {
|
|
||||||
match &field.ty {
|
|
||||||
syn::Type::BareFn(function) => get_bare_fn_input_type(&function),
|
|
||||||
_ => unimplemented!(
|
|
||||||
"Please specify the type as a bare fn type.
|
|
||||||
That is: `fn(<args>) -> <outputs>`"
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn get_return_type_of_bare_fn_field(field: &FunctionDeclaration) -> Option<Type> {
|
|
||||||
match &field.ty {
|
|
||||||
syn::Type::BareFn(function) => get_bare_fn_return_type(&function),
|
|
||||||
_ => unimplemented!(
|
|
||||||
"Please specify the type as a bare fn type.
|
|
||||||
That is: `fn(<args>) -> <outputs>`"
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_bare_fn_return_type(function: &TypeBareFn) -> Option<Type> {
|
|
||||||
let return_path: &ReturnType = &function.output;
|
|
||||||
match return_path {
|
|
||||||
ReturnType::Default => None,
|
|
||||||
ReturnType::Type(_, return_type) => Some(*return_type.to_owned()),
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2023 - 2024:
|
||||||
|
* The Trinitrix Project <soispha@vhack.eu, antifallobst@systemausfall.org>
|
||||||
|
* SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
|
*
|
||||||
|
* This file is part of the Trixy crate for Trinitrix.
|
||||||
|
*
|
||||||
|
* Trixy is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the Lesser GNU General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* and the Lesser GNU General Public License along with this program.
|
||||||
|
* If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use proc_macro2::TokenStream as TokenStream2;
|
||||||
|
use quote::quote;
|
||||||
|
|
||||||
|
pub mod lua_functions_to_globals;
|
||||||
|
pub mod rust_wrapper_functions;
|
||||||
|
|
||||||
|
mod function;
|
||||||
|
|
||||||
|
/// #[derive(Debug)]
|
||||||
|
/// pub enum Command {
|
||||||
|
/// Greet(String),
|
||||||
|
/// }
|
||||||
|
/// pub fn add_lua_functions_to_globals(
|
||||||
|
/// lua: mlua::Lua,
|
||||||
|
/// tx: tokio::sync::mpsc::Sender<Event>,
|
||||||
|
/// ) -> mlua::Lua {
|
||||||
|
/// lua.set_app_data(tx);
|
||||||
|
/// let globals = lua.globals();
|
||||||
|
/// {
|
||||||
|
/// let wrapped_lua_function_greet = lua
|
||||||
|
/// .create_async_function(greet)
|
||||||
|
/// .expect(
|
||||||
|
/// format!(
|
||||||
|
/// "The function: `{}` should be defined",
|
||||||
|
/// "greet",
|
||||||
|
/// )
|
||||||
|
/// );
|
||||||
|
/// globals
|
||||||
|
/// .set("greet", wrapped_lua_function_greet)
|
||||||
|
/// .expect("Setting a static global value should work");
|
||||||
|
/// }
|
||||||
|
/// drop(globals);
|
||||||
|
/// lua
|
||||||
|
/// }
|
||||||
|
/// async fn greet(lua: &mlua::Lua, input: String) -> Result<String, mlua::Error> {
|
||||||
|
/// let (callback_tx, callback_rx) = tokio::sync::oneshot::channel::<String>();
|
||||||
|
/// let tx: core::cell::Ref<tokio::sync::mpsc::Sender<Event>> = lua
|
||||||
|
/// .app_data_ref()
|
||||||
|
/// .expect("This should exist, it was set before");
|
||||||
|
/// (*tx)
|
||||||
|
/// .send(Event::CommandEvent(Command::Greet(input.clone()), Some(callback_tx)))
|
||||||
|
/// .await
|
||||||
|
/// .expect("This should work, as the receiver is not dropped");
|
||||||
|
/// match callback_rx.await {
|
||||||
|
/// Ok(output) => {
|
||||||
|
/// return Ok(output);
|
||||||
|
/// }
|
||||||
|
/// Err(err) => {
|
||||||
|
/// return Err(mlua::Error::ExternalError(std::sync::Arc::new(err)));
|
||||||
|
/// }
|
||||||
|
/// };
|
||||||
|
/// }
|
||||||
|
pub fn generate() -> TokenStream2 {}
|
||||||
|
|
||||||
|
// pub fn generate(input: &DataCommandEnum) -> TokenStream2 {
|
||||||
|
// let add_lua_functions_to_globals = generate_add_lua_functions_to_globals(input);
|
||||||
|
// let rust_wrapper_functions = generate_rust_wrapper_functions(None, input);
|
||||||
|
// quote! {
|
||||||
|
// #add_lua_functions_to_globals
|
||||||
|
// #rust_wrapper_functions
|
||||||
|
// }
|
||||||
|
// }
|
Reference in New Issue