the rest of the functions wrapped with macro
This commit is contained in:
		
							parent
							
								
									c492cfab6b
								
							
						
					
					
						commit
						b79a2534fc
					
				
					 7 changed files with 485 additions and 485 deletions
				
			
		| 
						 | 
					@ -633,12 +633,6 @@ typedef struct Header {
 | 
				
			||||||
extern "C" {
 | 
					extern "C" {
 | 
				
			||||||
#endif // __cplusplus
 | 
					#endif // __cplusplus
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Call this function at the beginning of main to enable rust logging controlled by the
 | 
					 | 
				
			||||||
 * `RUST_LOG` environment variable. See [env_logger](https://docs.rs/env_logger/latest/env_logger/).
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void init_env_logger(void);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 *Clones a [`Bitmap`] instance.
 | 
					 *Clones a [`Bitmap`] instance.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -1655,7 +1649,7 @@ void sp_cmd_clear_free(struct ClearCommand */*notnull*/ instance);
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Does not affect brightness.
 | 
					 * Does not affect brightness.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Returns: a new [ClearCommand] instance.
 | 
					 * Returns: a new [`ClearCommand`] instance.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This function is part of the sp_cmd_clear module.
 | 
					 * This function is part of the sp_cmd_clear module.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
| 
						 | 
					@ -1752,7 +1746,7 @@ void sp_cmd_fade_out_free(struct FadeOutCommand */*notnull*/ instance);
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * A yet-to-be-tested command.
 | 
					 * A yet-to-be-tested command.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Returns: a new [FadeOutCommand] instance.
 | 
					 * Returns: a new [`FadeOutCommand`] instance.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This function is part of the sp_cmd_fade_out module.
 | 
					 * This function is part of the sp_cmd_fade_out module.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
| 
						 | 
					@ -1762,6 +1756,8 @@ struct FadeOutCommand */*notnull*/ sp_cmd_fade_out_new(void);
 | 
				
			||||||
 * Clones an [SPCommand] instance.
 | 
					 * Clones an [SPCommand] instance.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * returns: a new [SPCommand] instance.
 | 
					 * returns: a new [SPCommand] instance.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This function is part of the sp_cmd_generic module.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
struct Command sp_cmd_generic_clone(struct Command command);
 | 
					struct Command sp_cmd_generic_clone(struct Command command);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1776,6 +1772,8 @@ struct Command sp_cmd_generic_clone(struct Command command);
 | 
				
			||||||
 * SPCommand c = sp_cmd_clear_into_generic(sp_cmd_clear_new());
 | 
					 * SPCommand c = sp_cmd_clear_into_generic(sp_cmd_clear_new());
 | 
				
			||||||
 * sp_command_free(c);
 | 
					 * sp_command_free(c);
 | 
				
			||||||
 * ```
 | 
					 * ```
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This function is part of the sp_cmd_generic module.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
void sp_cmd_generic_free(struct Command command);
 | 
					void sp_cmd_generic_free(struct Command command);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1784,6 +1782,8 @@ void sp_cmd_generic_free(struct Command command);
 | 
				
			||||||
 * The [SPCommand] gets consumed.
 | 
					 * The [SPCommand] gets consumed.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Returns tag [CommandTag::Invalid] in case of an error.
 | 
					 * Returns tag [CommandTag::Invalid] in case of an error.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This function is part of the sp_cmd_generic module.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
struct Packet *sp_cmd_generic_into_packet(struct Command command);
 | 
					struct Packet *sp_cmd_generic_into_packet(struct Command command);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1793,6 +1793,8 @@ struct Packet *sp_cmd_generic_into_packet(struct Command command);
 | 
				
			||||||
 * The packet is dropped in the process.
 | 
					 * The packet is dropped in the process.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Returns: pointer to new [SPCommand] instance or NULL if parsing failed.
 | 
					 * Returns: pointer to new [SPCommand] instance or NULL if parsing failed.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This function is part of the sp_cmd_generic module.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
struct Command sp_cmd_generic_try_from_packet(struct Packet */*notnull*/ packet);
 | 
					struct Command sp_cmd_generic_try_from_packet(struct Packet */*notnull*/ packet);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1808,7 +1810,7 @@ void sp_cmd_hard_reset_free(struct HardResetCommand */*notnull*/ instance);
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Please do not send this in your normal program flow.
 | 
					 * Please do not send this in your normal program flow.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Returns: a new [HardResetCommand] instance.
 | 
					 * Returns: a new [`HardResetCommand`] instance.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This function is part of the sp_cmd_hard_reset module.
 | 
					 * This function is part of the sp_cmd_hard_reset module.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
| 
						 | 
					@ -1942,6 +1944,14 @@ void sp_cp437_grid_set(Cp437Grid */*notnull*/ instance,
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
size_t sp_cp437_grid_width(Cp437Grid */*notnull*/ instance);
 | 
					size_t sp_cp437_grid_width(Cp437Grid */*notnull*/ instance);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Call this function at the beginning of main to enable rust logging controlled by the
 | 
				
			||||||
 | 
					 * `RUST_LOG` environment variable. See [env_logger](https://docs.rs/env_logger/latest/env_logger/).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This function is part of the sp_envlogger module.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void sp_envlogger_init(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 *Clones a [`Packet`] instance.
 | 
					 *Clones a [`Packet`] instance.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -1960,6 +1970,8 @@ void sp_packet_free(struct Packet */*notnull*/ instance);
 | 
				
			||||||
 * Creates a raw [Packet] from parts.
 | 
					 * Creates a raw [Packet] from parts.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * returns: new instance. Will never return null.
 | 
					 * returns: new instance. Will never return null.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This function is part of the sp_packet module.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
struct Packet */*notnull*/ sp_packet_from_parts(struct Header header,
 | 
					struct Packet */*notnull*/ sp_packet_from_parts(struct Header header,
 | 
				
			||||||
                                                struct ByteSlice payload);
 | 
					                                                struct ByteSlice payload);
 | 
				
			||||||
| 
						 | 
					@ -1972,11 +1984,14 @@ struct Packet */*notnull*/ sp_packet_from_parts(struct Header header,
 | 
				
			||||||
struct Header sp_packet_get_header(struct Packet */*notnull*/ instance);
 | 
					struct Header sp_packet_get_header(struct Packet */*notnull*/ instance);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Returns a pointer to the header field of the provided packet.
 | 
					 * Gets a reference to the field `header` of the [`servicepoint::Packet`].
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * The returned header can be changed and will be valid for the lifetime of the packet.
 | 
					 * - The returned reference inherits the lifetime of object in which it is contained.
 | 
				
			||||||
 | 
					 * - The returned pointer may not be used in a function that consumes the instance, e.g. to create a command.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This function is part of the sp_packet module.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
struct Header */*notnull*/ sp_packet_get_header_mut(struct Packet */*notnull*/ packet);
 | 
					struct Header */*notnull*/ sp_packet_get_header_mut(struct Packet */*notnull*/ instance);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Returns a pointer to the current payload of the provided packet.
 | 
					 * Returns a pointer to the current payload of the provided packet.
 | 
				
			||||||
| 
						 | 
					@ -1984,6 +1999,8 @@ struct Header */*notnull*/ sp_packet_get_header_mut(struct Packet */*notnull*/ p
 | 
				
			||||||
 * Returns an [ByteSlice::INVALID] instance in case the packet does not have any payload.
 | 
					 * 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.
 | 
					 * The returned memory can be changed and will be valid until a new payload is set.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This function is part of the sp_packet module.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
struct ByteSlice sp_packet_get_payload(struct Packet */*notnull*/ packet);
 | 
					struct ByteSlice sp_packet_get_payload(struct Packet */*notnull*/ packet);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1993,9 +2010,11 @@ struct ByteSlice sp_packet_get_payload(struct Packet */*notnull*/ packet);
 | 
				
			||||||
 * # Panics
 | 
					 * # Panics
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * - if the buffer is not big enough to hold header+payload.
 | 
					 * - if the buffer is not big enough to hold header+payload.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This function is part of the sp_packet module.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
void sp_packet_serialize_to(struct Packet */*notnull*/ packet,
 | 
					size_t sp_packet_serialize_to(struct Packet */*notnull*/ packet,
 | 
				
			||||||
                            struct ByteSlice buffer);
 | 
					                              struct ByteSlice buffer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Sets the value of field `header` of the [`servicepoint::Packet`].
 | 
					 * Sets the value of field `header` of the [`servicepoint::Packet`].
 | 
				
			||||||
| 
						 | 
					@ -2009,6 +2028,8 @@ void sp_packet_set_header(struct Packet */*notnull*/ instance,
 | 
				
			||||||
 * Sets the payload of the provided packet to the provided data.
 | 
					 * Sets the payload of the provided packet to the provided data.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This makes previous payload pointers invalid.
 | 
					 * This makes previous payload pointers invalid.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This function is part of the sp_packet module.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
void sp_packet_set_payload(struct Packet */*notnull*/ packet,
 | 
					void sp_packet_set_payload(struct Packet */*notnull*/ packet,
 | 
				
			||||||
                           struct ByteSlice data);
 | 
					                           struct ByteSlice data);
 | 
				
			||||||
| 
						 | 
					@ -2017,6 +2038,8 @@ void sp_packet_set_payload(struct Packet */*notnull*/ packet,
 | 
				
			||||||
 * Tries to load a [Packet] from the passed array with the specified length.
 | 
					 * Tries to load a [Packet] from the passed array with the specified length.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * returns: NULL in case of an error, pointer to the allocated packet otherwise
 | 
					 * returns: NULL in case of an error, pointer to the allocated packet otherwise
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This function is part of the sp_packet module.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
struct Packet *sp_packet_try_load(struct ByteSlice data);
 | 
					struct Packet *sp_packet_try_load(struct ByteSlice data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2024,6 +2047,8 @@ struct Packet *sp_packet_try_load(struct ByteSlice data);
 | 
				
			||||||
 * Converts u16 into [CommandCode].
 | 
					 * Converts u16 into [CommandCode].
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * If the provided value is not valid, false is returned and result is not changed.
 | 
					 * If the provided value is not valid, false is returned and result is not changed.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This function is part of the sp module.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
bool sp_u16_to_command_code(uint16_t code,
 | 
					bool sp_u16_to_command_code(uint16_t code,
 | 
				
			||||||
                            CommandCode *result);
 | 
					                            CommandCode *result);
 | 
				
			||||||
| 
						 | 
					@ -2047,6 +2072,8 @@ void sp_udp_free(struct UdpSocket */*notnull*/ instance);
 | 
				
			||||||
 * if (connection != NULL)
 | 
					 * if (connection != NULL)
 | 
				
			||||||
 *     sp_udp_send_command(connection, sp_command_clear());
 | 
					 *     sp_udp_send_command(connection, sp_command_clear());
 | 
				
			||||||
 * ```
 | 
					 * ```
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This function is part of the sp_udp module.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
struct UdpSocket *sp_udp_open(char */*notnull*/ host);
 | 
					struct UdpSocket *sp_udp_open(char */*notnull*/ host);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2062,6 +2089,8 @@ struct UdpSocket *sp_udp_open(char */*notnull*/ host);
 | 
				
			||||||
 * if (connection != NULL)
 | 
					 * if (connection != NULL)
 | 
				
			||||||
 *     sp_udp_send_command(connection, sp_command_clear());
 | 
					 *     sp_udp_send_command(connection, sp_command_clear());
 | 
				
			||||||
 * ```
 | 
					 * ```
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This function is part of the sp_udp module.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
struct UdpSocket *sp_udp_open_ipv4(uint8_t ip1,
 | 
					struct UdpSocket *sp_udp_open_ipv4(uint8_t ip1,
 | 
				
			||||||
                                   uint8_t ip2,
 | 
					                                   uint8_t ip2,
 | 
				
			||||||
| 
						 | 
					@ -2081,6 +2110,8 @@ struct UdpSocket *sp_udp_open_ipv4(uint8_t ip1,
 | 
				
			||||||
 * ```C
 | 
					 * ```C
 | 
				
			||||||
 * sp_udp_send_command(connection, sp_command_brightness(5));
 | 
					 * sp_udp_send_command(connection, sp_command_brightness(5));
 | 
				
			||||||
 * ```
 | 
					 * ```
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This function is part of the sp_udp module.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
bool sp_udp_send_command(struct UdpSocket */*notnull*/ connection,
 | 
					bool sp_udp_send_command(struct UdpSocket */*notnull*/ connection,
 | 
				
			||||||
                         struct Command command);
 | 
					                         struct Command command);
 | 
				
			||||||
| 
						 | 
					@ -2095,6 +2126,8 @@ bool sp_udp_send_command(struct UdpSocket */*notnull*/ connection,
 | 
				
			||||||
 * ```C
 | 
					 * ```C
 | 
				
			||||||
 * sp_udp_send_header(connection, sp_command_brightness(5));
 | 
					 * sp_udp_send_header(connection, sp_command_brightness(5));
 | 
				
			||||||
 * ```
 | 
					 * ```
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This function is part of the sp_udp module.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
bool sp_udp_send_header(struct UdpSocket */*notnull*/ udp_connection,
 | 
					bool sp_udp_send_header(struct UdpSocket */*notnull*/ udp_connection,
 | 
				
			||||||
                        struct Header header);
 | 
					                        struct Header header);
 | 
				
			||||||
| 
						 | 
					@ -2105,6 +2138,8 @@ bool sp_udp_send_header(struct UdpSocket */*notnull*/ udp_connection,
 | 
				
			||||||
 * The passed `packet` gets consumed.
 | 
					 * The passed `packet` gets consumed.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * returns: true in case of success
 | 
					 * returns: true in case of success
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This function is part of the sp_udp module.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
bool sp_udp_send_packet(struct UdpSocket */*notnull*/ connection,
 | 
					bool sp_udp_send_packet(struct UdpSocket */*notnull*/ connection,
 | 
				
			||||||
                        struct Packet */*notnull*/ packet);
 | 
					                        struct Packet */*notnull*/ packet);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,39 +5,33 @@ use crate::{
 | 
				
			||||||
use servicepoint::{ClearCommand, FadeOutCommand, HardResetCommand};
 | 
					use servicepoint::{ClearCommand, FadeOutCommand, HardResetCommand};
 | 
				
			||||||
use std::ptr::NonNull;
 | 
					use std::ptr::NonNull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
wrap_functions!(sp_cmd_clear;
 | 
					macro_rules! wrap_cc_only {
 | 
				
			||||||
 | 
					    ($prefix:ident :: $typ:ident ; $(#[$meta:meta])*) => {
 | 
				
			||||||
 | 
					        wrap_functions!($prefix;
 | 
				
			||||||
 | 
					            $(#[$meta])*
 | 
				
			||||||
 | 
					            ///
 | 
				
			||||||
 | 
					            #[doc = concat!(" Returns: a new [`",stringify!($typ),"`] instance.")]
 | 
				
			||||||
 | 
					            fn new() -> NonNull<$typ> {
 | 
				
			||||||
 | 
					                heap_move_nonnull($typ)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        wrap_free!($prefix :: $typ);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					wrap_cc_only!(sp_cmd_clear::ClearCommand;
 | 
				
			||||||
    /// Set all pixels to the off state.
 | 
					    /// Set all pixels to the off state.
 | 
				
			||||||
    ///
 | 
					    ///
 | 
				
			||||||
    /// Does not affect brightness.
 | 
					    /// Does not affect brightness.
 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// Returns: a new [ClearCommand] instance.
 | 
					 | 
				
			||||||
    fn new() -> NonNull<ClearCommand> {
 | 
					 | 
				
			||||||
        heap_move_nonnull(ClearCommand)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
wrap_free!(sp_cmd_clear::ClearCommand);
 | 
					wrap_cc_only!(sp_cmd_hard_reset::HardResetCommand;
 | 
				
			||||||
 | 
					 | 
				
			||||||
wrap_functions!(sp_cmd_hard_reset;
 | 
					 | 
				
			||||||
    /// Kills the udp daemon on the display, which usually results in a restart.
 | 
					    /// Kills the udp daemon on the display, which usually results in a restart.
 | 
				
			||||||
    ///
 | 
					    ///
 | 
				
			||||||
    /// Please do not send this in your normal program flow.
 | 
					    /// Please do not send this in your normal program flow.
 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// Returns: a new [HardResetCommand] instance.
 | 
					 | 
				
			||||||
    fn new() -> NonNull<HardResetCommand> {
 | 
					 | 
				
			||||||
        heap_move_nonnull(HardResetCommand)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
wrap_free!(sp_cmd_hard_reset::HardResetCommand);
 | 
					wrap_cc_only!(sp_cmd_fade_out::FadeOutCommand;
 | 
				
			||||||
 | 
					 | 
				
			||||||
wrap_functions!(sp_cmd_fade_out;
 | 
					 | 
				
			||||||
    /// A yet-to-be-tested command.
 | 
					    /// A yet-to-be-tested command.
 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// Returns: a new [FadeOutCommand] instance.
 | 
					 | 
				
			||||||
    fn new() -> NonNull<FadeOutCommand> {
 | 
					 | 
				
			||||||
        heap_move_nonnull(FadeOutCommand)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					 | 
				
			||||||
wrap_free!(sp_cmd_fade_out::FadeOutCommand);
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,9 @@
 | 
				
			||||||
use crate::mem::{
 | 
					use crate::{
 | 
				
			||||||
    heap_clone, heap_drop, heap_move, heap_move_nonnull, heap_move_ok,
 | 
					    macros::wrap_functions,
 | 
				
			||||||
    heap_remove,
 | 
					    mem::{
 | 
				
			||||||
 | 
					        heap_clone, heap_drop, heap_move, heap_move_nonnull, heap_move_ok,
 | 
				
			||||||
 | 
					        heap_remove,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use servicepoint::{
 | 
					use servicepoint::{
 | 
				
			||||||
    BitVecCommand, BitmapCommand, BrightnessGridCommand, CharGridCommand,
 | 
					    BitVecCommand, BitmapCommand, BrightnessGridCommand, CharGridCommand,
 | 
				
			||||||
| 
						 | 
					@ -66,233 +69,233 @@ impl SPCommand {
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Tries to turn a [Packet] into a [SPCommand].
 | 
					wrap_functions!(sp_cmd_generic;
 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// The packet is dropped in the process.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// Returns: pointer to new [SPCommand] instance or NULL if parsing failed.
 | 
					 | 
				
			||||||
#[no_mangle]
 | 
					 | 
				
			||||||
pub unsafe extern "C" fn sp_cmd_generic_try_from_packet(
 | 
					 | 
				
			||||||
    packet: NonNull<Packet>,
 | 
					 | 
				
			||||||
) -> SPCommand {
 | 
					 | 
				
			||||||
    let packet = *unsafe { Box::from_raw(packet.as_ptr()) };
 | 
					 | 
				
			||||||
    servicepoint::TypedCommand::try_from(packet)
 | 
					 | 
				
			||||||
        .map(|value| match value {
 | 
					 | 
				
			||||||
            TypedCommand::Clear(clear) => SPCommand {
 | 
					 | 
				
			||||||
                tag: CommandTag::Clear,
 | 
					 | 
				
			||||||
                data: CommandUnion {
 | 
					 | 
				
			||||||
                    clear: heap_move_nonnull(clear),
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            TypedCommand::CharGrid(char_grid) => SPCommand {
 | 
					 | 
				
			||||||
                tag: CommandTag::CharGrid,
 | 
					 | 
				
			||||||
                data: CommandUnion {
 | 
					 | 
				
			||||||
                    char_grid: heap_move_nonnull(char_grid),
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            TypedCommand::Cp437Grid(cp437_grid) => SPCommand {
 | 
					 | 
				
			||||||
                tag: CommandTag::Cp437Grid,
 | 
					 | 
				
			||||||
                data: CommandUnion {
 | 
					 | 
				
			||||||
                    cp437_grid: heap_move_nonnull(cp437_grid),
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            TypedCommand::Bitmap(bitmap) => SPCommand {
 | 
					 | 
				
			||||||
                tag: CommandTag::Bitmap,
 | 
					 | 
				
			||||||
                data: CommandUnion {
 | 
					 | 
				
			||||||
                    bitmap: heap_move_nonnull(bitmap),
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            TypedCommand::Brightness(global_brightness) => SPCommand {
 | 
					 | 
				
			||||||
                tag: CommandTag::GlobalBrightness,
 | 
					 | 
				
			||||||
                data: CommandUnion {
 | 
					 | 
				
			||||||
                    global_brightness: heap_move_nonnull(global_brightness),
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            TypedCommand::BrightnessGrid(brightness_grid) => SPCommand {
 | 
					 | 
				
			||||||
                tag: CommandTag::BrightnessGrid,
 | 
					 | 
				
			||||||
                data: CommandUnion {
 | 
					 | 
				
			||||||
                    brightness_grid: heap_move_nonnull(brightness_grid),
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            TypedCommand::BitVec(bitvec) => SPCommand {
 | 
					 | 
				
			||||||
                tag: CommandTag::BitVec,
 | 
					 | 
				
			||||||
                data: CommandUnion {
 | 
					 | 
				
			||||||
                    bitvec: heap_move_nonnull(bitvec),
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            TypedCommand::HardReset(hard_reset) => SPCommand {
 | 
					 | 
				
			||||||
                tag: CommandTag::HardReset,
 | 
					 | 
				
			||||||
                data: CommandUnion {
 | 
					 | 
				
			||||||
                    hard_reset: heap_move_nonnull(hard_reset),
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            TypedCommand::FadeOut(fade_out) => SPCommand {
 | 
					 | 
				
			||||||
                tag: CommandTag::FadeOut,
 | 
					 | 
				
			||||||
                data: CommandUnion {
 | 
					 | 
				
			||||||
                    fade_out: heap_move_nonnull(fade_out),
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            #[allow(deprecated)]
 | 
					 | 
				
			||||||
            TypedCommand::BitmapLegacy(bitmap_legacy) => SPCommand {
 | 
					 | 
				
			||||||
                tag: CommandTag::BitmapLegacy,
 | 
					 | 
				
			||||||
                data: CommandUnion {
 | 
					 | 
				
			||||||
                    bitmap_legacy: heap_move_nonnull(bitmap_legacy),
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
        })
 | 
					 | 
				
			||||||
        .unwrap_or_else(move |_| SPCommand {
 | 
					 | 
				
			||||||
            tag: CommandTag::Invalid,
 | 
					 | 
				
			||||||
            data: CommandUnion { null: null_mut() },
 | 
					 | 
				
			||||||
        })
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Clones an [SPCommand] instance.
 | 
					    /// Tries to turn a [Packet] into a [SPCommand].
 | 
				
			||||||
///
 | 
					    ///
 | 
				
			||||||
/// returns: a new [SPCommand] instance.
 | 
					    /// The packet is dropped in the process.
 | 
				
			||||||
#[no_mangle]
 | 
					    ///
 | 
				
			||||||
pub unsafe extern "C" fn sp_cmd_generic_clone(command: SPCommand) -> SPCommand {
 | 
					    /// Returns: pointer to new [SPCommand] instance or NULL if parsing failed.
 | 
				
			||||||
    unsafe {
 | 
					    fn try_from_packet(
 | 
				
			||||||
        match command.tag {
 | 
					        packet: NonNull<Packet>,
 | 
				
			||||||
            CommandTag::Clear => SPCommand {
 | 
					    ) -> SPCommand {
 | 
				
			||||||
                tag: CommandTag::Clear,
 | 
					        let packet = *unsafe { Box::from_raw(packet.as_ptr()) };
 | 
				
			||||||
                data: CommandUnion {
 | 
					        servicepoint::TypedCommand::try_from(packet)
 | 
				
			||||||
                    clear: heap_clone(command.data.clear),
 | 
					            .map(|value| match value {
 | 
				
			||||||
 | 
					                TypedCommand::Clear(clear) => SPCommand {
 | 
				
			||||||
 | 
					                    tag: CommandTag::Clear,
 | 
				
			||||||
 | 
					                    data: CommandUnion {
 | 
				
			||||||
 | 
					                        clear: heap_move_nonnull(clear),
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
            },
 | 
					                TypedCommand::CharGrid(char_grid) => SPCommand {
 | 
				
			||||||
            CommandTag::CharGrid => SPCommand {
 | 
					                    tag: CommandTag::CharGrid,
 | 
				
			||||||
                tag: CommandTag::CharGrid,
 | 
					                    data: CommandUnion {
 | 
				
			||||||
                data: CommandUnion {
 | 
					                        char_grid: heap_move_nonnull(char_grid),
 | 
				
			||||||
                    char_grid: heap_clone(command.data.char_grid),
 | 
					                    },
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
            },
 | 
					                TypedCommand::Cp437Grid(cp437_grid) => SPCommand {
 | 
				
			||||||
            CommandTag::Cp437Grid => SPCommand {
 | 
					                    tag: CommandTag::Cp437Grid,
 | 
				
			||||||
                tag: CommandTag::Cp437Grid,
 | 
					                    data: CommandUnion {
 | 
				
			||||||
                data: CommandUnion {
 | 
					                        cp437_grid: heap_move_nonnull(cp437_grid),
 | 
				
			||||||
                    cp437_grid: heap_clone(command.data.cp437_grid),
 | 
					                    },
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
            },
 | 
					                TypedCommand::Bitmap(bitmap) => SPCommand {
 | 
				
			||||||
            CommandTag::Bitmap => SPCommand {
 | 
					                    tag: CommandTag::Bitmap,
 | 
				
			||||||
                tag: CommandTag::Bitmap,
 | 
					                    data: CommandUnion {
 | 
				
			||||||
                data: CommandUnion {
 | 
					                        bitmap: heap_move_nonnull(bitmap),
 | 
				
			||||||
                    bitmap: heap_clone(command.data.bitmap),
 | 
					                    },
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
            },
 | 
					                TypedCommand::Brightness(global_brightness) => SPCommand {
 | 
				
			||||||
            CommandTag::GlobalBrightness => SPCommand {
 | 
					                    tag: CommandTag::GlobalBrightness,
 | 
				
			||||||
                tag: CommandTag::GlobalBrightness,
 | 
					                    data: CommandUnion {
 | 
				
			||||||
                data: CommandUnion {
 | 
					                        global_brightness: heap_move_nonnull(global_brightness),
 | 
				
			||||||
                    global_brightness: heap_clone(
 | 
					                    },
 | 
				
			||||||
                        command.data.global_brightness,
 | 
					 | 
				
			||||||
                    ),
 | 
					 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
            },
 | 
					                TypedCommand::BrightnessGrid(brightness_grid) => SPCommand {
 | 
				
			||||||
            CommandTag::BrightnessGrid => SPCommand {
 | 
					                    tag: CommandTag::BrightnessGrid,
 | 
				
			||||||
                tag: CommandTag::BrightnessGrid,
 | 
					                    data: CommandUnion {
 | 
				
			||||||
                data: CommandUnion {
 | 
					                        brightness_grid: heap_move_nonnull(brightness_grid),
 | 
				
			||||||
                    brightness_grid: heap_clone(command.data.brightness_grid),
 | 
					                    },
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
            },
 | 
					                TypedCommand::BitVec(bitvec) => SPCommand {
 | 
				
			||||||
            CommandTag::BitVec => SPCommand {
 | 
					                    tag: CommandTag::BitVec,
 | 
				
			||||||
                tag: CommandTag::BitVec,
 | 
					                    data: CommandUnion {
 | 
				
			||||||
                data: CommandUnion {
 | 
					                        bitvec: heap_move_nonnull(bitvec),
 | 
				
			||||||
                    bitvec: heap_clone(command.data.bitvec),
 | 
					                    },
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
            },
 | 
					                TypedCommand::HardReset(hard_reset) => SPCommand {
 | 
				
			||||||
            CommandTag::HardReset => SPCommand {
 | 
					                    tag: CommandTag::HardReset,
 | 
				
			||||||
                tag: CommandTag::HardReset,
 | 
					                    data: CommandUnion {
 | 
				
			||||||
                data: CommandUnion {
 | 
					                        hard_reset: heap_move_nonnull(hard_reset),
 | 
				
			||||||
                    hard_reset: heap_clone(command.data.hard_reset),
 | 
					                    },
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
            },
 | 
					                TypedCommand::FadeOut(fade_out) => SPCommand {
 | 
				
			||||||
            CommandTag::FadeOut => SPCommand {
 | 
					                    tag: CommandTag::FadeOut,
 | 
				
			||||||
                tag: CommandTag::FadeOut,
 | 
					                    data: CommandUnion {
 | 
				
			||||||
                data: CommandUnion {
 | 
					                        fade_out: heap_move_nonnull(fade_out),
 | 
				
			||||||
                    fade_out: heap_clone(command.data.fade_out),
 | 
					                    },
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
            },
 | 
					                #[allow(deprecated)]
 | 
				
			||||||
            #[allow(deprecated)]
 | 
					                TypedCommand::BitmapLegacy(bitmap_legacy) => SPCommand {
 | 
				
			||||||
            CommandTag::BitmapLegacy => SPCommand {
 | 
					                    tag: CommandTag::BitmapLegacy,
 | 
				
			||||||
                tag: CommandTag::BitmapLegacy,
 | 
					                    data: CommandUnion {
 | 
				
			||||||
                data: CommandUnion {
 | 
					                        bitmap_legacy: heap_move_nonnull(bitmap_legacy),
 | 
				
			||||||
                    bitmap_legacy: heap_clone(command.data.bitmap_legacy),
 | 
					                    },
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
            },
 | 
					            })
 | 
				
			||||||
            CommandTag::Invalid => SPCommand::INVALID,
 | 
					            .unwrap_or_else(move |_| SPCommand {
 | 
				
			||||||
        }
 | 
					                tag: CommandTag::Invalid,
 | 
				
			||||||
 | 
					                data: CommandUnion { null: null_mut() },
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Deallocates an [SPCommand].
 | 
					    /// Clones an [SPCommand] instance.
 | 
				
			||||||
///
 | 
					    ///
 | 
				
			||||||
/// Commands with an invalid `tag` do not have to be freed as the `data` pointer should be null.
 | 
					    /// returns: a new [SPCommand] instance.
 | 
				
			||||||
///
 | 
					    fn clone(command: SPCommand) -> SPCommand {
 | 
				
			||||||
/// # Examples
 | 
					        unsafe {
 | 
				
			||||||
///
 | 
					            match command.tag {
 | 
				
			||||||
/// ```C
 | 
					                CommandTag::Clear => SPCommand {
 | 
				
			||||||
/// SPCommand c = sp_cmd_clear_into_generic(sp_cmd_clear_new());
 | 
					                    tag: CommandTag::Clear,
 | 
				
			||||||
/// sp_command_free(c);
 | 
					                    data: CommandUnion {
 | 
				
			||||||
/// ```
 | 
					                        clear: heap_clone(command.data.clear),
 | 
				
			||||||
#[no_mangle]
 | 
					                    },
 | 
				
			||||||
pub unsafe extern "C" fn sp_cmd_generic_free(command: SPCommand) {
 | 
					                },
 | 
				
			||||||
    unsafe {
 | 
					                CommandTag::CharGrid => SPCommand {
 | 
				
			||||||
        match command.tag {
 | 
					                    tag: CommandTag::CharGrid,
 | 
				
			||||||
            CommandTag::Invalid => (),
 | 
					                    data: CommandUnion {
 | 
				
			||||||
            CommandTag::Bitmap => heap_drop(command.data.bitmap),
 | 
					                        char_grid: heap_clone(command.data.char_grid),
 | 
				
			||||||
            CommandTag::BitVec => heap_drop(command.data.bitvec),
 | 
					                    },
 | 
				
			||||||
            CommandTag::BrightnessGrid => {
 | 
					                },
 | 
				
			||||||
                heap_drop(command.data.brightness_grid)
 | 
					                CommandTag::Cp437Grid => SPCommand {
 | 
				
			||||||
 | 
					                    tag: CommandTag::Cp437Grid,
 | 
				
			||||||
 | 
					                    data: CommandUnion {
 | 
				
			||||||
 | 
					                        cp437_grid: heap_clone(command.data.cp437_grid),
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                CommandTag::Bitmap => SPCommand {
 | 
				
			||||||
 | 
					                    tag: CommandTag::Bitmap,
 | 
				
			||||||
 | 
					                    data: CommandUnion {
 | 
				
			||||||
 | 
					                        bitmap: heap_clone(command.data.bitmap),
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                CommandTag::GlobalBrightness => SPCommand {
 | 
				
			||||||
 | 
					                    tag: CommandTag::GlobalBrightness,
 | 
				
			||||||
 | 
					                    data: CommandUnion {
 | 
				
			||||||
 | 
					                        global_brightness: heap_clone(
 | 
				
			||||||
 | 
					                            command.data.global_brightness,
 | 
				
			||||||
 | 
					                        ),
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                CommandTag::BrightnessGrid => SPCommand {
 | 
				
			||||||
 | 
					                    tag: CommandTag::BrightnessGrid,
 | 
				
			||||||
 | 
					                    data: CommandUnion {
 | 
				
			||||||
 | 
					                        brightness_grid: heap_clone(command.data.brightness_grid),
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                CommandTag::BitVec => SPCommand {
 | 
				
			||||||
 | 
					                    tag: CommandTag::BitVec,
 | 
				
			||||||
 | 
					                    data: CommandUnion {
 | 
				
			||||||
 | 
					                        bitvec: heap_clone(command.data.bitvec),
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                CommandTag::HardReset => SPCommand {
 | 
				
			||||||
 | 
					                    tag: CommandTag::HardReset,
 | 
				
			||||||
 | 
					                    data: CommandUnion {
 | 
				
			||||||
 | 
					                        hard_reset: heap_clone(command.data.hard_reset),
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                CommandTag::FadeOut => SPCommand {
 | 
				
			||||||
 | 
					                    tag: CommandTag::FadeOut,
 | 
				
			||||||
 | 
					                    data: CommandUnion {
 | 
				
			||||||
 | 
					                        fade_out: heap_clone(command.data.fade_out),
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                #[allow(deprecated)]
 | 
				
			||||||
 | 
					                CommandTag::BitmapLegacy => SPCommand {
 | 
				
			||||||
 | 
					                    tag: CommandTag::BitmapLegacy,
 | 
				
			||||||
 | 
					                    data: CommandUnion {
 | 
				
			||||||
 | 
					                        bitmap_legacy: heap_clone(command.data.bitmap_legacy),
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                CommandTag::Invalid => SPCommand::INVALID,
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            CommandTag::CharGrid => heap_drop(command.data.char_grid),
 | 
					 | 
				
			||||||
            CommandTag::Cp437Grid => heap_drop(command.data.cp437_grid),
 | 
					 | 
				
			||||||
            CommandTag::GlobalBrightness => {
 | 
					 | 
				
			||||||
                heap_drop(command.data.global_brightness)
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            CommandTag::Clear => heap_drop(command.data.clear),
 | 
					 | 
				
			||||||
            CommandTag::HardReset => heap_drop(command.data.hard_reset),
 | 
					 | 
				
			||||||
            CommandTag::FadeOut => heap_drop(command.data.fade_out),
 | 
					 | 
				
			||||||
            CommandTag::BitmapLegacy => heap_drop(command.data.bitmap_legacy),
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Tries to turn a [SPCommand] into a [Packet].
 | 
					    /// Deallocates an [SPCommand].
 | 
				
			||||||
/// The [SPCommand] gets consumed.
 | 
					    ///
 | 
				
			||||||
///
 | 
					    /// Commands with an invalid `tag` do not have to be freed as the `data` pointer should be null.
 | 
				
			||||||
/// Returns tag [CommandTag::Invalid] in case of an error.
 | 
					    ///
 | 
				
			||||||
#[no_mangle]
 | 
					    /// # Examples
 | 
				
			||||||
pub unsafe extern "C" fn sp_cmd_generic_into_packet(
 | 
					    ///
 | 
				
			||||||
    command: SPCommand,
 | 
					    /// ```C
 | 
				
			||||||
) -> *mut Packet {
 | 
					    /// SPCommand c = sp_cmd_clear_into_generic(sp_cmd_clear_new());
 | 
				
			||||||
    match command.tag {
 | 
					    /// sp_command_free(c);
 | 
				
			||||||
        CommandTag::Invalid => null_mut(),
 | 
					    /// ```
 | 
				
			||||||
        CommandTag::Bitmap => {
 | 
					    fn free(command: SPCommand) {
 | 
				
			||||||
            heap_move_ok(unsafe { heap_remove(command.data.bitmap).try_into() })
 | 
					        unsafe {
 | 
				
			||||||
        }
 | 
					            match command.tag {
 | 
				
			||||||
        CommandTag::BitVec => {
 | 
					                CommandTag::Invalid => (),
 | 
				
			||||||
            heap_move_ok(unsafe { heap_remove(command.data.bitvec).try_into() })
 | 
					                CommandTag::Bitmap => heap_drop(command.data.bitmap),
 | 
				
			||||||
        }
 | 
					                CommandTag::BitVec => heap_drop(command.data.bitvec),
 | 
				
			||||||
        CommandTag::BrightnessGrid => heap_move_ok(unsafe {
 | 
					                CommandTag::BrightnessGrid => {
 | 
				
			||||||
            heap_remove(command.data.brightness_grid).try_into()
 | 
					                    heap_drop(command.data.brightness_grid)
 | 
				
			||||||
        }),
 | 
					                }
 | 
				
			||||||
        CommandTag::CharGrid => heap_move_ok(unsafe {
 | 
					                CommandTag::CharGrid => heap_drop(command.data.char_grid),
 | 
				
			||||||
            heap_remove(command.data.char_grid).try_into()
 | 
					                CommandTag::Cp437Grid => heap_drop(command.data.cp437_grid),
 | 
				
			||||||
        }),
 | 
					                CommandTag::GlobalBrightness => {
 | 
				
			||||||
        CommandTag::Cp437Grid => heap_move_ok(unsafe {
 | 
					                    heap_drop(command.data.global_brightness)
 | 
				
			||||||
            heap_remove(command.data.cp437_grid).try_into()
 | 
					                }
 | 
				
			||||||
        }),
 | 
					                CommandTag::Clear => heap_drop(command.data.clear),
 | 
				
			||||||
        CommandTag::GlobalBrightness => heap_move(unsafe {
 | 
					                CommandTag::HardReset => heap_drop(command.data.hard_reset),
 | 
				
			||||||
            heap_remove(command.data.global_brightness).into()
 | 
					                CommandTag::FadeOut => heap_drop(command.data.fade_out),
 | 
				
			||||||
        }),
 | 
					                CommandTag::BitmapLegacy => heap_drop(command.data.bitmap_legacy),
 | 
				
			||||||
        CommandTag::Clear => {
 | 
					            }
 | 
				
			||||||
            heap_move(unsafe { heap_remove(command.data.clear).into() })
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        CommandTag::HardReset => {
 | 
					 | 
				
			||||||
            heap_move(unsafe { heap_remove(command.data.hard_reset).into() })
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        CommandTag::FadeOut => {
 | 
					 | 
				
			||||||
            heap_move(unsafe { heap_remove(command.data.fade_out).into() })
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        CommandTag::BitmapLegacy => {
 | 
					 | 
				
			||||||
            heap_move(unsafe { heap_remove(command.data.bitmap_legacy).into() })
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					
 | 
				
			||||||
 | 
					    /// Tries to turn a [SPCommand] into a [Packet].
 | 
				
			||||||
 | 
					    /// The [SPCommand] gets consumed.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// Returns tag [CommandTag::Invalid] in case of an error.
 | 
				
			||||||
 | 
					    fn into_packet(
 | 
				
			||||||
 | 
					        command: SPCommand,
 | 
				
			||||||
 | 
					    ) -> *mut Packet {
 | 
				
			||||||
 | 
					        match command.tag {
 | 
				
			||||||
 | 
					            CommandTag::Invalid => null_mut(),
 | 
				
			||||||
 | 
					            CommandTag::Bitmap => {
 | 
				
			||||||
 | 
					                heap_move_ok(unsafe { heap_remove(command.data.bitmap).try_into() })
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            CommandTag::BitVec => {
 | 
				
			||||||
 | 
					                heap_move_ok(unsafe { heap_remove(command.data.bitvec).try_into() })
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            CommandTag::BrightnessGrid => heap_move_ok(unsafe {
 | 
				
			||||||
 | 
					                heap_remove(command.data.brightness_grid).try_into()
 | 
				
			||||||
 | 
					            }),
 | 
				
			||||||
 | 
					            CommandTag::CharGrid => heap_move_ok(unsafe {
 | 
				
			||||||
 | 
					                heap_remove(command.data.char_grid).try_into()
 | 
				
			||||||
 | 
					            }),
 | 
				
			||||||
 | 
					            CommandTag::Cp437Grid => heap_move_ok(unsafe {
 | 
				
			||||||
 | 
					                heap_remove(command.data.cp437_grid).try_into()
 | 
				
			||||||
 | 
					            }),
 | 
				
			||||||
 | 
					            CommandTag::GlobalBrightness => heap_move(unsafe {
 | 
				
			||||||
 | 
					                heap_remove(command.data.global_brightness).into()
 | 
				
			||||||
 | 
					            }),
 | 
				
			||||||
 | 
					            CommandTag::Clear => {
 | 
				
			||||||
 | 
					                heap_move(unsafe { heap_remove(command.data.clear).into() })
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            CommandTag::HardReset => {
 | 
				
			||||||
 | 
					                heap_move(unsafe { heap_remove(command.data.hard_reset).into() })
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            CommandTag::FadeOut => {
 | 
				
			||||||
 | 
					                heap_move(unsafe { heap_remove(command.data.fade_out).into() })
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            CommandTag::BitmapLegacy => {
 | 
				
			||||||
 | 
					                heap_move(unsafe { heap_remove(command.data.bitmap_legacy).into() })
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,7 +35,7 @@ impl ByteSlice {
 | 
				
			||||||
        unsafe { std::slice::from_raw_parts(self.start, self.length) }
 | 
					        unsafe { std::slice::from_raw_parts(self.start, self.length) }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub(crate) unsafe fn as_slice_mut(&mut self) -> &mut [u8] {
 | 
					    pub(crate) unsafe fn as_slice_mut(&self) -> &mut [u8] {
 | 
				
			||||||
        unsafe { std::slice::from_raw_parts_mut(self.start, self.length) }
 | 
					        unsafe { std::slice::from_raw_parts_mut(self.start, self.length) }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										15
									
								
								src/lib.rs
									
										
									
									
									
								
							
							
						
						
									
										15
									
								
								src/lib.rs
									
										
									
									
									
								
							| 
						 | 
					@ -47,10 +47,13 @@ pub struct DisplayBitVec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[cfg(feature = "env_logger")]
 | 
					#[cfg(feature = "env_logger")]
 | 
				
			||||||
mod feature_env_logger {
 | 
					mod feature_env_logger {
 | 
				
			||||||
    /// Call this function at the beginning of main to enable rust logging controlled by the
 | 
					    use crate::macros::wrap_functions;
 | 
				
			||||||
    /// `RUST_LOG` environment variable. See [env_logger](https://docs.rs/env_logger/latest/env_logger/).
 | 
					
 | 
				
			||||||
    #[no_mangle]
 | 
					    wrap_functions!(sp_envlogger;
 | 
				
			||||||
    pub unsafe extern "C" fn init_env_logger() {
 | 
					        /// Call this function at the beginning of main to enable rust logging controlled by the
 | 
				
			||||||
        env_logger::init();
 | 
					        /// `RUST_LOG` environment variable. See [env_logger](https://docs.rs/env_logger/latest/env_logger/).
 | 
				
			||||||
    }
 | 
					        fn init() {
 | 
				
			||||||
 | 
					            env_logger::init();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										163
									
								
								src/packet.rs
									
										
									
									
									
								
							
							
						
						
									
										163
									
								
								src/packet.rs
									
										
									
									
									
								
							| 
						 | 
					@ -1,95 +1,72 @@
 | 
				
			||||||
use crate::{
 | 
					use crate::{
 | 
				
			||||||
    containers::ByteSlice,
 | 
					    containers::ByteSlice,
 | 
				
			||||||
    macros::{wrap_clone, wrap_fields, wrap_free},
 | 
					    macros::{wrap_clone, wrap_fields, wrap_free, wrap_functions},
 | 
				
			||||||
    mem::{heap_move_nonnull, heap_move_ok},
 | 
					    mem::{heap_move_nonnull, heap_move_ok},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use servicepoint::{CommandCode, Header, Packet};
 | 
					use servicepoint::{CommandCode, Header, Packet};
 | 
				
			||||||
use std::ptr::NonNull;
 | 
					use std::ptr::NonNull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Tries to load a [Packet] from the passed array with the specified length.
 | 
					wrap_functions!(sp_packet;
 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// returns: NULL in case of an error, pointer to the allocated packet otherwise
 | 
					 | 
				
			||||||
#[no_mangle]
 | 
					 | 
				
			||||||
pub unsafe extern "C" fn sp_packet_try_load(data: ByteSlice) -> *mut Packet {
 | 
					 | 
				
			||||||
    let data = unsafe { data.as_slice() };
 | 
					 | 
				
			||||||
    heap_move_ok(servicepoint::Packet::try_from(data))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Creates a raw [Packet] from parts.
 | 
					    /// Tries to load a [Packet] from the passed array with the specified length.
 | 
				
			||||||
///
 | 
					    ///
 | 
				
			||||||
/// returns: new instance. Will never return null.
 | 
					    /// returns: NULL in case of an error, pointer to the allocated packet otherwise
 | 
				
			||||||
#[no_mangle]
 | 
					    fn try_load(data: ByteSlice) -> *mut Packet {
 | 
				
			||||||
pub unsafe extern "C" fn sp_packet_from_parts(
 | 
					        let data = unsafe { data.as_slice() };
 | 
				
			||||||
    header: Header,
 | 
					        heap_move_ok(servicepoint::Packet::try_from(data))
 | 
				
			||||||
    payload: ByteSlice,
 | 
					 | 
				
			||||||
) -> NonNull<Packet> {
 | 
					 | 
				
			||||||
    let payload = if payload == ByteSlice::INVALID {
 | 
					 | 
				
			||||||
        None
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        Some(Vec::from(unsafe { payload.as_slice() }))
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    heap_move_nonnull(Packet { header, payload })
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Returns a pointer to the header field of the provided packet.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// The returned header can be changed and will be valid for the lifetime of the packet.
 | 
					 | 
				
			||||||
#[no_mangle]
 | 
					 | 
				
			||||||
pub unsafe extern "C" fn sp_packet_get_header_mut(
 | 
					 | 
				
			||||||
    packet: NonNull<Packet>,
 | 
					 | 
				
			||||||
) -> NonNull<Header> {
 | 
					 | 
				
			||||||
    NonNull::from(unsafe { &mut (*packet.as_ptr()).header })
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// 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.
 | 
					 | 
				
			||||||
#[no_mangle]
 | 
					 | 
				
			||||||
pub unsafe extern "C" fn sp_packet_get_payload(
 | 
					 | 
				
			||||||
    packet: NonNull<Packet>,
 | 
					 | 
				
			||||||
) -> ByteSlice {
 | 
					 | 
				
			||||||
    unsafe {
 | 
					 | 
				
			||||||
        match &mut (*packet.as_ptr()).payload {
 | 
					 | 
				
			||||||
            None => ByteSlice::INVALID,
 | 
					 | 
				
			||||||
            Some(payload) => ByteSlice::from_slice(payload),
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Sets the payload of the provided packet to the provided data.
 | 
					    /// Creates a raw [Packet] from parts.
 | 
				
			||||||
///
 | 
					    ///
 | 
				
			||||||
/// This makes previous payload pointers invalid.
 | 
					    /// returns: new instance. Will never return null.
 | 
				
			||||||
#[no_mangle]
 | 
					    fn from_parts(header: Header, payload: ByteSlice) -> NonNull<Packet> {
 | 
				
			||||||
pub unsafe extern "C" fn sp_packet_set_payload(
 | 
					        let payload = if payload == ByteSlice::INVALID {
 | 
				
			||||||
    packet: NonNull<Packet>,
 | 
					 | 
				
			||||||
    data: ByteSlice,
 | 
					 | 
				
			||||||
) {
 | 
					 | 
				
			||||||
    unsafe {
 | 
					 | 
				
			||||||
        (*packet.as_ptr()).payload = if data == ByteSlice::INVALID {
 | 
					 | 
				
			||||||
            None
 | 
					            None
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            Some(data.as_slice().to_vec())
 | 
					            Some(Vec::from(unsafe { payload.as_slice() }))
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        heap_move_nonnull(Packet { header, payload })
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// 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(packet: NonNull<Packet>) -> ByteSlice {
 | 
				
			||||||
 | 
					        unsafe {
 | 
				
			||||||
 | 
					            match &mut (*packet.as_ptr()).payload {
 | 
				
			||||||
 | 
					                None => ByteSlice::INVALID,
 | 
				
			||||||
 | 
					                Some(payload) => ByteSlice::from_slice(payload),
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Serialize the packet into the provided buffer.
 | 
					    /// Sets the payload of the provided packet to the provided data.
 | 
				
			||||||
///
 | 
					    ///
 | 
				
			||||||
/// # Panics
 | 
					    /// This makes previous payload pointers invalid.
 | 
				
			||||||
///
 | 
					    fn set_payload(packet: NonNull<Packet>, data: ByteSlice) {
 | 
				
			||||||
/// - if the buffer is not big enough to hold header+payload.
 | 
					        unsafe {
 | 
				
			||||||
#[no_mangle]
 | 
					            (*packet.as_ptr()).payload = if data == ByteSlice::INVALID {
 | 
				
			||||||
pub unsafe extern "C" fn sp_packet_serialize_to(
 | 
					                None
 | 
				
			||||||
    packet: NonNull<Packet>,
 | 
					            } else {
 | 
				
			||||||
    mut buffer: ByteSlice,
 | 
					                Some(data.as_slice().to_vec())
 | 
				
			||||||
) {
 | 
					            }
 | 
				
			||||||
    unsafe {
 | 
					        }
 | 
				
			||||||
        packet.as_ref().serialize_to(buffer.as_slice_mut());
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					
 | 
				
			||||||
 | 
					    /// Serialize the packet into the provided buffer.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// # Panics
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// - if the buffer is not big enough to hold header+payload.
 | 
				
			||||||
 | 
					    fn serialize_to(packet: NonNull<Packet>, buffer: ByteSlice) -> usize {
 | 
				
			||||||
 | 
					        unsafe {
 | 
				
			||||||
 | 
					            packet.as_ref().serialize_to(buffer.as_slice_mut()).unwrap_or(0)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
wrap_clone!(sp_packet::Packet);
 | 
					wrap_clone!(sp_packet::Packet);
 | 
				
			||||||
wrap_free!(sp_packet::Packet);
 | 
					wrap_free!(sp_packet::Packet);
 | 
				
			||||||
| 
						 | 
					@ -98,25 +75,29 @@ wrap_fields!(
 | 
				
			||||||
    sp_packet::Packet;
 | 
					    sp_packet::Packet;
 | 
				
			||||||
    prop header: Header {
 | 
					    prop header: Header {
 | 
				
			||||||
        get();
 | 
					        get();
 | 
				
			||||||
 | 
					        mut get();
 | 
				
			||||||
        set(value);
 | 
					        set(value);
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Converts u16 into [CommandCode].
 | 
					wrap_functions!(sp;
 | 
				
			||||||
///
 | 
					
 | 
				
			||||||
/// If the provided value is not valid, false is returned and result is not changed.
 | 
					    /// Converts u16 into [CommandCode].
 | 
				
			||||||
#[no_mangle]
 | 
					    ///
 | 
				
			||||||
pub unsafe extern "C" fn sp_u16_to_command_code(
 | 
					    /// If the provided value is not valid, false is returned and result is not changed.
 | 
				
			||||||
    code: u16,
 | 
					    fn u16_to_command_code(
 | 
				
			||||||
    result: *mut CommandCode,
 | 
					        code: u16,
 | 
				
			||||||
) -> bool {
 | 
					        result: *mut CommandCode,
 | 
				
			||||||
    match CommandCode::try_from(code) {
 | 
					    ) -> bool {
 | 
				
			||||||
        Ok(code) => {
 | 
					        match CommandCode::try_from(code) {
 | 
				
			||||||
            unsafe {
 | 
					            Ok(code) => {
 | 
				
			||||||
                *result = code;
 | 
					                unsafe {
 | 
				
			||||||
 | 
					                    *result = code;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                true
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            true
 | 
					            Err(_) => false,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        Err(_) => false,
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										254
									
								
								src/udp.rs
									
										
									
									
									
								
							
							
						
						
									
										254
									
								
								src/udp.rs
									
										
									
									
									
								
							| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
use crate::{
 | 
					use crate::{
 | 
				
			||||||
    commands::{CommandTag, SPCommand},
 | 
					    commands::{CommandTag, SPCommand},
 | 
				
			||||||
    macros::wrap_free,
 | 
					    macros::{wrap_free, wrap_functions},
 | 
				
			||||||
    mem::{heap_move_ok, heap_remove},
 | 
					    mem::{heap_move_ok, heap_remove},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use servicepoint::{Header, Packet, UdpSocketExt};
 | 
					use servicepoint::{Header, Packet, UdpSocketExt};
 | 
				
			||||||
| 
						 | 
					@ -10,138 +10,122 @@ use std::{
 | 
				
			||||||
    ptr::NonNull,
 | 
					    ptr::NonNull,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Creates a new instance of [UdpSocket].
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// returns: NULL if connection fails, or connected instance
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// # Examples
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// ```C
 | 
					 | 
				
			||||||
/// UdpSocket connection = sp_udp_open("172.23.42.29:2342");
 | 
					 | 
				
			||||||
/// if (connection != NULL)
 | 
					 | 
				
			||||||
///     sp_udp_send_command(connection, sp_command_clear());
 | 
					 | 
				
			||||||
/// ```
 | 
					 | 
				
			||||||
#[no_mangle]
 | 
					 | 
				
			||||||
pub unsafe extern "C" fn sp_udp_open(host: NonNull<c_char>) -> *mut UdpSocket {
 | 
					 | 
				
			||||||
    let host = unsafe { CStr::from_ptr(host.as_ptr()) }
 | 
					 | 
				
			||||||
        .to_str()
 | 
					 | 
				
			||||||
        .expect("Bad encoding");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    heap_move_ok(UdpSocket::bind_connect(host))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Creates a new instance of [UdpSocket].
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// returns: NULL if connection fails, or connected instance
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// # Examples
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// ```C
 | 
					 | 
				
			||||||
/// UdpSocket connection = sp_udp_open_ipv4(172, 23, 42, 29, 2342);
 | 
					 | 
				
			||||||
/// if (connection != NULL)
 | 
					 | 
				
			||||||
///     sp_udp_send_command(connection, sp_command_clear());
 | 
					 | 
				
			||||||
/// ```
 | 
					 | 
				
			||||||
#[no_mangle]
 | 
					 | 
				
			||||||
pub unsafe extern "C" fn sp_udp_open_ipv4(
 | 
					 | 
				
			||||||
    ip1: u8,
 | 
					 | 
				
			||||||
    ip2: u8,
 | 
					 | 
				
			||||||
    ip3: u8,
 | 
					 | 
				
			||||||
    ip4: u8,
 | 
					 | 
				
			||||||
    port: u16,
 | 
					 | 
				
			||||||
) -> *mut UdpSocket {
 | 
					 | 
				
			||||||
    let addr = SocketAddrV4::new(Ipv4Addr::from([ip1, ip2, ip3, ip4]), port);
 | 
					 | 
				
			||||||
    heap_move_ok(UdpSocket::bind_connect(addr))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Sends a [Packet] to the display using the [UdpSocket].
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// The passed `packet` gets consumed.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// returns: true in case of success
 | 
					 | 
				
			||||||
#[no_mangle]
 | 
					 | 
				
			||||||
pub unsafe extern "C" fn sp_udp_send_packet(
 | 
					 | 
				
			||||||
    connection: NonNull<UdpSocket>,
 | 
					 | 
				
			||||||
    packet: NonNull<Packet>,
 | 
					 | 
				
			||||||
) -> bool {
 | 
					 | 
				
			||||||
    let packet = unsafe { heap_remove(packet) };
 | 
					 | 
				
			||||||
    unsafe { connection.as_ref().send(&Vec::from(packet)) }.is_ok()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Sends a [SPCommand] to the display using the [UdpSocket].
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// The passed `command` gets consumed.
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// returns: true in case of success
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// # Examples
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// ```C
 | 
					 | 
				
			||||||
/// sp_udp_send_command(connection, sp_command_brightness(5));
 | 
					 | 
				
			||||||
/// ```
 | 
					 | 
				
			||||||
#[no_mangle]
 | 
					 | 
				
			||||||
pub unsafe extern "C" fn sp_udp_send_command(
 | 
					 | 
				
			||||||
    connection: NonNull<UdpSocket>,
 | 
					 | 
				
			||||||
    command: SPCommand,
 | 
					 | 
				
			||||||
) -> bool {
 | 
					 | 
				
			||||||
    unsafe {
 | 
					 | 
				
			||||||
        match command.tag {
 | 
					 | 
				
			||||||
            CommandTag::Invalid => return false,
 | 
					 | 
				
			||||||
            CommandTag::Bitmap => connection
 | 
					 | 
				
			||||||
                .as_ref()
 | 
					 | 
				
			||||||
                .send_command(heap_remove(command.data.bitmap)),
 | 
					 | 
				
			||||||
            CommandTag::BitVec => connection
 | 
					 | 
				
			||||||
                .as_ref()
 | 
					 | 
				
			||||||
                .send_command(heap_remove(command.data.bitvec)),
 | 
					 | 
				
			||||||
            CommandTag::BrightnessGrid => connection
 | 
					 | 
				
			||||||
                .as_ref()
 | 
					 | 
				
			||||||
                .send_command(heap_remove(command.data.brightness_grid)),
 | 
					 | 
				
			||||||
            CommandTag::CharGrid => connection
 | 
					 | 
				
			||||||
                .as_ref()
 | 
					 | 
				
			||||||
                .send_command(heap_remove(command.data.char_grid)),
 | 
					 | 
				
			||||||
            CommandTag::Cp437Grid => connection
 | 
					 | 
				
			||||||
                .as_ref()
 | 
					 | 
				
			||||||
                .send_command(heap_remove(command.data.cp437_grid)),
 | 
					 | 
				
			||||||
            CommandTag::GlobalBrightness => connection
 | 
					 | 
				
			||||||
                .as_ref()
 | 
					 | 
				
			||||||
                .send_command(heap_remove(command.data.global_brightness)),
 | 
					 | 
				
			||||||
            CommandTag::Clear => connection
 | 
					 | 
				
			||||||
                .as_ref()
 | 
					 | 
				
			||||||
                .send_command(heap_remove(command.data.clear)),
 | 
					 | 
				
			||||||
            CommandTag::HardReset => connection
 | 
					 | 
				
			||||||
                .as_ref()
 | 
					 | 
				
			||||||
                .send_command(heap_remove(command.data.hard_reset)),
 | 
					 | 
				
			||||||
            CommandTag::FadeOut => connection
 | 
					 | 
				
			||||||
                .as_ref()
 | 
					 | 
				
			||||||
                .send_command(heap_remove(command.data.fade_out)),
 | 
					 | 
				
			||||||
            CommandTag::BitmapLegacy => connection
 | 
					 | 
				
			||||||
                .as_ref()
 | 
					 | 
				
			||||||
                .send_command(heap_remove(command.data.bitmap_legacy)),
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    .is_some()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Sends a [Header] to the display using the [UdpSocket].
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// returns: true in case of success
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// # Examples
 | 
					 | 
				
			||||||
///
 | 
					 | 
				
			||||||
/// ```C
 | 
					 | 
				
			||||||
/// sp_udp_send_header(connection, sp_command_brightness(5));
 | 
					 | 
				
			||||||
/// ```
 | 
					 | 
				
			||||||
#[no_mangle]
 | 
					 | 
				
			||||||
pub unsafe extern "C" fn sp_udp_send_header(
 | 
					 | 
				
			||||||
    udp_connection: NonNull<UdpSocket>,
 | 
					 | 
				
			||||||
    header: Header,
 | 
					 | 
				
			||||||
) -> bool {
 | 
					 | 
				
			||||||
    let packet = Packet {
 | 
					 | 
				
			||||||
        header,
 | 
					 | 
				
			||||||
        payload: None,
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
    unsafe { udp_connection.as_ref() }
 | 
					 | 
				
			||||||
        .send(&Vec::from(packet))
 | 
					 | 
				
			||||||
        .is_ok()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
wrap_free!(sp_udp::UdpSocket);
 | 
					wrap_free!(sp_udp::UdpSocket);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					wrap_functions!(sp_udp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Creates a new instance of [UdpSocket].
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// returns: NULL if connection fails, or connected instance
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// # Examples
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// ```C
 | 
				
			||||||
 | 
					    /// UdpSocket connection = sp_udp_open("172.23.42.29:2342");
 | 
				
			||||||
 | 
					    /// if (connection != NULL)
 | 
				
			||||||
 | 
					    ///     sp_udp_send_command(connection, sp_command_clear());
 | 
				
			||||||
 | 
					    /// ```
 | 
				
			||||||
 | 
					    fn open(host: NonNull<c_char>) -> *mut UdpSocket {
 | 
				
			||||||
 | 
					        let host = unsafe { CStr::from_ptr(host.as_ptr()) }
 | 
				
			||||||
 | 
					            .to_str()
 | 
				
			||||||
 | 
					            .expect("Bad encoding");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        heap_move_ok(UdpSocket::bind_connect(host))
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Creates a new instance of [UdpSocket].
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// returns: NULL if connection fails, or connected instance
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// # Examples
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// ```C
 | 
				
			||||||
 | 
					    /// UdpSocket connection = sp_udp_open_ipv4(172, 23, 42, 29, 2342);
 | 
				
			||||||
 | 
					    /// if (connection != NULL)
 | 
				
			||||||
 | 
					    ///     sp_udp_send_command(connection, sp_command_clear());
 | 
				
			||||||
 | 
					    /// ```
 | 
				
			||||||
 | 
					    fn open_ipv4(ip1: u8, ip2: u8, ip3: u8, ip4: u8, port: u16) -> *mut UdpSocket {
 | 
				
			||||||
 | 
					        let addr = SocketAddrV4::new(Ipv4Addr::from([ip1, ip2, ip3, ip4]), port);
 | 
				
			||||||
 | 
					        heap_move_ok(UdpSocket::bind_connect(addr))
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Sends a [Packet] to the display using the [UdpSocket].
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// The passed `packet` gets consumed.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// returns: true in case of success
 | 
				
			||||||
 | 
					    fn send_packet(connection: NonNull<UdpSocket>, packet: NonNull<Packet>) -> bool {
 | 
				
			||||||
 | 
					        let packet = unsafe { heap_remove(packet) };
 | 
				
			||||||
 | 
					        unsafe { connection.as_ref().send(&Vec::from(packet)) }.is_ok()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Sends a [SPCommand] to the display using the [UdpSocket].
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// The passed `command` gets consumed.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// returns: true in case of success
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// # Examples
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// ```C
 | 
				
			||||||
 | 
					    /// sp_udp_send_command(connection, sp_command_brightness(5));
 | 
				
			||||||
 | 
					    /// ```
 | 
				
			||||||
 | 
					    fn send_command(connection: NonNull<UdpSocket>, command: SPCommand) -> bool {
 | 
				
			||||||
 | 
					        unsafe {
 | 
				
			||||||
 | 
					            match command.tag {
 | 
				
			||||||
 | 
					                CommandTag::Invalid => return false,
 | 
				
			||||||
 | 
					                CommandTag::Bitmap => connection
 | 
				
			||||||
 | 
					                    .as_ref()
 | 
				
			||||||
 | 
					                    .send_command(heap_remove(command.data.bitmap)),
 | 
				
			||||||
 | 
					                CommandTag::BitVec => connection
 | 
				
			||||||
 | 
					                    .as_ref()
 | 
				
			||||||
 | 
					                    .send_command(heap_remove(command.data.bitvec)),
 | 
				
			||||||
 | 
					                CommandTag::BrightnessGrid => connection
 | 
				
			||||||
 | 
					                    .as_ref()
 | 
				
			||||||
 | 
					                    .send_command(heap_remove(command.data.brightness_grid)),
 | 
				
			||||||
 | 
					                CommandTag::CharGrid => connection
 | 
				
			||||||
 | 
					                    .as_ref()
 | 
				
			||||||
 | 
					                    .send_command(heap_remove(command.data.char_grid)),
 | 
				
			||||||
 | 
					                CommandTag::Cp437Grid => connection
 | 
				
			||||||
 | 
					                    .as_ref()
 | 
				
			||||||
 | 
					                    .send_command(heap_remove(command.data.cp437_grid)),
 | 
				
			||||||
 | 
					                CommandTag::GlobalBrightness => connection
 | 
				
			||||||
 | 
					                    .as_ref()
 | 
				
			||||||
 | 
					                    .send_command(heap_remove(command.data.global_brightness)),
 | 
				
			||||||
 | 
					                CommandTag::Clear => connection
 | 
				
			||||||
 | 
					                    .as_ref()
 | 
				
			||||||
 | 
					                    .send_command(heap_remove(command.data.clear)),
 | 
				
			||||||
 | 
					                CommandTag::HardReset => connection
 | 
				
			||||||
 | 
					                    .as_ref()
 | 
				
			||||||
 | 
					                    .send_command(heap_remove(command.data.hard_reset)),
 | 
				
			||||||
 | 
					                CommandTag::FadeOut => connection
 | 
				
			||||||
 | 
					                    .as_ref()
 | 
				
			||||||
 | 
					                    .send_command(heap_remove(command.data.fade_out)),
 | 
				
			||||||
 | 
					                CommandTag::BitmapLegacy => connection
 | 
				
			||||||
 | 
					                    .as_ref()
 | 
				
			||||||
 | 
					                    .send_command(heap_remove(command.data.bitmap_legacy)),
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .is_some()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Sends a [Header] to the display using the [UdpSocket].
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// returns: true in case of success
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// # Examples
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// ```C
 | 
				
			||||||
 | 
					    /// sp_udp_send_header(connection, sp_command_brightness(5));
 | 
				
			||||||
 | 
					    /// ```
 | 
				
			||||||
 | 
					    fn send_header(udp_connection: NonNull<UdpSocket>, header: Header) -> bool {
 | 
				
			||||||
 | 
					        let packet = Packet {
 | 
				
			||||||
 | 
					            header,
 | 
				
			||||||
 | 
					            payload: None,
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        unsafe { udp_connection.as_ref() }
 | 
				
			||||||
 | 
					            .send(&Vec::from(packet))
 | 
				
			||||||
 | 
					            .is_ok()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue