Compare commits

...

8 Commits

Author SHA1 Message Date
Benedikt Peetz b750bb8495 chore(version): v0.1.0 2024-05-04 10:24:33 +02:00
Benedikt Peetz d57beeebd4 build(cog): Avoid building the project with nix, as this fails 2024-05-04 10:23:59 +02:00
Benedikt Peetz ec11a129bd fix(gitignore): Don't ignore the `Cargo.lock` file 2024-05-04 10:22:46 +02:00
Benedikt Peetz ddd9255c2e build(cog): Remove wrong toml header 2024-05-04 10:22:03 +02:00
Benedikt Peetz 07c38468ce chore(treewide): Renew copyright headers 2024-05-04 10:20:25 +02:00
Benedikt Peetz c7b8fb3f86 build(cog): Use new `renew_copyright_header` script 2024-05-04 10:19:57 +02:00
Benedikt Peetz 0a60c894d2 feat!(src/macros): Store allocation location in all strings
This makes it possible to automatically free the string in the correct
way expected by both c and rust.
Rust strings can now just be freed by the rust allocator, whilst c
strings are forgotten, so that the c allocator may free them.

BREAKING CHANGE: All usage of explicit mentions `std::string::String`
                 in your `handle_cmd` function will need to be replaced
                 by `trixy::types::newtypes::String`. Otherwise these
                 types should provide the same methods.
2024-05-04 10:12:20 +02:00
Benedikt Peetz 86427b0c1a refactor(src/macros/generate/host): Merge host generation in one module 2024-05-04 08:23:36 +02:00
16 changed files with 1203 additions and 254 deletions

4
.gitignore vendored
View File

@ -25,7 +25,3 @@
# dev env # dev env
.direnv .direnv
.ccls-cache .ccls-cache
# trixy is a library
Cargo.lock

412
Cargo.lock generated Normal file
View File

