From 4ef14834addb34546540a660ed0a5914cc1d78c7 Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Wed, 18 Jun 2025 00:14:18 +0200 Subject: [PATCH 01/12] update ci --- .github/workflows/rust.yml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index d0f1da3..f3763b6 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -30,11 +30,6 @@ jobs: - name: build run: cargo build - - name: generate bindings - run: ./generate-binding.sh - - name: check that generated files did not change - run: output=$(git status --porcelain) && [ -z "$output" ] - - name: build example -- glibc release run: cd example && make -r clean-all && make -r LIBC=gnu LINK=dynamic PROFILE=release - name: build example -- glibc debug @@ -52,6 +47,14 @@ jobs: - name: install rust targets run: rustup toolchain install nightly -t aarch64-unknown-linux-gnu -c rust-src --no-self-update + - name: install csbindgen + run: rustup run nightly cargo install cbindgen@0.29 + + - name: generate bindings + run: ./generate-binding.sh + - name: check that generated files did not change + run: output=$(git status --porcelain) && [ -z "$output" ] + - name: build example -- glibc size_optimized run: cd example && make clean-all -r && make -r LIBC=gnu LINK=dynamic PROFILE=size_optimized CARGO="rustup run nightly cargo" LTO=1 From 5e1a466bbfccba7853f00f1f62f91e5c62e4c3de Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Wed, 18 Jun 2025 17:25:11 +0200 Subject: [PATCH 02/12] fix Makefile --- example/Makefile | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/example/Makefile b/example/Makefile index 5659216..0a56e1a 100644 --- a/example/Makefile +++ b/example/Makefile @@ -47,6 +47,8 @@ CARGOFLAGS += --manifest-path=$(REPO_ROOT)/Cargo.toml \ --target=$(RUST_TARGET) \ --target-dir=cargo +STATIC_LINK_LIBS += -lservicepoint_binding_c +_servicepoint_cflags := -I $(REPO_ROOT)/include -L $(CARGO_OBJDIR) CFLAGS += -Wall -Wextra -pedantic -fwhole-program -fPIE -pie _no_debug_cflags := -ffunction-sections -fdata-sections -Wl,--gc-sections size_optimized_CFLAGS += -Oz \ @@ -69,7 +71,7 @@ debug_CFLAGS += -Og static_CFLAGS += -static $(STATIC_LINK_LIBS) dynamic_CFLAGS += -Wl,-Bstatic $(STATIC_LINK_LIBS) -Wl,-Bdynamic -_servicepoint_cflags := $(pkg-config --libs servicepoint --cflags) +_servicepoint_cflags := $(shell pkg-config --libs servicepoint --cflags || echo -I $(REPO_ROOT)/include -L $(CARGO_OBJDIR)) CFLAGS += $($(_libc)_CFLAGS) $($(_profile)_CFLAGS) $($(_link_type)_CFLAGS) $(_servicepoint_cflags) ifeq ($(LTO), 1) CFLAGS += -flto @@ -103,9 +105,9 @@ _unstripped_bins := $(addsuffix _unstripped, $(_bins)) .PHONY: all build-rust -all: $(_bins) +all: build-rust $(_bins) -$(_unstripped_bins): %_unstripped: src/%.c src/helpers.h build-rust +$(_unstripped_bins): %_unstripped : src/%.c src/helpers.h build-rust $(CC) $< $(CFLAGS) -o $@ $(_bins): %: %_unstripped From b92dcc565af3a36866429f0f3cd4864a97ffb17d Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Wed, 18 Jun 2025 17:39:30 +0200 Subject: [PATCH 03/12] multiple methods in one macro invocation --- src/containers/bitmap.rs | 30 ++++++++---------------------- src/containers/bitvec.rs | 30 ++++++++---------------------- src/containers/brightness_grid.rs | 30 ++++++++---------------------- src/containers/char_grid.rs | 27 ++++++++------------------- src/containers/cp437_grid.rs | 21 +++------------------ src/macros.rs | 21 +++++++++++++-------- 6 files changed, 48 insertions(+), 111 deletions(-) diff --git a/src/containers/bitmap.rs b/src/containers/bitmap.rs index 9b96d10..81af42d 100644 --- a/src/containers/bitmap.rs +++ b/src/containers/bitmap.rs @@ -1,6 +1,6 @@ use crate::{ containers::ByteSlice, - macros::{wrap_clone, wrap_free, wrap_method}, + macros::{wrap_clone, wrap_free, wrap_methods}, mem::{heap_move_nonnull, heap_move_ok, heap_move_some, heap_remove}, }; use servicepoint::{ @@ -83,8 +83,9 @@ pub unsafe extern "C" fn sp_bitmap_from_bitvec( wrap_clone!(sp_bitmap::Bitmap); wrap_free!(sp_bitmap::Bitmap); -wrap_method!( +wrap_methods!( sp_bitmap::Bitmap; + /// Gets the current value at the specified position. /// /// # Arguments @@ -95,10 +96,7 @@ wrap_method!( /// /// - when accessing `x` or `y` out of bounds ref fn get(x: usize, y: usize) -> bool; -); - -wrap_method!( - sp_bitmap::Bitmap; + /// Sets the value of the specified position. /// /// # Arguments @@ -110,32 +108,20 @@ wrap_method!( /// /// - when accessing `x` or `y` out of bounds mut fn set(x: usize, y: usize, value: bool); -); - -wrap_method!( - sp_bitmap::Bitmap; + /// Sets the state of all pixels in the [Bitmap]. /// /// # Arguments /// /// - `value`: the value to set all pixels to mut fn fill(value: bool); -); - -wrap_method!( - sp_bitmap::Bitmap; + /// Gets the width in pixels. ref fn width() -> usize; -); - -wrap_method!( - sp_bitmap::Bitmap; + /// Gets the height in pixels. ref fn height() -> usize; -); - -wrap_method!( - sp_bitmap::Bitmap; + /// Gets an unsafe reference to the data of the [Bitmap] instance. /// /// The returned memory is valid for the lifetime of the bitmap. diff --git a/src/containers/bitvec.rs b/src/containers/bitvec.rs index aad2a88..bceae0b 100644 --- a/src/containers/bitvec.rs +++ b/src/containers/bitvec.rs @@ -1,6 +1,6 @@ use crate::{ containers::ByteSlice, - macros::{wrap_clone, wrap_free, wrap_method}, + macros::{wrap_clone, wrap_free, wrap_methods}, mem::{heap_move_nonnull, heap_move_ok, heap_remove}, }; use servicepoint::{ @@ -38,8 +38,9 @@ pub unsafe extern "C" fn sp_bitvec_load( wrap_clone!(sp_bitvec::DisplayBitVec); wrap_free!(sp_bitvec::DisplayBitVec); -wrap_method!( +wrap_methods!( sp_bitvec::DisplayBitVec; + /// Gets the value of a bit. /// /// # Arguments @@ -54,10 +55,7 @@ wrap_method!( /// - when accessing `index` out of bounds ref fn get(index: usize) -> bool; |result| result.map(|x| *x).unwrap_or(false); -); - -wrap_method!( - sp_bitvec::DisplayBitVec; + /// Sets the value of a bit. /// /// # Arguments @@ -69,32 +67,20 @@ wrap_method!( /// /// - when accessing `index` out of bounds mut fn set(index: usize, value: bool); -); - -wrap_method!( - sp_bitvec::DisplayBitVec; + /// Sets the value of all bits. /// /// # Arguments /// /// - `value`: the value to set all bits to mut fn fill(value: bool); -); - -wrap_method!( - sp_bitvec::DisplayBitVec; + /// Gets the length in bits. ref fn len() -> usize; -); - -wrap_method!( - sp_bitvec::DisplayBitVec; + /// Returns true if length is 0. ref fn is_empty() -> bool; -); - -wrap_method!( - sp_bitvec::DisplayBitVec; + /// Gets an unsafe reference to the data of the [DisplayBitVec] instance. /// /// The returned memory is valid for the lifetime of the bitvec. diff --git a/src/containers/brightness_grid.rs b/src/containers/brightness_grid.rs index 54491c2..4e15599 100644 --- a/src/containers/brightness_grid.rs +++ b/src/containers/brightness_grid.rs @@ -1,6 +1,6 @@ use crate::{ containers::ByteSlice, - macros::{wrap_clone, wrap_free, wrap_method}, + macros::{wrap_clone, wrap_free, wrap_methods}, mem::{heap_move_nonnull, heap_move_ok, heap_move_some, heap_remove}, }; use servicepoint::{ @@ -55,8 +55,9 @@ pub unsafe extern "C" fn sp_brightness_grid_load( wrap_clone!(sp_brightness_grid::BrightnessGrid); wrap_free!(sp_brightness_grid::BrightnessGrid); -wrap_method!( +wrap_methods!( sp_brightness_grid::BrightnessGrid; + /// Gets the current value at the specified position. /// /// # Arguments @@ -68,10 +69,7 @@ wrap_method!( /// # Panics /// - When accessing `x` or `y` out of bounds. ref fn get(x: usize, y: usize) -> Brightness; -); - -wrap_method!( - sp_brightness_grid::BrightnessGrid; + /// Sets the value of the specified position. /// /// # Arguments @@ -85,32 +83,20 @@ wrap_method!( /// /// - When accessing `x` or `y` out of bounds. mut fn set(x: usize, y: usize, value: Brightness); -); - -wrap_method!( - sp_brightness_grid::BrightnessGrid; + /// Sets the value of all cells. /// /// # Arguments /// /// - `value`: the value to set all cells to mut fn fill(value: Brightness); -); - -wrap_method!( - sp_brightness_grid::BrightnessGrid; + /// Gets the width of the grid. ref fn width() -> usize; -); - -wrap_method!( - sp_brightness_grid::BrightnessGrid; + /// Gets the height of the grid. ref fn height() -> usize; -); - -wrap_method!( - sp_brightness_grid::BrightnessGrid; + /// Gets an unsafe reference to the data of the instance. /// /// The returned memory is valid for the lifetime of the grid. diff --git a/src/containers/char_grid.rs b/src/containers/char_grid.rs index 5db7897..dddae0b 100644 --- a/src/containers/char_grid.rs +++ b/src/containers/char_grid.rs @@ -1,6 +1,6 @@ use crate::{ containers::ByteSlice, - macros::{wrap_clone, wrap_free, wrap_method}, + macros::{wrap_clone, wrap_free, wrap_methods}, mem::{heap_move_nonnull, heap_move_ok, heap_remove}, }; use servicepoint::{CharGrid, CharGridCommand, Grid, Origin, Packet}; @@ -42,8 +42,9 @@ pub unsafe extern "C" fn sp_char_grid_load( wrap_clone!(sp_char_grid::CharGrid); wrap_free!(sp_char_grid::CharGrid); -wrap_method!( +wrap_methods!( sp_char_grid::CharGrid; + /// Returns the current value at the specified position. /// /// # Arguments @@ -54,11 +55,8 @@ wrap_method!( /// /// - when accessing `x` or `y` out of bounds ref fn get(x: usize, y: usize) -> u32; - | char | char as u32 -); - -wrap_method!( - sp_char_grid::CharGrid; + | char | char as u32; + /// Sets the value of the specified position in the grid. /// /// # Arguments @@ -74,10 +72,7 @@ wrap_method!( /// - when providing values that cannot be converted to Rust's `char`. mut fn set(x: usize, y: usize, value: u32); let value = char::from_u32(value).unwrap(); -); - -wrap_method!( - sp_char_grid::CharGrid; + /// Sets the value of all cells in the grid. /// /// # Arguments @@ -86,16 +81,10 @@ wrap_method!( /// - when providing values that cannot be converted to Rust's `char`. mut fn fill(value: u32); let value = char::from_u32(value).unwrap(); -); - -wrap_method!( - sp_char_grid::CharGrid; + /// Gets the width of the grid. ref fn width() -> usize; -); - -wrap_method!( - sp_char_grid::CharGrid; + /// Gets the height of the grid. ref fn height() -> usize; ); diff --git a/src/containers/cp437_grid.rs b/src/containers/cp437_grid.rs index 5d7b84f..166083f 100644 --- a/src/containers/cp437_grid.rs +++ b/src/containers/cp437_grid.rs @@ -1,6 +1,6 @@ use crate::{ containers::ByteSlice, - macros::{wrap_clone, wrap_free, wrap_method}, + macros::{wrap_clone, wrap_free, wrap_methods}, mem::{heap_move_nonnull, heap_move_ok, heap_move_some, heap_remove}, }; use servicepoint::{ @@ -33,7 +33,7 @@ pub unsafe extern "C" fn sp_cp437_grid_load( wrap_clone!(sp_cp437_grid::Cp437Grid); wrap_free!(sp_cp437_grid::Cp437Grid); -wrap_method!( +wrap_methods!( sp_cp437_grid::Cp437Grid; /// Gets the current value at the specified position. /// @@ -45,10 +45,7 @@ wrap_method!( /// /// - when accessing `x` or `y` out of bounds ref fn get(x: usize, y: usize) -> u8; -); -wrap_method!( - sp_cp437_grid::Cp437Grid; /// Sets the value at the specified position. /// /// # Arguments @@ -62,10 +59,7 @@ wrap_method!( /// /// - when accessing `x` or `y` out of bounds mut fn set(x: usize, y: usize, value: u8); -); -wrap_method!( - sp_cp437_grid::Cp437Grid; /// Sets the value of all cells in the grid. /// /// # Arguments @@ -73,22 +67,13 @@ wrap_method!( /// - `cp437_grid`: instance to write to /// - `value`: the value to set all cells to mut fn fill(value: u8); -); -wrap_method!( - sp_cp437_grid::Cp437Grid; /// Gets the width of the grid. ref fn width() -> usize; -); -wrap_method!( - sp_cp437_grid::Cp437Grid; /// Gets the height of the grid. ref fn height() -> usize; -); - -wrap_method!( - sp_cp437_grid::Cp437Grid; + /// Gets an unsafe reference to the data of the grid. /// /// The returned memory is valid for the lifetime of the instance. diff --git a/src/macros.rs b/src/macros.rs index df21e23..fc6e524 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -35,16 +35,18 @@ macro_rules! nonnull_as_mut { } // meta required on purpose, because otherwise the added documentation would suppress warnings -macro_rules! wrap_method { +macro_rules! wrap_methods { ( $prefix:ident :: $object_type:ty; - $(#[$meta:meta])+ - $ref_or_mut:ident fn $function:ident($($param_name:ident: $param_type:ty),*) - $(-> $return_type:ty$(; |$it:ident | $return_expr:expr)?)? - $(; let $param_let_name:ident = $param_let_expr:expr)* - $(;)? + $( + $(#[$meta:meta])+ + $ref_or_mut:ident fn $function:ident($($param_name:ident: $param_type:ty),*) + $(-> $return_type:ty$(; |$it:ident | $return_expr:expr)?)?; + $($(let $param_let_name:ident = $param_let_expr:expr);+;)? + )* ) => { paste::paste! { + $( #[doc = concat!(" Calls [`servicepoint::", stringify!($object_type), "::", stringify!($function), "`].")] #[doc = ""] @@ -55,7 +57,9 @@ macro_rules! wrap_method { $($param_name: $param_type),* ) $(-> $return_type)? { let instance = unsafe { $crate::macros:: [< nonnull_as_ $ref_or_mut >] !(instance) }; - $(let $param_let_name = $param_let_expr;)* + $( + $(let $param_let_name = $param_let_expr;)* + )? #[allow( unused_variables, reason = "This variable may not be used depending on macro variables" )] @@ -68,6 +72,7 @@ macro_rules! wrap_method { return result; )? } + )* } }; } @@ -142,5 +147,5 @@ macro_rules! wrap_fields { pub(crate) use { nonnull_as_mut, nonnull_as_ref, wrap_clone, wrap_fields, wrap_free, - wrap_method, + wrap_methods, }; From a06c3a83aa0e987b7cf66733d0447051727df7ae Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Wed, 18 Jun 2025 17:51:32 +0200 Subject: [PATCH 04/12] tweak dsl --- src/containers/bitmap.rs | 18 ++++++++++-------- src/containers/bitvec.rs | 23 +++++++++++++---------- src/containers/brightness_grid.rs | 23 ++++++++++++----------- src/containers/char_grid.rs | 25 ++++++++++++++----------- src/containers/cp437_grid.rs | 7 ++++--- src/macros.rs | 14 +++++++++----- 6 files changed, 62 insertions(+), 48 deletions(-) diff --git a/src/containers/bitmap.rs b/src/containers/bitmap.rs index 81af42d..ae0d2ae 100644 --- a/src/containers/bitmap.rs +++ b/src/containers/bitmap.rs @@ -85,7 +85,7 @@ wrap_free!(sp_bitmap::Bitmap); wrap_methods!( sp_bitmap::Bitmap; - + /// Gets the current value at the specified position. /// /// # Arguments @@ -96,7 +96,7 @@ wrap_methods!( /// /// - when accessing `x` or `y` out of bounds ref fn get(x: usize, y: usize) -> bool; - + /// Sets the value of the specified position. /// /// # Arguments @@ -108,25 +108,27 @@ wrap_methods!( /// /// - when accessing `x` or `y` out of bounds mut fn set(x: usize, y: usize, value: bool); - + /// Sets the state of all pixels in the [Bitmap]. /// /// # Arguments /// /// - `value`: the value to set all pixels to mut fn fill(value: bool); - + /// Gets the width in pixels. ref fn width() -> usize; - + /// Gets the height in pixels. ref fn height() -> usize; - + /// Gets an unsafe reference to the data of the [Bitmap] instance. /// /// The returned memory is valid for the lifetime of the bitmap. - mut fn data_ref_mut() -> ByteSlice; - |slice| unsafe { ByteSlice::from_slice(slice) }; + mut fn data_ref_mut() -> ByteSlice { + + return(slice) { unsafe { ByteSlice::from_slice(slice) } }; + }; ); /// Consumes the Bitmap and returns the contained BitVec. diff --git a/src/containers/bitvec.rs b/src/containers/bitvec.rs index bceae0b..76d716a 100644 --- a/src/containers/bitvec.rs +++ b/src/containers/bitvec.rs @@ -40,7 +40,7 @@ wrap_free!(sp_bitvec::DisplayBitVec); wrap_methods!( sp_bitvec::DisplayBitVec; - + /// Gets the value of a bit. /// /// # Arguments @@ -53,9 +53,11 @@ wrap_methods!( /// # Panics /// /// - when accessing `index` out of bounds - ref fn get(index: usize) -> bool; - |result| result.map(|x| *x).unwrap_or(false); - + ref fn get(index: usize) -> bool { + return(result) { result.map(|x| *x).unwrap_or(false) }; + }; + + /// Sets the value of a bit. /// /// # Arguments @@ -67,25 +69,26 @@ wrap_methods!( /// /// - when accessing `index` out of bounds mut fn set(index: usize, value: bool); - + /// Sets the value of all bits. /// /// # Arguments /// /// - `value`: the value to set all bits to mut fn fill(value: bool); - + /// Gets the length in bits. ref fn len() -> usize; - + /// Returns true if length is 0. ref fn is_empty() -> bool; - + /// Gets an unsafe reference to the data of the [DisplayBitVec] instance. /// /// The returned memory is valid for the lifetime of the bitvec. - mut fn as_raw_mut_slice() -> ByteSlice; - |slice| unsafe { ByteSlice::from_slice(slice) }; + mut fn as_raw_mut_slice() -> ByteSlice { + return(slice) { unsafe { ByteSlice::from_slice(slice) } }; + }; ); /// Creates a [BitVecCommand] and immediately turns that into a [Packet]. diff --git a/src/containers/brightness_grid.rs b/src/containers/brightness_grid.rs index 4e15599..a3590b8 100644 --- a/src/containers/brightness_grid.rs +++ b/src/containers/brightness_grid.rs @@ -57,7 +57,7 @@ wrap_free!(sp_brightness_grid::BrightnessGrid); wrap_methods!( sp_brightness_grid::BrightnessGrid; - + /// Gets the current value at the specified position. /// /// # Arguments @@ -69,7 +69,7 @@ wrap_methods!( /// # Panics /// - When accessing `x` or `y` out of bounds. ref fn get(x: usize, y: usize) -> Brightness; - + /// Sets the value of the specified position. /// /// # Arguments @@ -83,29 +83,30 @@ wrap_methods!( /// /// - When accessing `x` or `y` out of bounds. mut fn set(x: usize, y: usize, value: Brightness); - + /// Sets the value of all cells. /// /// # Arguments /// /// - `value`: the value to set all cells to mut fn fill(value: Brightness); - + /// Gets the width of the grid. ref fn width() -> usize; - + /// Gets the height of the grid. ref fn height() -> usize; - + /// Gets an unsafe reference to the data of the instance. /// /// The returned memory is valid for the lifetime of the grid. - mut fn data_ref_mut() -> ByteSlice; - |br_slice| unsafe { - //noinspection RsAssertEqual - const _: () = assert!(size_of::() == 1); + mut fn data_ref_mut() -> ByteSlice { + return(br_slice) { unsafe { + //noinspection RsAssertEqual + const _: () = assert!(size_of::() == 1); - ByteSlice::from_slice(transmute::<&mut [Brightness], &mut [u8]>(br_slice)) + ByteSlice::from_slice(transmute::<&mut [Brightness], &mut [u8]>(br_slice)) + }}; }; ); diff --git a/src/containers/char_grid.rs b/src/containers/char_grid.rs index dddae0b..1b70202 100644 --- a/src/containers/char_grid.rs +++ b/src/containers/char_grid.rs @@ -44,7 +44,7 @@ wrap_free!(sp_char_grid::CharGrid); wrap_methods!( sp_char_grid::CharGrid; - + /// Returns the current value at the specified position. /// /// # Arguments @@ -54,9 +54,10 @@ wrap_methods!( /// # Panics /// /// - when accessing `x` or `y` out of bounds - ref fn get(x: usize, y: usize) -> u32; - | char | char as u32; - + ref fn get(x: usize, y: usize) -> u32 { + return(char) { char as u32 }; + }; + /// Sets the value of the specified position in the grid. /// /// # Arguments @@ -70,21 +71,23 @@ wrap_methods!( /// /// - when accessing `x` or `y` out of bounds /// - when providing values that cannot be converted to Rust's `char`. - mut fn set(x: usize, y: usize, value: u32); - let value = char::from_u32(value).unwrap(); - + mut fn set(x: usize, y: usize, value: u32) { + prepare(value) { char::from_u32(value).unwrap() }; + }; + /// Sets the value of all cells in the grid. /// /// # Arguments /// /// - `value`: the value to set all cells to /// - when providing values that cannot be converted to Rust's `char`. - mut fn fill(value: u32); - let value = char::from_u32(value).unwrap(); - + mut fn fill(value: u32) { + prepare(value) { char::from_u32(value).unwrap() }; + }; + /// Gets the width of the grid. ref fn width() -> usize; - + /// Gets the height of the grid. ref fn height() -> usize; ); diff --git a/src/containers/cp437_grid.rs b/src/containers/cp437_grid.rs index 166083f..d6ae17f 100644 --- a/src/containers/cp437_grid.rs +++ b/src/containers/cp437_grid.rs @@ -73,12 +73,13 @@ wrap_methods!( /// Gets the height of the grid. ref fn height() -> usize; - + /// Gets an unsafe reference to the data of the grid. /// /// The returned memory is valid for the lifetime of the instance. - mut fn data_ref_mut() -> ByteSlice; - | slice | unsafe { ByteSlice::from_slice(slice) }; + mut fn data_ref_mut() -> ByteSlice { + return(slice) { unsafe { ByteSlice::from_slice(slice) } }; + }; ); /// Creates a [Cp437GridCommand] and immediately turns that into a [Packet]. diff --git a/src/macros.rs b/src/macros.rs index fc6e524..cbadc14 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -41,8 +41,12 @@ macro_rules! wrap_methods { $( $(#[$meta:meta])+ $ref_or_mut:ident fn $function:ident($($param_name:ident: $param_type:ty),*) - $(-> $return_type:ty$(; |$it:ident | $return_expr:expr)?)?; - $($(let $param_let_name:ident = $param_let_expr:expr);+;)? + $(-> $return_type:ty)? + $({ + $($(prepare($param_let_name:ident) $param_let_expr:block);+;)? + $(return($it:ident) $return_expr:block;)? + })? + ; )* ) => { paste::paste! { @@ -57,9 +61,9 @@ macro_rules! wrap_methods { $($param_name: $param_type),* ) $(-> $return_type)? { let instance = unsafe { $crate::macros:: [< nonnull_as_ $ref_or_mut >] !(instance) }; - $( + $($( $(let $param_let_name = $param_let_expr;)* - )? + )?)? #[allow( unused_variables, reason = "This variable may not be used depending on macro variables" )] @@ -69,8 +73,8 @@ macro_rules! wrap_methods { let $it = result; let result = $return_expr; )? - return result; )? + return result; } )* } From 749e22493765c448306227a3a01d6eaf5ec906fa Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Wed, 18 Jun 2025 20:30:55 +0200 Subject: [PATCH 05/12] wrap_function without defined signature --- include/servicepoint.h | 79 ++++++++- src/commands/bitmap_command.rs | 77 ++++----- src/commands/bitvec_command.rs | 74 ++++---- src/commands/brightness_grid_command.rs | 69 ++++---- src/commands/cc_only_commands.rs | 58 ++++--- src/commands/char_grid_command.rs | 73 ++++---- src/commands/cp437_grid_command.rs | 69 ++++---- src/commands/global_brightness_command.rs | 31 ++-- src/containers/bitmap.rs | 195 +++++++++++----------- src/containers/bitvec.rs | 93 +++++------ src/containers/brightness_grid.rs | 120 ++++++------- src/containers/char_grid.rs | 101 +++++------ src/containers/cp437_grid.rs | 78 ++++----- src/macros.rs | 32 +++- 14 files changed, 630 insertions(+), 519 deletions(-) diff --git a/include/servicepoint.h b/include/servicepoint.h index 02d0688..5960987 100644 --- a/include/servicepoint.h +++ b/include/servicepoint.h @@ -675,6 +675,8 @@ void sp_bitmap_free(struct Bitmap */*notnull*/ instance); * The provided BitVec gets consumed. * * Returns NULL in case of error. + * + * This function is part of the sp_bitmap module. */ struct Bitmap *sp_bitmap_from_bitvec(size_t width, BitVec */*notnull*/ bitvec); @@ -702,6 +704,8 @@ size_t sp_bitmap_height(struct Bitmap */*notnull*/ instance); /** * Consumes the Bitmap and returns the contained BitVec. + * + * This function is part of the sp_bitmap module. */ BitVec */*notnull*/ sp_bitmap_into_bitvec(struct Bitmap */*notnull*/ bitmap); @@ -711,6 +715,8 @@ BitVec */*notnull*/ sp_bitmap_into_bitvec(struct Bitmap */*notnull*/ bitmap); * The provided [Bitmap] gets consumed. * * Returns NULL in case of an error. + * + * This function is part of the sp_bitmap module. */ struct Packet *sp_bitmap_into_packet(struct Bitmap */*notnull*/ bitmap, size_t x, @@ -726,6 +732,8 @@ struct Packet *sp_bitmap_into_packet(struct Bitmap */*notnull*/ bitmap, * - `height`: size in pixels in y-direction * * returns: [Bitmap] that contains a copy of the provided data, or NULL in case of an error. + * + * This function is part of the sp_bitmap module. */ struct Bitmap *sp_bitmap_load(size_t width, size_t height, @@ -755,6 +763,8 @@ struct Bitmap *sp_bitmap_load(size_t width, * sp_bitmap_set(grid, 0, 0, false); * sp_bitmap_free(grid); * ``` + * + * This function is part of the sp_bitmap module. */ struct Bitmap *sp_bitmap_new(size_t width, size_t height); @@ -762,6 +772,8 @@ struct Bitmap *sp_bitmap_new(size_t width, size_t height); * Creates a new [Bitmap] with a size matching the screen. * * returns: [Bitmap] initialized to all pixels off. + * + * This function is part of the sp_bitmap module. */ struct Bitmap */*notnull*/ sp_bitmap_new_max_sized(void); @@ -845,6 +857,8 @@ bool sp_bitvec_get(BitVec */*notnull*/ instance, size_t index); * The provided [DisplayBitVec] gets consumed. * * Returns NULL in case of an error. + * + * This function is part of the sp_bitvec module. */ struct Packet *sp_bitvec_into_packet(BitVec */*notnull*/ bitvec, size_t offset, @@ -869,6 +883,8 @@ size_t sp_bitvec_len(BitVec */*notnull*/ instance); * Interpret the data as a series of bits and load then into a new [DisplayBitVec] instance. * * returns: [DisplayBitVec] instance containing data. + * + * This function is part of the sp_bitvec module. */ BitVec */*notnull*/ sp_bitvec_load(struct ByteSlice data); @@ -884,6 +900,8 @@ BitVec */*notnull*/ sp_bitvec_load(struct ByteSlice data); * # Panics * * - when `size` is not divisible by 8. + * + * This function is part of the sp_bitvec module. */ BitVec */*notnull*/ sp_bitvec_new(size_t size); @@ -965,6 +983,8 @@ size_t sp_brightness_grid_height(BrightnessGrid */*notnull*/ instance); * The provided [BrightnessGrid] gets consumed. * * Returns NULL in case of an error. + * + * This function is part of the sp_brightness_grid module. */ struct Packet *sp_brightness_grid_into_packet(BrightnessGrid */*notnull*/ grid, size_t x, @@ -976,6 +996,8 @@ struct Packet *sp_brightness_grid_into_packet(BrightnessGrid */*notnull*/ grid, * Any out of range values will be set to [Brightness::MAX] or [Brightness::MIN]. * * returns: new [BrightnessGrid] instance, or NULL in case of an error. + * + * This function is part of the sp_brightness_grid module. */ BrightnessGrid *sp_brightness_grid_load(size_t width, size_t height, @@ -999,6 +1021,8 @@ BrightnessGrid *sp_brightness_grid_load(size_t width, * TypedCommand *command = sp_command_char_brightness(grid); * sp_udp_free(connection); * ``` + * + * This function is part of the sp_brightness_grid module. */ BrightnessGrid */*notnull*/ sp_brightness_grid_new(size_t width, size_t height); @@ -1080,6 +1104,8 @@ size_t sp_char_grid_height(CharGrid */*notnull*/ instance); * The provided [CharGrid] gets consumed. * * Returns NULL in case of an error. + * + * This function is part of the sp_char_grid module. */ struct Packet *sp_char_grid_into_packet(CharGrid */*notnull*/ grid, size_t x, @@ -1089,6 +1115,8 @@ struct Packet *sp_char_grid_into_packet(CharGrid */*notnull*/ grid, * Loads a [CharGrid] with the specified dimensions from the provided data. * * returns: new CharGrid or NULL in case of an error + * + * This function is part of the sp_char_grid module. */ CharGrid *sp_char_grid_load(size_t width, size_t height, struct ByteSlice data); @@ -1105,6 +1133,8 @@ CharGrid *sp_char_grid_load(size_t width, size_t height, struct ByteSlice data); * sp_char_grid_set(grid, 0, 0, '!'); * sp_char_grid_free(grid); * ``` + * + * This function is part of the sp_char_grid module. */ CharGrid */*notnull*/ sp_char_grid_new(size_t width, size_t height); @@ -1152,6 +1182,8 @@ void sp_cmd_bitmap_free(struct BitmapCommand */*notnull*/ instance); * leaving other fields as their default values. * * Rust equivalent: `BitmapCommand::from(bitmap)` + * + * This function is part of the sp_cmd_bitmap module. */ struct BitmapCommand */*notnull*/ sp_cmd_bitmap_from_bitmap(struct Bitmap */*notnull*/ bitmap); @@ -1183,6 +1215,8 @@ void sp_cmd_bitmap_get_origin(struct BitmapCommand */*notnull*/ command, * The passed [Bitmap] gets consumed. * * Returns: a new [BitmapCommand] instance. + * + * This function is part of the sp_cmd_bitmap module. */ struct BitmapCommand */*notnull*/ sp_cmd_bitmap_new(struct Bitmap */*notnull*/ bitmap, size_t origin_x, @@ -1212,6 +1246,8 @@ void sp_cmd_bitmap_set_origin(struct BitmapCommand */*notnull*/ command, * Tries to turn a [BitmapCommand] into a [Packet]. * * Returns: NULL or a [Packet] containing the command. + * + * This function is part of the sp_cmd_bitmap module. */ struct Packet *sp_cmd_bitmap_try_into_packet(struct BitmapCommand */*notnull*/ command); @@ -1258,6 +1294,8 @@ BinaryOperation sp_cmd_bitvec_get_operation(struct BitVecCommand */*notnull*/ in * For example, [`BinaryOperation::Or`] can be used to turn on some pixels without affecting other pixels. * * The contained [`DisplayBitVec`] is always uncompressed. + * + * This function is part of the sp_cmd_bitvec module. */ struct BitVecCommand */*notnull*/ sp_cmd_bitvec_new(BitVec */*notnull*/ bitvec, size_t offset, @@ -1292,6 +1330,8 @@ void sp_cmd_bitvec_set_operation(struct BitVecCommand */*notnull*/ instance, * Tries to turn a [BitVecCommand] into a [Packet]. * * Returns: NULL or a [Packet] containing the command. + * + * This function is part of the sp_cmd_bitvec module. */ struct Packet *sp_cmd_bitvec_try_into_packet(struct BitVecCommand */*notnull*/ command); @@ -1310,12 +1350,19 @@ void sp_cmd_brightness_global_free(struct GlobalBrightnessCommand */*notnull*/ i */ Brightness sp_cmd_brightness_global_get_brightness(struct GlobalBrightnessCommand */*notnull*/ instance); +/** + * Turns the command into a packet + * + * This function is part of the sp_cmd_brightness_global module. + */ struct Packet */*notnull*/ sp_cmd_brightness_global_into_packet(struct GlobalBrightnessCommand */*notnull*/ command); /** * Set the brightness of all tiles to the same value. * * Returns: a new [GlobalBrightnessCommand] instance. + * + * This function is part of the sp_cmd_brightness_global module. */ struct GlobalBrightnessCommand */*notnull*/ sp_cmd_brightness_global_new(Brightness brightness); @@ -1338,6 +1385,8 @@ void sp_cmd_brightness_grid_free(struct BrightnessGridCommand */*notnull*/ insta /** * Moves the provided [BrightnessGrid] into a new [BrightnessGridCommand], * leaving other fields as their default values. + * + * This function is part of the sp_cmd_brightness_grid module. */ struct BrightnessGridCommand */*notnull*/ sp_cmd_brightness_grid_from_grid(BrightnessGrid */*notnull*/ grid); @@ -1357,6 +1406,8 @@ void sp_cmd_brightness_grid_get_origin(struct BrightnessGridCommand */*notnull*/ * Tries to turn a [BrightnessGridCommand] into a [Packet]. * * Returns: NULL or a [Packet] containing the command. + * + * This function is part of the sp_cmd_brightness_grid module. */ struct Packet *sp_cmd_brightness_grid_into_packet(struct BrightnessGridCommand */*notnull*/ command); @@ -1366,6 +1417,8 @@ struct Packet *sp_cmd_brightness_grid_into_packet(struct BrightnessGridCommand * * The passed [BrightnessGrid] gets consumed. * * Returns: a new [BrightnessGridCommand] instance. + * + * This function is part of the sp_cmd_brightness_grid module. */ struct BrightnessGridCommand */*notnull*/ sp_cmd_brightness_grid_new(BrightnessGrid */*notnull*/ grid, size_t origin_x, @@ -1397,13 +1450,15 @@ void sp_cmd_char_grid_free(struct CharGridCommand */*notnull*/ instance); /** * Moves the provided [CharGrid] into a new [CharGridCommand], * leaving other fields as their default values. + * + * This function is part of the sp_cmd_char_grid module. */ struct CharGridCommand */*notnull*/ sp_cmd_char_grid_from_grid(CharGrid */*notnull*/ grid); /** * Returns a pointer to the [CharGrid] contained in the [CharGridCommand]. */ -CharGrid *sp_cmd_char_grid_get(struct CharGridCommand */*notnull*/ command); +CharGrid */*notnull*/ sp_cmd_char_grid_get(struct CharGridCommand */*notnull*/ command); /** * Reads the origin field of the [CharGridCommand]. @@ -1418,6 +1473,8 @@ void sp_cmd_char_grid_get_origin(struct CharGridCommand */*notnull*/ command, * The passed [CharGrid] gets consumed. * * Returns: a new [CharGridCommand] instance. + * + * This function is part of the sp_cmd_char_grid module. */ struct CharGridCommand */*notnull*/ sp_cmd_char_grid_new(CharGrid */*notnull*/ grid, size_t origin_x, @@ -1440,6 +1497,8 @@ void sp_cmd_char_grid_set_origin(struct CharGridCommand */*notnull*/ command, * Tries to turn a [CharGridCommand] into a [Packet]. * * Returns: NULL or a [Packet] containing the command. + * + * This function is part of the sp_cmd_char_grid module. */ struct Packet *sp_cmd_char_grid_try_into_packet(struct CharGridCommand */*notnull*/ command); @@ -1454,6 +1513,8 @@ void sp_cmd_clear_free(struct ClearCommand */*notnull*/ instance); * Does not affect brightness. * * Returns: a new [ClearCommand] instance. + * + * This function is part of the sp_cmd_clear module. */ struct ClearCommand */*notnull*/ sp_cmd_clear_new(void); @@ -1470,6 +1531,8 @@ void sp_cmd_cp437_grid_free(struct Cp437GridCommand */*notnull*/ instance); /** * Moves the provided [Cp437Grid] into a new [Cp437GridCommand], * leaving other fields as their default values. + * + * This function is part of the sp_cmd_cp437_grid module. */ struct Cp437GridCommand */*notnull*/ sp_cmd_cp437_grid_from_grid(Cp437Grid */*notnull*/ grid); @@ -1498,6 +1561,8 @@ void sp_cmd_cp437_grid_get_origin(struct Cp437GridCommand */*notnull*/ command, * The text is sent in the form of a 2D grid of [CP-437] encoded characters. * * The origin is relative to the top-left of the display. + * + * This function is part of the sp_cmd_cp437_grid module. */ struct Cp437GridCommand */*notnull*/ sp_cmd_cp437_grid_new(Cp437Grid */*notnull*/ grid, size_t origin_x, @@ -1524,6 +1589,8 @@ void sp_cmd_cp437_grid_set_origin(struct Cp437GridCommand */*notnull*/ command, * Tries to turn a [Cp437GridCommand] into a [Packet]. * * Returns: NULL or a [Packet] containing the command. + * + * This function is part of the sp_cmd_cp437_grid module. */ struct Packet *sp_cmd_cp437_grid_try_into_packet(struct Cp437GridCommand */*notnull*/ command); @@ -1536,6 +1603,8 @@ void sp_cmd_fade_out_free(struct FadeOutCommand */*notnull*/ instance); * A yet-to-be-tested command. * * Returns: a new [FadeOutCommand] instance. + * + * This function is part of the sp_cmd_fade_out module. */ struct FadeOutCommand */*notnull*/ sp_cmd_fade_out_new(void); @@ -1588,6 +1657,8 @@ void sp_cmd_hard_reset_free(struct HardResetCommand */*notnull*/ instance); * Please do not send this in your normal program flow. * * Returns: a new [HardResetCommand] instance. + * + * This function is part of the sp_cmd_hard_reset module. */ struct HardResetCommand */*notnull*/ sp_cmd_hard_reset_new(void); @@ -1650,6 +1721,8 @@ size_t sp_cp437_grid_height(Cp437Grid */*notnull*/ instance); * The provided [Cp437Grid] gets consumed. * * Returns NULL in case of an error. + * + * This function is part of the sp_cp437_grid module. */ struct Packet *sp_cp437_grid_into_packet(Cp437Grid */*notnull*/ grid, size_t x, @@ -1657,6 +1730,8 @@ struct Packet *sp_cp437_grid_into_packet(Cp437Grid */*notnull*/ grid, /** * Loads a [Cp437Grid] with the specified dimensions from the provided data. + * + * This function is part of the sp_cp437_grid module. */ Cp437Grid *sp_cp437_grid_load(size_t width, size_t height, @@ -1666,6 +1741,8 @@ Cp437Grid *sp_cp437_grid_load(size_t width, * Creates a new [Cp437Grid] with the specified dimensions. * * returns: [Cp437Grid] initialized to 0. + * + * This function is part of the sp_cp437_grid module. */ Cp437Grid */*notnull*/ sp_cp437_grid_new(size_t width, size_t height); diff --git a/src/commands/bitmap_command.rs b/src/commands/bitmap_command.rs index 3bfcf20..f4c9a7e 100644 --- a/src/commands/bitmap_command.rs +++ b/src/commands/bitmap_command.rs @@ -1,49 +1,50 @@ use crate::{ - macros::{wrap_clone, wrap_fields, wrap_free}, + macros::{wrap_clone, wrap_fields, wrap_free, wrap_functions}, mem::{heap_move_nonnull, heap_move_ok, heap_remove}, }; use servicepoint::{Bitmap, BitmapCommand, CompressionCode, Origin, Packet}; use std::ptr::NonNull; -/// Sets a window of pixels to the specified values. -/// -/// The passed [Bitmap] gets consumed. -/// -/// Returns: a new [BitmapCommand] instance. -#[no_mangle] -pub unsafe extern "C" fn sp_cmd_bitmap_new( - bitmap: NonNull, - origin_x: usize, - origin_y: usize, - compression: CompressionCode, -) -> NonNull { - heap_move_nonnull(BitmapCommand { - bitmap: unsafe { heap_remove(bitmap) }, - origin: Origin::new(origin_x, origin_y), - compression, - }) -} +wrap_functions!(sp_cmd_bitmap; -/// Move the provided [Bitmap] into a new [BitmapCommand], -/// leaving other fields as their default values. -/// -/// Rust equivalent: `BitmapCommand::from(bitmap)` -#[no_mangle] -pub unsafe extern "C" fn sp_cmd_bitmap_from_bitmap( - bitmap: NonNull, -) -> NonNull { - heap_move_nonnull(unsafe { heap_remove(bitmap) }.into()) -} + /// Sets a window of pixels to the specified values. + /// + /// The passed [Bitmap] gets consumed. + /// + /// Returns: a new [BitmapCommand] instance. + fn new( + bitmap: NonNull, + origin_x: usize, + origin_y: usize, + compression: CompressionCode, + ) -> NonNull { + heap_move_nonnull(BitmapCommand { + bitmap: unsafe { heap_remove(bitmap) }, + origin: Origin::new(origin_x, origin_y), + compression, + }) + } -/// Tries to turn a [BitmapCommand] into a [Packet]. -/// -/// Returns: NULL or a [Packet] containing the command. -#[no_mangle] -pub unsafe extern "C" fn sp_cmd_bitmap_try_into_packet( - command: NonNull, -) -> *mut Packet { - heap_move_ok(unsafe { heap_remove(command) }.try_into()) -} + /// Move the provided [Bitmap] into a new [BitmapCommand], + /// leaving other fields as their default values. + /// + /// Rust equivalent: `BitmapCommand::from(bitmap)` + fn from_bitmap( + bitmap: NonNull, + ) -> NonNull { + heap_move_nonnull(unsafe { heap_remove(bitmap) }.into()) + } + + /// Tries to turn a [BitmapCommand] into a [Packet]. + /// + /// Returns: NULL or a [Packet] containing the command. + fn try_into_packet( + command: NonNull, + ) -> *mut Packet { + heap_move_ok(unsafe { heap_remove(command) }.try_into()) + } + +); wrap_clone!(sp_cmd_bitmap::BitmapCommand); wrap_free!(sp_cmd_bitmap::BitmapCommand); diff --git a/src/commands/bitvec_command.rs b/src/commands/bitvec_command.rs index 7ccbf31..7dfed38 100644 --- a/src/commands/bitvec_command.rs +++ b/src/commands/bitvec_command.rs @@ -1,5 +1,5 @@ use crate::{ - macros::{wrap_clone, wrap_fields, wrap_free}, + macros::{wrap_clone, wrap_fields, wrap_free, wrap_functions}, mem::{heap_move_nonnull, heap_move_ok, heap_remove}, }; use servicepoint::{ @@ -8,42 +8,44 @@ use servicepoint::{ }; use std::ptr::NonNull; -/// Set pixel data starting at the pixel offset on screen. -/// -/// The screen will continuously overwrite more pixel data without regarding the offset, meaning -/// once the starting row is full, overwriting will continue on column 0. -/// -/// The [`BinaryOperation`] will be applied on the display comparing old and sent bit. -/// -/// `new_bit = old_bit op sent_bit` -/// -/// For example, [`BinaryOperation::Or`] can be used to turn on some pixels without affecting other pixels. -/// -/// The contained [`DisplayBitVec`] is always uncompressed. -#[no_mangle] -pub unsafe extern "C" fn sp_cmd_bitvec_new( - bitvec: NonNull, - offset: usize, - operation: BinaryOperation, - compression: CompressionCode, -) -> NonNull { - heap_move_nonnull(BitVecCommand { - bitvec: unsafe { heap_remove(bitvec) }, - offset, - operation, - compression, - }) -} +wrap_functions!(sp_cmd_bitvec; -/// Tries to turn a [BitVecCommand] into a [Packet]. -/// -/// Returns: NULL or a [Packet] containing the command. -#[no_mangle] -pub unsafe extern "C" fn sp_cmd_bitvec_try_into_packet( - command: NonNull, -) -> *mut Packet { - heap_move_ok(unsafe { heap_remove(command) }.try_into()) -} + /// Set pixel data starting at the pixel offset on screen. + /// + /// The screen will continuously overwrite more pixel data without regarding the offset, meaning + /// once the starting row is full, overwriting will continue on column 0. + /// + /// The [`BinaryOperation`] will be applied on the display comparing old and sent bit. + /// + /// `new_bit = old_bit op sent_bit` + /// + /// For example, [`BinaryOperation::Or`] can be used to turn on some pixels without affecting other pixels. + /// + /// The contained [`DisplayBitVec`] is always uncompressed. + fn new( + bitvec: NonNull, + offset: usize, + operation: BinaryOperation, + compression: CompressionCode, + ) -> NonNull { + heap_move_nonnull(BitVecCommand { + bitvec: unsafe { heap_remove(bitvec) }, + offset, + operation, + compression, + }) + } + + /// Tries to turn a [BitVecCommand] into a [Packet]. + /// + /// Returns: NULL or a [Packet] containing the command. + fn try_into_packet( + command: NonNull, + ) -> *mut Packet { + heap_move_ok(unsafe { heap_remove(command) }.try_into()) + } + +); wrap_clone!(sp_cmd_bitvec::BitVecCommand); wrap_free!(sp_cmd_bitvec::BitVecCommand); diff --git a/src/commands/brightness_grid_command.rs b/src/commands/brightness_grid_command.rs index 9c5069e..b4e6e23 100644 --- a/src/commands/brightness_grid_command.rs +++ b/src/commands/brightness_grid_command.rs @@ -1,45 +1,46 @@ use crate::{ - macros::{wrap_clone, wrap_free}, + macros::{wrap_clone, wrap_free, wrap_functions}, mem::{heap_move_nonnull, heap_move_ok, heap_remove}, }; use servicepoint::{BrightnessGrid, BrightnessGridCommand, Origin, Packet}; use std::ptr::NonNull; -/// Set the brightness of individual tiles in a rectangular area of the display. -/// -/// The passed [BrightnessGrid] gets consumed. -/// -/// Returns: a new [BrightnessGridCommand] instance. -#[no_mangle] -pub unsafe extern "C" fn sp_cmd_brightness_grid_new( - grid: NonNull, - origin_x: usize, - origin_y: usize, -) -> NonNull { - heap_move_nonnull(BrightnessGridCommand { - grid: unsafe { heap_remove(grid) }, - origin: Origin::new(origin_x, origin_y), - }) -} +wrap_functions!(sp_cmd_brightness_grid; -/// Moves the provided [BrightnessGrid] into a new [BrightnessGridCommand], -/// leaving other fields as their default values. -#[no_mangle] -pub unsafe extern "C" fn sp_cmd_brightness_grid_from_grid( - grid: NonNull, -) -> NonNull { - heap_move_nonnull(unsafe { heap_remove(grid) }.into()) -} + /// Set the brightness of individual tiles in a rectangular area of the display. + /// + /// The passed [BrightnessGrid] gets consumed. + /// + /// Returns: a new [BrightnessGridCommand] instance. + fn new( + grid: NonNull, + origin_x: usize, + origin_y: usize, + ) -> NonNull { + heap_move_nonnull(BrightnessGridCommand { + grid: unsafe { heap_remove(grid) }, + origin: Origin::new(origin_x, origin_y), + }) + } -/// Tries to turn a [BrightnessGridCommand] into a [Packet]. -/// -/// Returns: NULL or a [Packet] containing the command. -#[no_mangle] -pub unsafe extern "C" fn sp_cmd_brightness_grid_into_packet( - command: NonNull, -) -> *mut Packet { - heap_move_ok(unsafe { heap_remove(command) }.try_into()) -} + /// Moves the provided [BrightnessGrid] into a new [BrightnessGridCommand], + /// leaving other fields as their default values. + fn from_grid( + grid: NonNull, + ) -> NonNull { + heap_move_nonnull(unsafe { heap_remove(grid) }.into()) + } + + /// Tries to turn a [BrightnessGridCommand] into a [Packet]. + /// + /// Returns: NULL or a [Packet] containing the command. + fn into_packet( + command: NonNull, + ) -> *mut Packet { + heap_move_ok(unsafe { heap_remove(command) }.try_into()) + } + +); wrap_clone!(sp_cmd_brightness_grid::BrightnessGridCommand); wrap_free!(sp_cmd_brightness_grid::BrightnessGridCommand); diff --git a/src/commands/cc_only_commands.rs b/src/commands/cc_only_commands.rs index fc73303..234b781 100644 --- a/src/commands/cc_only_commands.rs +++ b/src/commands/cc_only_commands.rs @@ -1,37 +1,43 @@ -use crate::{macros::wrap_free, mem::heap_move_nonnull}; +use crate::{ + macros::{wrap_free, wrap_functions}, + mem::heap_move_nonnull, +}; use servicepoint::{ClearCommand, FadeOutCommand, HardResetCommand}; use std::ptr::NonNull; -/// Set all pixels to the off state. -/// -/// Does not affect brightness. -/// -/// Returns: a new [ClearCommand] instance. -#[no_mangle] -pub unsafe extern "C" fn sp_cmd_clear_new() -> NonNull { - heap_move_nonnull(ClearCommand) -} +wrap_functions!(sp_cmd_clear; + /// Set all pixels to the off state. + /// + /// Does not affect brightness. + /// + /// Returns: a new [ClearCommand] instance. + fn new() -> NonNull { + heap_move_nonnull(ClearCommand) + } +); wrap_free!(sp_cmd_clear::ClearCommand); -/// Kills the udp daemon on the display, which usually results in a restart. -/// -/// Please do not send this in your normal program flow. -/// -/// Returns: a new [HardResetCommand] instance. -#[no_mangle] -pub unsafe extern "C" fn sp_cmd_hard_reset_new() -> NonNull { - heap_move_nonnull(HardResetCommand) -} +wrap_functions!(sp_cmd_hard_reset; + /// Kills the udp daemon on the display, which usually results in a restart. + /// + /// Please do not send this in your normal program flow. + /// + /// Returns: a new [HardResetCommand] instance. + fn new() -> NonNull { + heap_move_nonnull(HardResetCommand) + } +); wrap_free!(sp_cmd_hard_reset::HardResetCommand); -/// A yet-to-be-tested command. -/// -/// Returns: a new [FadeOutCommand] instance. -#[no_mangle] -pub unsafe extern "C" fn sp_cmd_fade_out_new() -> NonNull { - heap_move_nonnull(FadeOutCommand) -} +wrap_functions!(sp_cmd_fade_out; + /// A yet-to-be-tested command. + /// + /// Returns: a new [FadeOutCommand] instance. + fn new() -> NonNull { + heap_move_nonnull(FadeOutCommand) + } +); wrap_free!(sp_cmd_fade_out::FadeOutCommand); diff --git a/src/commands/char_grid_command.rs b/src/commands/char_grid_command.rs index b895718..0ef90c0 100644 --- a/src/commands/char_grid_command.rs +++ b/src/commands/char_grid_command.rs @@ -1,45 +1,46 @@ use crate::{ - macros::{wrap_clone, wrap_free}, + macros::{wrap_clone, wrap_free, wrap_functions}, mem::{heap_move_nonnull, heap_move_ok, heap_remove}, }; use servicepoint::{CharGrid, CharGridCommand, Origin, Packet}; use std::ptr::NonNull; -/// Show UTF-8 encoded text on the screen. -/// -/// The passed [CharGrid] gets consumed. -/// -/// Returns: a new [CharGridCommand] instance. -#[no_mangle] -pub unsafe extern "C" fn sp_cmd_char_grid_new( - grid: NonNull, - origin_x: usize, - origin_y: usize, -) -> NonNull { - heap_move_nonnull(CharGridCommand { - grid: unsafe { heap_remove(grid) }, - origin: Origin::new(origin_x, origin_y), - }) -} +wrap_functions!(sp_cmd_char_grid; -/// Moves the provided [CharGrid] into a new [CharGridCommand], -/// leaving other fields as their default values. -#[no_mangle] -pub unsafe extern "C" fn sp_cmd_char_grid_from_grid( - grid: NonNull, -) -> NonNull { - heap_move_nonnull(unsafe { heap_remove(grid) }.into()) -} + /// Show UTF-8 encoded text on the screen. + /// + /// The passed [CharGrid] gets consumed. + /// + /// Returns: a new [CharGridCommand] instance. + fn new( + grid: NonNull, + origin_x: usize, + origin_y: usize, + ) -> NonNull { + heap_move_nonnull(CharGridCommand { + grid: unsafe { heap_remove(grid) }, + origin: Origin::new(origin_x, origin_y), + }) + } -/// Tries to turn a [CharGridCommand] into a [Packet]. -/// -/// Returns: NULL or a [Packet] containing the command. -#[no_mangle] -pub unsafe extern "C" fn sp_cmd_char_grid_try_into_packet( - command: NonNull, -) -> *mut Packet { - heap_move_ok(unsafe { heap_remove(command) }.try_into()) -} + /// Moves the provided [CharGrid] into a new [CharGridCommand], + /// leaving other fields as their default values. + fn from_grid( + grid: NonNull, + ) -> NonNull { + heap_move_nonnull(unsafe { heap_remove(grid) }.into()) + } + + /// Tries to turn a [CharGridCommand] into a [Packet]. + /// + /// Returns: NULL or a [Packet] containing the command. + fn try_into_packet( + command: NonNull, + ) -> *mut Packet { + heap_move_ok(unsafe { heap_remove(command) }.try_into()) + } + +); wrap_clone!(sp_cmd_char_grid::CharGridCommand); wrap_free!(sp_cmd_char_grid::CharGridCommand); @@ -59,8 +60,8 @@ pub unsafe extern "C" fn sp_cmd_char_grid_set( #[no_mangle] pub unsafe extern "C" fn sp_cmd_char_grid_get( mut command: NonNull, -) -> *mut CharGrid { - unsafe { &mut command.as_mut().grid } +) -> NonNull { + unsafe { NonNull::from(&mut command.as_mut().grid) } } /// Reads the origin field of the [CharGridCommand]. diff --git a/src/commands/cp437_grid_command.rs b/src/commands/cp437_grid_command.rs index 3f1fa9f..da8380a 100644 --- a/src/commands/cp437_grid_command.rs +++ b/src/commands/cp437_grid_command.rs @@ -1,45 +1,46 @@ use crate::{ - macros::{wrap_clone, wrap_free}, + macros::{wrap_clone, wrap_free, wrap_functions}, mem::{heap_move_nonnull, heap_move_ok, heap_remove}, }; use servicepoint::{Cp437Grid, Cp437GridCommand, Origin, Packet}; use std::ptr::NonNull; -/// Show text on the screen. -/// -/// The text is sent in the form of a 2D grid of [CP-437] encoded characters. -/// -/// The origin is relative to the top-left of the display. -#[no_mangle] -pub unsafe extern "C" fn sp_cmd_cp437_grid_new( - grid: NonNull, - origin_x: usize, - origin_y: usize, -) -> NonNull { - heap_move_nonnull(Cp437GridCommand { - grid: unsafe { heap_remove(grid) }, - origin: Origin::new(origin_x, origin_y), - }) -} +wrap_functions!(sp_cmd_cp437_grid; -/// Moves the provided [Cp437Grid] into a new [Cp437GridCommand], -/// leaving other fields as their default values. -#[no_mangle] -pub unsafe extern "C" fn sp_cmd_cp437_grid_from_grid( - grid: NonNull, -) -> NonNull { - heap_move_nonnull(unsafe { heap_remove(grid) }.into()) -} + /// Show text on the screen. + /// + /// The text is sent in the form of a 2D grid of [CP-437] encoded characters. + /// + /// The origin is relative to the top-left of the display. + fn new( + grid: NonNull, + origin_x: usize, + origin_y: usize, + ) -> NonNull { + heap_move_nonnull(Cp437GridCommand { + grid: unsafe { heap_remove(grid) }, + origin: Origin::new(origin_x, origin_y), + }) + } -/// Tries to turn a [Cp437GridCommand] into a [Packet]. -/// -/// Returns: NULL or a [Packet] containing the command. -#[no_mangle] -pub unsafe extern "C" fn sp_cmd_cp437_grid_try_into_packet( - command: NonNull, -) -> *mut Packet { - heap_move_ok(unsafe { heap_remove(command) }.try_into()) -} + /// Moves the provided [Cp437Grid] into a new [Cp437GridCommand], + /// leaving other fields as their default values. + fn from_grid( + grid: NonNull, + ) -> NonNull { + heap_move_nonnull(unsafe { heap_remove(grid) }.into()) + } + + /// Tries to turn a [Cp437GridCommand] into a [Packet]. + /// + /// Returns: NULL or a [Packet] containing the command. + fn try_into_packet( + command: NonNull, + ) -> *mut Packet { + heap_move_ok(unsafe { heap_remove(command) }.try_into()) + } + +); wrap_clone!(sp_cmd_cp437_grid::Cp437GridCommand); wrap_free!(sp_cmd_cp437_grid::Cp437GridCommand); diff --git a/src/commands/global_brightness_command.rs b/src/commands/global_brightness_command.rs index e695ef0..35bcbe0 100644 --- a/src/commands/global_brightness_command.rs +++ b/src/commands/global_brightness_command.rs @@ -1,26 +1,25 @@ use crate::{ - macros::{wrap_clone, wrap_fields, wrap_free}, + macros::{wrap_clone, wrap_fields, wrap_free, wrap_functions}, mem::{heap_move_nonnull, heap_remove}, }; use servicepoint::{Brightness, GlobalBrightnessCommand, Packet}; use std::ptr::NonNull; -/// Set the brightness of all tiles to the same value. -/// -/// Returns: a new [GlobalBrightnessCommand] instance. -#[no_mangle] -pub unsafe extern "C" fn sp_cmd_brightness_global_new( - brightness: Brightness, -) -> NonNull { - heap_move_nonnull(GlobalBrightnessCommand::from(brightness)) -} +wrap_functions!(sp_cmd_brightness_global; -#[no_mangle] -pub unsafe extern "C" fn sp_cmd_brightness_global_into_packet( - command: NonNull, -) -> NonNull { - heap_move_nonnull(unsafe { heap_remove(command) }.into()) -} + /// Set the brightness of all tiles to the same value. + /// + /// Returns: a new [GlobalBrightnessCommand] instance. + fn new(brightness: Brightness) -> NonNull { + heap_move_nonnull(GlobalBrightnessCommand::from(brightness)) + } + + /// Turns the command into a packet + fn into_packet(command: NonNull) -> NonNull { + heap_move_nonnull(unsafe { heap_remove(command) }.into()) + } + +); wrap_clone!(sp_cmd_brightness_global::GlobalBrightnessCommand); wrap_free!(sp_cmd_brightness_global::GlobalBrightnessCommand); diff --git a/src/containers/bitmap.rs b/src/containers/bitmap.rs index ae0d2ae..6d502d9 100644 --- a/src/containers/bitmap.rs +++ b/src/containers/bitmap.rs @@ -1,6 +1,6 @@ use crate::{ containers::ByteSlice, - macros::{wrap_clone, wrap_free, wrap_methods}, + macros::{wrap_clone, wrap_free, wrap_functions, wrap_methods}, mem::{heap_move_nonnull, heap_move_ok, heap_move_some, heap_remove}, }; use servicepoint::{ @@ -9,80 +9,102 @@ use servicepoint::{ }; use std::ptr::NonNull; -/// Creates a new [Bitmap] with the specified dimensions. -/// -/// # Arguments -/// -/// - `width`: size in pixels in x-direction -/// - `height`: size in pixels in y-direction -/// -/// returns: [Bitmap] initialized to all pixels off, or NULL in case of an error. -/// -/// # Errors -/// -/// In the following cases, this function will return NULL: -/// -/// - when the width is not dividable by 8 -/// -/// # Examples -/// -/// ```C -/// Cp437Grid grid = sp_bitmap_new(8, 3); -/// sp_bitmap_fill(grid, true); -/// sp_bitmap_set(grid, 0, 0, false); -/// sp_bitmap_free(grid); -/// ``` -#[no_mangle] -pub unsafe extern "C" fn sp_bitmap_new( - width: usize, - height: usize, -) -> *mut Bitmap { - heap_move_some(Bitmap::new(width, height)) -} - -/// Creates a new [Bitmap] with a size matching the screen. -/// -/// returns: [Bitmap] initialized to all pixels off. -#[no_mangle] -pub unsafe extern "C" fn sp_bitmap_new_max_sized() -> NonNull { - heap_move_nonnull(Bitmap::max_sized()) -} - -/// Loads a [Bitmap] with the specified dimensions from the provided data. -/// -/// # Arguments -/// -/// - `width`: size in pixels in x-direction -/// - `height`: size in pixels in y-direction -/// -/// returns: [Bitmap] that contains a copy of the provided data, or NULL in case of an error. -#[no_mangle] -pub unsafe extern "C" fn sp_bitmap_load( - width: usize, - height: usize, - data: ByteSlice, -) -> *mut Bitmap { - let data = unsafe { data.as_slice() }; - heap_move_ok(Bitmap::load(width, height, data)) -} - -/// Tries to convert the BitVec to a Bitmap. -/// -/// The provided BitVec gets consumed. -/// -/// Returns NULL in case of error. -#[no_mangle] -pub unsafe extern "C" fn sp_bitmap_from_bitvec( - width: usize, - bitvec: NonNull, -) -> *mut Bitmap { - let bitvec = unsafe { heap_remove(bitvec) }; - heap_move_ok(Bitmap::from_bitvec(width, bitvec)) -} - wrap_clone!(sp_bitmap::Bitmap); wrap_free!(sp_bitmap::Bitmap); +wrap_functions!(sp_bitmap; + + /// Creates a new [Bitmap] with the specified dimensions. + /// + /// # Arguments + /// + /// - `width`: size in pixels in x-direction + /// - `height`: size in pixels in y-direction + /// + /// returns: [Bitmap] initialized to all pixels off, or NULL in case of an error. + /// + /// # Errors + /// + /// In the following cases, this function will return NULL: + /// + /// - when the width is not dividable by 8 + /// + /// # Examples + /// + /// ```C + /// Cp437Grid grid = sp_bitmap_new(8, 3); + /// sp_bitmap_fill(grid, true); + /// sp_bitmap_set(grid, 0, 0, false); + /// sp_bitmap_free(grid); + /// ``` + fn new(width: usize, height: usize) -> *mut Bitmap { + heap_move_some(Bitmap::new(width, height)) + } + + /// Creates a new [Bitmap] with a size matching the screen. + /// + /// returns: [Bitmap] initialized to all pixels off. + fn new_max_sized() -> NonNull { + heap_move_nonnull(Bitmap::max_sized()) + } + + /// Loads a [Bitmap] with the specified dimensions from the provided data. + /// + /// # Arguments + /// + /// - `width`: size in pixels in x-direction + /// - `height`: size in pixels in y-direction + /// + /// returns: [Bitmap] that contains a copy of the provided data, or NULL in case of an error. + fn load( + width: usize, + height: usize, + data: ByteSlice, + ) -> *mut Bitmap { + let data = unsafe { data.as_slice() }; + heap_move_ok(Bitmap::load(width, height, data)) + } + + /// Tries to convert the BitVec to a Bitmap. + /// + /// The provided BitVec gets consumed. + /// + /// Returns NULL in case of error. + fn from_bitvec( + width: usize, + bitvec: NonNull, + ) -> *mut Bitmap { + let bitvec = unsafe { heap_remove(bitvec) }; + heap_move_ok(Bitmap::from_bitvec(width, bitvec)) + } + /// Consumes the Bitmap and returns the contained BitVec. + fn into_bitvec( + bitmap: NonNull + ) -> NonNull { + let bitmap = unsafe { heap_remove(bitmap) }; + heap_move_nonnull(bitmap.into()) + } + + /// Creates a [BitmapCommand] and immediately turns that into a [Packet]. + /// + /// The provided [Bitmap] gets consumed. + /// + /// Returns NULL in case of an error. + fn into_packet( + bitmap: NonNull, + x: usize, + y: usize, + compression: CompressionCode, + ) -> *mut Packet { + let bitmap = unsafe { heap_remove(bitmap) }; + heap_move_ok(Packet::try_from(BitmapCommand { + bitmap, + origin: Origin::new(x, y), + compression, + })) + } +); + wrap_methods!( sp_bitmap::Bitmap; @@ -130,32 +152,3 @@ wrap_methods!( return(slice) { unsafe { ByteSlice::from_slice(slice) } }; }; ); - -/// Consumes the Bitmap and returns the contained BitVec. -#[no_mangle] -pub unsafe extern "C" fn sp_bitmap_into_bitvec( - bitmap: NonNull, -) -> NonNull { - let bitmap = unsafe { heap_remove(bitmap) }; - heap_move_nonnull(bitmap.into()) -} - -/// Creates a [BitmapCommand] and immediately turns that into a [Packet]. -/// -/// The provided [Bitmap] gets consumed. -/// -/// Returns NULL in case of an error. -#[no_mangle] -pub unsafe extern "C" fn sp_bitmap_into_packet( - bitmap: NonNull, - x: usize, - y: usize, - compression: CompressionCode, -) -> *mut Packet { - let bitmap = unsafe { heap_remove(bitmap) }; - heap_move_ok(Packet::try_from(BitmapCommand { - bitmap, - origin: Origin::new(x, y), - compression, - })) -} diff --git a/src/containers/bitvec.rs b/src/containers/bitvec.rs index 76d716a..e232ab5 100644 --- a/src/containers/bitvec.rs +++ b/src/containers/bitvec.rs @@ -1,6 +1,6 @@ use crate::{ containers::ByteSlice, - macros::{wrap_clone, wrap_free, wrap_methods}, + macros::{wrap_clone, wrap_free, wrap_functions, wrap_methods}, mem::{heap_move_nonnull, heap_move_ok, heap_remove}, }; use servicepoint::{ @@ -8,32 +8,52 @@ use servicepoint::{ }; use std::ptr::NonNull; -/// Creates a new [DisplayBitVec] instance. -/// -/// # Arguments -/// -/// - `size`: size in bits. -/// -/// returns: [DisplayBitVec] with all bits set to false. -/// -/// # Panics -/// -/// - when `size` is not divisible by 8. -#[no_mangle] -pub unsafe extern "C" fn sp_bitvec_new(size: usize) -> NonNull { - heap_move_nonnull(DisplayBitVec::repeat(false, size)) -} +wrap_functions!(sp_bitvec; -/// Interpret the data as a series of bits and load then into a new [DisplayBitVec] instance. -/// -/// returns: [DisplayBitVec] instance containing data. -#[no_mangle] -pub unsafe extern "C" fn sp_bitvec_load( - data: ByteSlice, -) -> NonNull { - let data = unsafe { data.as_slice() }; - heap_move_nonnull(DisplayBitVec::from_slice(data)) -} + /// Creates a new [DisplayBitVec] instance. + /// + /// # Arguments + /// + /// - `size`: size in bits. + /// + /// returns: [DisplayBitVec] with all bits set to false. + /// + /// # Panics + /// + /// - when `size` is not divisible by 8. + fn new(size: usize) -> NonNull { + heap_move_nonnull(DisplayBitVec::repeat(false, size)) + } + + /// Interpret the data as a series of bits and load then into a new [DisplayBitVec] instance. + /// + /// returns: [DisplayBitVec] instance containing data. + fn load(data: ByteSlice) -> NonNull { + let data = unsafe { data.as_slice() }; + heap_move_nonnull(DisplayBitVec::from_slice(data)) + } + + /// Creates a [BitVecCommand] and immediately turns that into a [Packet]. + /// + /// The provided [DisplayBitVec] gets consumed. + /// + /// Returns NULL in case of an error. + fn into_packet( + bitvec: NonNull, + offset: usize, + operation: BinaryOperation, + compression: CompressionCode, + ) -> *mut Packet { + let bitvec = unsafe { heap_remove(bitvec) }; + heap_move_ok(Packet::try_from(BitVecCommand { + bitvec, + offset, + operation, + compression, + })) + } + +); wrap_clone!(sp_bitvec::DisplayBitVec); wrap_free!(sp_bitvec::DisplayBitVec); @@ -90,24 +110,3 @@ wrap_methods!( return(slice) { unsafe { ByteSlice::from_slice(slice) } }; }; ); - -/// Creates a [BitVecCommand] and immediately turns that into a [Packet]. -/// -/// The provided [DisplayBitVec] gets consumed. -/// -/// Returns NULL in case of an error. -#[no_mangle] -pub unsafe extern "C" fn sp_bitvec_into_packet( - bitvec: NonNull, - offset: usize, - operation: BinaryOperation, - compression: CompressionCode, -) -> *mut Packet { - let bitvec = unsafe { heap_remove(bitvec) }; - heap_move_ok(Packet::try_from(BitVecCommand { - bitvec, - offset, - operation, - compression, - })) -} diff --git a/src/containers/brightness_grid.rs b/src/containers/brightness_grid.rs index a3590b8..2374b47 100644 --- a/src/containers/brightness_grid.rs +++ b/src/containers/brightness_grid.rs @@ -1,3 +1,4 @@ +use crate::macros::wrap_functions; use crate::{ containers::ByteSlice, macros::{wrap_clone, wrap_free, wrap_methods}, @@ -9,48 +10,67 @@ use servicepoint::{ }; use std::{mem::transmute, ptr::NonNull}; -/// Creates a new [BrightnessGrid] with the specified dimensions. -/// -/// returns: [BrightnessGrid] initialized to 0. -/// -/// # Examples -/// ```C -/// UdpSocket *connection = sp_udp_open("127.0.0.1:2342"); -/// if (connection == NULL) -/// return 1; -/// -/// BrightnessGrid *grid = sp_brightness_grid_new(2, 2); -/// sp_brightness_grid_set(grid, 0, 0, 0); -/// sp_brightness_grid_set(grid, 1, 1, 10); -/// -/// TypedCommand *command = sp_command_char_brightness(grid); -/// sp_udp_free(connection); -/// ``` -#[no_mangle] -pub unsafe extern "C" fn sp_brightness_grid_new( - width: usize, - height: usize, -) -> NonNull { - heap_move_nonnull(BrightnessGrid::new(width, height)) -} +wrap_functions!(sp_brightness_grid; -/// Loads a [BrightnessGrid] with the specified dimensions from the provided data. -/// -/// Any out of range values will be set to [Brightness::MAX] or [Brightness::MIN]. -/// -/// returns: new [BrightnessGrid] instance, or NULL in case of an error. -#[no_mangle] -pub unsafe extern "C" fn sp_brightness_grid_load( - width: usize, - height: usize, - data: ByteSlice, -) -> *mut BrightnessGrid { - let data = unsafe { data.as_slice() }; - heap_move_some( - ByteGrid::load(width, height, data) - .map(move |grid| grid.map(Brightness::saturating_from)), - ) -} + /// Creates a new [BrightnessGrid] with the specified dimensions. + /// + /// returns: [BrightnessGrid] initialized to 0. + /// + /// # Examples + /// ```C + /// UdpSocket *connection = sp_udp_open("127.0.0.1:2342"); + /// if (connection == NULL) + /// return 1; + /// + /// BrightnessGrid *grid = sp_brightness_grid_new(2, 2); + /// sp_brightness_grid_set(grid, 0, 0, 0); + /// sp_brightness_grid_set(grid, 1, 1, 10); + /// + /// TypedCommand *command = sp_command_char_brightness(grid); + /// sp_udp_free(connection); + /// ``` + fn new( + width: usize, + height: usize, + ) -> NonNull { + heap_move_nonnull(BrightnessGrid::new(width, height)) + } + + /// Loads a [BrightnessGrid] with the specified dimensions from the provided data. + /// + /// Any out of range values will be set to [Brightness::MAX] or [Brightness::MIN]. + /// + /// returns: new [BrightnessGrid] instance, or NULL in case of an error. + fn load( + width: usize, + height: usize, + data: ByteSlice, + ) -> *mut BrightnessGrid { + let data = unsafe { data.as_slice() }; + heap_move_some( + ByteGrid::load(width, height, data) + .map(move |grid| grid.map(Brightness::saturating_from)), + ) + } + + /// Creates a [BrightnessGridCommand] and immediately turns that into a [Packet]. + /// + /// The provided [BrightnessGrid] gets consumed. + /// + /// Returns NULL in case of an error. + fn into_packet( + grid: NonNull, + x: usize, + y: usize, + ) -> *mut Packet { + let grid = unsafe { heap_remove(grid) }; + heap_move_ok(Packet::try_from(BrightnessGridCommand { + grid, + origin: Origin::new(x, y), + })) + } + +); wrap_clone!(sp_brightness_grid::BrightnessGrid); wrap_free!(sp_brightness_grid::BrightnessGrid); @@ -109,21 +129,3 @@ wrap_methods!( }}; }; ); - -/// Creates a [BrightnessGridCommand] and immediately turns that into a [Packet]. -/// -/// The provided [BrightnessGrid] gets consumed. -/// -/// Returns NULL in case of an error. -#[no_mangle] -pub unsafe extern "C" fn sp_brightness_grid_into_packet( - grid: NonNull, - x: usize, - y: usize, -) -> *mut Packet { - let grid = unsafe { heap_remove(grid) }; - heap_move_ok(Packet::try_from(BrightnessGridCommand { - grid, - origin: Origin::new(x, y), - })) -} diff --git a/src/containers/char_grid.rs b/src/containers/char_grid.rs index 1b70202..782e2aa 100644 --- a/src/containers/char_grid.rs +++ b/src/containers/char_grid.rs @@ -1,43 +1,62 @@ use crate::{ containers::ByteSlice, - macros::{wrap_clone, wrap_free, wrap_methods}, + macros::{wrap_clone, wrap_free, wrap_functions, wrap_methods}, mem::{heap_move_nonnull, heap_move_ok, heap_remove}, }; use servicepoint::{CharGrid, CharGridCommand, Grid, Origin, Packet}; use std::ptr::NonNull; -/// Creates a new [CharGrid] with the specified dimensions. -/// -/// returns: [CharGrid] initialized to 0. -/// -/// # Examples -/// -/// ```C -/// CharGrid grid = sp_char_grid_new(4, 3); -/// sp_char_grid_fill(grid, '?'); -/// sp_char_grid_set(grid, 0, 0, '!'); -/// sp_char_grid_free(grid); -/// ``` -#[no_mangle] -pub unsafe extern "C" fn sp_char_grid_new( - width: usize, - height: usize, -) -> NonNull { - heap_move_nonnull(CharGrid::new(width, height)) -} +wrap_functions!(sp_char_grid; -/// Loads a [CharGrid] with the specified dimensions from the provided data. -/// -/// returns: new CharGrid or NULL in case of an error -#[no_mangle] -pub unsafe extern "C" fn sp_char_grid_load( - width: usize, - height: usize, - data: ByteSlice, -) -> *mut CharGrid { - let data = unsafe { data.as_slice() }; - heap_move_ok(CharGrid::load_utf8(width, height, data.to_vec())) -} + /// Creates a new [CharGrid] with the specified dimensions. + /// + /// returns: [CharGrid] initialized to 0. + /// + /// # Examples + /// + /// ```C + /// CharGrid grid = sp_char_grid_new(4, 3); + /// sp_char_grid_fill(grid, '?'); + /// sp_char_grid_set(grid, 0, 0, '!'); + /// sp_char_grid_free(grid); + /// ``` + fn new( + width: usize, + height: usize, + ) -> NonNull { + heap_move_nonnull(CharGrid::new(width, height)) + } + + /// Loads a [CharGrid] with the specified dimensions from the provided data. + /// + /// returns: new CharGrid or NULL in case of an error + fn load( + width: usize, + height: usize, + data: ByteSlice, + ) -> *mut CharGrid { + let data = unsafe { data.as_slice() }; + heap_move_ok(CharGrid::load_utf8(width, height, data.to_vec())) + } + + /// Creates a [CharGridCommand] and immediately turns that into a [Packet]. + /// + /// The provided [CharGrid] gets consumed. + /// + /// Returns NULL in case of an error. + fn into_packet( + grid: NonNull, + x: usize, + y: usize, + ) -> *mut Packet { + let grid = unsafe { heap_remove(grid) }; + heap_move_ok(Packet::try_from(CharGridCommand { + grid, + origin: Origin::new(x, y), + })) + } + +); wrap_clone!(sp_char_grid::CharGrid); wrap_free!(sp_char_grid::CharGrid); @@ -91,21 +110,3 @@ wrap_methods!( /// Gets the height of the grid. ref fn height() -> usize; ); - -/// Creates a [CharGridCommand] and immediately turns that into a [Packet]. -/// -/// The provided [CharGrid] gets consumed. -/// -/// Returns NULL in case of an error. -#[no_mangle] -pub unsafe extern "C" fn sp_char_grid_into_packet( - grid: NonNull, - x: usize, - y: usize, -) -> *mut Packet { - let grid = unsafe { heap_remove(grid) }; - heap_move_ok(Packet::try_from(CharGridCommand { - grid, - origin: Origin::new(x, y), - })) -} diff --git a/src/containers/cp437_grid.rs b/src/containers/cp437_grid.rs index d6ae17f..2ed9aba 100644 --- a/src/containers/cp437_grid.rs +++ b/src/containers/cp437_grid.rs @@ -1,3 +1,4 @@ +use crate::macros::wrap_functions; use crate::{ containers::ByteSlice, macros::{wrap_clone, wrap_free, wrap_methods}, @@ -8,27 +9,46 @@ use servicepoint::{ }; use std::ptr::NonNull; -/// Creates a new [Cp437Grid] with the specified dimensions. -/// -/// returns: [Cp437Grid] initialized to 0. -#[no_mangle] -pub unsafe extern "C" fn sp_cp437_grid_new( - width: usize, - height: usize, -) -> NonNull { - heap_move_nonnull(Cp437Grid::new(width, height)) -} +wrap_functions!(sp_cp437_grid; -/// Loads a [Cp437Grid] with the specified dimensions from the provided data. -#[no_mangle] -pub unsafe extern "C" fn sp_cp437_grid_load( - width: usize, - height: usize, - data: ByteSlice, -) -> *mut Cp437Grid { - let data = unsafe { data.as_slice() }; - heap_move_some(Cp437Grid::load(width, height, data)) -} + /// Creates a new [Cp437Grid] with the specified dimensions. + /// + /// returns: [Cp437Grid] initialized to 0. + fn new( + width: usize, + height: usize, + ) -> NonNull { + heap_move_nonnull(Cp437Grid::new(width, height)) + } + + /// Loads a [Cp437Grid] with the specified dimensions from the provided data. + fn load( + width: usize, + height: usize, + data: ByteSlice, + ) -> *mut Cp437Grid { + let data = unsafe { data.as_slice() }; + heap_move_some(Cp437Grid::load(width, height, data)) + } + + /// Creates a [Cp437GridCommand] and immediately turns that into a [Packet]. + /// + /// The provided [Cp437Grid] gets consumed. + /// + /// Returns NULL in case of an error. + fn into_packet( + grid: NonNull, + x: usize, + y: usize, + ) -> *mut Packet { + let grid = unsafe { heap_remove(grid) }; + heap_move_ok(Packet::try_from(Cp437GridCommand { + grid, + origin: Origin::new(x, y), + })) + } + +); wrap_clone!(sp_cp437_grid::Cp437Grid); wrap_free!(sp_cp437_grid::Cp437Grid); @@ -81,21 +101,3 @@ wrap_methods!( return(slice) { unsafe { ByteSlice::from_slice(slice) } }; }; ); - -/// Creates a [Cp437GridCommand] and immediately turns that into a [Packet]. -/// -/// The provided [Cp437Grid] gets consumed. -/// -/// Returns NULL in case of an error. -#[no_mangle] -pub unsafe extern "C" fn sp_cp437_grid_into_packet( - grid: NonNull, - x: usize, - y: usize, -) -> *mut Packet { - let grid = unsafe { heap_remove(grid) }; - heap_move_ok(Packet::try_from(Cp437GridCommand { - grid, - origin: Origin::new(x, y), - })) -} diff --git a/src/macros.rs b/src/macros.rs index cbadc14..48952db 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -47,7 +47,7 @@ macro_rules! wrap_methods { $(return($it:ident) $return_expr:block;)? })? ; - )* + )+ ) => { paste::paste! { $( @@ -76,7 +76,7 @@ macro_rules! wrap_methods { )? return result; } - )* + )+ } }; } @@ -149,7 +149,33 @@ macro_rules! wrap_fields { }; } +macro_rules! wrap_functions { + ( + $prefix:ident; + $( + $(#[$meta:meta])+ + fn $function:ident($($param_name:ident: $param_type:ty),*$(,)?) + $(-> $return_type:ty)? + $block:block + )+ + ) => { + ::paste::paste! { + $( + $(#[$meta])* + #[doc = ""] + #[doc = concat!(" This function is part of the ", stringify!($prefix), " module.")] + #[no_mangle] + pub unsafe extern "C" fn [<$prefix _ $function>]( + $($param_name: $param_type),* + ) $(-> $return_type)? + $block + + )+ + } + }; +} + pub(crate) use { nonnull_as_mut, nonnull_as_ref, wrap_clone, wrap_fields, wrap_free, - wrap_methods, + wrap_functions, wrap_methods, }; From a51fe07d8485c0bfa534aecc3f780599d7fb4c5a Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Wed, 18 Jun 2025 20:41:22 +0200 Subject: [PATCH 06/12] use macros in macros --- include/servicepoint.h | 218 +++++++++++++++++++++++++++++++++-------- src/macros.rs | 141 +++++++++++++------------- 2 files changed, 248 insertions(+), 111 deletions(-) diff --git a/include/servicepoint.h b/include/servicepoint.h index 5960987..e001ddd 100644 --- a/include/servicepoint.h +++ b/include/servicepoint.h @@ -640,7 +640,9 @@ extern "C" { void init_env_logger(void); /** - *Clones a [Bitmap] instance. + *Clones a [`Bitmap`] instance. + * + * This function is part of the sp_bitmap module. */ struct Bitmap */*notnull*/ sp_bitmap_clone(struct Bitmap */*notnull*/ instance); @@ -650,6 +652,8 @@ struct Bitmap */*notnull*/ sp_bitmap_clone(struct Bitmap */*notnull*/ instance); * Gets an unsafe reference to the data of the [Bitmap] instance. * * The returned memory is valid for the lifetime of the bitmap. + * + * This function is part of the sp_bitmap module. */ struct ByteSlice sp_bitmap_data_ref_mut(struct Bitmap */*notnull*/ instance); @@ -661,11 +665,15 @@ struct ByteSlice sp_bitmap_data_ref_mut(struct Bitmap */*notnull*/ instance); * # Arguments * * - `value`: the value to set all pixels to + * + * This function is part of the sp_bitmap module. */ void sp_bitmap_fill(struct Bitmap */*notnull*/ instance, bool value); /** - *Deallocates a [Bitmap] instance. + *Deallocates a [`Bitmap`] instance. + * + * This function is part of the sp_bitmap module. */ void sp_bitmap_free(struct Bitmap */*notnull*/ instance); @@ -692,6 +700,8 @@ struct Bitmap *sp_bitmap_from_bitvec(size_t width, BitVec */*notnull*/ bitvec); * # Panics * * - when accessing `x` or `y` out of bounds + * + * This function is part of the sp_bitmap module. */ bool sp_bitmap_get(struct Bitmap */*notnull*/ instance, size_t x, size_t y); @@ -699,6 +709,8 @@ bool sp_bitmap_get(struct Bitmap */*notnull*/ instance, size_t x, size_t y); * Calls [`servicepoint::Bitmap::height`]. * * Gets the height in pixels. + * + * This function is part of the sp_bitmap module. */ size_t sp_bitmap_height(struct Bitmap */*notnull*/ instance); @@ -790,6 +802,8 @@ struct Bitmap */*notnull*/ sp_bitmap_new_max_sized(void); * # Panics * * - when accessing `x` or `y` out of bounds + * + * This function is part of the sp_bitmap module. */ void sp_bitmap_set(struct Bitmap */*notnull*/ instance, size_t x, @@ -800,6 +814,8 @@ void sp_bitmap_set(struct Bitmap */*notnull*/ instance, * Calls [`servicepoint::Bitmap::width`]. * * Gets the width in pixels. + * + * This function is part of the sp_bitmap module. */ size_t sp_bitmap_width(struct Bitmap */*notnull*/ instance); @@ -809,11 +825,15 @@ size_t sp_bitmap_width(struct Bitmap */*notnull*/ instance); * Gets an unsafe reference to the data of the [DisplayBitVec] instance. * * The returned memory is valid for the lifetime of the bitvec. + * + * This function is part of the sp_bitvec module. */ struct ByteSlice sp_bitvec_as_raw_mut_slice(BitVec */*notnull*/ instance); /** - *Clones a [DisplayBitVec] instance. + *Clones a [`DisplayBitVec`] instance. + * + * This function is part of the sp_bitvec module. */ BitVec */*notnull*/ sp_bitvec_clone(BitVec */*notnull*/ instance); @@ -825,11 +845,15 @@ BitVec */*notnull*/ sp_bitvec_clone(BitVec */*notnull*/ instance); * # Arguments * * - `value`: the value to set all bits to + * + * This function is part of the sp_bitvec module. */ void sp_bitvec_fill(BitVec */*notnull*/ instance, bool value); /** - *Deallocates a [DisplayBitVec] instance. + *Deallocates a [`DisplayBitVec`] instance. + * + * This function is part of the sp_bitvec module. */ void sp_bitvec_free(BitVec */*notnull*/ instance); @@ -848,6 +872,8 @@ void sp_bitvec_free(BitVec */*notnull*/ instance); * # Panics * * - when accessing `index` out of bounds + * + * This function is part of the sp_bitvec module. */ bool sp_bitvec_get(BitVec */*notnull*/ instance, size_t index); @@ -869,6 +895,8 @@ struct Packet *sp_bitvec_into_packet(BitVec */*notnull*/ bitvec, * Calls [`servicepoint::DisplayBitVec::is_empty`]. * * Returns true if length is 0. + * + * This function is part of the sp_bitvec module. */ bool sp_bitvec_is_empty(BitVec */*notnull*/ instance); @@ -876,6 +904,8 @@ bool sp_bitvec_is_empty(BitVec */*notnull*/ instance); * Calls [`servicepoint::DisplayBitVec::len`]. * * Gets the length in bits. + * + * This function is part of the sp_bitvec module. */ size_t sp_bitvec_len(BitVec */*notnull*/ instance); @@ -918,11 +948,15 @@ BitVec */*notnull*/ sp_bitvec_new(size_t size); * # Panics * * - when accessing `index` out of bounds + * + * This function is part of the sp_bitvec module. */ void sp_bitvec_set(BitVec */*notnull*/ instance, size_t index, bool value); /** - *Clones a [BrightnessGrid] instance. + *Clones a [`BrightnessGrid`] instance. + * + * This function is part of the sp_brightness_grid module. */ BrightnessGrid */*notnull*/ sp_brightness_grid_clone(BrightnessGrid */*notnull*/ instance); @@ -932,6 +966,8 @@ BrightnessGrid */*notnull*/ sp_brightness_grid_clone(BrightnessGrid */*notnull*/ * Gets an unsafe reference to the data of the instance. * * The returned memory is valid for the lifetime of the grid. + * + * This function is part of the sp_brightness_grid module. */ struct ByteSlice sp_brightness_grid_data_ref_mut(BrightnessGrid */*notnull*/ instance); @@ -943,12 +979,16 @@ struct ByteSlice sp_brightness_grid_data_ref_mut(BrightnessGrid */*notnull*/ ins * # Arguments * * - `value`: the value to set all cells to + * + * This function is part of the sp_brightness_grid module. */ void sp_brightness_grid_fill(BrightnessGrid */*notnull*/ instance, Brightness value); /** - *Deallocates a [BrightnessGrid] instance. + *Deallocates a [`BrightnessGrid`] instance. + * + * This function is part of the sp_brightness_grid module. */ void sp_brightness_grid_free(BrightnessGrid */*notnull*/ instance); @@ -965,6 +1005,8 @@ void sp_brightness_grid_free(BrightnessGrid */*notnull*/ instance); * * # Panics * - When accessing `x` or `y` out of bounds. + * + * This function is part of the sp_brightness_grid module. */ Brightness sp_brightness_grid_get(BrightnessGrid */*notnull*/ instance, size_t x, @@ -974,6 +1016,8 @@ Brightness sp_brightness_grid_get(BrightnessGrid */*notnull*/ instance, * Calls [`servicepoint::BrightnessGrid::height`]. * * Gets the height of the grid. + * + * This function is part of the sp_brightness_grid module. */ size_t sp_brightness_grid_height(BrightnessGrid */*notnull*/ instance); @@ -1041,6 +1085,8 @@ BrightnessGrid */*notnull*/ sp_brightness_grid_new(size_t width, size_t height); * # Panics * * - When accessing `x` or `y` out of bounds. + * + * This function is part of the sp_brightness_grid module. */ void sp_brightness_grid_set(BrightnessGrid */*notnull*/ instance, size_t x, @@ -1051,11 +1097,15 @@ void sp_brightness_grid_set(BrightnessGrid */*notnull*/ instance, * Calls [`servicepoint::BrightnessGrid::width`]. * * Gets the width of the grid. + * + * This function is part of the sp_brightness_grid module. */ size_t sp_brightness_grid_width(BrightnessGrid */*notnull*/ instance); /** - *Clones a [CharGrid] instance. + *Clones a [`CharGrid`] instance. + * + * This function is part of the sp_char_grid module. */ CharGrid */*notnull*/ sp_char_grid_clone(CharGrid */*notnull*/ instance); @@ -1068,11 +1118,15 @@ CharGrid */*notnull*/ sp_char_grid_clone(CharGrid */*notnull*/ instance); * * - `value`: the value to set all cells to * - when providing values that cannot be converted to Rust's `char`. + * + * This function is part of the sp_char_grid module. */ void sp_char_grid_fill(CharGrid */*notnull*/ instance, uint32_t value); /** - *Deallocates a [CharGrid] instance. + *Deallocates a [`CharGrid`] instance. + * + * This function is part of the sp_char_grid module. */ void sp_char_grid_free(CharGrid */*notnull*/ instance); @@ -1088,6 +1142,8 @@ void sp_char_grid_free(CharGrid */*notnull*/ instance); * # Panics * * - when accessing `x` or `y` out of bounds + * + * This function is part of the sp_char_grid module. */ uint32_t sp_char_grid_get(CharGrid */*notnull*/ instance, size_t x, size_t y); @@ -1095,6 +1151,8 @@ uint32_t sp_char_grid_get(CharGrid */*notnull*/ instance, size_t x, size_t y); * Calls [`servicepoint::CharGrid::height`]. * * Gets the height of the grid. + * + * This function is part of the sp_char_grid module. */ size_t sp_char_grid_height(CharGrid */*notnull*/ instance); @@ -1154,6 +1212,8 @@ CharGrid */*notnull*/ sp_char_grid_new(size_t width, size_t height); * * - when accessing `x` or `y` out of bounds * - when providing values that cannot be converted to Rust's `char`. + * + * This function is part of the sp_char_grid module. */ void sp_char_grid_set(CharGrid */*notnull*/ instance, size_t x, @@ -1164,16 +1224,22 @@ void sp_char_grid_set(CharGrid */*notnull*/ instance, * Calls [`servicepoint::CharGrid::width`]. * * Gets the width of the grid. + * + * This function is part of the sp_char_grid module. */ size_t sp_char_grid_width(CharGrid */*notnull*/ instance); /** - *Clones a [BitmapCommand] instance. + *Clones a [`BitmapCommand`] instance. + * + * This function is part of the sp_cmd_bitmap module. */ struct BitmapCommand */*notnull*/ sp_cmd_bitmap_clone(struct BitmapCommand */*notnull*/ instance); /** - *Deallocates a [BitmapCommand] instance. + *Deallocates a [`BitmapCommand`] instance. + * + * This function is part of the sp_cmd_bitmap module. */ void sp_cmd_bitmap_free(struct BitmapCommand */*notnull*/ instance); @@ -1198,7 +1264,9 @@ struct BitmapCommand */*notnull*/ sp_cmd_bitmap_from_bitmap(struct Bitmap */*not struct Bitmap */*notnull*/ sp_cmd_bitmap_get(struct BitmapCommand */*notnull*/ command); /** - *Gets the value of field `compression` of the [`servicepoint::BitmapCommand`]. + * Gets the value of field `compression` of the [`servicepoint::BitmapCommand`]. + * + * This function is part of the sp_cmd_bitmap module. */ CompressionCode sp_cmd_bitmap_get_compression(struct BitmapCommand */*notnull*/ instance); @@ -1230,7 +1298,9 @@ void sp_cmd_bitmap_set(struct BitmapCommand */*notnull*/ command, struct Bitmap */*notnull*/ bitmap); /** - *Sets the value of field `compression` of the [`servicepoint::BitmapCommand`]. + * Sets the value of field `compression` of the [`servicepoint::BitmapCommand`]. + * + * This function is part of the sp_cmd_bitmap module. */ void sp_cmd_bitmap_set_compression(struct BitmapCommand */*notnull*/ instance, CompressionCode value); @@ -1252,12 +1322,16 @@ void sp_cmd_bitmap_set_origin(struct BitmapCommand */*notnull*/ command, struct Packet *sp_cmd_bitmap_try_into_packet(struct BitmapCommand */*notnull*/ command); /** - *Clones a [BitVecCommand] instance. + *Clones a [`BitVecCommand`] instance. + * + * This function is part of the sp_cmd_bitvec module. */ struct BitVecCommand */*notnull*/ sp_cmd_bitvec_clone(struct BitVecCommand */*notnull*/ instance); /** - *Deallocates a [BitVecCommand] instance. + *Deallocates a [`BitVecCommand`] instance. + * + * This function is part of the sp_cmd_bitvec module. */ void sp_cmd_bitvec_free(struct BitVecCommand */*notnull*/ instance); @@ -1267,17 +1341,23 @@ void sp_cmd_bitvec_free(struct BitVecCommand */*notnull*/ instance); BitVec *sp_cmd_bitvec_get(struct BitVecCommand */*notnull*/ command); /** - *Gets the value of field `compression` of the [`servicepoint::BitVecCommand`]. + * Gets the value of field `compression` of the [`servicepoint::BitVecCommand`]. + * + * This function is part of the sp_cmd_bitvec module. */ CompressionCode sp_cmd_bitvec_get_compression(struct BitVecCommand */*notnull*/ instance); /** - *Gets the value of field `offset` of the [`servicepoint::BitVecCommand`]. + * Gets the value of field `offset` of the [`servicepoint::BitVecCommand`]. + * + * This function is part of the sp_cmd_bitvec module. */ Offset sp_cmd_bitvec_get_offset(struct BitVecCommand */*notnull*/ instance); /** - *Gets the value of field `operation` of the [`servicepoint::BitVecCommand`]. + * Gets the value of field `operation` of the [`servicepoint::BitVecCommand`]. + * + * This function is part of the sp_cmd_bitvec module. */ BinaryOperation sp_cmd_bitvec_get_operation(struct BitVecCommand */*notnull*/ instance); @@ -1309,19 +1389,25 @@ void sp_cmd_bitvec_set(struct BitVecCommand */*notnull*/ command, BitVec */*notnull*/ bitvec); /** - *Sets the value of field `compression` of the [`servicepoint::BitVecCommand`]. + * Sets the value of field `compression` of the [`servicepoint::BitVecCommand`]. + * + * This function is part of the sp_cmd_bitvec module. */ void sp_cmd_bitvec_set_compression(struct BitVecCommand */*notnull*/ instance, CompressionCode value); /** - *Sets the value of field `offset` of the [`servicepoint::BitVecCommand`]. + * Sets the value of field `offset` of the [`servicepoint::BitVecCommand`]. + * + * This function is part of the sp_cmd_bitvec module. */ void sp_cmd_bitvec_set_offset(struct BitVecCommand */*notnull*/ instance, Offset value); /** - *Sets the value of field `operation` of the [`servicepoint::BitVecCommand`]. + * Sets the value of field `operation` of the [`servicepoint::BitVecCommand`]. + * + * This function is part of the sp_cmd_bitvec module. */ void sp_cmd_bitvec_set_operation(struct BitVecCommand */*notnull*/ instance, BinaryOperation value); @@ -1336,17 +1422,23 @@ void sp_cmd_bitvec_set_operation(struct BitVecCommand */*notnull*/ instance, struct Packet *sp_cmd_bitvec_try_into_packet(struct BitVecCommand */*notnull*/ command); /** - *Clones a [GlobalBrightnessCommand] instance. + *Clones a [`GlobalBrightnessCommand`] instance. + * + * This function is part of the sp_cmd_brightness_global module. */ struct GlobalBrightnessCommand */*notnull*/ sp_cmd_brightness_global_clone(struct GlobalBrightnessCommand */*notnull*/ instance); /** - *Deallocates a [GlobalBrightnessCommand] instance. + *Deallocates a [`GlobalBrightnessCommand`] instance. + * + * This function is part of the sp_cmd_brightness_global module. */ void sp_cmd_brightness_global_free(struct GlobalBrightnessCommand */*notnull*/ instance); /** - *Gets the value of field `brightness` of the [`servicepoint::GlobalBrightnessCommand`]. + * Gets the value of field `brightness` of the [`servicepoint::GlobalBrightnessCommand`]. + * + * This function is part of the sp_cmd_brightness_global module. */ Brightness sp_cmd_brightness_global_get_brightness(struct GlobalBrightnessCommand */*notnull*/ instance); @@ -1367,18 +1459,24 @@ struct Packet */*notnull*/ sp_cmd_brightness_global_into_packet(struct GlobalBri struct GlobalBrightnessCommand */*notnull*/ sp_cmd_brightness_global_new(Brightness brightness); /** - *Sets the value of field `brightness` of the [`servicepoint::GlobalBrightnessCommand`]. + * Sets the value of field `brightness` of the [`servicepoint::GlobalBrightnessCommand`]. + * + * This function is part of the sp_cmd_brightness_global module. */ void sp_cmd_brightness_global_set_brightness(struct GlobalBrightnessCommand */*notnull*/ instance, Brightness value); /** - *Clones a [BrightnessGridCommand] instance. + *Clones a [`BrightnessGridCommand`] instance. + * + * This function is part of the sp_cmd_brightness_grid module. */ struct BrightnessGridCommand */*notnull*/ sp_cmd_brightness_grid_clone(struct BrightnessGridCommand */*notnull*/ instance); /** - *Deallocates a [BrightnessGridCommand] instance. + *Deallocates a [`BrightnessGridCommand`] instance. + * + * This function is part of the sp_cmd_brightness_grid module. */ void sp_cmd_brightness_grid_free(struct BrightnessGridCommand */*notnull*/ instance); @@ -1438,12 +1536,16 @@ void sp_cmd_brightness_grid_set_origin(struct BrightnessGridCommand */*notnull*/ size_t origin_y); /** - *Clones a [CharGridCommand] instance. + *Clones a [`CharGridCommand`] instance. + * + * This function is part of the sp_cmd_char_grid module. */ struct CharGridCommand */*notnull*/ sp_cmd_char_grid_clone(struct CharGridCommand */*notnull*/ instance); /** - *Deallocates a [CharGridCommand] instance. + *Deallocates a [`CharGridCommand`] instance. + * + * This function is part of the sp_cmd_char_grid module. */ void sp_cmd_char_grid_free(struct CharGridCommand */*notnull*/ instance); @@ -1503,7 +1605,9 @@ void sp_cmd_char_grid_set_origin(struct CharGridCommand */*notnull*/ command, struct Packet *sp_cmd_char_grid_try_into_packet(struct CharGridCommand */*notnull*/ command); /** - *Deallocates a [ClearCommand] instance. + *Deallocates a [`ClearCommand`] instance. + * + * This function is part of the sp_cmd_clear module. */ void sp_cmd_clear_free(struct ClearCommand */*notnull*/ instance); @@ -1519,12 +1623,16 @@ void sp_cmd_clear_free(struct ClearCommand */*notnull*/ instance); struct ClearCommand */*notnull*/ sp_cmd_clear_new(void); /** - *Clones a [Cp437GridCommand] instance. + *Clones a [`Cp437GridCommand`] instance. + * + * This function is part of the sp_cmd_cp437_grid module. */ struct Cp437GridCommand */*notnull*/ sp_cmd_cp437_grid_clone(struct Cp437GridCommand */*notnull*/ instance); /** - *Deallocates a [Cp437GridCommand] instance. + *Deallocates a [`Cp437GridCommand`] instance. + * + * This function is part of the sp_cmd_cp437_grid module. */ void sp_cmd_cp437_grid_free(struct Cp437GridCommand */*notnull*/ instance); @@ -1595,7 +1703,9 @@ void sp_cmd_cp437_grid_set_origin(struct Cp437GridCommand */*notnull*/ command, struct Packet *sp_cmd_cp437_grid_try_into_packet(struct Cp437GridCommand */*notnull*/ command); /** - *Deallocates a [FadeOutCommand] instance. + *Deallocates a [`FadeOutCommand`] instance. + * + * This function is part of the sp_cmd_fade_out module. */ void sp_cmd_fade_out_free(struct FadeOutCommand */*notnull*/ instance); @@ -1647,7 +1757,9 @@ struct Packet *sp_cmd_generic_into_packet(struct Command command); struct Command sp_cmd_generic_try_from_packet(struct Packet */*notnull*/ packet); /** - *Deallocates a [HardResetCommand] instance. + *Deallocates a [`HardResetCommand`] instance. + * + * This function is part of the sp_cmd_hard_reset module. */ void sp_cmd_hard_reset_free(struct HardResetCommand */*notnull*/ instance); @@ -1663,7 +1775,9 @@ void sp_cmd_hard_reset_free(struct HardResetCommand */*notnull*/ instance); struct HardResetCommand */*notnull*/ sp_cmd_hard_reset_new(void); /** - *Clones a [Cp437Grid] instance. + *Clones a [`Cp437Grid`] instance. + * + * This function is part of the sp_cp437_grid module. */ Cp437Grid */*notnull*/ sp_cp437_grid_clone(Cp437Grid */*notnull*/ instance); @@ -1673,6 +1787,8 @@ Cp437Grid */*notnull*/ sp_cp437_grid_clone(Cp437Grid */*notnull*/ instance); * Gets an unsafe reference to the data of the grid. * * The returned memory is valid for the lifetime of the instance. + * + * This function is part of the sp_cp437_grid module. */ struct ByteSlice sp_cp437_grid_data_ref_mut(Cp437Grid */*notnull*/ instance); @@ -1685,11 +1801,15 @@ struct ByteSlice sp_cp437_grid_data_ref_mut(Cp437Grid */*notnull*/ instance); * * - `cp437_grid`: instance to write to * - `value`: the value to set all cells to + * + * This function is part of the sp_cp437_grid module. */ void sp_cp437_grid_fill(Cp437Grid */*notnull*/ instance, uint8_t value); /** - *Deallocates a [Cp437Grid] instance. + *Deallocates a [`Cp437Grid`] instance. + * + * This function is part of the sp_cp437_grid module. */ void sp_cp437_grid_free(Cp437Grid */*notnull*/ instance); @@ -1705,6 +1825,8 @@ void sp_cp437_grid_free(Cp437Grid */*notnull*/ instance); * # Panics * * - when accessing `x` or `y` out of bounds + * + * This function is part of the sp_cp437_grid module. */ uint8_t sp_cp437_grid_get(Cp437Grid */*notnull*/ instance, size_t x, size_t y); @@ -1712,6 +1834,8 @@ uint8_t sp_cp437_grid_get(Cp437Grid */*notnull*/ instance, size_t x, size_t y); * Calls [`servicepoint::Cp437Grid::height`]. * * Gets the height of the grid. + * + * This function is part of the sp_cp437_grid module. */ size_t sp_cp437_grid_height(Cp437Grid */*notnull*/ instance); @@ -1761,6 +1885,8 @@ Cp437Grid */*notnull*/ sp_cp437_grid_new(size_t width, size_t height); * # Panics * * - when accessing `x` or `y` out of bounds + * + * This function is part of the sp_cp437_grid module. */ void sp_cp437_grid_set(Cp437Grid */*notnull*/ instance, size_t x, @@ -1771,16 +1897,22 @@ void sp_cp437_grid_set(Cp437Grid */*notnull*/ instance, * Calls [`servicepoint::Cp437Grid::width`]. * * Gets the width of the grid. + * + * This function is part of the sp_cp437_grid module. */ size_t sp_cp437_grid_width(Cp437Grid */*notnull*/ instance); /** - *Clones a [Packet] instance. + *Clones a [`Packet`] instance. + * + * This function is part of the sp_packet module. */ struct Packet */*notnull*/ sp_packet_clone(struct Packet */*notnull*/ instance); /** - *Deallocates a [Packet] instance. + *Deallocates a [`Packet`] instance. + * + * This function is part of the sp_packet module. */ void sp_packet_free(struct Packet */*notnull*/ instance); @@ -1793,7 +1925,9 @@ struct Packet */*notnull*/ sp_packet_from_parts(struct Header header, struct ByteSlice payload); /** - *Gets the value of field `header` of the [`servicepoint::Packet`]. + * Gets the value of field `header` of the [`servicepoint::Packet`]. + * + * This function is part of the sp_packet module. */ struct Header sp_packet_get_header(struct Packet */*notnull*/ instance); @@ -1824,7 +1958,9 @@ void sp_packet_serialize_to(struct Packet */*notnull*/ packet, struct ByteSlice buffer); /** - *Sets the value of field `header` of the [`servicepoint::Packet`]. + * Sets the value of field `header` of the [`servicepoint::Packet`]. + * + * This function is part of the sp_packet module. */ void sp_packet_set_header(struct Packet */*notnull*/ instance, struct Header value); @@ -1853,7 +1989,9 @@ bool sp_u16_to_command_code(uint16_t code, CommandCode *result); /** - *Deallocates a [UdpSocket] instance. + *Deallocates a [`UdpSocket`] instance. + * + * This function is part of the sp_udp module. */ void sp_udp_free(struct UdpSocket */*notnull*/ instance); diff --git a/src/macros.rs b/src/macros.rs index 48952db..8d4ba47 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -1,24 +1,22 @@ macro_rules! wrap_free { ($prefix:ident :: $typ:ty) => { - paste::paste! { - #[doc = concat!("Deallocates a [", stringify!($typ), "] instance.")] - #[no_mangle] - pub unsafe extern "C" fn [<$prefix _free>](instance: NonNull<$typ>) { + $crate::macros::wrap_functions!($prefix; + #[doc = concat!("Deallocates a [`", stringify!($typ), "`] instance.")] + fn free(instance: NonNull<$typ>) { unsafe { $crate::mem::heap_drop(instance) } } - } + ); }; } macro_rules! wrap_clone { ($prefix:ident :: $typ:ty) => { - paste::paste! { - #[doc = concat!("Clones a [", stringify!($typ), "] instance.")] - #[no_mangle] - pub unsafe extern "C" fn [<$prefix _clone>](instance: NonNull<$typ>) -> NonNull<$typ> { + $crate::macros::wrap_functions!($prefix; + #[doc = concat!("Clones a [`", stringify!($typ), "`] instance.")] + fn clone(instance: NonNull<$typ>) -> NonNull<$typ> { unsafe { $crate::mem::heap_clone(instance) } } - } + ); }; } @@ -50,33 +48,34 @@ macro_rules! wrap_methods { )+ ) => { paste::paste! { + $crate::macros::wrap_functions!($prefix; $( - #[doc = concat!(" Calls [`servicepoint::", stringify!($object_type), - "::", stringify!($function), "`].")] - #[doc = ""] - $(#[$meta])* - #[no_mangle] - pub unsafe extern "C" fn [<$prefix _ $function>]( - instance: NonNull<$object_type>, - $($param_name: $param_type),* - ) $(-> $return_type)? { - let instance = unsafe { $crate::macros:: [< nonnull_as_ $ref_or_mut >] !(instance) }; - $($( - $(let $param_let_name = $param_let_expr;)* - )?)? - #[allow( - unused_variables, - reason = "This variable may not be used depending on macro variables" )] - let result = instance.$function($($param_name),*); - $( + #[doc = concat!(" Calls [`servicepoint::", stringify!($object_type), + "::", stringify!($function), "`].")] + #[doc = ""] + $(#[$meta])* + fn $function( + instance: NonNull<$object_type>, + $($param_name: $param_type),* + ) $(-> $return_type)? { + let instance = unsafe { $crate::macros:: [< nonnull_as_ $ref_or_mut >] !(instance) }; + $($( + $(let $param_let_name = $param_let_expr;)* + )?)? + #[allow( + unused_variables, + reason = "This variable may not be used depending on macro variables" )] + let result = instance.$function($($param_name),*); $( - let $it = result; - let result = $return_expr; + $( + let $it = result; + let result = $return_expr; + )? )? - )? - return result; - } + return result; + } )+ + ); } }; } @@ -103,48 +102,48 @@ macro_rules! wrap_fields { )+ ) => { paste::paste! { - $( + $crate::macros::wrap_functions!($prefix; $( - #[doc = concat!("Gets the value of field `", stringify!($prop_name), - "` of the [`servicepoint::",stringify!($object_type),"`].")] - $($( - #[doc = ""] - #[$get_meta] - )*)? - #[no_mangle] - pub unsafe extern "C" fn [<$prefix _ get _ $prop_name>]( - instance: NonNull<$object_type> - ) -> $prop_type { - let instance = unsafe { $crate::macros::nonnull_as_ref!(instance) }; - let $prop_name = instance.$prop_name; + $( + #[doc = concat!(" Gets the value of field `", stringify!($prop_name), + "` of the [`servicepoint::",stringify!($object_type),"`].")] $($( - let $prop_name = $get_expr; - )?)? - return $prop_name; - } - )? + #[doc = ""] + #[$get_meta] + )*)? + fn []( + instance: NonNull<$object_type> + ) -> $prop_type { + let instance = unsafe { $crate::macros::nonnull_as_ref!(instance) }; + let $prop_name = instance.$prop_name; + $($( + let $prop_name = $get_expr; + )?)? + return $prop_name; + } + )? - $( - #[doc = concat!("Sets the value of field `", stringify!($prop_name), - "` of the [`servicepoint::",stringify!($object_type),"`].")] - $($( - #[doc = ""] - #[$set_meta] - )*)? - #[no_mangle] - pub unsafe extern "C" fn [<$prefix _ set _ $prop_name>]( - instance: NonNull<$object_type>, - value: $prop_type, - ) { - let instance = unsafe { $crate::macros::nonnull_as_mut!(instance) }; + $( + #[doc = concat!(" Sets the value of field `", stringify!($prop_name), + "` of the [`servicepoint::",stringify!($object_type),"`].")] $($( - let $value = value; - let value = $set_expr; - )?)? - instance.$prop_name = value; - } - )? - )+ + #[doc = ""] + #[$set_meta] + )*)? + fn []( + instance: NonNull<$object_type>, + value: $prop_type, + ) { + let instance = unsafe { $crate::macros::nonnull_as_mut!(instance) }; + $($( + let $value = value; + let value = $set_expr; + )?)? + instance.$prop_name = value; + } + )? + )+ + ); } }; } From 9ddab5e19a87fea40f40b8a3f1ae2144238d789c Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Wed, 18 Jun 2025 00:14:18 +0200 Subject: [PATCH 07/12] update ci --- .github/workflows/rust.yml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index d0f1da3..75139b5 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -30,11 +30,6 @@ jobs: - name: build run: cargo build - - name: generate bindings - run: ./generate-binding.sh - - name: check that generated files did not change - run: output=$(git status --porcelain) && [ -z "$output" ] - - name: build example -- glibc release run: cd example && make -r clean-all && make -r LIBC=gnu LINK=dynamic PROFILE=release - name: build example -- glibc debug @@ -52,6 +47,14 @@ jobs: - name: install rust targets run: rustup toolchain install nightly -t aarch64-unknown-linux-gnu -c rust-src --no-self-update + - name: install csbindgen + run: rustup run nightly cargo install cbindgen@0.29.0 + + - name: generate bindings + run: ./generate-binding.sh + - name: check that generated files did not change + run: output=$(git status --porcelain) && [ -z "$output" ] + - name: build example -- glibc size_optimized run: cd example && make clean-all -r && make -r LIBC=gnu LINK=dynamic PROFILE=size_optimized CARGO="rustup run nightly cargo" LTO=1 From 7d52ccf638a08abd43a9f94a98c2477ea977adfe Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Wed, 18 Jun 2025 17:25:11 +0200 Subject: [PATCH 08/12] fix Makefile --- example/Makefile | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/example/Makefile b/example/Makefile index 5659216..0a56e1a 100644 --- a/example/Makefile +++ b/example/Makefile @@ -47,6 +47,8 @@ CARGOFLAGS += --manifest-path=$(REPO_ROOT)/Cargo.toml \ --target=$(RUST_TARGET) \ --target-dir=cargo +STATIC_LINK_LIBS += -lservicepoint_binding_c +_servicepoint_cflags := -I $(REPO_ROOT)/include -L $(CARGO_OBJDIR) CFLAGS += -Wall -Wextra -pedantic -fwhole-program -fPIE -pie _no_debug_cflags := -ffunction-sections -fdata-sections -Wl,--gc-sections size_optimized_CFLAGS += -Oz \ @@ -69,7 +71,7 @@ debug_CFLAGS += -Og static_CFLAGS += -static $(STATIC_LINK_LIBS) dynamic_CFLAGS += -Wl,-Bstatic $(STATIC_LINK_LIBS) -Wl,-Bdynamic -_servicepoint_cflags := $(pkg-config --libs servicepoint --cflags) +_servicepoint_cflags := $(shell pkg-config --libs servicepoint --cflags || echo -I $(REPO_ROOT)/include -L $(CARGO_OBJDIR)) CFLAGS += $($(_libc)_CFLAGS) $($(_profile)_CFLAGS) $($(_link_type)_CFLAGS) $(_servicepoint_cflags) ifeq ($(LTO), 1) CFLAGS += -flto @@ -103,9 +105,9 @@ _unstripped_bins := $(addsuffix _unstripped, $(_bins)) .PHONY: all build-rust -all: $(_bins) +all: build-rust $(_bins) -$(_unstripped_bins): %_unstripped: src/%.c src/helpers.h build-rust +$(_unstripped_bins): %_unstripped : src/%.c src/helpers.h build-rust $(CC) $< $(CFLAGS) -o $@ $(_bins): %: %_unstripped From 35e9c36ccdd0fc9038ee475adda296990c646dfd Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Wed, 18 Jun 2025 17:39:30 +0200 Subject: [PATCH 09/12] multiple methods in one macro invocation --- src/containers/bitmap.rs | 30 ++++++++---------------------- src/containers/bitvec.rs | 30 ++++++++---------------------- src/containers/brightness_grid.rs | 30 ++++++++---------------------- src/containers/char_grid.rs | 27 ++++++++------------------- src/containers/cp437_grid.rs | 21 +++------------------ src/macros.rs | 21 +++++++++++++-------- 6 files changed, 48 insertions(+), 111 deletions(-) diff --git a/src/containers/bitmap.rs b/src/containers/bitmap.rs index 9b96d10..81af42d 100644 --- a/src/containers/bitmap.rs +++ b/src/containers/bitmap.rs @@ -1,6 +1,6 @@ use crate::{ containers::ByteSlice, - macros::{wrap_clone, wrap_free, wrap_method}, + macros::{wrap_clone, wrap_free, wrap_methods}, mem::{heap_move_nonnull, heap_move_ok, heap_move_some, heap_remove}, }; use servicepoint::{ @@ -83,8 +83,9 @@ pub unsafe extern "C" fn sp_bitmap_from_bitvec( wrap_clone!(sp_bitmap::Bitmap); wrap_free!(sp_bitmap::Bitmap); -wrap_method!( +wrap_methods!( sp_bitmap::Bitmap; + /// Gets the current value at the specified position. /// /// # Arguments @@ -95,10 +96,7 @@ wrap_method!( /// /// - when accessing `x` or `y` out of bounds ref fn get(x: usize, y: usize) -> bool; -); - -wrap_method!( - sp_bitmap::Bitmap; + /// Sets the value of the specified position. /// /// # Arguments @@ -110,32 +108,20 @@ wrap_method!( /// /// - when accessing `x` or `y` out of bounds mut fn set(x: usize, y: usize, value: bool); -); - -wrap_method!( - sp_bitmap::Bitmap; + /// Sets the state of all pixels in the [Bitmap]. /// /// # Arguments /// /// - `value`: the value to set all pixels to mut fn fill(value: bool); -); - -wrap_method!( - sp_bitmap::Bitmap; + /// Gets the width in pixels. ref fn width() -> usize; -); - -wrap_method!( - sp_bitmap::Bitmap; + /// Gets the height in pixels. ref fn height() -> usize; -); - -wrap_method!( - sp_bitmap::Bitmap; + /// Gets an unsafe reference to the data of the [Bitmap] instance. /// /// The returned memory is valid for the lifetime of the bitmap. diff --git a/src/containers/bitvec.rs b/src/containers/bitvec.rs index aad2a88..bceae0b 100644 --- a/src/containers/bitvec.rs +++ b/src/containers/bitvec.rs @@ -1,6 +1,6 @@ use crate::{ containers::ByteSlice, - macros::{wrap_clone, wrap_free, wrap_method}, + macros::{wrap_clone, wrap_free, wrap_methods}, mem::{heap_move_nonnull, heap_move_ok, heap_remove}, }; use servicepoint::{ @@ -38,8 +38,9 @@ pub unsafe extern "C" fn sp_bitvec_load( wrap_clone!(sp_bitvec::DisplayBitVec); wrap_free!(sp_bitvec::DisplayBitVec); -wrap_method!( +wrap_methods!( sp_bitvec::DisplayBitVec; + /// Gets the value of a bit. /// /// # Arguments @@ -54,10 +55,7 @@ wrap_method!( /// - when accessing `index` out of bounds ref fn get(index: usize) -> bool; |result| result.map(|x| *x).unwrap_or(false); -); - -wrap_method!( - sp_bitvec::DisplayBitVec; + /// Sets the value of a bit. /// /// # Arguments @@ -69,32 +67,20 @@ wrap_method!( /// /// - when accessing `index` out of bounds mut fn set(index: usize, value: bool); -); - -wrap_method!( - sp_bitvec::DisplayBitVec; + /// Sets the value of all bits. /// /// # Arguments /// /// - `value`: the value to set all bits to mut fn fill(value: bool); -); - -wrap_method!( - sp_bitvec::DisplayBitVec; + /// Gets the length in bits. ref fn len() -> usize; -); - -wrap_method!( - sp_bitvec::DisplayBitVec; + /// Returns true if length is 0. ref fn is_empty() -> bool; -); - -wrap_method!( - sp_bitvec::DisplayBitVec; + /// Gets an unsafe reference to the data of the [DisplayBitVec] instance. /// /// The returned memory is valid for the lifetime of the bitvec. diff --git a/src/containers/brightness_grid.rs b/src/containers/brightness_grid.rs index 54491c2..4e15599 100644 --- a/src/containers/brightness_grid.rs +++ b/src/containers/brightness_grid.rs @@ -1,6 +1,6 @@ use crate::{ containers::ByteSlice, - macros::{wrap_clone, wrap_free, wrap_method}, + macros::{wrap_clone, wrap_free, wrap_methods}, mem::{heap_move_nonnull, heap_move_ok, heap_move_some, heap_remove}, }; use servicepoint::{ @@ -55,8 +55,9 @@ pub unsafe extern "C" fn sp_brightness_grid_load( wrap_clone!(sp_brightness_grid::BrightnessGrid); wrap_free!(sp_brightness_grid::BrightnessGrid); -wrap_method!( +wrap_methods!( sp_brightness_grid::BrightnessGrid; + /// Gets the current value at the specified position. /// /// # Arguments @@ -68,10 +69,7 @@ wrap_method!( /// # Panics /// - When accessing `x` or `y` out of bounds. ref fn get(x: usize, y: usize) -> Brightness; -); - -wrap_method!( - sp_brightness_grid::BrightnessGrid; + /// Sets the value of the specified position. /// /// # Arguments @@ -85,32 +83,20 @@ wrap_method!( /// /// - When accessing `x` or `y` out of bounds. mut fn set(x: usize, y: usize, value: Brightness); -); - -wrap_method!( - sp_brightness_grid::BrightnessGrid; + /// Sets the value of all cells. /// /// # Arguments /// /// - `value`: the value to set all cells to mut fn fill(value: Brightness); -); - -wrap_method!( - sp_brightness_grid::BrightnessGrid; + /// Gets the width of the grid. ref fn width() -> usize; -); - -wrap_method!( - sp_brightness_grid::BrightnessGrid; + /// Gets the height of the grid. ref fn height() -> usize; -); - -wrap_method!( - sp_brightness_grid::BrightnessGrid; + /// Gets an unsafe reference to the data of the instance. /// /// The returned memory is valid for the lifetime of the grid. diff --git a/src/containers/char_grid.rs b/src/containers/char_grid.rs index 5db7897..dddae0b 100644 --- a/src/containers/char_grid.rs +++ b/src/containers/char_grid.rs @@ -1,6 +1,6 @@ use crate::{ containers::ByteSlice, - macros::{wrap_clone, wrap_free, wrap_method}, + macros::{wrap_clone, wrap_free, wrap_methods}, mem::{heap_move_nonnull, heap_move_ok, heap_remove}, }; use servicepoint::{CharGrid, CharGridCommand, Grid, Origin, Packet}; @@ -42,8 +42,9 @@ pub unsafe extern "C" fn sp_char_grid_load( wrap_clone!(sp_char_grid::CharGrid); wrap_free!(sp_char_grid::CharGrid); -wrap_method!( +wrap_methods!( sp_char_grid::CharGrid; + /// Returns the current value at the specified position. /// /// # Arguments @@ -54,11 +55,8 @@ wrap_method!( /// /// - when accessing `x` or `y` out of bounds ref fn get(x: usize, y: usize) -> u32; - | char | char as u32 -); - -wrap_method!( - sp_char_grid::CharGrid; + | char | char as u32; + /// Sets the value of the specified position in the grid. /// /// # Arguments @@ -74,10 +72,7 @@ wrap_method!( /// - when providing values that cannot be converted to Rust's `char`. mut fn set(x: usize, y: usize, value: u32); let value = char::from_u32(value).unwrap(); -); - -wrap_method!( - sp_char_grid::CharGrid; + /// Sets the value of all cells in the grid. /// /// # Arguments @@ -86,16 +81,10 @@ wrap_method!( /// - when providing values that cannot be converted to Rust's `char`. mut fn fill(value: u32); let value = char::from_u32(value).unwrap(); -); - -wrap_method!( - sp_char_grid::CharGrid; + /// Gets the width of the grid. ref fn width() -> usize; -); - -wrap_method!( - sp_char_grid::CharGrid; + /// Gets the height of the grid. ref fn height() -> usize; ); diff --git a/src/containers/cp437_grid.rs b/src/containers/cp437_grid.rs index 5d7b84f..166083f 100644 --- a/src/containers/cp437_grid.rs +++ b/src/containers/cp437_grid.rs @@ -1,6 +1,6 @@ use crate::{ containers::ByteSlice, - macros::{wrap_clone, wrap_free, wrap_method}, + macros::{wrap_clone, wrap_free, wrap_methods}, mem::{heap_move_nonnull, heap_move_ok, heap_move_some, heap_remove}, }; use servicepoint::{ @@ -33,7 +33,7 @@ pub unsafe extern "C" fn sp_cp437_grid_load( wrap_clone!(sp_cp437_grid::Cp437Grid); wrap_free!(sp_cp437_grid::Cp437Grid); -wrap_method!( +wrap_methods!( sp_cp437_grid::Cp437Grid; /// Gets the current value at the specified position. /// @@ -45,10 +45,7 @@ wrap_method!( /// /// - when accessing `x` or `y` out of bounds ref fn get(x: usize, y: usize) -> u8; -); -wrap_method!( - sp_cp437_grid::Cp437Grid; /// Sets the value at the specified position. /// /// # Arguments @@ -62,10 +59,7 @@ wrap_method!( /// /// - when accessing `x` or `y` out of bounds mut fn set(x: usize, y: usize, value: u8); -); -wrap_method!( - sp_cp437_grid::Cp437Grid; /// Sets the value of all cells in the grid. /// /// # Arguments @@ -73,22 +67,13 @@ wrap_method!( /// - `cp437_grid`: instance to write to /// - `value`: the value to set all cells to mut fn fill(value: u8); -); -wrap_method!( - sp_cp437_grid::Cp437Grid; /// Gets the width of the grid. ref fn width() -> usize; -); -wrap_method!( - sp_cp437_grid::Cp437Grid; /// Gets the height of the grid. ref fn height() -> usize; -); - -wrap_method!( - sp_cp437_grid::Cp437Grid; + /// Gets an unsafe reference to the data of the grid. /// /// The returned memory is valid for the lifetime of the instance. diff --git a/src/macros.rs b/src/macros.rs index df21e23..fc6e524 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -35,16 +35,18 @@ macro_rules! nonnull_as_mut { } // meta required on purpose, because otherwise the added documentation would suppress warnings -macro_rules! wrap_method { +macro_rules! wrap_methods { ( $prefix:ident :: $object_type:ty; - $(#[$meta:meta])+ - $ref_or_mut:ident fn $function:ident($($param_name:ident: $param_type:ty),*) - $(-> $return_type:ty$(; |$it:ident | $return_expr:expr)?)? - $(; let $param_let_name:ident = $param_let_expr:expr)* - $(;)? + $( + $(#[$meta:meta])+ + $ref_or_mut:ident fn $function:ident($($param_name:ident: $param_type:ty),*) + $(-> $return_type:ty$(; |$it:ident | $return_expr:expr)?)?; + $($(let $param_let_name:ident = $param_let_expr:expr);+;)? + )* ) => { paste::paste! { + $( #[doc = concat!(" Calls [`servicepoint::", stringify!($object_type), "::", stringify!($function), "`].")] #[doc = ""] @@ -55,7 +57,9 @@ macro_rules! wrap_method { $($param_name: $param_type),* ) $(-> $return_type)? { let instance = unsafe { $crate::macros:: [< nonnull_as_ $ref_or_mut >] !(instance) }; - $(let $param_let_name = $param_let_expr;)* + $( + $(let $param_let_name = $param_let_expr;)* + )? #[allow( unused_variables, reason = "This variable may not be used depending on macro variables" )] @@ -68,6 +72,7 @@ macro_rules! wrap_method { return result; )? } + )* } }; } @@ -142,5 +147,5 @@ macro_rules! wrap_fields { pub(crate) use { nonnull_as_mut, nonnull_as_ref, wrap_clone, wrap_fields, wrap_free, - wrap_method, + wrap_methods, }; From bf4e35151497bb8550f15877c48c3c12136b7221 Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Wed, 18 Jun 2025 17:51:32 +0200 Subject: [PATCH 10/12] tweak dsl --- src/containers/bitmap.rs | 18 ++++++++++-------- src/containers/bitvec.rs | 23 +++++++++++++---------- src/containers/brightness_grid.rs | 23 ++++++++++++----------- src/containers/char_grid.rs | 25 ++++++++++++++----------- src/containers/cp437_grid.rs | 7 ++++--- src/macros.rs | 14 +++++++++----- 6 files changed, 62 insertions(+), 48 deletions(-) diff --git a/src/containers/bitmap.rs b/src/containers/bitmap.rs index 81af42d..ae0d2ae 100644 --- a/src/containers/bitmap.rs +++ b/src/containers/bitmap.rs @@ -85,7 +85,7 @@ wrap_free!(sp_bitmap::Bitmap); wrap_methods!( sp_bitmap::Bitmap; - + /// Gets the current value at the specified position. /// /// # Arguments @@ -96,7 +96,7 @@ wrap_methods!( /// /// - when accessing `x` or `y` out of bounds ref fn get(x: usize, y: usize) -> bool; - + /// Sets the value of the specified position. /// /// # Arguments @@ -108,25 +108,27 @@ wrap_methods!( /// /// - when accessing `x` or `y` out of bounds mut fn set(x: usize, y: usize, value: bool); - + /// Sets the state of all pixels in the [Bitmap]. /// /// # Arguments /// /// - `value`: the value to set all pixels to mut fn fill(value: bool); - + /// Gets the width in pixels. ref fn width() -> usize; - + /// Gets the height in pixels. ref fn height() -> usize; - + /// Gets an unsafe reference to the data of the [Bitmap] instance. /// /// The returned memory is valid for the lifetime of the bitmap. - mut fn data_ref_mut() -> ByteSlice; - |slice| unsafe { ByteSlice::from_slice(slice) }; + mut fn data_ref_mut() -> ByteSlice { + + return(slice) { unsafe { ByteSlice::from_slice(slice) } }; + }; ); /// Consumes the Bitmap and returns the contained BitVec. diff --git a/src/containers/bitvec.rs b/src/containers/bitvec.rs index bceae0b..76d716a 100644 --- a/src/containers/bitvec.rs +++ b/src/containers/bitvec.rs @@ -40,7 +40,7 @@ wrap_free!(sp_bitvec::DisplayBitVec); wrap_methods!( sp_bitvec::DisplayBitVec; - + /// Gets the value of a bit. /// /// # Arguments @@ -53,9 +53,11 @@ wrap_methods!( /// # Panics /// /// - when accessing `index` out of bounds - ref fn get(index: usize) -> bool; - |result| result.map(|x| *x).unwrap_or(false); - + ref fn get(index: usize) -> bool { + return(result) { result.map(|x| *x).unwrap_or(false) }; + }; + + /// Sets the value of a bit. /// /// # Arguments @@ -67,25 +69,26 @@ wrap_methods!( /// /// - when accessing `index` out of bounds mut fn set(index: usize, value: bool); - + /// Sets the value of all bits. /// /// # Arguments /// /// - `value`: the value to set all bits to mut fn fill(value: bool); - + /// Gets the length in bits. ref fn len() -> usize; - + /// Returns true if length is 0. ref fn is_empty() -> bool; - + /// Gets an unsafe reference to the data of the [DisplayBitVec] instance. /// /// The returned memory is valid for the lifetime of the bitvec. - mut fn as_raw_mut_slice() -> ByteSlice; - |slice| unsafe { ByteSlice::from_slice(slice) }; + mut fn as_raw_mut_slice() -> ByteSlice { + return(slice) { unsafe { ByteSlice::from_slice(slice) } }; + }; ); /// Creates a [BitVecCommand] and immediately turns that into a [Packet]. diff --git a/src/containers/brightness_grid.rs b/src/containers/brightness_grid.rs index 4e15599..a3590b8 100644 --- a/src/containers/brightness_grid.rs +++ b/src/containers/brightness_grid.rs @@ -57,7 +57,7 @@ wrap_free!(sp_brightness_grid::BrightnessGrid); wrap_methods!( sp_brightness_grid::BrightnessGrid; - + /// Gets the current value at the specified position. /// /// # Arguments @@ -69,7 +69,7 @@ wrap_methods!( /// # Panics /// - When accessing `x` or `y` out of bounds. ref fn get(x: usize, y: usize) -> Brightness; - + /// Sets the value of the specified position. /// /// # Arguments @@ -83,29 +83,30 @@ wrap_methods!( /// /// - When accessing `x` or `y` out of bounds. mut fn set(x: usize, y: usize, value: Brightness); - + /// Sets the value of all cells. /// /// # Arguments /// /// - `value`: the value to set all cells to mut fn fill(value: Brightness); - + /// Gets the width of the grid. ref fn width() -> usize; - + /// Gets the height of the grid. ref fn height() -> usize; - + /// Gets an unsafe reference to the data of the instance. /// /// The returned memory is valid for the lifetime of the grid. - mut fn data_ref_mut() -> ByteSlice; - |br_slice| unsafe { - //noinspection RsAssertEqual - const _: () = assert!(size_of::() == 1); + mut fn data_ref_mut() -> ByteSlice { + return(br_slice) { unsafe { + //noinspection RsAssertEqual + const _: () = assert!(size_of::() == 1); - ByteSlice::from_slice(transmute::<&mut [Brightness], &mut [u8]>(br_slice)) + ByteSlice::from_slice(transmute::<&mut [Brightness], &mut [u8]>(br_slice)) + }}; }; ); diff --git a/src/containers/char_grid.rs b/src/containers/char_grid.rs index dddae0b..1b70202 100644 --- a/src/containers/char_grid.rs +++ b/src/containers/char_grid.rs @@ -44,7 +44,7 @@ wrap_free!(sp_char_grid::CharGrid); wrap_methods!( sp_char_grid::CharGrid; - + /// Returns the current value at the specified position. /// /// # Arguments @@ -54,9 +54,10 @@ wrap_methods!( /// # Panics /// /// - when accessing `x` or `y` out of bounds - ref fn get(x: usize, y: usize) -> u32; - | char | char as u32; - + ref fn get(x: usize, y: usize) -> u32 { + return(char) { char as u32 }; + }; + /// Sets the value of the specified position in the grid. /// /// # Arguments @@ -70,21 +71,23 @@ wrap_methods!( /// /// - when accessing `x` or `y` out of bounds /// - when providing values that cannot be converted to Rust's `char`. - mut fn set(x: usize, y: usize, value: u32); - let value = char::from_u32(value).unwrap(); - + mut fn set(x: usize, y: usize, value: u32) { + prepare(value) { char::from_u32(value).unwrap() }; + }; + /// Sets the value of all cells in the grid. /// /// # Arguments /// /// - `value`: the value to set all cells to /// - when providing values that cannot be converted to Rust's `char`. - mut fn fill(value: u32); - let value = char::from_u32(value).unwrap(); - + mut fn fill(value: u32) { + prepare(value) { char::from_u32(value).unwrap() }; + }; + /// Gets the width of the grid. ref fn width() -> usize; - + /// Gets the height of the grid. ref fn height() -> usize; ); diff --git a/src/containers/cp437_grid.rs b/src/containers/cp437_grid.rs index 166083f..d6ae17f 100644 --- a/src/containers/cp437_grid.rs +++ b/src/containers/cp437_grid.rs @@ -73,12 +73,13 @@ wrap_methods!( /// Gets the height of the grid. ref fn height() -> usize; - + /// Gets an unsafe reference to the data of the grid. /// /// The returned memory is valid for the lifetime of the instance. - mut fn data_ref_mut() -> ByteSlice; - | slice | unsafe { ByteSlice::from_slice(slice) }; + mut fn data_ref_mut() -> ByteSlice { + return(slice) { unsafe { ByteSlice::from_slice(slice) } }; + }; ); /// Creates a [Cp437GridCommand] and immediately turns that into a [Packet]. diff --git a/src/macros.rs b/src/macros.rs index fc6e524..cbadc14 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -41,8 +41,12 @@ macro_rules! wrap_methods { $( $(#[$meta:meta])+ $ref_or_mut:ident fn $function:ident($($param_name:ident: $param_type:ty),*) - $(-> $return_type:ty$(; |$it:ident | $return_expr:expr)?)?; - $($(let $param_let_name:ident = $param_let_expr:expr);+;)? + $(-> $return_type:ty)? + $({ + $($(prepare($param_let_name:ident) $param_let_expr:block);+;)? + $(return($it:ident) $return_expr:block;)? + })? + ; )* ) => { paste::paste! { @@ -57,9 +61,9 @@ macro_rules! wrap_methods { $($param_name: $param_type),* ) $(-> $return_type)? { let instance = unsafe { $crate::macros:: [< nonnull_as_ $ref_or_mut >] !(instance) }; - $( + $($( $(let $param_let_name = $param_let_expr;)* - )? + )?)? #[allow( unused_variables, reason = "This variable may not be used depending on macro variables" )] @@ -69,8 +73,8 @@ macro_rules! wrap_methods { let $it = result; let result = $return_expr; )? - return result; )? + return result; } )* } From 27f231eba02045fd85cb458a548a08c8dad1a817 Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Wed, 18 Jun 2025 20:30:55 +0200 Subject: [PATCH 11/12] wrap_function without defined signature --- include/servicepoint.h | 79 ++++++++- src/commands/bitmap_command.rs | 77 ++++----- src/commands/bitvec_command.rs | 74 ++++---- src/commands/brightness_grid_command.rs | 69 ++++---- src/commands/cc_only_commands.rs | 58 ++++--- src/commands/char_grid_command.rs | 73 ++++---- src/commands/cp437_grid_command.rs | 69 ++++---- src/commands/global_brightness_command.rs | 31 ++-- src/containers/bitmap.rs | 195 +++++++++++----------- src/containers/bitvec.rs | 93 +++++------ src/containers/brightness_grid.rs | 120 ++++++------- src/containers/char_grid.rs | 101 +++++------ src/containers/cp437_grid.rs | 78 ++++----- src/macros.rs | 32 +++- 14 files changed, 630 insertions(+), 519 deletions(-) diff --git a/include/servicepoint.h b/include/servicepoint.h index 02d0688..5960987 100644 --- a/include/servicepoint.h +++ b/include/servicepoint.h @@ -675,6 +675,8 @@ void sp_bitmap_free(struct Bitmap */*notnull*/ instance); * The provided BitVec gets consumed. * * Returns NULL in case of error. + * + * This function is part of the sp_bitmap module. */ struct Bitmap *sp_bitmap_from_bitvec(size_t width, BitVec */*notnull*/ bitvec); @@ -702,6 +704,8 @@ size_t sp_bitmap_height(struct Bitmap */*notnull*/ instance); /** * Consumes the Bitmap and returns the contained BitVec. + * + * This function is part of the sp_bitmap module. */ BitVec */*notnull*/ sp_bitmap_into_bitvec(struct Bitmap */*notnull*/ bitmap); @@ -711,6 +715,8 @@ BitVec */*notnull*/ sp_bitmap_into_bitvec(struct Bitmap */*notnull*/ bitmap); * The provided [Bitmap] gets consumed. * * Returns NULL in case of an error. + * + * This function is part of the sp_bitmap module. */ struct Packet *sp_bitmap_into_packet(struct Bitmap */*notnull*/ bitmap, size_t x, @@ -726,6 +732,8 @@ struct Packet *sp_bitmap_into_packet(struct Bitmap */*notnull*/ bitmap, * - `height`: size in pixels in y-direction * * returns: [Bitmap] that contains a copy of the provided data, or NULL in case of an error. + * + * This function is part of the sp_bitmap module. */ struct Bitmap *sp_bitmap_load(size_t width, size_t height, @@ -755,6 +763,8 @@ struct Bitmap *sp_bitmap_load(size_t width, * sp_bitmap_set(grid, 0, 0, false); * sp_bitmap_free(grid); * ``` + * + * This function is part of the sp_bitmap module. */ struct Bitmap *sp_bitmap_new(size_t width, size_t height); @@ -762,6 +772,8 @@ struct Bitmap *sp_bitmap_new(size_t width, size_t height); * Creates a new [Bitmap] with a size matching the screen. * * returns: [Bitmap] initialized to all pixels off. + * + * This function is part of the sp_bitmap module. */ struct Bitmap */*notnull*/ sp_bitmap_new_max_sized(void); @@ -845,6 +857,8 @@ bool sp_bitvec_get(BitVec */*notnull*/ instance, size_t index); * The provided [DisplayBitVec] gets consumed. * * Returns NULL in case of an error. + * + * This function is part of the sp_bitvec module. */ struct Packet *sp_bitvec_into_packet(BitVec */*notnull*/ bitvec, size_t offset, @@ -869,6 +883,8 @@ size_t sp_bitvec_len(BitVec */*notnull*/ instance); * Interpret the data as a series of bits and load then into a new [DisplayBitVec] instance. * * returns: [DisplayBitVec] instance containing data. + * + * This function is part of the sp_bitvec module. */ BitVec */*notnull*/ sp_bitvec_load(struct ByteSlice data); @@ -884,6 +900,8 @@ BitVec */*notnull*/ sp_bitvec_load(struct ByteSlice data); * # Panics * * - when `size` is not divisible by 8. + * + * This function is part of the sp_bitvec module. */ BitVec */*notnull*/ sp_bitvec_new(size_t size); @@ -965,6 +983,8 @@ size_t sp_brightness_grid_height(BrightnessGrid */*notnull*/ instance); * The provided [BrightnessGrid] gets consumed. * * Returns NULL in case of an error. + * + * This function is part of the sp_brightness_grid module. */ struct Packet *sp_brightness_grid_into_packet(BrightnessGrid */*notnull*/ grid, size_t x, @@ -976,6 +996,8 @@ struct Packet *sp_brightness_grid_into_packet(BrightnessGrid */*notnull*/ grid, * Any out of range values will be set to [Brightness::MAX] or [Brightness::MIN]. * * returns: new [BrightnessGrid] instance, or NULL in case of an error. + * + * This function is part of the sp_brightness_grid module. */ BrightnessGrid *sp_brightness_grid_load(size_t width, size_t height, @@ -999,6 +1021,8 @@ BrightnessGrid *sp_brightness_grid_load(size_t width, * TypedCommand *command = sp_command_char_brightness(grid); * sp_udp_free(connection); * ``` + * + * This function is part of the sp_brightness_grid module. */ BrightnessGrid */*notnull*/ sp_brightness_grid_new(size_t width, size_t height); @@ -1080,6 +1104,8 @@ size_t sp_char_grid_height(CharGrid */*notnull*/ instance); * The provided [CharGrid] gets consumed. * * Returns NULL in case of an error. + * + * This function is part of the sp_char_grid module. */ struct Packet *sp_char_grid_into_packet(CharGrid */*notnull*/ grid, size_t x, @@ -1089,6 +1115,8 @@ struct Packet *sp_char_grid_into_packet(CharGrid */*notnull*/ grid, * Loads a [CharGrid] with the specified dimensions from the provided data. * * returns: new CharGrid or NULL in case of an error + * + * This function is part of the sp_char_grid module. */ CharGrid *sp_char_grid_load(size_t width, size_t height, struct ByteSlice data); @@ -1105,6 +1133,8 @@ CharGrid *sp_char_grid_load(size_t width, size_t height, struct ByteSlice data); * sp_char_grid_set(grid, 0, 0, '!'); * sp_char_grid_free(grid); * ``` + * + * This function is part of the sp_char_grid module. */ CharGrid */*notnull*/ sp_char_grid_new(size_t width, size_t height); @@ -1152,6 +1182,8 @@ void sp_cmd_bitmap_free(struct BitmapCommand */*notnull*/ instance); * leaving other fields as their default values. * * Rust equivalent: `BitmapCommand::from(bitmap)` + * + * This function is part of the sp_cmd_bitmap module. */ struct BitmapCommand */*notnull*/ sp_cmd_bitmap_from_bitmap(struct Bitmap */*notnull*/ bitmap); @@ -1183,6 +1215,8 @@ void sp_cmd_bitmap_get_origin(struct BitmapCommand */*notnull*/ command, * The passed [Bitmap] gets consumed. * * Returns: a new [BitmapCommand] instance. + * + * This function is part of the sp_cmd_bitmap module. */ struct BitmapCommand */*notnull*/ sp_cmd_bitmap_new(struct Bitmap */*notnull*/ bitmap, size_t origin_x, @@ -1212,6 +1246,8 @@ void sp_cmd_bitmap_set_origin(struct BitmapCommand */*notnull*/ command, * Tries to turn a [BitmapCommand] into a [Packet]. * * Returns: NULL or a [Packet] containing the command. + * + * This function is part of the sp_cmd_bitmap module. */ struct Packet *sp_cmd_bitmap_try_into_packet(struct BitmapCommand */*notnull*/ command); @@ -1258,6 +1294,8 @@ BinaryOperation sp_cmd_bitvec_get_operation(struct BitVecCommand */*notnull*/ in * For example, [`BinaryOperation::Or`] can be used to turn on some pixels without affecting other pixels. * * The contained [`DisplayBitVec`] is always uncompressed. + * + * This function is part of the sp_cmd_bitvec module. */ struct BitVecCommand */*notnull*/ sp_cmd_bitvec_new(BitVec */*notnull*/ bitvec, size_t offset, @@ -1292,6 +1330,8 @@ void sp_cmd_bitvec_set_operation(struct BitVecCommand */*notnull*/ instance, * Tries to turn a [BitVecCommand] into a [Packet]. * * Returns: NULL or a [Packet] containing the command. + * + * This function is part of the sp_cmd_bitvec module. */ struct Packet *sp_cmd_bitvec_try_into_packet(struct BitVecCommand */*notnull*/ command); @@ -1310,12 +1350,19 @@ void sp_cmd_brightness_global_free(struct GlobalBrightnessCommand */*notnull*/ i */ Brightness sp_cmd_brightness_global_get_brightness(struct GlobalBrightnessCommand */*notnull*/ instance); +/** + * Turns the command into a packet + * + * This function is part of the sp_cmd_brightness_global module. + */ struct Packet */*notnull*/ sp_cmd_brightness_global_into_packet(struct GlobalBrightnessCommand */*notnull*/ command); /** * Set the brightness of all tiles to the same value. * * Returns: a new [GlobalBrightnessCommand] instance. + * + * This function is part of the sp_cmd_brightness_global module. */ struct GlobalBrightnessCommand */*notnull*/ sp_cmd_brightness_global_new(Brightness brightness); @@ -1338,6 +1385,8 @@ void sp_cmd_brightness_grid_free(struct BrightnessGridCommand */*notnull*/ insta /** * Moves the provided [BrightnessGrid] into a new [BrightnessGridCommand], * leaving other fields as their default values. + * + * This function is part of the sp_cmd_brightness_grid module. */ struct BrightnessGridCommand */*notnull*/ sp_cmd_brightness_grid_from_grid(BrightnessGrid */*notnull*/ grid); @@ -1357,6 +1406,8 @@ void sp_cmd_brightness_grid_get_origin(struct BrightnessGridCommand */*notnull*/ * Tries to turn a [BrightnessGridCommand] into a [Packet]. * * Returns: NULL or a [Packet] containing the command. + * + * This function is part of the sp_cmd_brightness_grid module. */ struct Packet *sp_cmd_brightness_grid_into_packet(struct BrightnessGridCommand */*notnull*/ command); @@ -1366,6 +1417,8 @@ struct Packet *sp_cmd_brightness_grid_into_packet(struct BrightnessGridCommand * * The passed [BrightnessGrid] gets consumed. * * Returns: a new [BrightnessGridCommand] instance. + * + * This function is part of the sp_cmd_brightness_grid module. */ struct BrightnessGridCommand */*notnull*/ sp_cmd_brightness_grid_new(BrightnessGrid */*notnull*/ grid, size_t origin_x, @@ -1397,13 +1450,15 @@ void sp_cmd_char_grid_free(struct CharGridCommand */*notnull*/ instance); /** * Moves the provided [CharGrid] into a new [CharGridCommand], * leaving other fields as their default values. + * + * This function is part of the sp_cmd_char_grid module. */ struct CharGridCommand */*notnull*/ sp_cmd_char_grid_from_grid(CharGrid */*notnull*/ grid); /** * Returns a pointer to the [CharGrid] contained in the [CharGridCommand]. */ -CharGrid *sp_cmd_char_grid_get(struct CharGridCommand */*notnull*/ command); +CharGrid */*notnull*/ sp_cmd_char_grid_get(struct CharGridCommand */*notnull*/ command); /** * Reads the origin field of the [CharGridCommand]. @@ -1418,6 +1473,8 @@ void sp_cmd_char_grid_get_origin(struct CharGridCommand */*notnull*/ command, * The passed [CharGrid] gets consumed. * * Returns: a new [CharGridCommand] instance. + * + * This function is part of the sp_cmd_char_grid module. */ struct CharGridCommand */*notnull*/ sp_cmd_char_grid_new(CharGrid */*notnull*/ grid, size_t origin_x, @@ -1440,6 +1497,8 @@ void sp_cmd_char_grid_set_origin(struct CharGridCommand */*notnull*/ command, * Tries to turn a [CharGridCommand] into a [Packet]. * * Returns: NULL or a [Packet] containing the command. + * + * This function is part of the sp_cmd_char_grid module. */ struct Packet *sp_cmd_char_grid_try_into_packet(struct CharGridCommand */*notnull*/ command); @@ -1454,6 +1513,8 @@ void sp_cmd_clear_free(struct ClearCommand */*notnull*/ instance); * Does not affect brightness. * * Returns: a new [ClearCommand] instance. + * + * This function is part of the sp_cmd_clear module. */ struct ClearCommand */*notnull*/ sp_cmd_clear_new(void); @@ -1470,6 +1531,8 @@ void sp_cmd_cp437_grid_free(struct Cp437GridCommand */*notnull*/ instance); /** * Moves the provided [Cp437Grid] into a new [Cp437GridCommand], * leaving other fields as their default values. + * + * This function is part of the sp_cmd_cp437_grid module. */ struct Cp437GridCommand */*notnull*/ sp_cmd_cp437_grid_from_grid(Cp437Grid */*notnull*/ grid); @@ -1498,6 +1561,8 @@ void sp_cmd_cp437_grid_get_origin(struct Cp437GridCommand */*notnull*/ command, * The text is sent in the form of a 2D grid of [CP-437] encoded characters. * * The origin is relative to the top-left of the display. + * + * This function is part of the sp_cmd_cp437_grid module. */ struct Cp437GridCommand */*notnull*/ sp_cmd_cp437_grid_new(Cp437Grid */*notnull*/ grid, size_t origin_x, @@ -1524,6 +1589,8 @@ void sp_cmd_cp437_grid_set_origin(struct Cp437GridCommand */*notnull*/ command, * Tries to turn a [Cp437GridCommand] into a [Packet]. * * Returns: NULL or a [Packet] containing the command. + * + * This function is part of the sp_cmd_cp437_grid module. */ struct Packet *sp_cmd_cp437_grid_try_into_packet(struct Cp437GridCommand */*notnull*/ command); @@ -1536,6 +1603,8 @@ void sp_cmd_fade_out_free(struct FadeOutCommand */*notnull*/ instance); * A yet-to-be-tested command. * * Returns: a new [FadeOutCommand] instance. + * + * This function is part of the sp_cmd_fade_out module. */ struct FadeOutCommand */*notnull*/ sp_cmd_fade_out_new(void); @@ -1588,6 +1657,8 @@ void sp_cmd_hard_reset_free(struct HardResetCommand */*notnull*/ instance); * Please do not send this in your normal program flow. * * Returns: a new [HardResetCommand] instance. + * + * This function is part of the sp_cmd_hard_reset module. */ struct HardResetCommand */*notnull*/ sp_cmd_hard_reset_new(void); @@ -1650,6 +1721,8 @@ size_t sp_cp437_grid_height(Cp437Grid */*notnull*/ instance); * The provided [Cp437Grid] gets consumed. * * Returns NULL in case of an error. + * + * This function is part of the sp_cp437_grid module. */ struct Packet *sp_cp437_grid_into_packet(Cp437Grid */*notnull*/ grid, size_t x, @@ -1657,6 +1730,8 @@ struct Packet *sp_cp437_grid_into_packet(Cp437Grid */*notnull*/ grid, /** * Loads a [Cp437Grid] with the specified dimensions from the provided data. + * + * This function is part of the sp_cp437_grid module. */ Cp437Grid *sp_cp437_grid_load(size_t width, size_t height, @@ -1666,6 +1741,8 @@ Cp437Grid *sp_cp437_grid_load(size_t width, * Creates a new [Cp437Grid] with the specified dimensions. * * returns: [Cp437Grid] initialized to 0. + * + * This function is part of the sp_cp437_grid module. */ Cp437Grid */*notnull*/ sp_cp437_grid_new(size_t width, size_t height); diff --git a/src/commands/bitmap_command.rs b/src/commands/bitmap_command.rs index 3bfcf20..f4c9a7e 100644 --- a/src/commands/bitmap_command.rs +++ b/src/commands/bitmap_command.rs @@ -1,49 +1,50 @@ use crate::{ - macros::{wrap_clone, wrap_fields, wrap_free}, + macros::{wrap_clone, wrap_fields, wrap_free, wrap_functions}, mem::{heap_move_nonnull, heap_move_ok, heap_remove}, }; use servicepoint::{Bitmap, BitmapCommand, CompressionCode, Origin, Packet}; use std::ptr::NonNull; -/// Sets a window of pixels to the specified values. -/// -/// The passed [Bitmap] gets consumed. -/// -/// Returns: a new [BitmapCommand] instance. -#[no_mangle] -pub unsafe extern "C" fn sp_cmd_bitmap_new( - bitmap: NonNull, - origin_x: usize, - origin_y: usize, - compression: CompressionCode, -) -> NonNull { - heap_move_nonnull(BitmapCommand { - bitmap: unsafe { heap_remove(bitmap) }, - origin: Origin::new(origin_x, origin_y), - compression, - }) -} +wrap_functions!(sp_cmd_bitmap; -/// Move the provided [Bitmap] into a new [BitmapCommand], -/// leaving other fields as their default values. -/// -/// Rust equivalent: `BitmapCommand::from(bitmap)` -#[no_mangle] -pub unsafe extern "C" fn sp_cmd_bitmap_from_bitmap( - bitmap: NonNull, -) -> NonNull { - heap_move_nonnull(unsafe { heap_remove(bitmap) }.into()) -} + /// Sets a window of pixels to the specified values. + /// + /// The passed [Bitmap] gets consumed. + /// + /// Returns: a new [BitmapCommand] instance. + fn new( + bitmap: NonNull, + origin_x: usize, + origin_y: usize, + compression: CompressionCode, + ) -> NonNull { + heap_move_nonnull(BitmapCommand { + bitmap: unsafe { heap_remove(bitmap) }, + origin: Origin::new(origin_x, origin_y), + compression, + }) + } -/// Tries to turn a [BitmapCommand] into a [Packet]. -/// -/// Returns: NULL or a [Packet] containing the command. -#[no_mangle] -pub unsafe extern "C" fn sp_cmd_bitmap_try_into_packet( - command: NonNull, -) -> *mut Packet { - heap_move_ok(unsafe { heap_remove(command) }.try_into()) -} + /// Move the provided [Bitmap] into a new [BitmapCommand], + /// leaving other fields as their default values. + /// + /// Rust equivalent: `BitmapCommand::from(bitmap)` + fn from_bitmap( + bitmap: NonNull, + ) -> NonNull { + heap_move_nonnull(unsafe { heap_remove(bitmap) }.into()) + } + + /// Tries to turn a [BitmapCommand] into a [Packet]. + /// + /// Returns: NULL or a [Packet] containing the command. + fn try_into_packet( + command: NonNull, + ) -> *mut Packet { + heap_move_ok(unsafe { heap_remove(command) }.try_into()) + } + +); wrap_clone!(sp_cmd_bitmap::BitmapCommand); wrap_free!(sp_cmd_bitmap::BitmapCommand); diff --git a/src/commands/bitvec_command.rs b/src/commands/bitvec_command.rs index 7ccbf31..7dfed38 100644 --- a/src/commands/bitvec_command.rs +++ b/src/commands/bitvec_command.rs @@ -1,5 +1,5 @@ use crate::{ - macros::{wrap_clone, wrap_fields, wrap_free}, + macros::{wrap_clone, wrap_fields, wrap_free, wrap_functions}, mem::{heap_move_nonnull, heap_move_ok, heap_remove}, }; use servicepoint::{ @@ -8,42 +8,44 @@ use servicepoint::{ }; use std::ptr::NonNull; -/// Set pixel data starting at the pixel offset on screen. -/// -/// The screen will continuously overwrite more pixel data without regarding the offset, meaning -/// once the starting row is full, overwriting will continue on column 0. -/// -/// The [`BinaryOperation`] will be applied on the display comparing old and sent bit. -/// -/// `new_bit = old_bit op sent_bit` -/// -/// For example, [`BinaryOperation::Or`] can be used to turn on some pixels without affecting other pixels. -/// -/// The contained [`DisplayBitVec`] is always uncompressed. -#[no_mangle] -pub unsafe extern "C" fn sp_cmd_bitvec_new( - bitvec: NonNull, - offset: usize, - operation: BinaryOperation, - compression: CompressionCode, -) -> NonNull { - heap_move_nonnull(BitVecCommand { - bitvec: unsafe { heap_remove(bitvec) }, - offset, - operation, - compression, - }) -} +wrap_functions!(sp_cmd_bitvec; -/// Tries to turn a [BitVecCommand] into a [Packet]. -/// -/// Returns: NULL or a [Packet] containing the command. -#[no_mangle] -pub unsafe extern "C" fn sp_cmd_bitvec_try_into_packet( - command: NonNull, -) -> *mut Packet { - heap_move_ok(unsafe { heap_remove(command) }.try_into()) -} + /// Set pixel data starting at the pixel offset on screen. + /// + /// The screen will continuously overwrite more pixel data without regarding the offset, meaning + /// once the starting row is full, overwriting will continue on column 0. + /// + /// The [`BinaryOperation`] will be applied on the display comparing old and sent bit. + /// + /// `new_bit = old_bit op sent_bit` + /// + /// For example, [`BinaryOperation::Or`] can be used to turn on some pixels without affecting other pixels. + /// + /// The contained [`DisplayBitVec`] is always uncompressed. + fn new( + bitvec: NonNull, + offset: usize, + operation: BinaryOperation, + compression: CompressionCode, + ) -> NonNull { + heap_move_nonnull(BitVecCommand { + bitvec: unsafe { heap_remove(bitvec) }, + offset, + operation, + compression, + }) + } + + /// Tries to turn a [BitVecCommand] into a [Packet]. + /// + /// Returns: NULL or a [Packet] containing the command. + fn try_into_packet( + command: NonNull, + ) -> *mut Packet { + heap_move_ok(unsafe { heap_remove(command) }.try_into()) + } + +); wrap_clone!(sp_cmd_bitvec::BitVecCommand); wrap_free!(sp_cmd_bitvec::BitVecCommand); diff --git a/src/commands/brightness_grid_command.rs b/src/commands/brightness_grid_command.rs index 9c5069e..b4e6e23 100644 --- a/src/commands/brightness_grid_command.rs +++ b/src/commands/brightness_grid_command.rs @@ -1,45 +1,46 @@ use crate::{ - macros::{wrap_clone, wrap_free}, + macros::{wrap_clone, wrap_free, wrap_functions}, mem::{heap_move_nonnull, heap_move_ok, heap_remove}, }; use servicepoint::{BrightnessGrid, BrightnessGridCommand, Origin, Packet}; use std::ptr::NonNull; -/// Set the brightness of individual tiles in a rectangular area of the display. -/// -/// The passed [BrightnessGrid] gets consumed. -/// -/// Returns: a new [BrightnessGridCommand] instance. -#[no_mangle] -pub unsafe extern "C" fn sp_cmd_brightness_grid_new( - grid: NonNull, - origin_x: usize, - origin_y: usize, -) -> NonNull { - heap_move_nonnull(BrightnessGridCommand { - grid: unsafe { heap_remove(grid) }, - origin: Origin::new(origin_x, origin_y), - }) -} +wrap_functions!(sp_cmd_brightness_grid; -/// Moves the provided [BrightnessGrid] into a new [BrightnessGridCommand], -/// leaving other fields as their default values. -#[no_mangle] -pub unsafe extern "C" fn sp_cmd_brightness_grid_from_grid( - grid: NonNull, -) -> NonNull { - heap_move_nonnull(unsafe { heap_remove(grid) }.into()) -} + /// Set the brightness of individual tiles in a rectangular area of the display. + /// + /// The passed [BrightnessGrid] gets consumed. + /// + /// Returns: a new [BrightnessGridCommand] instance. + fn new( + grid: NonNull, + origin_x: usize, + origin_y: usize, + ) -> NonNull { + heap_move_nonnull(BrightnessGridCommand { + grid: unsafe { heap_remove(grid) }, + origin: Origin::new(origin_x, origin_y), + }) + } -/// Tries to turn a [BrightnessGridCommand] into a [Packet]. -/// -/// Returns: NULL or a [Packet] containing the command. -#[no_mangle] -pub unsafe extern "C" fn sp_cmd_brightness_grid_into_packet( - command: NonNull, -) -> *mut Packet { - heap_move_ok(unsafe { heap_remove(command) }.try_into()) -} + /// Moves the provided [BrightnessGrid] into a new [BrightnessGridCommand], + /// leaving other fields as their default values. + fn from_grid( + grid: NonNull, + ) -> NonNull { + heap_move_nonnull(unsafe { heap_remove(grid) }.into()) + } + + /// Tries to turn a [BrightnessGridCommand] into a [Packet]. + /// + /// Returns: NULL or a [Packet] containing the command. + fn into_packet( + command: NonNull, + ) -> *mut Packet { + heap_move_ok(unsafe { heap_remove(command) }.try_into()) + } + +); wrap_clone!(sp_cmd_brightness_grid::BrightnessGridCommand); wrap_free!(sp_cmd_brightness_grid::BrightnessGridCommand); diff --git a/src/commands/cc_only_commands.rs b/src/commands/cc_only_commands.rs index fc73303..234b781 100644 --- a/src/commands/cc_only_commands.rs +++ b/src/commands/cc_only_commands.rs @@ -1,37 +1,43 @@ -use crate::{macros::wrap_free, mem::heap_move_nonnull}; +use crate::{ + macros::{wrap_free, wrap_functions}, + mem::heap_move_nonnull, +}; use servicepoint::{ClearCommand, FadeOutCommand, HardResetCommand}; use std::ptr::NonNull; -/// Set all pixels to the off state. -/// -/// Does not affect brightness. -/// -/// Returns: a new [ClearCommand] instance. -#[no_mangle] -pub unsafe extern "C" fn sp_cmd_clear_new() -> NonNull { - heap_move_nonnull(ClearCommand) -} +wrap_functions!(sp_cmd_clear; + /// Set all pixels to the off state. + /// + /// Does not affect brightness. + /// + /// Returns: a new [ClearCommand] instance. + fn new() -> NonNull { + heap_move_nonnull(ClearCommand) + } +); wrap_free!(sp_cmd_clear::ClearCommand); -/// Kills the udp daemon on the display, which usually results in a restart. -/// -/// Please do not send this in your normal program flow. -/// -/// Returns: a new [HardResetCommand] instance. -#[no_mangle] -pub unsafe extern "C" fn sp_cmd_hard_reset_new() -> NonNull { - heap_move_nonnull(HardResetCommand) -} +wrap_functions!(sp_cmd_hard_reset; + /// Kills the udp daemon on the display, which usually results in a restart. + /// + /// Please do not send this in your normal program flow. + /// + /// Returns: a new [HardResetCommand] instance. + fn new() -> NonNull { + heap_move_nonnull(HardResetCommand) + } +); wrap_free!(sp_cmd_hard_reset::HardResetCommand); -/// A yet-to-be-tested command. -/// -/// Returns: a new [FadeOutCommand] instance. -#[no_mangle] -pub unsafe extern "C" fn sp_cmd_fade_out_new() -> NonNull { - heap_move_nonnull(FadeOutCommand) -} +wrap_functions!(sp_cmd_fade_out; + /// A yet-to-be-tested command. + /// + /// Returns: a new [FadeOutCommand] instance. + fn new() -> NonNull { + heap_move_nonnull(FadeOutCommand) + } +); wrap_free!(sp_cmd_fade_out::FadeOutCommand); diff --git a/src/commands/char_grid_command.rs b/src/commands/char_grid_command.rs index b895718..0ef90c0 100644 --- a/src/commands/char_grid_command.rs +++ b/src/commands/char_grid_command.rs @@ -1,45 +1,46 @@ use crate::{ - macros::{wrap_clone, wrap_free}, + macros::{wrap_clone, wrap_free, wrap_functions}, mem::{heap_move_nonnull, heap_move_ok, heap_remove}, }; use servicepoint::{CharGrid, CharGridCommand, Origin, Packet}; use std::ptr::NonNull; -/// Show UTF-8 encoded text on the screen. -/// -/// The passed [CharGrid] gets consumed. -/// -/// Returns: a new [CharGridCommand] instance. -#[no_mangle] -pub unsafe extern "C" fn sp_cmd_char_grid_new( - grid: NonNull, - origin_x: usize, - origin_y: usize, -) -> NonNull { - heap_move_nonnull(CharGridCommand { - grid: unsafe { heap_remove(grid) }, - origin: Origin::new(origin_x, origin_y), - }) -} +wrap_functions!(sp_cmd_char_grid; -/// Moves the provided [CharGrid] into a new [CharGridCommand], -/// leaving other fields as their default values. -#[no_mangle] -pub unsafe extern "C" fn sp_cmd_char_grid_from_grid( - grid: NonNull, -) -> NonNull { - heap_move_nonnull(unsafe { heap_remove(grid) }.into()) -} + /// Show UTF-8 encoded text on the screen. + /// + /// The passed [CharGrid] gets consumed. + /// + /// Returns: a new [CharGridCommand] instance. + fn new( + grid: NonNull, + origin_x: usize, + origin_y: usize, + ) -> NonNull { + heap_move_nonnull(CharGridCommand { + grid: unsafe { heap_remove(grid) }, + origin: Origin::new(origin_x, origin_y), + }) + } -/// Tries to turn a [CharGridCommand] into a [Packet]. -/// -/// Returns: NULL or a [Packet] containing the command. -#[no_mangle] -pub unsafe extern "C" fn sp_cmd_char_grid_try_into_packet( - command: NonNull, -) -> *mut Packet { - heap_move_ok(unsafe { heap_remove(command) }.try_into()) -} + /// Moves the provided [CharGrid] into a new [CharGridCommand], + /// leaving other fields as their default values. + fn from_grid( + grid: NonNull, + ) -> NonNull { + heap_move_nonnull(unsafe { heap_remove(grid) }.into()) + } + + /// Tries to turn a [CharGridCommand] into a [Packet]. + /// + /// Returns: NULL or a [Packet] containing the command. + fn try_into_packet( + command: NonNull, + ) -> *mut Packet { + heap_move_ok(unsafe { heap_remove(command) }.try_into()) + } + +); wrap_clone!(sp_cmd_char_grid::CharGridCommand); wrap_free!(sp_cmd_char_grid::CharGridCommand); @@ -59,8 +60,8 @@ pub unsafe extern "C" fn sp_cmd_char_grid_set( #[no_mangle] pub unsafe extern "C" fn sp_cmd_char_grid_get( mut command: NonNull, -) -> *mut CharGrid { - unsafe { &mut command.as_mut().grid } +) -> NonNull { + unsafe { NonNull::from(&mut command.as_mut().grid) } } /// Reads the origin field of the [CharGridCommand]. diff --git a/src/commands/cp437_grid_command.rs b/src/commands/cp437_grid_command.rs index 3f1fa9f..da8380a 100644 --- a/src/commands/cp437_grid_command.rs +++ b/src/commands/cp437_grid_command.rs @@ -1,45 +1,46 @@ use crate::{ - macros::{wrap_clone, wrap_free}, + macros::{wrap_clone, wrap_free, wrap_functions}, mem::{heap_move_nonnull, heap_move_ok, heap_remove}, }; use servicepoint::{Cp437Grid, Cp437GridCommand, Origin, Packet}; use std::ptr::NonNull; -/// Show text on the screen. -/// -/// The text is sent in the form of a 2D grid of [CP-437] encoded characters. -/// -/// The origin is relative to the top-left of the display. -#[no_mangle] -pub unsafe extern "C" fn sp_cmd_cp437_grid_new( - grid: NonNull, - origin_x: usize, - origin_y: usize, -) -> NonNull { - heap_move_nonnull(Cp437GridCommand { - grid: unsafe { heap_remove(grid) }, - origin: Origin::new(origin_x, origin_y), - }) -} +wrap_functions!(sp_cmd_cp437_grid; -/// Moves the provided [Cp437Grid] into a new [Cp437GridCommand], -/// leaving other fields as their default values. -#[no_mangle] -pub unsafe extern "C" fn sp_cmd_cp437_grid_from_grid( - grid: NonNull, -) -> NonNull { - heap_move_nonnull(unsafe { heap_remove(grid) }.into()) -} + /// Show text on the screen. + /// + /// The text is sent in the form of a 2D grid of [CP-437] encoded characters. + /// + /// The origin is relative to the top-left of the display. + fn new( + grid: NonNull, + origin_x: usize, + origin_y: usize, + ) -> NonNull { + heap_move_nonnull(Cp437GridCommand { + grid: unsafe { heap_remove(grid) }, + origin: Origin::new(origin_x, origin_y), + }) + } -/// Tries to turn a [Cp437GridCommand] into a [Packet]. -/// -/// Returns: NULL or a [Packet] containing the command. -#[no_mangle] -pub unsafe extern "C" fn sp_cmd_cp437_grid_try_into_packet( - command: NonNull, -) -> *mut Packet { - heap_move_ok(unsafe { heap_remove(command) }.try_into()) -} + /// Moves the provided [Cp437Grid] into a new [Cp437GridCommand], + /// leaving other fields as their default values. + fn from_grid( + grid: NonNull, + ) -> NonNull { + heap_move_nonnull(unsafe { heap_remove(grid) }.into()) + } + + /// Tries to turn a [Cp437GridCommand] into a [Packet]. + /// + /// Returns: NULL or a [Packet] containing the command. + fn try_into_packet( + command: NonNull, + ) -> *mut Packet { + heap_move_ok(unsafe { heap_remove(command) }.try_into()) + } + +); wrap_clone!(sp_cmd_cp437_grid::Cp437GridCommand); wrap_free!(sp_cmd_cp437_grid::Cp437GridCommand); diff --git a/src/commands/global_brightness_command.rs b/src/commands/global_brightness_command.rs index e695ef0..35bcbe0 100644 --- a/src/commands/global_brightness_command.rs +++ b/src/commands/global_brightness_command.rs @@ -1,26 +1,25 @@ use crate::{ - macros::{wrap_clone, wrap_fields, wrap_free}, + macros::{wrap_clone, wrap_fields, wrap_free, wrap_functions}, mem::{heap_move_nonnull, heap_remove}, }; use servicepoint::{Brightness, GlobalBrightnessCommand, Packet}; use std::ptr::NonNull; -/// Set the brightness of all tiles to the same value. -/// -/// Returns: a new [GlobalBrightnessCommand] instance. -#[no_mangle] -pub unsafe extern "C" fn sp_cmd_brightness_global_new( - brightness: Brightness, -) -> NonNull { - heap_move_nonnull(GlobalBrightnessCommand::from(brightness)) -} +wrap_functions!(sp_cmd_brightness_global; -#[no_mangle] -pub unsafe extern "C" fn sp_cmd_brightness_global_into_packet( - command: NonNull, -) -> NonNull { - heap_move_nonnull(unsafe { heap_remove(command) }.into()) -} + /// Set the brightness of all tiles to the same value. + /// + /// Returns: a new [GlobalBrightnessCommand] instance. + fn new(brightness: Brightness) -> NonNull { + heap_move_nonnull(GlobalBrightnessCommand::from(brightness)) + } + + /// Turns the command into a packet + fn into_packet(command: NonNull) -> NonNull { + heap_move_nonnull(unsafe { heap_remove(command) }.into()) + } + +); wrap_clone!(sp_cmd_brightness_global::GlobalBrightnessCommand); wrap_free!(sp_cmd_brightness_global::GlobalBrightnessCommand); diff --git a/src/containers/bitmap.rs b/src/containers/bitmap.rs index ae0d2ae..6d502d9 100644 --- a/src/containers/bitmap.rs +++ b/src/containers/bitmap.rs @@ -1,6 +1,6 @@ use crate::{ containers::ByteSlice, - macros::{wrap_clone, wrap_free, wrap_methods}, + macros::{wrap_clone, wrap_free, wrap_functions, wrap_methods}, mem::{heap_move_nonnull, heap_move_ok, heap_move_some, heap_remove}, }; use servicepoint::{ @@ -9,80 +9,102 @@ use servicepoint::{ }; use std::ptr::NonNull; -/// Creates a new [Bitmap] with the specified dimensions. -/// -/// # Arguments -/// -/// - `width`: size in pixels in x-direction -/// - `height`: size in pixels in y-direction -/// -/// returns: [Bitmap] initialized to all pixels off, or NULL in case of an error. -/// -/// # Errors -/// -/// In the following cases, this function will return NULL: -/// -/// - when the width is not dividable by 8 -/// -/// # Examples -/// -/// ```C -/// Cp437Grid grid = sp_bitmap_new(8, 3); -/// sp_bitmap_fill(grid, true); -/// sp_bitmap_set(grid, 0, 0, false); -/// sp_bitmap_free(grid); -/// ``` -#[no_mangle] -pub unsafe extern "C" fn sp_bitmap_new( - width: usize, - height: usize, -) -> *mut Bitmap { - heap_move_some(Bitmap::new(width, height)) -} - -/// Creates a new [Bitmap] with a size matching the screen. -/// -/// returns: [Bitmap] initialized to all pixels off. -#[no_mangle] -pub unsafe extern "C" fn sp_bitmap_new_max_sized() -> NonNull { - heap_move_nonnull(Bitmap::max_sized()) -} - -/// Loads a [Bitmap] with the specified dimensions from the provided data. -/// -/// # Arguments -/// -/// - `width`: size in pixels in x-direction -/// - `height`: size in pixels in y-direction -/// -/// returns: [Bitmap] that contains a copy of the provided data, or NULL in case of an error. -#[no_mangle] -pub unsafe extern "C" fn sp_bitmap_load( - width: usize, - height: usize, - data: ByteSlice, -) -> *mut Bitmap { - let data = unsafe { data.as_slice() }; - heap_move_ok(Bitmap::load(width, height, data)) -} - -/// Tries to convert the BitVec to a Bitmap. -/// -/// The provided BitVec gets consumed. -/// -/// Returns NULL in case of error. -#[no_mangle] -pub unsafe extern "C" fn sp_bitmap_from_bitvec( - width: usize, - bitvec: NonNull, -) -> *mut Bitmap { - let bitvec = unsafe { heap_remove(bitvec) }; - heap_move_ok(Bitmap::from_bitvec(width, bitvec)) -} - wrap_clone!(sp_bitmap::Bitmap); wrap_free!(sp_bitmap::Bitmap); +wrap_functions!(sp_bitmap; + + /// Creates a new [Bitmap] with the specified dimensions. + /// + /// # Arguments + /// + /// - `width`: size in pixels in x-direction + /// - `height`: size in pixels in y-direction + /// + /// returns: [Bitmap] initialized to all pixels off, or NULL in case of an error. + /// + /// # Errors + /// + /// In the following cases, this function will return NULL: + /// + /// - when the width is not dividable by 8 + /// + /// # Examples + /// + /// ```C + /// Cp437Grid grid = sp_bitmap_new(8, 3); + /// sp_bitmap_fill(grid, true); + /// sp_bitmap_set(grid, 0, 0, false); + /// sp_bitmap_free(grid); + /// ``` + fn new(width: usize, height: usize) -> *mut Bitmap { + heap_move_some(Bitmap::new(width, height)) + } + + /// Creates a new [Bitmap] with a size matching the screen. + /// + /// returns: [Bitmap] initialized to all pixels off. + fn new_max_sized() -> NonNull { + heap_move_nonnull(Bitmap::max_sized()) + } + + /// Loads a [Bitmap] with the specified dimensions from the provided data. + /// + /// # Arguments + /// + /// - `width`: size in pixels in x-direction + /// - `height`: size in pixels in y-direction + /// + /// returns: [Bitmap] that contains a copy of the provided data, or NULL in case of an error. + fn load( + width: usize, + height: usize, + data: ByteSlice, + ) -> *mut Bitmap { + let data = unsafe { data.as_slice() }; + heap_move_ok(Bitmap::load(width, height, data)) + } + + /// Tries to convert the BitVec to a Bitmap. + /// + /// The provided BitVec gets consumed. + /// + /// Returns NULL in case of error. + fn from_bitvec( + width: usize, + bitvec: NonNull, + ) -> *mut Bitmap { + let bitvec = unsafe { heap_remove(bitvec) }; + heap_move_ok(Bitmap::from_bitvec(width, bitvec)) + } + /// Consumes the Bitmap and returns the contained BitVec. + fn into_bitvec( + bitmap: NonNull + ) -> NonNull { + let bitmap = unsafe { heap_remove(bitmap) }; + heap_move_nonnull(bitmap.into()) + } + + /// Creates a [BitmapCommand] and immediately turns that into a [Packet]. + /// + /// The provided [Bitmap] gets consumed. + /// + /// Returns NULL in case of an error. + fn into_packet( + bitmap: NonNull, + x: usize, + y: usize, + compression: CompressionCode, + ) -> *mut Packet { + let bitmap = unsafe { heap_remove(bitmap) }; + heap_move_ok(Packet::try_from(BitmapCommand { + bitmap, + origin: Origin::new(x, y), + compression, + })) + } +); + wrap_methods!( sp_bitmap::Bitmap; @@ -130,32 +152,3 @@ wrap_methods!( return(slice) { unsafe { ByteSlice::from_slice(slice) } }; }; ); - -/// Consumes the Bitmap and returns the contained BitVec. -#[no_mangle] -pub unsafe extern "C" fn sp_bitmap_into_bitvec( - bitmap: NonNull, -) -> NonNull { - let bitmap = unsafe { heap_remove(bitmap) }; - heap_move_nonnull(bitmap.into()) -} - -/// Creates a [BitmapCommand] and immediately turns that into a [Packet]. -/// -/// The provided [Bitmap] gets consumed. -/// -/// Returns NULL in case of an error. -#[no_mangle] -pub unsafe extern "C" fn sp_bitmap_into_packet( - bitmap: NonNull, - x: usize, - y: usize, - compression: CompressionCode, -) -> *mut Packet { - let bitmap = unsafe { heap_remove(bitmap) }; - heap_move_ok(Packet::try_from(BitmapCommand { - bitmap, - origin: Origin::new(x, y), - compression, - })) -} diff --git a/src/containers/bitvec.rs b/src/containers/bitvec.rs index 76d716a..e232ab5 100644 --- a/src/containers/bitvec.rs +++ b/src/containers/bitvec.rs @@ -1,6 +1,6 @@ use crate::{ containers::ByteSlice, - macros::{wrap_clone, wrap_free, wrap_methods}, + macros::{wrap_clone, wrap_free, wrap_functions, wrap_methods}, mem::{heap_move_nonnull, heap_move_ok, heap_remove}, }; use servicepoint::{ @@ -8,32 +8,52 @@ use servicepoint::{ }; use std::ptr::NonNull; -/// Creates a new [DisplayBitVec] instance. -/// -/// # Arguments -/// -/// - `size`: size in bits. -/// -/// returns: [DisplayBitVec] with all bits set to false. -/// -/// # Panics -/// -/// - when `size` is not divisible by 8. -#[no_mangle] -pub unsafe extern "C" fn sp_bitvec_new(size: usize) -> NonNull { - heap_move_nonnull(DisplayBitVec::repeat(false, size)) -} +wrap_functions!(sp_bitvec; -/// Interpret the data as a series of bits and load then into a new [DisplayBitVec] instance. -/// -/// returns: [DisplayBitVec] instance containing data. -#[no_mangle] -pub unsafe extern "C" fn sp_bitvec_load( - data: ByteSlice, -) -> NonNull { - let data = unsafe { data.as_slice() }; - heap_move_nonnull(DisplayBitVec::from_slice(data)) -} + /// Creates a new [DisplayBitVec] instance. + /// + /// # Arguments + /// + /// - `size`: size in bits. + /// + /// returns: [DisplayBitVec] with all bits set to false. + /// + /// # Panics + /// + /// - when `size` is not divisible by 8. + fn new(size: usize) -> NonNull { + heap_move_nonnull(DisplayBitVec::repeat(false, size)) + } + + /// Interpret the data as a series of bits and load then into a new [DisplayBitVec] instance. + /// + /// returns: [DisplayBitVec] instance containing data. + fn load(data: ByteSlice) -> NonNull { + let data = unsafe { data.as_slice() }; + heap_move_nonnull(DisplayBitVec::from_slice(data)) + } + + /// Creates a [BitVecCommand] and immediately turns that into a [Packet]. + /// + /// The provided [DisplayBitVec] gets consumed. + /// + /// Returns NULL in case of an error. + fn into_packet( + bitvec: NonNull, + offset: usize, + operation: BinaryOperation, + compression: CompressionCode, + ) -> *mut Packet { + let bitvec = unsafe { heap_remove(bitvec) }; + heap_move_ok(Packet::try_from(BitVecCommand { + bitvec, + offset, + operation, + compression, + })) + } + +); wrap_clone!(sp_bitvec::DisplayBitVec); wrap_free!(sp_bitvec::DisplayBitVec); @@ -90,24 +110,3 @@ wrap_methods!( return(slice) { unsafe { ByteSlice::from_slice(slice) } }; }; ); - -/// Creates a [BitVecCommand] and immediately turns that into a [Packet]. -/// -/// The provided [DisplayBitVec] gets consumed. -/// -/// Returns NULL in case of an error. -#[no_mangle] -pub unsafe extern "C" fn sp_bitvec_into_packet( - bitvec: NonNull, - offset: usize, - operation: BinaryOperation, - compression: CompressionCode, -) -> *mut Packet { - let bitvec = unsafe { heap_remove(bitvec) }; - heap_move_ok(Packet::try_from(BitVecCommand { - bitvec, - offset, - operation, - compression, - })) -} diff --git a/src/containers/brightness_grid.rs b/src/containers/brightness_grid.rs index a3590b8..2374b47 100644 --- a/src/containers/brightness_grid.rs +++ b/src/containers/brightness_grid.rs @@ -1,3 +1,4 @@ +use crate::macros::wrap_functions; use crate::{ containers::ByteSlice, macros::{wrap_clone, wrap_free, wrap_methods}, @@ -9,48 +10,67 @@ use servicepoint::{ }; use std::{mem::transmute, ptr::NonNull}; -/// Creates a new [BrightnessGrid] with the specified dimensions. -/// -/// returns: [BrightnessGrid] initialized to 0. -/// -/// # Examples -/// ```C -/// UdpSocket *connection = sp_udp_open("127.0.0.1:2342"); -/// if (connection == NULL) -/// return 1; -/// -/// BrightnessGrid *grid = sp_brightness_grid_new(2, 2); -/// sp_brightness_grid_set(grid, 0, 0, 0); -/// sp_brightness_grid_set(grid, 1, 1, 10); -/// -/// TypedCommand *command = sp_command_char_brightness(grid); -/// sp_udp_free(connection); -/// ``` -#[no_mangle] -pub unsafe extern "C" fn sp_brightness_grid_new( - width: usize, - height: usize, -) -> NonNull { - heap_move_nonnull(BrightnessGrid::new(width, height)) -} +wrap_functions!(sp_brightness_grid; -/// Loads a [BrightnessGrid] with the specified dimensions from the provided data. -/// -/// Any out of range values will be set to [Brightness::MAX] or [Brightness::MIN]. -/// -/// returns: new [BrightnessGrid] instance, or NULL in case of an error. -#[no_mangle] -pub unsafe extern "C" fn sp_brightness_grid_load( - width: usize, - height: usize, - data: ByteSlice, -) -> *mut BrightnessGrid { - let data = unsafe { data.as_slice() }; - heap_move_some( - ByteGrid::load(width, height, data) - .map(move |grid| grid.map(Brightness::saturating_from)), - ) -} + /// Creates a new [BrightnessGrid] with the specified dimensions. + /// + /// returns: [BrightnessGrid] initialized to 0. + /// + /// # Examples + /// ```C + /// UdpSocket *connection = sp_udp_open("127.0.0.1:2342"); + /// if (connection == NULL) + /// return 1; + /// + /// BrightnessGrid *grid = sp_brightness_grid_new(2, 2); + /// sp_brightness_grid_set(grid, 0, 0, 0); + /// sp_brightness_grid_set(grid, 1, 1, 10); + /// + /// TypedCommand *command = sp_command_char_brightness(grid); + /// sp_udp_free(connection); + /// ``` + fn new( + width: usize, + height: usize, + ) -> NonNull { + heap_move_nonnull(BrightnessGrid::new(width, height)) + } + + /// Loads a [BrightnessGrid] with the specified dimensions from the provided data. + /// + /// Any out of range values will be set to [Brightness::MAX] or [Brightness::MIN]. + /// + /// returns: new [BrightnessGrid] instance, or NULL in case of an error. + fn load( + width: usize, + height: usize, + data: ByteSlice, + ) -> *mut BrightnessGrid { + let data = unsafe { data.as_slice() }; + heap_move_some( + ByteGrid::load(width, height, data) + .map(move |grid| grid.map(Brightness::saturating_from)), + ) + } + + /// Creates a [BrightnessGridCommand] and immediately turns that into a [Packet]. + /// + /// The provided [BrightnessGrid] gets consumed. + /// + /// Returns NULL in case of an error. + fn into_packet( + grid: NonNull, + x: usize, + y: usize, + ) -> *mut Packet { + let grid = unsafe { heap_remove(grid) }; + heap_move_ok(Packet::try_from(BrightnessGridCommand { + grid, + origin: Origin::new(x, y), + })) + } + +); wrap_clone!(sp_brightness_grid::BrightnessGrid); wrap_free!(sp_brightness_grid::BrightnessGrid); @@ -109,21 +129,3 @@ wrap_methods!( }}; }; ); - -/// Creates a [BrightnessGridCommand] and immediately turns that into a [Packet]. -/// -/// The provided [BrightnessGrid] gets consumed. -/// -/// Returns NULL in case of an error. -#[no_mangle] -pub unsafe extern "C" fn sp_brightness_grid_into_packet( - grid: NonNull, - x: usize, - y: usize, -) -> *mut Packet { - let grid = unsafe { heap_remove(grid) }; - heap_move_ok(Packet::try_from(BrightnessGridCommand { - grid, - origin: Origin::new(x, y), - })) -} diff --git a/src/containers/char_grid.rs b/src/containers/char_grid.rs index 1b70202..782e2aa 100644 --- a/src/containers/char_grid.rs +++ b/src/containers/char_grid.rs @@ -1,43 +1,62 @@ use crate::{ containers::ByteSlice, - macros::{wrap_clone, wrap_free, wrap_methods}, + macros::{wrap_clone, wrap_free, wrap_functions, wrap_methods}, mem::{heap_move_nonnull, heap_move_ok, heap_remove}, }; use servicepoint::{CharGrid, CharGridCommand, Grid, Origin, Packet}; use std::ptr::NonNull; -/// Creates a new [CharGrid] with the specified dimensions. -/// -/// returns: [CharGrid] initialized to 0. -/// -/// # Examples -/// -/// ```C -/// CharGrid grid = sp_char_grid_new(4, 3); -/// sp_char_grid_fill(grid, '?'); -/// sp_char_grid_set(grid, 0, 0, '!'); -/// sp_char_grid_free(grid); -/// ``` -#[no_mangle] -pub unsafe extern "C" fn sp_char_grid_new( - width: usize, - height: usize, -) -> NonNull { - heap_move_nonnull(CharGrid::new(width, height)) -} +wrap_functions!(sp_char_grid; -/// Loads a [CharGrid] with the specified dimensions from the provided data. -/// -/// returns: new CharGrid or NULL in case of an error -#[no_mangle] -pub unsafe extern "C" fn sp_char_grid_load( - width: usize, - height: usize, - data: ByteSlice, -) -> *mut CharGrid { - let data = unsafe { data.as_slice() }; - heap_move_ok(CharGrid::load_utf8(width, height, data.to_vec())) -} + /// Creates a new [CharGrid] with the specified dimensions. + /// + /// returns: [CharGrid] initialized to 0. + /// + /// # Examples + /// + /// ```C + /// CharGrid grid = sp_char_grid_new(4, 3); + /// sp_char_grid_fill(grid, '?'); + /// sp_char_grid_set(grid, 0, 0, '!'); + /// sp_char_grid_free(grid); + /// ``` + fn new( + width: usize, + height: usize, + ) -> NonNull { + heap_move_nonnull(CharGrid::new(width, height)) + } + + /// Loads a [CharGrid] with the specified dimensions from the provided data. + /// + /// returns: new CharGrid or NULL in case of an error + fn load( + width: usize, + height: usize, + data: ByteSlice, + ) -> *mut CharGrid { + let data = unsafe { data.as_slice() }; + heap_move_ok(CharGrid::load_utf8(width, height, data.to_vec())) + } + + /// Creates a [CharGridCommand] and immediately turns that into a [Packet]. + /// + /// The provided [CharGrid] gets consumed. + /// + /// Returns NULL in case of an error. + fn into_packet( + grid: NonNull, + x: usize, + y: usize, + ) -> *mut Packet { + let grid = unsafe { heap_remove(grid) }; + heap_move_ok(Packet::try_from(CharGridCommand { + grid, + origin: Origin::new(x, y), + })) + } + +); wrap_clone!(sp_char_grid::CharGrid); wrap_free!(sp_char_grid::CharGrid); @@ -91,21 +110,3 @@ wrap_methods!( /// Gets the height of the grid. ref fn height() -> usize; ); - -/// Creates a [CharGridCommand] and immediately turns that into a [Packet]. -/// -/// The provided [CharGrid] gets consumed. -/// -/// Returns NULL in case of an error. -#[no_mangle] -pub unsafe extern "C" fn sp_char_grid_into_packet( - grid: NonNull, - x: usize, - y: usize, -) -> *mut Packet { - let grid = unsafe { heap_remove(grid) }; - heap_move_ok(Packet::try_from(CharGridCommand { - grid, - origin: Origin::new(x, y), - })) -} diff --git a/src/containers/cp437_grid.rs b/src/containers/cp437_grid.rs index d6ae17f..2ed9aba 100644 --- a/src/containers/cp437_grid.rs +++ b/src/containers/cp437_grid.rs @@ -1,3 +1,4 @@ +use crate::macros::wrap_functions; use crate::{ containers::ByteSlice, macros::{wrap_clone, wrap_free, wrap_methods}, @@ -8,27 +9,46 @@ use servicepoint::{ }; use std::ptr::NonNull; -/// Creates a new [Cp437Grid] with the specified dimensions. -/// -/// returns: [Cp437Grid] initialized to 0. -#[no_mangle] -pub unsafe extern "C" fn sp_cp437_grid_new( - width: usize, - height: usize, -) -> NonNull { - heap_move_nonnull(Cp437Grid::new(width, height)) -} +wrap_functions!(sp_cp437_grid; -/// Loads a [Cp437Grid] with the specified dimensions from the provided data. -#[no_mangle] -pub unsafe extern "C" fn sp_cp437_grid_load( - width: usize, - height: usize, - data: ByteSlice, -) -> *mut Cp437Grid { - let data = unsafe { data.as_slice() }; - heap_move_some(Cp437Grid::load(width, height, data)) -} + /// Creates a new [Cp437Grid] with the specified dimensions. + /// + /// returns: [Cp437Grid] initialized to 0. + fn new( + width: usize, + height: usize, + ) -> NonNull { + heap_move_nonnull(Cp437Grid::new(width, height)) + } + + /// Loads a [Cp437Grid] with the specified dimensions from the provided data. + fn load( + width: usize, + height: usize, + data: ByteSlice, + ) -> *mut Cp437Grid { + let data = unsafe { data.as_slice() }; + heap_move_some(Cp437Grid::load(width, height, data)) + } + + /// Creates a [Cp437GridCommand] and immediately turns that into a [Packet]. + /// + /// The provided [Cp437Grid] gets consumed. + /// + /// Returns NULL in case of an error. + fn into_packet( + grid: NonNull, + x: usize, + y: usize, + ) -> *mut Packet { + let grid = unsafe { heap_remove(grid) }; + heap_move_ok(Packet::try_from(Cp437GridCommand { + grid, + origin: Origin::new(x, y), + })) + } + +); wrap_clone!(sp_cp437_grid::Cp437Grid); wrap_free!(sp_cp437_grid::Cp437Grid); @@ -81,21 +101,3 @@ wrap_methods!( return(slice) { unsafe { ByteSlice::from_slice(slice) } }; }; ); - -/// Creates a [Cp437GridCommand] and immediately turns that into a [Packet]. -/// -/// The provided [Cp437Grid] gets consumed. -/// -/// Returns NULL in case of an error. -#[no_mangle] -pub unsafe extern "C" fn sp_cp437_grid_into_packet( - grid: NonNull, - x: usize, - y: usize, -) -> *mut Packet { - let grid = unsafe { heap_remove(grid) }; - heap_move_ok(Packet::try_from(Cp437GridCommand { - grid, - origin: Origin::new(x, y), - })) -} diff --git a/src/macros.rs b/src/macros.rs index cbadc14..48952db 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -47,7 +47,7 @@ macro_rules! wrap_methods { $(return($it:ident) $return_expr:block;)? })? ; - )* + )+ ) => { paste::paste! { $( @@ -76,7 +76,7 @@ macro_rules! wrap_methods { )? return result; } - )* + )+ } }; } @@ -149,7 +149,33 @@ macro_rules! wrap_fields { }; } +macro_rules! wrap_functions { + ( + $prefix:ident; + $( + $(#[$meta:meta])+ + fn $function:ident($($param_name:ident: $param_type:ty),*$(,)?) + $(-> $return_type:ty)? + $block:block + )+ + ) => { + ::paste::paste! { + $( + $(#[$meta])* + #[doc = ""] + #[doc = concat!(" This function is part of the ", stringify!($prefix), " module.")] + #[no_mangle] + pub unsafe extern "C" fn [<$prefix _ $function>]( + $($param_name: $param_type),* + ) $(-> $return_type)? + $block + + )+ + } + }; +} + pub(crate) use { nonnull_as_mut, nonnull_as_ref, wrap_clone, wrap_fields, wrap_free, - wrap_methods, + wrap_functions, wrap_methods, }; From 21987d05f37ab5696b3fbbffe794507df65f1ce9 Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Wed, 18 Jun 2025 20:41:22 +0200 Subject: [PATCH 12/12] use macros in macros --- include/servicepoint.h | 218 +++++++++++++++++++++++++++++++++-------- src/macros.rs | 141 +++++++++++++------------- 2 files changed, 248 insertions(+), 111 deletions(-) diff --git a/include/servicepoint.h b/include/servicepoint.h index 5960987..e001ddd 100644 --- a/include/servicepoint.h +++ b/include/servicepoint.h @@ -640,7 +640,9 @@ extern "C" { void init_env_logger(void); /** - *Clones a [Bitmap] instance. + *Clones a [`Bitmap`] instance. + * + * This function is part of the sp_bitmap module. */ struct Bitmap */*notnull*/ sp_bitmap_clone(struct Bitmap */*notnull*/ instance); @@ -650,6 +652,8 @@ struct Bitmap */*notnull*/ sp_bitmap_clone(struct Bitmap */*notnull*/ instance); * Gets an unsafe reference to the data of the [Bitmap] instance. * * The returned memory is valid for the lifetime of the bitmap. + * + * This function is part of the sp_bitmap module. */ struct ByteSlice sp_bitmap_data_ref_mut(struct Bitmap */*notnull*/ instance); @@ -661,11 +665,15 @@ struct ByteSlice sp_bitmap_data_ref_mut(struct Bitmap */*notnull*/ instance); * # Arguments * * - `value`: the value to set all pixels to + * + * This function is part of the sp_bitmap module. */ void sp_bitmap_fill(struct Bitmap */*notnull*/ instance, bool value); /** - *Deallocates a [Bitmap] instance. + *Deallocates a [`Bitmap`] instance. + * + * This function is part of the sp_bitmap module. */ void sp_bitmap_free(struct Bitmap */*notnull*/ instance); @@ -692,6 +700,8 @@ struct Bitmap *sp_bitmap_from_bitvec(size_t width, BitVec */*notnull*/ bitvec); * # Panics * * - when accessing `x` or `y` out of bounds + * + * This function is part of the sp_bitmap module. */ bool sp_bitmap_get(struct Bitmap */*notnull*/ instance, size_t x, size_t y); @@ -699,6 +709,8 @@ bool sp_bitmap_get(struct Bitmap */*notnull*/ instance, size_t x, size_t y); * Calls [`servicepoint::Bitmap::height`]. * * Gets the height in pixels. + * + * This function is part of the sp_bitmap module. */ size_t sp_bitmap_height(struct Bitmap */*notnull*/ instance); @@ -790,6 +802,8 @@ struct Bitmap */*notnull*/ sp_bitmap_new_max_sized(void); * # Panics * * - when accessing `x` or `y` out of bounds + * + * This function is part of the sp_bitmap module. */ void sp_bitmap_set(struct Bitmap */*notnull*/ instance, size_t x, @@ -800,6 +814,8 @@ void sp_bitmap_set(struct Bitmap */*notnull*/ instance, * Calls [`servicepoint::Bitmap::width`]. * * Gets the width in pixels. + * + * This function is part of the sp_bitmap module. */ size_t sp_bitmap_width(struct Bitmap */*notnull*/ instance); @@ -809,11 +825,15 @@ size_t sp_bitmap_width(struct Bitmap */*notnull*/ instance); * Gets an unsafe reference to the data of the [DisplayBitVec] instance. * * The returned memory is valid for the lifetime of the bitvec. + * + * This function is part of the sp_bitvec module. */ struct ByteSlice sp_bitvec_as_raw_mut_slice(BitVec */*notnull*/ instance); /** - *Clones a [DisplayBitVec] instance. + *Clones a [`DisplayBitVec`] instance. + * + * This function is part of the sp_bitvec module. */ BitVec */*notnull*/ sp_bitvec_clone(BitVec */*notnull*/ instance); @@ -825,11 +845,15 @@ BitVec */*notnull*/ sp_bitvec_clone(BitVec */*notnull*/ instance); * # Arguments * * - `value`: the value to set all bits to + * + * This function is part of the sp_bitvec module. */ void sp_bitvec_fill(BitVec */*notnull*/ instance, bool value); /** - *Deallocates a [DisplayBitVec] instance. + *Deallocates a [`DisplayBitVec`] instance. + * + * This function is part of the sp_bitvec module. */ void sp_bitvec_free(BitVec */*notnull*/ instance); @@ -848,6 +872,8 @@ void sp_bitvec_free(BitVec */*notnull*/ instance); * # Panics * * - when accessing `index` out of bounds + * + * This function is part of the sp_bitvec module. */ bool sp_bitvec_get(BitVec */*notnull*/ instance, size_t index); @@ -869,6 +895,8 @@ struct Packet *sp_bitvec_into_packet(BitVec */*notnull*/ bitvec, * Calls [`servicepoint::DisplayBitVec::is_empty`]. * * Returns true if length is 0. + * + * This function is part of the sp_bitvec module. */ bool sp_bitvec_is_empty(BitVec */*notnull*/ instance); @@ -876,6 +904,8 @@ bool sp_bitvec_is_empty(BitVec */*notnull*/ instance); * Calls [`servicepoint::DisplayBitVec::len`]. * * Gets the length in bits. + * + * This function is part of the sp_bitvec module. */ size_t sp_bitvec_len(BitVec */*notnull*/ instance); @@ -918,11 +948,15 @@ BitVec */*notnull*/ sp_bitvec_new(size_t size); * # Panics * * - when accessing `index` out of bounds + * + * This function is part of the sp_bitvec module. */ void sp_bitvec_set(BitVec */*notnull*/ instance, size_t index, bool value); /** - *Clones a [BrightnessGrid] instance. + *Clones a [`BrightnessGrid`] instance. + * + * This function is part of the sp_brightness_grid module. */ BrightnessGrid */*notnull*/ sp_brightness_grid_clone(BrightnessGrid */*notnull*/ instance); @@ -932,6 +966,8 @@ BrightnessGrid */*notnull*/ sp_brightness_grid_clone(BrightnessGrid */*notnull*/ * Gets an unsafe reference to the data of the instance. * * The returned memory is valid for the lifetime of the grid. + * + * This function is part of the sp_brightness_grid module. */ struct ByteSlice sp_brightness_grid_data_ref_mut(BrightnessGrid */*notnull*/ instance); @@ -943,12 +979,16 @@ struct ByteSlice sp_brightness_grid_data_ref_mut(BrightnessGrid */*notnull*/ ins * # Arguments * * - `value`: the value to set all cells to + * + * This function is part of the sp_brightness_grid module. */ void sp_brightness_grid_fill(BrightnessGrid */*notnull*/ instance, Brightness value); /** - *Deallocates a [BrightnessGrid] instance. + *Deallocates a [`BrightnessGrid`] instance. + * + * This function is part of the sp_brightness_grid module. */ void sp_brightness_grid_free(BrightnessGrid */*notnull*/ instance); @@ -965,6 +1005,8 @@ void sp_brightness_grid_free(BrightnessGrid */*notnull*/ instance); * * # Panics * - When accessing `x` or `y` out of bounds. + * + * This function is part of the sp_brightness_grid module. */ Brightness sp_brightness_grid_get(BrightnessGrid */*notnull*/ instance, size_t x, @@ -974,6 +1016,8 @@ Brightness sp_brightness_grid_get(BrightnessGrid */*notnull*/ instance, * Calls [`servicepoint::BrightnessGrid::height`]. * * Gets the height of the grid. + * + * This function is part of the sp_brightness_grid module. */ size_t sp_brightness_grid_height(BrightnessGrid */*notnull*/ instance); @@ -1041,6 +1085,8 @@ BrightnessGrid */*notnull*/ sp_brightness_grid_new(size_t width, size_t height); * # Panics * * - When accessing `x` or `y` out of bounds. + * + * This function is part of the sp_brightness_grid module. */ void sp_brightness_grid_set(BrightnessGrid */*notnull*/ instance, size_t x, @@ -1051,11 +1097,15 @@ void sp_brightness_grid_set(BrightnessGrid */*notnull*/ instance, * Calls [`servicepoint::BrightnessGrid::width`]. * * Gets the width of the grid. + * + * This function is part of the sp_brightness_grid module. */ size_t sp_brightness_grid_width(BrightnessGrid */*notnull*/ instance); /** - *Clones a [CharGrid] instance. + *Clones a [`CharGrid`] instance. + * + * This function is part of the sp_char_grid module. */ CharGrid */*notnull*/ sp_char_grid_clone(CharGrid */*notnull*/ instance); @@ -1068,11 +1118,15 @@ CharGrid */*notnull*/ sp_char_grid_clone(CharGrid */*notnull*/ instance); * * - `value`: the value to set all cells to * - when providing values that cannot be converted to Rust's `char`. + * + * This function is part of the sp_char_grid module. */ void sp_char_grid_fill(CharGrid */*notnull*/ instance, uint32_t value); /** - *Deallocates a [CharGrid] instance. + *Deallocates a [`CharGrid`] instance. + * + * This function is part of the sp_char_grid module. */ void sp_char_grid_free(CharGrid */*notnull*/ instance); @@ -1088,6 +1142,8 @@ void sp_char_grid_free(CharGrid */*notnull*/ instance); * # Panics * * - when accessing `x` or `y` out of bounds + * + * This function is part of the sp_char_grid module. */ uint32_t sp_char_grid_get(CharGrid */*notnull*/ instance, size_t x, size_t y); @@ -1095,6 +1151,8 @@ uint32_t sp_char_grid_get(CharGrid */*notnull*/ instance, size_t x, size_t y); * Calls [`servicepoint::CharGrid::height`]. * * Gets the height of the grid. + * + * This function is part of the sp_char_grid module. */ size_t sp_char_grid_height(CharGrid */*notnull*/ instance); @@ -1154,6 +1212,8 @@ CharGrid */*notnull*/ sp_char_grid_new(size_t width, size_t height); * * - when accessing `x` or `y` out of bounds * - when providing values that cannot be converted to Rust's `char`. + * + * This function is part of the sp_char_grid module. */ void sp_char_grid_set(CharGrid */*notnull*/ instance, size_t x, @@ -1164,16 +1224,22 @@ void sp_char_grid_set(CharGrid */*notnull*/ instance, * Calls [`servicepoint::CharGrid::width`]. * * Gets the width of the grid. + * + * This function is part of the sp_char_grid module. */ size_t sp_char_grid_width(CharGrid */*notnull*/ instance); /** - *Clones a [BitmapCommand] instance. + *Clones a [`BitmapCommand`] instance. + * + * This function is part of the sp_cmd_bitmap module. */ struct BitmapCommand */*notnull*/ sp_cmd_bitmap_clone(struct BitmapCommand */*notnull*/ instance); /** - *Deallocates a [BitmapCommand] instance. + *Deallocates a [`BitmapCommand`] instance. + * + * This function is part of the sp_cmd_bitmap module. */ void sp_cmd_bitmap_free(struct BitmapCommand */*notnull*/ instance); @@ -1198,7 +1264,9 @@ struct BitmapCommand */*notnull*/ sp_cmd_bitmap_from_bitmap(struct Bitmap */*not struct Bitmap */*notnull*/ sp_cmd_bitmap_get(struct BitmapCommand */*notnull*/ command); /** - *Gets the value of field `compression` of the [`servicepoint::BitmapCommand`]. + * Gets the value of field `compression` of the [`servicepoint::BitmapCommand`]. + * + * This function is part of the sp_cmd_bitmap module. */ CompressionCode sp_cmd_bitmap_get_compression(struct BitmapCommand */*notnull*/ instance); @@ -1230,7 +1298,9 @@ void sp_cmd_bitmap_set(struct BitmapCommand */*notnull*/ command, struct Bitmap */*notnull*/ bitmap); /** - *Sets the value of field `compression` of the [`servicepoint::BitmapCommand`]. + * Sets the value of field `compression` of the [`servicepoint::BitmapCommand`]. + * + * This function is part of the sp_cmd_bitmap module. */ void sp_cmd_bitmap_set_compression(struct BitmapCommand */*notnull*/ instance, CompressionCode value); @@ -1252,12 +1322,16 @@ void sp_cmd_bitmap_set_origin(struct BitmapCommand */*notnull*/ command, struct Packet *sp_cmd_bitmap_try_into_packet(struct BitmapCommand */*notnull*/ command); /** - *Clones a [BitVecCommand] instance. + *Clones a [`BitVecCommand`] instance. + * + * This function is part of the sp_cmd_bitvec module. */ struct BitVecCommand */*notnull*/ sp_cmd_bitvec_clone(struct BitVecCommand */*notnull*/ instance); /** - *Deallocates a [BitVecCommand] instance. + *Deallocates a [`BitVecCommand`] instance. + * + * This function is part of the sp_cmd_bitvec module. */ void sp_cmd_bitvec_free(struct BitVecCommand */*notnull*/ instance); @@ -1267,17 +1341,23 @@ void sp_cmd_bitvec_free(struct BitVecCommand */*notnull*/ instance); BitVec *sp_cmd_bitvec_get(struct BitVecCommand */*notnull*/ command); /** - *Gets the value of field `compression` of the [`servicepoint::BitVecCommand`]. + * Gets the value of field `compression` of the [`servicepoint::BitVecCommand`]. + * + * This function is part of the sp_cmd_bitvec module. */ CompressionCode sp_cmd_bitvec_get_compression(struct BitVecCommand */*notnull*/ instance); /** - *Gets the value of field `offset` of the [`servicepoint::BitVecCommand`]. + * Gets the value of field `offset` of the [`servicepoint::BitVecCommand`]. + * + * This function is part of the sp_cmd_bitvec module. */ Offset sp_cmd_bitvec_get_offset(struct BitVecCommand */*notnull*/ instance); /** - *Gets the value of field `operation` of the [`servicepoint::BitVecCommand`]. + * Gets the value of field `operation` of the [`servicepoint::BitVecCommand`]. + * + * This function is part of the sp_cmd_bitvec module. */ BinaryOperation sp_cmd_bitvec_get_operation(struct BitVecCommand */*notnull*/ instance); @@ -1309,19 +1389,25 @@ void sp_cmd_bitvec_set(struct BitVecCommand */*notnull*/ command, BitVec */*notnull*/ bitvec); /** - *Sets the value of field `compression` of the [`servicepoint::BitVecCommand`]. + * Sets the value of field `compression` of the [`servicepoint::BitVecCommand`]. + * + * This function is part of the sp_cmd_bitvec module. */ void sp_cmd_bitvec_set_compression(struct BitVecCommand */*notnull*/ instance, CompressionCode value); /** - *Sets the value of field `offset` of the [`servicepoint::BitVecCommand`]. + * Sets the value of field `offset` of the [`servicepoint::BitVecCommand`]. + * + * This function is part of the sp_cmd_bitvec module. */ void sp_cmd_bitvec_set_offset(struct BitVecCommand */*notnull*/ instance, Offset value); /** - *Sets the value of field `operation` of the [`servicepoint::BitVecCommand`]. + * Sets the value of field `operation` of the [`servicepoint::BitVecCommand`]. + * + * This function is part of the sp_cmd_bitvec module. */ void sp_cmd_bitvec_set_operation(struct BitVecCommand */*notnull*/ instance, BinaryOperation value); @@ -1336,17 +1422,23 @@ void sp_cmd_bitvec_set_operation(struct BitVecCommand */*notnull*/ instance, struct Packet *sp_cmd_bitvec_try_into_packet(struct BitVecCommand */*notnull*/ command); /** - *Clones a [GlobalBrightnessCommand] instance. + *Clones a [`GlobalBrightnessCommand`] instance. + * + * This function is part of the sp_cmd_brightness_global module. */ struct GlobalBrightnessCommand */*notnull*/ sp_cmd_brightness_global_clone(struct GlobalBrightnessCommand */*notnull*/ instance); /** - *Deallocates a [GlobalBrightnessCommand] instance. + *Deallocates a [`GlobalBrightnessCommand`] instance. + * + * This function is part of the sp_cmd_brightness_global module. */ void sp_cmd_brightness_global_free(struct GlobalBrightnessCommand */*notnull*/ instance); /** - *Gets the value of field `brightness` of the [`servicepoint::GlobalBrightnessCommand`]. + * Gets the value of field `brightness` of the [`servicepoint::GlobalBrightnessCommand`]. + * + * This function is part of the sp_cmd_brightness_global module. */ Brightness sp_cmd_brightness_global_get_brightness(struct GlobalBrightnessCommand */*notnull*/ instance); @@ -1367,18 +1459,24 @@ struct Packet */*notnull*/ sp_cmd_brightness_global_into_packet(struct GlobalBri struct GlobalBrightnessCommand */*notnull*/ sp_cmd_brightness_global_new(Brightness brightness); /** - *Sets the value of field `brightness` of the [`servicepoint::GlobalBrightnessCommand`]. + * Sets the value of field `brightness` of the [`servicepoint::GlobalBrightnessCommand`]. + * + * This function is part of the sp_cmd_brightness_global module. */ void sp_cmd_brightness_global_set_brightness(struct GlobalBrightnessCommand */*notnull*/ instance, Brightness value); /** - *Clones a [BrightnessGridCommand] instance. + *Clones a [`BrightnessGridCommand`] instance. + * + * This function is part of the sp_cmd_brightness_grid module. */ struct BrightnessGridCommand */*notnull*/ sp_cmd_brightness_grid_clone(struct BrightnessGridCommand */*notnull*/ instance); /** - *Deallocates a [BrightnessGridCommand] instance. + *Deallocates a [`BrightnessGridCommand`] instance. + * + * This function is part of the sp_cmd_brightness_grid module. */ void sp_cmd_brightness_grid_free(struct BrightnessGridCommand */*notnull*/ instance); @@ -1438,12 +1536,16 @@ void sp_cmd_brightness_grid_set_origin(struct BrightnessGridCommand */*notnull*/ size_t origin_y); /** - *Clones a [CharGridCommand] instance. + *Clones a [`CharGridCommand`] instance. + * + * This function is part of the sp_cmd_char_grid module. */ struct CharGridCommand */*notnull*/ sp_cmd_char_grid_clone(struct CharGridCommand */*notnull*/ instance); /** - *Deallocates a [CharGridCommand] instance. + *Deallocates a [`CharGridCommand`] instance. + * + * This function is part of the sp_cmd_char_grid module. */ void sp_cmd_char_grid_free(struct CharGridCommand */*notnull*/ instance); @@ -1503,7 +1605,9 @@ void sp_cmd_char_grid_set_origin(struct CharGridCommand */*notnull*/ command, struct Packet *sp_cmd_char_grid_try_into_packet(struct CharGridCommand */*notnull*/ command); /** - *Deallocates a [ClearCommand] instance. + *Deallocates a [`ClearCommand`] instance. + * + * This function is part of the sp_cmd_clear module. */ void sp_cmd_clear_free(struct ClearCommand */*notnull*/ instance); @@ -1519,12 +1623,16 @@ void sp_cmd_clear_free(struct ClearCommand */*notnull*/ instance); struct ClearCommand */*notnull*/ sp_cmd_clear_new(void); /** - *Clones a [Cp437GridCommand] instance. + *Clones a [`Cp437GridCommand`] instance. + * + * This function is part of the sp_cmd_cp437_grid module. */ struct Cp437GridCommand */*notnull*/ sp_cmd_cp437_grid_clone(struct Cp437GridCommand */*notnull*/ instance); /** - *Deallocates a [Cp437GridCommand] instance. + *Deallocates a [`Cp437GridCommand`] instance. + * + * This function is part of the sp_cmd_cp437_grid module. */ void sp_cmd_cp437_grid_free(struct Cp437GridCommand */*notnull*/ instance); @@ -1595,7 +1703,9 @@ void sp_cmd_cp437_grid_set_origin(struct Cp437GridCommand */*notnull*/ command, struct Packet *sp_cmd_cp437_grid_try_into_packet(struct Cp437GridCommand */*notnull*/ command); /** - *Deallocates a [FadeOutCommand] instance. + *Deallocates a [`FadeOutCommand`] instance. + * + * This function is part of the sp_cmd_fade_out module. */ void sp_cmd_fade_out_free(struct FadeOutCommand */*notnull*/ instance); @@ -1647,7 +1757,9 @@ struct Packet *sp_cmd_generic_into_packet(struct Command command); struct Command sp_cmd_generic_try_from_packet(struct Packet */*notnull*/ packet); /** - *Deallocates a [HardResetCommand] instance. + *Deallocates a [`HardResetCommand`] instance. + * + * This function is part of the sp_cmd_hard_reset module. */ void sp_cmd_hard_reset_free(struct HardResetCommand */*notnull*/ instance); @@ -1663,7 +1775,9 @@ void sp_cmd_hard_reset_free(struct HardResetCommand */*notnull*/ instance); struct HardResetCommand */*notnull*/ sp_cmd_hard_reset_new(void); /** - *Clones a [Cp437Grid] instance. + *Clones a [`Cp437Grid`] instance. + * + * This function is part of the sp_cp437_grid module. */ Cp437Grid */*notnull*/ sp_cp437_grid_clone(Cp437Grid */*notnull*/ instance); @@ -1673,6 +1787,8 @@ Cp437Grid */*notnull*/ sp_cp437_grid_clone(Cp437Grid */*notnull*/ instance); * Gets an unsafe reference to the data of the grid. * * The returned memory is valid for the lifetime of the instance. + * + * This function is part of the sp_cp437_grid module. */ struct ByteSlice sp_cp437_grid_data_ref_mut(Cp437Grid */*notnull*/ instance); @@ -1685,11 +1801,15 @@ struct ByteSlice sp_cp437_grid_data_ref_mut(Cp437Grid */*notnull*/ instance); * * - `cp437_grid`: instance to write to * - `value`: the value to set all cells to + * + * This function is part of the sp_cp437_grid module. */ void sp_cp437_grid_fill(Cp437Grid */*notnull*/ instance, uint8_t value); /** - *Deallocates a [Cp437Grid] instance. + *Deallocates a [`Cp437Grid`] instance. + * + * This function is part of the sp_cp437_grid module. */ void sp_cp437_grid_free(Cp437Grid */*notnull*/ instance); @@ -1705,6 +1825,8 @@ void sp_cp437_grid_free(Cp437Grid */*notnull*/ instance); * # Panics * * - when accessing `x` or `y` out of bounds + * + * This function is part of the sp_cp437_grid module. */ uint8_t sp_cp437_grid_get(Cp437Grid */*notnull*/ instance, size_t x, size_t y); @@ -1712,6 +1834,8 @@ uint8_t sp_cp437_grid_get(Cp437Grid */*notnull*/ instance, size_t x, size_t y); * Calls [`servicepoint::Cp437Grid::height`]. * * Gets the height of the grid. + * + * This function is part of the sp_cp437_grid module. */ size_t sp_cp437_grid_height(Cp437Grid */*notnull*/ instance); @@ -1761,6 +1885,8 @@ Cp437Grid */*notnull*/ sp_cp437_grid_new(size_t width, size_t height); * # Panics * * - when accessing `x` or `y` out of bounds + * + * This function is part of the sp_cp437_grid module. */ void sp_cp437_grid_set(Cp437Grid */*notnull*/ instance, size_t x, @@ -1771,16 +1897,22 @@ void sp_cp437_grid_set(Cp437Grid */*notnull*/ instance, * Calls [`servicepoint::Cp437Grid::width`]. * * Gets the width of the grid. + * + * This function is part of the sp_cp437_grid module. */ size_t sp_cp437_grid_width(Cp437Grid */*notnull*/ instance); /** - *Clones a [Packet] instance. + *Clones a [`Packet`] instance. + * + * This function is part of the sp_packet module. */ struct Packet */*notnull*/ sp_packet_clone(struct Packet */*notnull*/ instance); /** - *Deallocates a [Packet] instance. + *Deallocates a [`Packet`] instance. + * + * This function is part of the sp_packet module. */ void sp_packet_free(struct Packet */*notnull*/ instance); @@ -1793,7 +1925,9 @@ struct Packet */*notnull*/ sp_packet_from_parts(struct Header header, struct ByteSlice payload); /** - *Gets the value of field `header` of the [`servicepoint::Packet`]. + * Gets the value of field `header` of the [`servicepoint::Packet`]. + * + * This function is part of the sp_packet module. */ struct Header sp_packet_get_header(struct Packet */*notnull*/ instance); @@ -1824,7 +1958,9 @@ void sp_packet_serialize_to(struct Packet */*notnull*/ packet, struct ByteSlice buffer); /** - *Sets the value of field `header` of the [`servicepoint::Packet`]. + * Sets the value of field `header` of the [`servicepoint::Packet`]. + * + * This function is part of the sp_packet module. */ void sp_packet_set_header(struct Packet */*notnull*/ instance, struct Header value); @@ -1853,7 +1989,9 @@ bool sp_u16_to_command_code(uint16_t code, CommandCode *result); /** - *Deallocates a [UdpSocket] instance. + *Deallocates a [`UdpSocket`] instance. + * + * This function is part of the sp_udp module. */ void sp_udp_free(struct UdpSocket */*notnull*/ instance); diff --git a/src/macros.rs b/src/macros.rs index 48952db..8d4ba47 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -1,24 +1,22 @@ macro_rules! wrap_free { ($prefix:ident :: $typ:ty) => { - paste::paste! { - #[doc = concat!("Deallocates a [", stringify!($typ), "] instance.")] - #[no_mangle] - pub unsafe extern "C" fn [<$prefix _free>](instance: NonNull<$typ>) { + $crate::macros::wrap_functions!($prefix; + #[doc = concat!("Deallocates a [`", stringify!($typ), "`] instance.")] + fn free(instance: NonNull<$typ>) { unsafe { $crate::mem::heap_drop(instance) } } - } + ); }; } macro_rules! wrap_clone { ($prefix:ident :: $typ:ty) => { - paste::paste! { - #[doc = concat!("Clones a [", stringify!($typ), "] instance.")] - #[no_mangle] - pub unsafe extern "C" fn [<$prefix _clone>](instance: NonNull<$typ>) -> NonNull<$typ> { + $crate::macros::wrap_functions!($prefix; + #[doc = concat!("Clones a [`", stringify!($typ), "`] instance.")] + fn clone(instance: NonNull<$typ>) -> NonNull<$typ> { unsafe { $crate::mem::heap_clone(instance) } } - } + ); }; } @@ -50,33 +48,34 @@ macro_rules! wrap_methods { )+ ) => { paste::paste! { + $crate::macros::wrap_functions!($prefix; $( - #[doc = concat!(" Calls [`servicepoint::", stringify!($object_type), - "::", stringify!($function), "`].")] - #[doc = ""] - $(#[$meta])* - #[no_mangle] - pub unsafe extern "C" fn [<$prefix _ $function>]( - instance: NonNull<$object_type>, - $($param_name: $param_type),* - ) $(-> $return_type)? { - let instance = unsafe { $crate::macros:: [< nonnull_as_ $ref_or_mut >] !(instance) }; - $($( - $(let $param_let_name = $param_let_expr;)* - )?)? - #[allow( - unused_variables, - reason = "This variable may not be used depending on macro variables" )] - let result = instance.$function($($param_name),*); - $( + #[doc = concat!(" Calls [`servicepoint::", stringify!($object_type), + "::", stringify!($function), "`].")] + #[doc = ""] + $(#[$meta])* + fn $function( + instance: NonNull<$object_type>, + $($param_name: $param_type),* + ) $(-> $return_type)? { + let instance = unsafe { $crate::macros:: [< nonnull_as_ $ref_or_mut >] !(instance) }; + $($( + $(let $param_let_name = $param_let_expr;)* + )?)? + #[allow( + unused_variables, + reason = "This variable may not be used depending on macro variables" )] + let result = instance.$function($($param_name),*); $( - let $it = result; - let result = $return_expr; + $( + let $it = result; + let result = $return_expr; + )? )? - )? - return result; - } + return result; + } )+ + ); } }; } @@ -103,48 +102,48 @@ macro_rules! wrap_fields { )+ ) => { paste::paste! { - $( + $crate::macros::wrap_functions!($prefix; $( - #[doc = concat!("Gets the value of field `", stringify!($prop_name), - "` of the [`servicepoint::",stringify!($object_type),"`].")] - $($( - #[doc = ""] - #[$get_meta] - )*)? - #[no_mangle] - pub unsafe extern "C" fn [<$prefix _ get _ $prop_name>]( - instance: NonNull<$object_type> - ) -> $prop_type { - let instance = unsafe { $crate::macros::nonnull_as_ref!(instance) }; - let $prop_name = instance.$prop_name; + $( + #[doc = concat!(" Gets the value of field `", stringify!($prop_name), + "` of the [`servicepoint::",stringify!($object_type),"`].")] $($( - let $prop_name = $get_expr; - )?)? - return $prop_name; - } - )? + #[doc = ""] + #[$get_meta] + )*)? + fn []( + instance: NonNull<$object_type> + ) -> $prop_type { + let instance = unsafe { $crate::macros::nonnull_as_ref!(instance) }; + let $prop_name = instance.$prop_name; + $($( + let $prop_name = $get_expr; + )?)? + return $prop_name; + } + )? - $( - #[doc = concat!("Sets the value of field `", stringify!($prop_name), - "` of the [`servicepoint::",stringify!($object_type),"`].")] - $($( - #[doc = ""] - #[$set_meta] - )*)? - #[no_mangle] - pub unsafe extern "C" fn [<$prefix _ set _ $prop_name>]( - instance: NonNull<$object_type>, - value: $prop_type, - ) { - let instance = unsafe { $crate::macros::nonnull_as_mut!(instance) }; + $( + #[doc = concat!(" Sets the value of field `", stringify!($prop_name), + "` of the [`servicepoint::",stringify!($object_type),"`].")] $($( - let $value = value; - let value = $set_expr; - )?)? - instance.$prop_name = value; - } - )? - )+ + #[doc = ""] + #[$set_meta] + )*)? + fn []( + instance: NonNull<$object_type>, + value: $prop_type, + ) { + let instance = unsafe { $crate::macros::nonnull_as_mut!(instance) }; + $($( + let $value = value; + let value = $set_expr; + )?)? + instance.$prop_name = value; + } + )? + )+ + ); } }; }