From 5beea6151a9fc135306c72865cb57f04b4bbfeca Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Thu, 26 Jun 2025 20:42:31 +0200 Subject: [PATCH] wip generic wrap --- src/commands/bitmap_command.rs | 4 +-- src/commands/bitvec_command.rs | 4 +-- src/commands/brightness_grid_command.rs | 4 +-- src/commands/char_grid_command.rs | 4 +-- src/commands/cp437_grid_command.rs | 4 +-- src/commands/generic_command.rs | 6 ++--- src/commands/global_brightness_command.rs | 4 +-- src/containers/bitmap.rs | 10 ++++---- src/containers/bitvec.rs | 18 ++++++------- src/containers/brightness_grid.rs | 8 +++--- src/containers/char_grid.rs | 13 +++++----- src/containers/cp437_grid.rs | 8 +++--- src/macros.rs | 31 ++++++++++++++++++++++- src/packet.rs | 14 ++++------ src/udp.rs | 10 ++++---- 15 files changed, 83 insertions(+), 59 deletions(-) diff --git a/src/commands/bitmap_command.rs b/src/commands/bitmap_command.rs index 40fbc1c..5b74924 100644 --- a/src/commands/bitmap_command.rs +++ b/src/commands/bitmap_command.rs @@ -1,13 +1,13 @@ use crate::{ commands::{wrap_command, wrap_origin_accessors}, - macros::{wrap_fields, wrap_functions}, + macros::{wrap, wrap_functions}, }; use servicepoint::{Bitmap, BitmapCommand, CompressionCode, Origin}; use std::ptr::NonNull; wrap_command!(Bitmap); -wrap_fields!(BitmapCommand; +wrap!(BitmapCommand; prop bitmap: Bitmap { get mut; set move; }; prop compression: CompressionCode { get; set; }; ); diff --git a/src/commands/bitvec_command.rs b/src/commands/bitvec_command.rs index f62b492..440850f 100644 --- a/src/commands/bitvec_command.rs +++ b/src/commands/bitvec_command.rs @@ -1,6 +1,6 @@ use crate::{ commands::wrap_command, - macros::{wrap_fields, wrap_functions}, + macros::{wrap, wrap_functions}, }; use servicepoint::{ BinaryOperation, BitVecCommand, CompressionCode, DisplayBitVec, Offset, @@ -9,7 +9,7 @@ use std::ptr::NonNull; wrap_command!(BitVec); -wrap_fields!(BitVecCommand; +wrap!(BitVecCommand; prop bitvec: DisplayBitVec { get mut; set move; }; prop offset: Offset { get; set; }; prop operation: BinaryOperation { get; set; }; diff --git a/src/commands/brightness_grid_command.rs b/src/commands/brightness_grid_command.rs index 007d645..23f5982 100644 --- a/src/commands/brightness_grid_command.rs +++ b/src/commands/brightness_grid_command.rs @@ -1,13 +1,13 @@ use crate::{ commands::{wrap_command, wrap_origin_accessors}, - macros::{wrap_fields, wrap_functions}, + macros::{wrap, wrap_functions}, }; use servicepoint::{BrightnessGrid, BrightnessGridCommand, Origin}; use std::ptr::NonNull; wrap_command!(BrightnessGrid); -wrap_fields!(BrightnessGridCommand; +wrap!(BrightnessGridCommand; prop grid: BrightnessGrid { get mut; set move; }; ); diff --git a/src/commands/char_grid_command.rs b/src/commands/char_grid_command.rs index 06f2070..dcd5bc7 100644 --- a/src/commands/char_grid_command.rs +++ b/src/commands/char_grid_command.rs @@ -1,13 +1,13 @@ use crate::{ commands::{wrap_command, wrap_origin_accessors}, - macros::{wrap_fields, wrap_functions}, + macros::{wrap, wrap_functions}, }; use servicepoint::{CharGrid, CharGridCommand, Origin}; use std::ptr::NonNull; wrap_command!(CharGrid); -wrap_fields!(CharGridCommand; +wrap!(CharGridCommand; prop grid: CharGrid { get mut; set move; }; ); diff --git a/src/commands/cp437_grid_command.rs b/src/commands/cp437_grid_command.rs index d4c0e88..90b2d3d 100644 --- a/src/commands/cp437_grid_command.rs +++ b/src/commands/cp437_grid_command.rs @@ -1,13 +1,13 @@ use crate::{ commands::{wrap_command, wrap_origin_accessors}, - macros::{wrap_fields, wrap_functions}, + macros::{wrap, wrap_functions}, }; use servicepoint::{Cp437Grid, Cp437GridCommand, Origin}; use std::ptr::NonNull; wrap_command!(Cp437Grid); -wrap_fields!(Cp437GridCommand; +wrap!(Cp437GridCommand; prop grid: Cp437Grid { get mut; set move; }; ); diff --git a/src/commands/generic_command.rs b/src/commands/generic_command.rs index c6a1323..4f71dc4 100644 --- a/src/commands/generic_command.rs +++ b/src/commands/generic_command.rs @@ -1,5 +1,5 @@ use crate::{ - macros::{derive_clone, derive_free, wrap_functions, wrap_methods}, + macros::{derive_clone, derive_free, wrap, wrap_functions}, mem::{ heap_clone, heap_drop, heap_move, heap_move_nonnull, heap_move_ok, heap_remove, @@ -250,12 +250,12 @@ wrap_functions!(associate GenericCommand; }; ); -wrap_methods! { GenericCommand; +wrap! { GenericCommand; /// Tries to turn a [GenericCommand] into a [Packet]. /// The [GenericCommand] gets consumed. /// /// Returns tag [CommandTag::Invalid] in case of an error. - fn try_into_packet(move command) -> val *mut Packet { + method try_into_packet(move command) -> val *mut Packet { match command.tag { CommandTag::Invalid => null_mut(), CommandTag::Bitmap => { diff --git a/src/commands/global_brightness_command.rs b/src/commands/global_brightness_command.rs index 6a883ab..06377ae 100644 --- a/src/commands/global_brightness_command.rs +++ b/src/commands/global_brightness_command.rs @@ -1,6 +1,6 @@ use crate::{ commands::wrap_command, - macros::{wrap_fields, wrap_functions}, + macros::{wrap, wrap_functions}, }; use servicepoint::{Brightness, GlobalBrightnessCommand}; use std::ptr::NonNull; @@ -16,6 +16,6 @@ wrap_functions!(associate GlobalBrightnessCommand; wrap_command!(GlobalBrightness); -wrap_fields!(GlobalBrightnessCommand; +wrap!(GlobalBrightnessCommand; prop brightness: Brightness { get; set; }; ); diff --git a/src/containers/bitmap.rs b/src/containers/bitmap.rs index b6ed4f3..acc959a 100644 --- a/src/containers/bitmap.rs +++ b/src/containers/bitmap.rs @@ -1,6 +1,6 @@ use crate::{ containers::{wrap_grid, ByteSlice}, - macros::{wrap_functions, wrap_methods}, + macros::{wrap, wrap_functions}, }; use servicepoint::{ Bitmap, BitmapCommand, CompressionCode, DataRef, DisplayBitVec, Grid, @@ -74,9 +74,9 @@ wrap_functions!(associate Bitmap; }; ); -wrap_methods!(Bitmap; +wrap!(Bitmap; /// Consumes the Bitmap and returns the contained BitVec. - fn into_bitvec(move bitmap) -> move NonNull { + method into_bitvec(move bitmap) -> move NonNull { bitmap.into() }; @@ -85,7 +85,7 @@ wrap_methods!(Bitmap; /// The provided [Bitmap] gets consumed. /// /// Returns NULL in case of an error. - fn try_into_packet(move bitmap, x: val usize, y: val usize, compression: val CompressionCode) -> move_ok *mut Packet { + method try_into_packet(move bitmap, x: val usize, y: val usize, compression: val CompressionCode) -> move_ok *mut Packet { Packet::try_from(BitmapCommand { bitmap, origin: Origin::new(x, y), @@ -96,5 +96,5 @@ wrap_methods!(Bitmap; /// Gets an unsafe reference to the data of the [Bitmap] instance. /// /// The returned memory is valid for the lifetime of the bitmap. - fn data_ref_mut(mut instance) -> slice ByteSlice; + method data_ref_mut(mut instance) -> slice ByteSlice; ); diff --git a/src/containers/bitvec.rs b/src/containers/bitvec.rs index b16dd92..c0627da 100644 --- a/src/containers/bitvec.rs +++ b/src/containers/bitvec.rs @@ -1,6 +1,6 @@ use crate::{ containers::{wrap_container, ByteSlice}, - macros::{wrap_functions, wrap_methods}, + macros::{wrap, wrap_functions}, }; use servicepoint::{ BinaryOperation, BitVecCommand, CompressionCode, DisplayBitVec, Packet, @@ -33,13 +33,13 @@ wrap_functions!(associate DisplayBitVec; }; ); -wrap_methods!(DisplayBitVec; +wrap!(DisplayBitVec; /// Creates a [BitVecCommand] and immediately turns that into a [Packet]. /// /// The provided [DisplayBitVec] gets consumed. /// /// Returns NULL in case of an error. - fn try_into_packet( + method try_into_packet( move bitvec, offset: val usize, operation: val BinaryOperation, @@ -65,7 +65,7 @@ wrap_methods!(DisplayBitVec; /// # Panics /// /// - when accessing `index` out of bounds - fn get(ref instance, index: val usize) -> val bool { + method get(ref instance, index: val usize) -> val bool { instance.get(index).map(|x| *x).unwrap_or(false) }; @@ -79,23 +79,23 @@ wrap_methods!(DisplayBitVec; /// # Panics /// /// - when accessing `index` out of bounds - fn set(mut instance, index: val usize, value: val bool); + method set(mut instance, index: val usize, value: val bool); /// Sets the value of all bits. /// /// # Arguments /// /// - `value`: the value to set all bits to - fn fill(mut instance, value: val bool); + method fill(mut instance, value: val bool); /// Gets the length in bits. - fn len(ref instance) -> val usize; + method len(ref instance) -> val usize; /// Returns true if length is 0. - fn is_empty(ref instance) -> val bool; + method is_empty(ref instance) -> val bool; /// Gets an unsafe reference to the data of the [DisplayBitVec] instance. /// /// The returned memory is valid for the lifetime of the bitvec. - fn as_raw_mut_slice(mut instance) -> slice ByteSlice; + method as_raw_mut_slice(mut instance) -> slice ByteSlice; ); diff --git a/src/containers/brightness_grid.rs b/src/containers/brightness_grid.rs index 19f6b7a..c6b7f13 100644 --- a/src/containers/brightness_grid.rs +++ b/src/containers/brightness_grid.rs @@ -1,6 +1,6 @@ use crate::{ containers::{wrap_grid, ByteSlice}, - macros::{wrap_functions, wrap_methods}, + macros::{wrap, wrap_functions}, }; use servicepoint::{ Brightness, BrightnessGrid, BrightnessGridCommand, ByteGrid, DataRef, Grid, @@ -47,13 +47,13 @@ wrap_functions!(associate BrightnessGrid; }; ); -wrap_methods!(BrightnessGrid; +wrap!(BrightnessGrid; /// Creates a [BrightnessGridCommand] and immediately turns that into a [Packet]. /// /// The provided [BrightnessGrid] gets consumed. /// /// Returns NULL in case of an error. - fn try_into_packet(move grid, x: val usize, y: val usize) -> move_ok *mut Packet { + method try_into_packet(move grid, x: val usize, y: val usize) -> move_ok *mut Packet { Packet::try_from(BrightnessGridCommand { grid, origin: Origin::new(x, y), @@ -63,7 +63,7 @@ wrap_methods!(BrightnessGrid; /// Gets an unsafe reference to the data of the instance. /// /// The returned memory is valid for the lifetime of the grid. - fn data_ref_mut(mut instance) -> slice ByteSlice { + method data_ref_mut(mut instance) -> slice ByteSlice { //noinspection RsAssertEqual const _: () = assert!(size_of::() == 1); diff --git a/src/containers/char_grid.rs b/src/containers/char_grid.rs index 98a2c5b..4323021 100644 --- a/src/containers/char_grid.rs +++ b/src/containers/char_grid.rs @@ -1,6 +1,6 @@ use crate::{ containers::{derive_get_width_height, wrap_container, ByteSlice}, - macros::{wrap_functions, wrap_methods}, + macros::{wrap, wrap_functions}, }; use servicepoint::{CharGrid, CharGridCommand, Grid, Origin, Packet}; use std::ptr::NonNull; @@ -33,8 +33,7 @@ wrap_functions!(associate CharGrid; }; ); -wrap_methods!(CharGrid; - +wrap!(CharGrid; /// Returns the current value at the specified position. /// /// # Arguments @@ -44,7 +43,7 @@ wrap_methods!(CharGrid; /// # Panics /// /// - when accessing `x` or `y` out of bounds - fn get(ref instance, x: val usize, y: val usize) -> val u32 { + method get(ref instance, x: val usize, y: val usize) -> val u32 { instance.get(x, y) as u32 }; @@ -61,7 +60,7 @@ wrap_methods!(CharGrid; /// /// - when accessing `x` or `y` out of bounds /// - when providing values that cannot be converted to Rust's `char`. - fn set(mut instance, x: val usize, y: val usize, value: val u32) { + method set(mut instance, x: val usize, y: val usize, value: val u32) { instance.set(x, y, char::from_u32(value).unwrap()) }; @@ -71,7 +70,7 @@ wrap_methods!(CharGrid; /// /// - `value`: the value to set all cells to /// - when providing values that cannot be converted to Rust's `char`. - fn fill(mut instance, value: val u32) { + method fill(mut instance, value: val u32) { instance.fill(char::from_u32(value).unwrap()) }; @@ -80,7 +79,7 @@ wrap_methods!(CharGrid; /// The provided [CharGrid] gets consumed. /// /// Returns NULL in case of an error. - fn try_into_packet(move grid, x: val usize, y: val usize) -> move_ok *mut Packet { + method try_into_packet(move grid, x: val usize, y: val usize) -> move_ok *mut Packet { 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 62f0eb2..2a157c2 100644 --- a/src/containers/cp437_grid.rs +++ b/src/containers/cp437_grid.rs @@ -1,6 +1,6 @@ use crate::{ containers::{wrap_grid, ByteSlice}, - macros::{wrap_functions, wrap_methods}, + macros::{wrap, wrap_functions}, }; use servicepoint::{ Cp437Grid, Cp437GridCommand, DataRef, Grid, Origin, Packet, @@ -23,13 +23,13 @@ wrap_functions!(associate Cp437Grid; }; ); -wrap_methods!(Cp437Grid; +wrap!(Cp437Grid; /// Creates a [Cp437GridCommand] and immediately turns that into a [Packet]. /// /// The provided [Cp437Grid] gets consumed. /// /// Returns NULL in case of an error. - fn try_into_packet(move grid, x: val usize, y: val usize) -> move_ok *mut Packet { + method try_into_packet(move grid, x: val usize, y: val usize) -> move_ok *mut Packet { Packet::try_from(Cp437GridCommand { grid, origin: Origin::new(x, y), @@ -39,5 +39,5 @@ wrap_methods!(Cp437Grid; /// Gets an unsafe reference to the data of the grid. /// /// The returned memory is valid for the lifetime of the instance. - fn data_ref_mut(mut instance) -> slice ByteSlice; + method data_ref_mut(mut instance) -> slice ByteSlice; ); diff --git a/src/macros.rs b/src/macros.rs index 79cd3af..ebcad75 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -263,8 +263,37 @@ macro_rules! wrap_functions { }; } +macro_rules! wrap { + ( + $object_type:ident; + $( + prop $prop_name:ident : $prop_type:ty { $($accessor:ident $($modifier:ident)?;)+ }; + )* + $( + $(#[$meta:meta])+ + method $function:ident($ref_or_mut:ident $instance:ident $(, $($param_name:ident: $param_modifier:ident $param_type:ty),*)?) + $(-> $return_modifier:ident $return_type:ty)? + $($impl:block)?; + )* + ) => { + $( + $crate::macros::wrap_fields!($object_type; + prop $prop_name : $prop_type { $($accessor $($modifier)?;)+ }; + ); + )* + $( + $crate::macros::wrap_method!($object_type; + $(#[$meta])+ + fn $function($ref_or_mut $instance $(, $($param_name: $param_modifier $param_type),*)?) + $(-> $return_modifier $return_type)? + $($impl)?; + ); + )* + }; +} + pub(crate) use { apply_param_modifier, apply_return_modifier, derive_clone, derive_free, - wrap_fields, wrap_fields_accessor, wrap_function, wrap_functions, + wrap, wrap_fields, wrap_fields_accessor, wrap_function, wrap_functions, wrap_method, wrap_methods, }; diff --git a/src/packet.rs b/src/packet.rs index bec75e5..71c746d 100644 --- a/src/packet.rs +++ b/src/packet.rs @@ -1,8 +1,6 @@ use crate::{ containers::ByteSlice, - macros::{ - derive_clone, derive_free, wrap_fields, wrap_functions, wrap_methods, - }, + macros::{derive_clone, derive_free, wrap, wrap_functions}, }; use servicepoint::{CommandCode, Header, Packet}; use std::ptr::NonNull; @@ -32,17 +30,15 @@ wrap_functions!(associate Packet; derive_clone!(Packet); derive_free!(Packet); -wrap_fields!(Packet; +wrap! {Packet; prop header: Header { get; get mut; set; }; -); -wrap_methods! { Packet; /// Returns a pointer to the current payload of the provided packet. /// /// Returns an [ByteSlice::INVALID] instance in case the packet does not have any payload. /// /// The returned memory can be changed and will be valid until a new payload is set. - fn get_payload(mut packet) -> val ByteSlice { + method get_payload(mut packet) -> val ByteSlice { match &mut packet.payload { None => ByteSlice::INVALID, Some(payload) => unsafe { ByteSlice::from_slice(payload) }, @@ -52,7 +48,7 @@ wrap_methods! { Packet; /// Sets the payload of the provided packet to the provided data. /// /// This makes previous payload pointers invalid. - fn set_payload(mut packet, data: val ByteSlice) { + method set_payload(mut packet, data: val ByteSlice) { packet.payload = if data == ByteSlice::INVALID { None } else { @@ -65,7 +61,7 @@ wrap_methods! { Packet; /// # Panics /// /// - if the buffer is not big enough to hold header+payload. - fn serialize_to(mut packet, buffer: val ByteSlice) -> val usize { + method serialize_to(mut packet, buffer: val ByteSlice) -> val usize { unsafe { packet.serialize_to(buffer.as_slice_mut()).unwrap_or(0) } diff --git a/src/udp.rs b/src/udp.rs index ba9b336..4fce7c0 100644 --- a/src/udp.rs +++ b/src/udp.rs @@ -1,6 +1,6 @@ use crate::{ commands::{CommandTag, GenericCommand}, - macros::{derive_free, wrap_functions, wrap_methods}, + macros::{derive_free, wrap, wrap_functions}, mem::heap_remove, }; use servicepoint::{Header, Packet, UdpSocketExt}; @@ -48,13 +48,13 @@ wrap_functions!(associate UdpSocket; }; ); -wrap_methods! {UdpSocket; +wrap! {UdpSocket; /// Sends a [Packet] to the display using the [UdpSocket]. /// /// The passed `packet` gets consumed. /// /// returns: true in case of success - fn send_packet(ref connection, packet: move NonNull) -> val bool { + method send_packet(ref connection, packet: move NonNull) -> val bool { connection.send(&Vec::from(packet)).is_ok() }; @@ -69,7 +69,7 @@ wrap_methods! {UdpSocket; /// ```C /// sp_udp_send_command(connection, sp_command_brightness(5)); /// ``` - fn send_command(ref connection, command: mut NonNull) -> val bool { + method send_command(ref connection, command: mut NonNull) -> val bool { unsafe { let result = match command.tag { CommandTag::Invalid => return false, @@ -98,7 +98,7 @@ wrap_methods! {UdpSocket; /// ```C /// sp_udp_send_header(connection, sp_command_brightness(5)); /// ``` - fn send_header(ref udp_connection, header: val Header) -> val bool { + method send_header(ref udp_connection, header: val Header) -> val bool { let packet = Packet { header, payload: None,