@ -0,0 +1,412 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "aho-corasick"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
dependencies = [
"memchr",
]
[[package]]
name = "anstream"
version = "0.6.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc"
[[package]]
name = "anstyle-parse"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648"
dependencies = [
"windows-sys",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7"
dependencies = [
"anstyle",
"windows-sys",
]
[[package]]
name = "bitflags"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
[[package]]
name = "clap"
version = "4.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0"
dependencies = [
"clap_builder",
"clap_derive",
]
[[package]]
name = "clap_builder"
version = "4.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4"
dependencies = [
"anstream",
"anstyle",
"clap_lex",
"strsim",
]
[[package]]
name = "clap_derive"
version = "4.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "clap_lex"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce"
[[package]]
name = "colorchoice"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
[[package]]
name = "convert_case"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca"
dependencies = [
"unicode-segmentation",
]
[[package]]
name = "diff"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8"
[[package]]
name = "getopts"
version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5"
dependencies = [
"unicode-width",
]
[[package]]
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "libc"
version = "0.2.153"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
[[package]]
name = "log"
version = "0.4.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
[[package]]
name = "memchr"
version = "2.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
[[package]]
name = "pretty_assertions"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66"
dependencies = [
"diff",
"yansi",
]
[[package]]
name = "prettyplease"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d3928fb5db768cb86f891ff014f0144589297e3c6a1aba6ed7cecfdace270c7"
dependencies = [
"proc-macro2",
"syn",
]
[[package]]
name = "proc-macro2"
version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e"
dependencies = [
"unicode-ident",
]
[[package]]
name = "pulldown-cmark"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dce76ce678ffc8e5675b22aa1405de0b7037e2fdf8913fea40d1926c6fe1e6e7"
dependencies = [
"bitflags",
"getopts",
"memchr",
"pulldown-cmark-escape",
"unicase",
]
[[package]]
name = "pulldown-cmark-escape"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5d8f9aa0e3cbcfaf8bf00300004ee3b72f74770f9cbac93f6928771f613276b"
[[package]]
name = "quote"
version = "1.0.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
dependencies = [
"proc-macro2",
]
[[package]]
name = "regex"
version = "1.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56"
[[package]]
name = "strsim"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01"
[[package]]
name = "syn"
version = "2.0.55"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "002a1b3dbf967edfafc32655d0f377ab0bb7b994aa1d32c8cc7e9b8bf3ebb8f0"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "thiserror"
version = "1.0.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "trixy"
version = "0.1.0"
dependencies = [
"clap",
"convert_case",
"libc",
"log",
"pretty_assertions",
"prettyplease",
"proc-macro2",
"pulldown-cmark",
"quote",
"regex",
"syn",
"thiserror",
]
[[package]]
name = "unicase"
version = "2.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89"
dependencies = [
"version_check",
]
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "unicode-segmentation"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202"
[[package]]
name = "unicode-width"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
[[package]]
name = "utf8parse"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
[[package]]
name = "version_check"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675"
[[package]]
name = "windows_i686_gnu"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3"
[[package]]
name = "windows_i686_msvc"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8"
[[package]]
name = "yansi"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec"

175
NEWS.md Normal file
View File

@ -0,0 +1,175 @@
<!--
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/>.
-->
# Changelog
All notable changes to this project will be documented in this file. See [conventional commits](https://www.conventionalcommits.org/) for commit guidelines.
______________________________________________________________________
## v0.1.0 - 2024-05-04
#### Bug Fixes
- **(bin/generate)** Actually only generate what was specified - (08df8e8) - *soispha*
- **(binary/parse)** Actually only perform the other steps, if asked for it - (4e3bdf2) - *soispha*
- **(docs/generate_docs)** Cd into the correct directory to make ebnf2pdf work - (9a0720e) - *soispha*
- **(example/main)** Ignore generated api.rs debugging file - (6bed2a8) - *soispha*
- **(generate/convert/host/rust/derive/structure)** Ignore `ptr` arg on todo - (bd0b3c7) - *soispha*
- **(gitignore)** Don't ignore the `Cargo.lock` file - (ec11a12) - Benedikt Peetz
- **(macros)** Mark the main generate function as must_use - (db5cd1a) - *soispha*
- **(macros)** Generate namespacesed types and convertible impls - (8b02d13) - *soispha*
- **(macros/c_api)** Add host generation support for structs and enums - (5fe757f) - *soispha*
- **(macros/c_api/header)** Format doc comments in a c-like way - (17fd954) - *soispha*
- **(macros/config/file_tree/markdown)** Change format to align with mdfmt - (5855d9b) - *soispha*
- **(macros/generate)** Correctly generate function types - (9a8ccc9) - *soispha*
- **(macros/generate/auxiliary/c/function)** Also add inputs when no output - (3d35d39) - *soispha*
- **(macros/generate/convert/auxiliary/c)** Correctly generate function types - (a66c687) - *soispha*
- **(macros/generate/convert/auxiliary/c/arguments)** Accept newlines - (bfeb620) - *soispha*
- **(macros/generate/host)** Add unified support for conversions - (b5f5ae8) - *soispha*
- **(macros/generate/host/c/function)** Actually call the callback function - (645b8d5) - *soispha*
- **(macros/generate/host/host/type)** The function type is a c pointer - (a58030c) - *soispha*
- **(parser/error)** Remove multiple errors from line number calc - (e512352) - *soispha*
- **(parser/lexing/error)** Improve the message of the `NoMatchesTaken` error - (ce1e4d8) - *soispha*
- **(parser/lexing/take_until_sucessive_match)** Add utf8 support - (fae3de8) - *soispha*
- **(parser/tokenizer)** Remove the tokenizer's death, when exposed to doc comments - (508dc2b) - *soispha*
- **(parser/unchecked/parse_structure)** Accept attributes on fields - (7a8dc66) - *soispha*
- **(scripts/renew_copyright_header)** Set correct template line lenght - (00a82ac) - *soispha*
- **(scripts/renew_copyright_header)** Add support for gitignore files - (9e7e9d7) - *soispha*
- **(scripts/renew_copyright_header)** Correctly handle shebangs - (3646e4a) - *soispha*
- **(scripts/renew_copyright_header)** Add per filetype handling - (3484ead) - *soispha*
- **(trixy)** Add thiserror dependency, as it's used in generated code - (e72c212) - *soispha*
- **(trixy)** Use public reexports - (b9e2641) - *soispha*
- **(trixy-macros)** Format the generated header with in the GNU style - (7c27cdc) - *soispha*
- **(trixy-parser)** Remove the `void` type - (a077ef1) - *soispha*
- **(trixy-types)** Conform to the api provided by the headers - (86b946b) - *soispha*
- **(trixy-types)** Rework c header files - (f699ca2) - *soispha*
- **(trixy/examples/main)** Improve c code - (5ce46a1) - *soispha*
- **(types)** Remove top-level support for generic types - (37ba451) - *soispha*
- **(types)** Improve support for generic rust types - (c2d21fd) - *soispha*
- **(types/error)** Add a pseudo error for infallible conversions - (9e37456) - *soispha*
- **(types/types_list)** Add the supported primitive types - (febb2de) - *soispha*
#### Build system
- **(.envrc)** Add `./target/debug` to PATH - (9233a13) - *soispha*
- **(.licensure.yml)** Update to really be usable - (cc50ec2) - *soispha*
- **(cog)** Avoid building the project with nix, as this fails - (d57beee) - Benedikt Peetz
- **(cog)** Remove wrong toml header - (ddd9255) - Benedikt Peetz
- **(cog)** Use new `renew_copyright_header` script - (c7b8fb3) - Benedikt Peetz
- **(cog.toml)** Use `nix fmt` (treefmt) instead of only `cargo fmt` - (86d0060) - *soispha*
- **(flake)** Update - (596197b) - *soispha*
- **(flake)** Update - (9630e10) - *soispha*
- **(flake)** Add treefmt - (1b8a33c) - *soispha*
- **(flake)** De-duplicate the `flake.lock` file - (3e59d53) - *soispha*
- **(licensure)** Add c headers to known files - (6e26bec) - *soispha*
- **(licensure)** Update to a better license template - (1a2267b) - *soispha*
- **(scripts/renew_copyright_header)** Init - (e9efc23) - *soispha*
- **(treewide)** Add relevant configuration for releases - (22904c9) - *soispha*
- **(update.sh)** Include the main example in the updates - (2e2028d) - *soispha*
- **(update.sh)** Add a shebang - (8104e80) - *soispha*
- **(update.sh)** Add an update script - (80c6dd4) - *soispha*
#### Documentation
- **(README)** Mention the binary - (366efd8) - *soispha*
- **(README)** Add - (06c61ad) - *soispha*
- **(example)** Update the example c and tri file to latest progress - (f688df1) - *soispha*
- **(example/main)** Update to include newly added callbacks - (7f6c76a) - *soispha*
- **(grammar.ebnf)** Don't reimplement already specified rules - (838181c) - *soispha*
- **(lib)** Add a description to the oneshot-senders - (e205ea4) - *soispha*
- **(macros/generate)** Improve error output - (73416da) - *soispha*
- **(parser/examples)** Add various examples (also the trinitrix main api) - (0ebbc43) - *soispha*
- **(parser/generate_docs)** Move shebang to first line - (1d49bdf) - *soispha*
- **(trixy-parser)** Update the railroad diagrams - (88aa3c3) - *soispha*
#### Features
- **(bin)** Add a binary, that helps in showing the generated code - (ec929da) - *soispha*
- **(example/valgrind)** Add a script to test the c example with valgrind - (eb31567) - *soispha*
- **(macros/c_api/header)** Add structs and enums to the c header - (6e72b7b) - *soispha*
- **(macros/config/file_tree)** Add support for parsing a FileTree from file - (89fd67c) - *soispha*
- **(macros/generate/convert/auxiliary)** Merge comments in c - (bb101c1) - *soispha*
- **(parser)** Associate a vector of nasps with every struct, enum, nasp - (a50936f) - *soispha*
- **(parser)** Add support for parsing function pointer types - (f73d3aa) - *soispha*
- **(parser)** Add support for parsing attributes - (add0d17) - *soispha*
- **(parser/bin)** Allow `lex` as an alias to `tokenize` - (21b0ce1) - *soispha*
- **(parser/lexing)** Desuger doc comments by running a regex on the file - (f1e9087) - *soispha*
- **(treewide)** Finalize basic c API - (e52f74b) - *soispha*
- **(treewide)** Add broken Vec<E>, Result\<T,E> and Option<T> types to c api - (b3c6a4c) - *soispha*
- **(treewide)** Provide a c api - (7d1a41a) - *soispha*
- **(trixy-macros)** Add rust host code generation - (ed96a50) - *soispha*
- **(trixy-parser)** Adapt Trixy to be a complete subset of rust - (b679987) - *soispha*
- **(types/try_from_impl)** Add a trixy::String from &str impl - (c69c00e) - *soispha*
#### Miscellaneous Chores
- **(.licensure.yml)** Remove unnecessary line in header comment - (dc000f2) - *soispha*
- **(.licensure.yml)** Add license spdx identifier - (7a95fa7) - *soispha*
- **(.licensure.yml)** Also add the license text to markdown files - (2f7be6f) - *soispha*
- **(Cargo.toml)** Add further required metadata - (0774ac2) - Benedikt Peetz
- **(Cargo.toml)** Add required metadata - (475e7ed) - Benedikt Peetz
- **(docs/generate_docs)** Add a `.sh` extension, so scripts recognize the ft - (a653dec) - *soispha*
- **(example)** Switch to full trinitrix API - (d2d18d9) - *soispha*
- **(parser/docs/grammar.pdf)** Update file - (c898c48) - *soispha*
- **(treewide)** Renew copyright headers - (07c3846) - Benedikt Peetz
- **(treewide)** Update license header - (5ab2bbb) - *soispha*
- **(treewide)** Add or update license header - (2b45995) - *soispha*
- **(treewide)** Add the new license header - (5a7bb00) - *soispha*
- **(treewide)** Remove old license header - (7ac6edb) - *soispha*
- **(treewide)** Move the trixy subcrates under one trixy crate - (21e1b75) - *soispha*
- **(treewide)** Add license headers - (0744c84) - *soispha*
- **(treewide)** Add license headers - (03f2450) - *soispha*
- Initial commit - (233fa3e) - soispha
#### Refactoring
- **(example/main/c)** Deduplicate error handling function - (cd5b0c9) - *soispha*
- **(macros/convertible_derive)** Generate the `Convertible` Trait impl - (18034e2) - *soispha*
- **(parser)** Use predictable names for tokens - (a4513e8) - *soispha*
- **(src/macros/generate/host)** Merge host generation in one module - (86427b0) - Benedikt Peetz
- **(treewide)** Rework file structure in `src/macros` - (eb7a901) - *soispha*
- **(types/headers/string)** Don't typedef a string type - (938e038) - *soispha*
#### Style
- **(flake)** Use yamlfmt instead of prettier - (4110f65) - *soispha*
- **(flake)** Add even more formatters - (fa6b046) - *soispha*
- **(treewide)** Format - (a766149) - *soispha*
- **(treewide)** format - (5ada3cb) - *soispha*
- **(treewide)** Reformat with treefmt (`nix fmt`) - (d904a19) - *soispha*
- **(treewide)** Reformat - (03f8eda) - *soispha*
#### Tests
- **(multiple)** Ignore, as it's not a important feature - (b1d47de) - *soispha*
- **(parser/checked/test)** Update test case - (0a6159e) - *soispha*
- **(scripts)** Add a script, which will help with generating and updating tests - (b85650e) - *soispha*
- **(tests)** Update `expected.md` files - (5a9de1a) - *soispha*
- **(tests)** Update - (475dde2) - *soispha*
- **(tests)** Add the positive tests (and delete the ones in rust) - (d48456d) - *soispha*
- **(trixy-parser)** Restore test functionality after nasp -> mod rename - (dc8a7ec) - *soispha*
- Add new multiline display for c auxiliary code - (055cf2d) - soispha
______________________________________________________________________
Changelog generated by [cocogitto](https://github.com/cocogitto/cocogitto).

View File

@ -19,14 +19,12 @@
# If not, see <https://www.gnu.org/licenses/>. # If not, see <https://www.gnu.org/licenses/>.
tag_prefix = "v" tag_prefix = "v"
branch_whitelist = ["main"] branch_whitelist = ["main", "prime"]
ignore_merge_commits = false ignore_merge_commits = false
[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 build", # 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
] ]
@ -36,8 +34,6 @@ post_bump_hooks = [
"git push origin v{{version}}", # push the new tag to origin "git push origin v{{version}}", # push the new tag to origin
] ]
[bump_profiles]
[changelog] [changelog]
path = "NEWS.md" path = "NEWS.md"
remote = "git.nerdcult.net" remote = "git.nerdcult.net"

291
example/main/Cargo.lock generated Normal file
View File

@ -0,0 +1,291 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "aho-corasick"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
dependencies = [
"memchr",
]
[[package]]
name = "bitflags"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "convert_case"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca"
dependencies = [
"unicode-segmentation",
]
[[package]]
name = "getopts"
version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5"
dependencies = [
"unicode-width",
]
[[package]]
name = "libc"
version = "0.2.153"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
[[package]]
name = "libloading"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19"
dependencies = [
"cfg-if",
"windows-targets",
]
[[package]]
name = "log"
version = "0.4.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
[[package]]
name = "memchr"
version = "2.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
[[package]]
name = "prettyplease"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d3928fb5db768cb86f891ff014f0144589297e3c6a1aba6ed7cecfdace270c7"
dependencies = [
"proc-macro2",
"syn",
]
[[package]]
name = "proc-macro2"
version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e"
dependencies = [
"unicode-ident",
]
[[package]]
name = "pulldown-cmark"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dce76ce678ffc8e5675b22aa1405de0b7037e2fdf8913fea40d1926c6fe1e6e7"
dependencies = [
"bitflags",
"getopts",
"memchr",
"pulldown-cmark-escape",
"unicase",
]
[[package]]
name = "pulldown-cmark-escape"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5d8f9aa0e3cbcfaf8bf00300004ee3b72f74770f9cbac93f6928771f613276b"
[[package]]
name = "quote"
version = "1.0.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
dependencies = [
"proc-macro2",
]
[[package]]
name = "regex"
version = "1.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56"
[[package]]
name = "syn"
version = "2.0.55"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "002a1b3dbf967edfafc32655d0f377ab0bb7b994aa1d32c8cc7e9b8bf3ebb8f0"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "thiserror"
version = "1.0.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "trixy"
version = "0.1.0"
dependencies = [
"convert_case",
"libc",
"log",
"prettyplease",
"proc-macro2",
"pulldown-cmark",
"quote",
"regex",
"syn",
"thiserror",
]
[[package]]
name = "trixy-example"
version = "0.1.0"
dependencies = [
"libloading",
"trixy",
]
[[package]]
name = "unicase"
version = "2.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89"
dependencies = [
"version_check",
]
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "unicode-segmentation"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202"
[[package]]
name = "unicode-width"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
[[package]]
name = "version_check"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "windows-targets"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675"
[[package]]
name = "windows_i686_gnu"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3"
[[package]]
name = "windows_i686_msvc"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8"

View File

@ -20,9 +20,10 @@
* If not, see <https://www.gnu.org/licenses/>. * If not, see <https://www.gnu.org/licenses/>.
*/ */
use std::{env, ffi::c_int, mem}; use std::{env, ffi::c_int};
use libloading::{Library, Symbol}; use libloading::{Library, Symbol};
use trixy::types::newtypes;
use crate::dogs::{DogType, TrainedDog}; use crate::dogs::{DogType, TrainedDog};
@ -30,6 +31,7 @@ include!(concat!(env!("OUT_DIR"), "/api.rs"));
// run `cargo run --bin api > ./src/bin/main/generated_api.rs` to output the generated api // run `cargo run --bin api > ./src/bin/main/generated_api.rs` to output the generated api
// mod generated_api; // mod generated_api;
// pub use generated_api::*;
fn handle_cmd(cmd: Commands) { fn handle_cmd(cmd: Commands) {
match cmd { match cmd {
@ -38,9 +40,11 @@ fn handle_cmd(cmd: Commands) {
let output = format!("Hi {}!", name); let output = format!("Hi {}!", name);
println!("(rust): {}", output); println!("(rust): {}", output);
trixy_output.send(output.into()).expect("Will work"); trixy_output.send(output.into()).expect("Will work");
mem::forget(name);
} }
dogs::Dogs::train_dog { trixy_output, dog } => { dogs::Dogs::train_dog {
trixy_output,
dog: _,
} => {
trixy_output trixy_output
.send( .send(
TrainedDog { TrainedDog {
@ -51,23 +55,19 @@ fn handle_cmd(cmd: Commands) {
.unwrap(), .unwrap(),
) )
.unwrap(); .unwrap();
mem::forget(dog);
} }
dogs::Dogs::guess_my_favourite_dog { dogs::Dogs::guess_my_favourite_dog {
trixy_output, trixy_output,
callback, callback,
} => { } => {
let fav_dog = callback("Frank".into(), 30); let fav_dog = callback("Frank".into(), 30);
let dog_name: String = fav_dog.name.clone().try_into().unwrap(); let dog_name: newtypes::String = fav_dog.name.clone().try_into().unwrap();
println!("(rust): They want a dog named: {}", dog_name); println!("(rust): They want a dog named: {}", dog_name);
trixy_output.send(DogType::Cat.into()).unwrap(); trixy_output.send(DogType::Cat.into()).unwrap();
mem::forget(dog_name);
} }
}, },
Commands::outstanding { name } => { Commands::outstanding { name } => {
println!("(rust): {} is outstanding!", name); println!("(rust): {} is outstanding!", name);
mem::forget(name);
} }
} }
} }

View File

@ -28,9 +28,6 @@ use crate::parser::command_spec::{Identifier, NamedType, Type};
mod doc_named_type; mod doc_named_type;
mod named_type; mod named_type;
// pub use doc_named_type::*;
// pub use named_type::*;
impl Type { impl Type {
pub fn to_c(&self) -> TokenStream2 { pub fn to_c(&self) -> TokenStream2 {
match self { match self {
@ -82,7 +79,7 @@ impl Type {
let type_name = trixy_build_in_types let type_name = trixy_build_in_types
.first() .first()
.expect("The names should not be dublicated, this should be the only value"); .expect("The names should not be duplicated, this should be the only value");
match *type_name { match *type_name {
"Result" => { "Result" => {

View File

@ -26,7 +26,6 @@ use quote::quote;
use crate::parser::command_spec::{Function, Identifier, NamedType, Type}; use crate::parser::command_spec::{Function, Identifier, NamedType, Type};
impl Function { impl Function {
// was called function_identifier_to_rust
pub fn to_rust_identifier<F>( pub fn to_rust_identifier<F>(
&self, &self,
input_fmt_fn: fn(&NamedType) -> TokenStream2, input_fmt_fn: fn(&NamedType) -> TokenStream2,

View File

@ -61,16 +61,22 @@ impl Type {
} }
} }
pub fn to_rust_typical(identifier: &Identifier, generic_args: &Vec<Type>) -> TokenStream2 { pub fn to_rust_typical(identifier: &Identifier, generic_args: &Vec<Type>) -> TokenStream2 {
match identifier {
Identifier { name, variant: _ } if name == "String" => {
// We wrap over the string to ensure that we know where it was allocated.
quote! {
trixy::types::newtypes::String
}
}
_ => {
let ident = identifier.to_rust(); let ident = identifier.to_rust();
let namespaces_path = Variant::to_rust_path(&identifier.variant);
let nasp_path = if let Some(nasp_path) = Variant::to_rust_path(&identifier.variant) { let nasp_path = if let Some(path) = &Variant::to_rust_path(&identifier.variant) {
if nasp_path.is_empty() { if path.is_empty() {
quote! { quote! {
crate :: crate ::
} }
} else { } else {
let path = namespaces_path;
quote! { quote! {
#path :: #path ::
} }
@ -84,10 +90,13 @@ impl Type {
#nasp_path #ident #nasp_path #ident
} }
} else { } else {
let generics: Vec<TokenStream2> = generic_args.iter().map(Type::to_rust).collect(); let generics: Vec<TokenStream2> =
generic_args.iter().map(Type::to_rust).collect();
quote! { quote! {
#nasp_path #ident <#(#generics),*> #nasp_path #ident <#(#generics),*>
} }
} }
} }
} }
}
}

View File

@ -1,75 +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::{
macros::config::trixy::TrixyConfig,
parser::command_spec::{CommandSpec, Enumeration, Structure},
};
/// This function generates the main c API provided by Trixy.
/// This works for example like this:
/// Turning this:
/// ```text
/// nasp trinitrix {
/// struct Callback {
/// func: String,
/// timeout: String,
/// };
///
/// enum CallbackPriority {
/// High,
/// Medium,
/// Low,
/// };
///
/// fn execute_callback(callback: Callback, priority: CallbackPriority);
/// }
/// ```
/// to this:
/// ```no_run
/// pub extern "C" fn exectute_callback(callback: Callback, priority: CallbackPriority) {
/// /* Here we simply call your handler function, with the command of the function */
/// }
/// ```
pub fn generate(trixy: &CommandSpec, config: &TrixyConfig) -> TokenStream2 {
let functions: TokenStream2 = trixy
.functions
.iter()
.map(|r#fn| r#fn.to_c(&config, &vec![]))
.collect();
let namespaced_functions: TokenStream2 = trixy
.namespaces
.iter()
.map(|nasp| nasp.to_c(&config, &vec![]))
.collect();
let structures: TokenStream2 = trixy.structures.iter().map(Structure::to_c).collect();
let enumerations: TokenStream2 = trixy.enumerations.iter().map(Enumeration::to_c).collect();
quote! {
#enumerations
#structures
#functions
#namespaced_functions
}
}

View File

@ -22,13 +22,14 @@
use crate::{ use crate::{
macros::{config::trixy::TrixyConfig, generate::host::format_rust}, macros::{config::trixy::TrixyConfig, generate::host::format_rust},
parser::command_spec::CommandSpec, parser::command_spec::{CommandSpec, Enumeration, Structure},
}; };
pub mod host; use proc_macro2::TokenStream as TokenStream2;
use quote::quote;
pub fn generate(trixy: &CommandSpec, config: &TrixyConfig) -> String { pub fn generate(trixy: &CommandSpec, config: &TrixyConfig) -> String {
let host_rust_code = host::generate(&trixy, &config); let host_rust_code = generate_code(&trixy, &config);
let rust_code = format_rust(host_rust_code); let rust_code = format_rust(host_rust_code);
@ -39,3 +40,48 @@ pub fn generate(trixy: &CommandSpec, config: &TrixyConfig) -> String {
rust_code rust_code
) )
} }
/// This function generates the main c API provided by Trixy.
/// This works for example like this:
/// Turning this:
/// ```text
/// nasp trinitrix {
/// struct Callback {
/// func: String,
/// timeout: String,
/// };
///
/// enum CallbackPriority {
/// High,
/// Medium,
/// Low,
/// };
///
/// fn execute_callback(callback: Callback, priority: CallbackPriority);
/// }
/// ```
/// to this:
/// ```no_run
/// pub extern "C" fn exectute_callback(callback: Callback, priority: CallbackPriority) {
/// /* Here we simply call your handler function, with the command of the function */
/// }
/// ```
pub fn generate_code(trixy: &CommandSpec, config: &TrixyConfig) -> TokenStream2 {
let functions: TokenStream2 = trixy
.functions
.iter()
.map(|r#fn| r#fn.to_c(&config, &vec![]))
.collect();
let namespaced_functions: TokenStream2 = trixy
.namespaces
.iter()
.map(|nasp| nasp.to_c(&config, &vec![]))
.collect();
let structures: TokenStream2 = trixy.structures.iter().map(Structure::to_c).collect();
let enumerations: TokenStream2 = trixy.enumerations.iter().map(Enumeration::to_c).collect();
quote! {
#enumerations
#structures
#functions
#namespaced_functions
}
}

View File

@ -1,115 +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/>.
*/
//! This module is responsible for generating the rust code used to interface with the api.
//! That includes the structs and enums declared in the trixy file and the enum used to describe the
//! command being executed.
use proc_macro2::TokenStream as TokenStream2;
use quote::quote;
use crate::{
macros::config::trixy::TrixyConfig,
parser::command_spec::{CommandSpec, Enumeration, Namespace, Structure},
};
/// This function turns, for example, the following trixy input into this rust code:
/// ```text
/// nasp trinitrix {
/// struct Callback {
/// func: String,
/// timeout: String,
/// };
///
/// enum CallbackPriority {
/// High,
/// Medium,
/// Low,
/// };
///
/// fn execute_callback(callback: Callback, priority: CallbackPriority) -> String;
/// }
/// ```
/// ```no_run
/// #[derive(Debug)]
/// pub enum Commands {
/// Trinitrix(trinitrix::Trinitrix),
/// }
/// pub mod trinitrix {
/// #[allow(non_camel_case_types)]
/// #[derive(Debug)]
/// struct Callback {
/// func: String,
/// timeout: String,
/// }
/// #[allow(non_camel_case_types)]
/// #[derive(Debug)]
/// enum CallbackPriority {
/// High,
/// Medium,
/// Low,
/// }
/// #[derive(Debug)]
/// pub enum Trinitrix {
/// #[allow(non_camel_case_types)]
/// execute_callback {
/// callback: Callback,
/// priority: CallbackPriority,
/// trixy_output: trixy::oneshot::channel<String>
/// },
/// }
/// }
/// ```
pub fn generate(trixy: &CommandSpec, _config: &TrixyConfig) -> TokenStream2 {
let modules: TokenStream2 = trixy
.namespaces
.iter()
.map(|nasp| nasp.to_rust_module(&vec![]))
.collect();
let structures: TokenStream2 = trixy.structures.iter().map(Structure::to_rust).collect();
let enumerations: TokenStream2 = trixy
.enumerations
.iter()
.map(Enumeration::to_rust)
.collect();
let functions: Vec<TokenStream2> = trixy
.functions
.iter()
.map(|r#fn| r#fn.to_rust(&[]))
.collect();
let namespace_modules: Vec<TokenStream2> = trixy
.namespaces
.iter()
.map(Namespace::to_rust_module_enum)
.collect();
quote! {
#structures
#enumerations
#[derive(Debug)]
pub enum Commands {
#(#functions,)*
#(#namespace_modules),*
}
#modules
}
}

View File

@ -20,14 +20,20 @@
* If not, see <https://www.gnu.org/licenses/>. * If not, see <https://www.gnu.org/licenses/>.
*/ */
use crate::parser::command_spec::CommandSpec; //! This module is responsible for generating the rust code used to interface with the api.
//! That includes the structs and enums declared in the trixy file and the enum used to describe the
//! command being executed.
use crate::macros::{config::trixy::TrixyConfig, generate::host::format_rust}; use proc_macro2::TokenStream as TokenStream2;
use quote::quote;
pub mod host; use crate::{
macros::{config::trixy::TrixyConfig, generate::host::format_rust},
parser::command_spec::{CommandSpec, Enumeration, Namespace, Structure},
};
pub fn generate(trixy: &CommandSpec, config: &TrixyConfig) -> String { pub fn generate(trixy: &CommandSpec, config: &TrixyConfig) -> String {
let host_rust_code = host::generate(&trixy, &config); let host_rust_code = generate_code(&trixy, &config);
let rust_code = format_rust(host_rust_code); let rust_code = format_rust(host_rust_code);
@ -38,3 +44,85 @@ pub fn generate(trixy: &CommandSpec, config: &TrixyConfig) -> String {
rust_code rust_code
) )
} }
/// This function turns, for example, the following trixy input into this rust code:
/// ```text
/// mod trinitrix {
/// struct Callback {
/// func: String,
/// timeout: String,
/// };
///
/// enum CallbackPriority {
/// High,
/// Medium,
/// Low,
/// };
///
/// fn execute_callback(callback: Callback, priority: CallbackPriority) -> String;
/// }
/// ```
/// ```no_run
/// #[derive(Debug)]
/// pub enum Commands {
/// Trinitrix(trinitrix::Trinitrix),
/// }
/// pub mod trinitrix {
/// #[allow(non_camel_case_types)]
/// #[derive(Debug)]
/// struct Callback {
/// func: String,
/// timeout: String,
/// }
/// #[allow(non_camel_case_types)]
/// #[derive(Debug)]
/// enum CallbackPriority {
/// High,
/// Medium,
/// Low,
/// }
/// #[derive(Debug)]
/// pub enum Trinitrix {
/// #[allow(non_camel_case_types)]
/// execute_callback {
/// callback: Callback,
/// priority: CallbackPriority,
/// trixy_output: trixy::oneshot::channel<String>
/// },
/// }
/// }
/// ```
pub fn generate_code(trixy: &CommandSpec, _config: &TrixyConfig) -> TokenStream2 {
let modules: TokenStream2 = trixy
.namespaces
.iter()
.map(|nasp| nasp.to_rust_module(&vec![]))
.collect();
let structures: TokenStream2 = trixy.structures.iter().map(Structure::to_rust).collect();
let enumerations: TokenStream2 = trixy
.enumerations
.iter()
.map(Enumeration::to_rust)
.collect();
let functions: Vec<TokenStream2> = trixy
.functions
.iter()
.map(|r#fn| r#fn.to_rust(&[]))
.collect();
let namespace_modules: Vec<TokenStream2> = trixy
.namespaces
.iter()
.map(Namespace::to_rust_module_enum)
.collect();
quote! {
#structures
#enumerations
#[derive(Debug)]
pub enum Commands {
#(#functions,)*
#(#namespace_modules),*
}
#modules
}
}

View File

@ -22,6 +22,7 @@
//! Trixy contains the types used by the [`trixy-macros`] crate to provide ffi safe types //! Trixy contains the types used by the [`trixy-macros`] crate to provide ffi safe types
pub mod error; pub mod error;
pub mod newtypes;
pub mod traits; pub mod traits;
pub mod types_list; pub mod types_list;

110
src/types/newtypes/mod.rs Normal file
View File

@ -0,0 +1,110 @@
/*
* 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/>.
*/
//! This module contains wrapper types for know rust types, where trixy needs to store additional
//! information
use std::{fmt::Display, mem, string};
#[derive(Debug, Default, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct String {
pub(crate) data: Option<string::String>,
pub(crate) alloc_location: AllocLocation,
}
#[derive(Clone, Hash, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
pub(crate) enum AllocLocation {
#[default]
Rust,
C,
}
impl From<&str> for String {
fn from(value: &str) -> Self {
Self {
// It's cloned here:
data: Some(value.to_owned()),
// The string is always allocated in rust, as we clone it above this comment
alloc_location: AllocLocation::Rust,
}
}
}
impl From<string::String> for String {
fn from(value: string::String) -> Self {
Self {
data: Some(value),
// We just assume that every std String is actually allocated in rust
alloc_location: AllocLocation::Rust,
}
}
}
impl Display for String {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.as_str())
}
}
impl String {
pub fn as_str(&self) -> &str {
&self
.data
.as_ref()
.expect("The string should only be empty when it's dropped")
}
pub fn into_std_string(mut self) -> string::String {
match self.alloc_location {
AllocLocation::C => {
// Re-allocate the string in rust
let c_alloc_string = mem::take(&mut self.data).expect("It should only be Some");
let rust_alloc_string = c_alloc_string.clone();
// This is here because of the same reason as in the drop impl: we just can't free
// a string allocated in c.
mem::forget(c_alloc_string);
rust_alloc_string
}
AllocLocation::Rust => {
let string = mem::take(&mut self.data).expect("Will always be some");
string
}
}
}
}
impl Drop for String {
fn drop(&mut self) {
match self.alloc_location {
AllocLocation::C => {
let string = mem::take(&mut self.data);
// C needs to free it's strings by itself. We cannot do the job of the c allocator,
// thus just forget about it here
mem::forget(string)
}
AllocLocation::Rust => {
// A rust allocated string can be free normally. We don't need to do anything here.
}
}
}
}

View File

@ -20,32 +20,51 @@
* If not, see <https://www.gnu.org/licenses/>. * If not, see <https://www.gnu.org/licenses/>.
*/ */
use crate::types::String; use crate::types::{
newtypes::{self, AllocLocation},
types_list,
};
use std::ffi::CString; use std::ffi::CString;
use super::convert_trait::Convertible; use super::convert_trait::Convertible;
impl From<std::string::String> for String { impl From<std::string::String> for types_list::String {
fn from(value: std::string::String) -> Self { fn from(value: std::string::String) -> Self {
let cstring = let cstring =
CString::new(value).expect("The input is a valid String, this always succeeds"); CString::new(value).expect("The input is a valid String, this always succeeds");
let c_char = cstring.into_ptr(); let c_char = cstring.into_ptr();
String(c_char) types_list::String(c_char)
} }
} }
/// Plainly here for convenience /// Plainly here for convenience
impl From<&str> for String { impl From<&str> for types_list::String {
fn from(value: &str) -> Self { fn from(value: &str) -> Self {
value.to_owned().into() value.to_owned().into()
} }
} }
impl TryFrom<String> for std::string::String { impl From<newtypes::String> for types_list::String {
fn from(value: newtypes::String) -> Self {
// NOTE: This is not really performant, but necessary as we otherwise would need c to
// differentiate between c allocated strings (which are freed by `free`) and rust allocated strings
// (which are freed by `string_free`) <2024-05-04>
let value_string = value.into_std_string();
value_string.into()
}
}
impl TryFrom<types_list::String> for newtypes::String {
type Error = crate::types::error::TypeConversionError; type Error = crate::types::error::TypeConversionError;
fn try_from(value: String) -> Result<Self, Self::Error> { fn try_from(value: types_list::String) -> Result<Self, Self::Error> {
let cstring = CString::from_ptr(value.0)?; let cstring = CString::from_ptr(value.0)?;
let string = cstring.into_string()?; let string = cstring.into_string()?;
Ok(string)
Ok(newtypes::String {
data: Some(string),
// TODO: You could of course do a rust-only round trip, but I think it's reasonable to
// assume, that all types_list::String values come from C <2024-05-04>
alloc_location: AllocLocation::C,
})
} }
} }