, CharGrid),
-
- /// Show text on the screen.
- ///
- /// The text is sent in the form of a 2D grid of [CP-437] encoded characters.
- ///
- /// You probably want to use [Command::Utf8Data] instead
- ///
- /// # Examples
- ///
- /// ```rust
- /// # use servicepoint::{Command, Connection, Origin, CharGrid, Cp437Grid};
- /// # let connection = Connection::Fake;
- /// let grid = CharGrid::from("Hello,\nWorld!");
- /// let grid = Cp437Grid::from(&grid);
- /// connection.send(Command::Cp437Data(Origin::ZERO, grid)).expect("send failed");
- /// ```
- ///
- /// ```rust
- /// # use servicepoint::{Command, Connection, Cp437Grid, Origin};
- /// # let connection = Connection::Fake;
- /// let grid = Cp437Grid::load_ascii("Hello\nWorld", 5, false).unwrap();
- /// connection.send(Command::Cp437Data(Origin::new(2, 2), grid)).unwrap();
- /// ```
- /// [CP-437]: https://en.wikipedia.org/wiki/Code_page_437
- Cp437Data(Origin, Cp437Grid),
-
- /// Overwrites a rectangular region of pixels.
- ///
- /// Origin coordinates must be divisible by 8.
- ///
- /// # Examples
- ///
- /// ```rust
- /// # use servicepoint::{Command, CompressionCode, Grid, Bitmap};
- /// # let connection = servicepoint::Connection::Fake;
- /// #
- /// let mut pixels = Bitmap::max_sized();
- /// // draw something to the pixels here
- /// # pixels.set(2, 5, true);
- ///
- /// // create command to send pixels
- /// let command = Command::BitmapLinearWin(
- /// servicepoint::Origin::ZERO,
- /// pixels,
- /// CompressionCode::Uncompressed
- /// );
- ///
- /// connection.send(command).expect("send failed");
- /// ```
- BitmapLinearWin(Origin, Bitmap, CompressionCode),
-
- /// Set the brightness of all tiles to the same value.
- ///
- /// # Examples
- ///
- /// ```rust
- /// # use servicepoint::{Brightness, Command, Connection};
- /// # let connection = Connection::open("127.0.0.1:2342").unwrap();
- /// let command = Command::Brightness(Brightness::MAX);
- /// connection.send(command).unwrap();
- /// ```
- Brightness(Brightness),
-
- /// Set the brightness of individual tiles in a rectangular area of the display.
- CharBrightness(Origin, BrightnessGrid),
-
- /// Set pixel data starting at the pixel offset on screen.
- ///
- /// The screen will continuously overwrite more pixel data without regarding the offset, meaning
- /// once the starting row is full, overwriting will continue on column 0.
- ///
- /// The contained [BitVec] is always uncompressed.
- BitmapLinear(Offset, BitVec, CompressionCode),
-
- /// Set pixel data according to an and-mask starting at the offset.
- ///
- /// The screen will continuously overwrite more pixel data without regarding the offset, meaning
- /// once the starting row is full, overwriting will continue on column 0.
- ///
- /// The contained [BitVec] is always uncompressed.
- BitmapLinearAnd(Offset, BitVec, CompressionCode),
-
- /// Set pixel data according to an or-mask starting at the offset.
- ///
- /// The screen will continuously overwrite more pixel data without regarding the offset, meaning
- /// once the starting row is full, overwriting will continue on column 0.
- ///
- /// The contained [BitVec] is always uncompressed.
- BitmapLinearOr(Offset, BitVec, CompressionCode),
-
- /// Set pixel data according to a xor-mask starting at the offset.
- ///
- /// The screen will continuously overwrite more pixel data without regarding the offset, meaning
- /// once the starting row is full, overwriting will continue on column 0.
- ///
- /// The contained [BitVec] is always uncompressed.
- BitmapLinearXor(Offset, BitVec, CompressionCode),
-
- /// Kills the udp daemon on the display, which usually results in a restart.
- ///
- /// Please do not send this in your normal program flow.
- ///
- /// # Examples
- ///
- /// ```rust
- /// # use servicepoint::{Command, Connection};
- /// # let connection = Connection::open("127.0.0.1:2342").unwrap();
- /// connection.send(Command::HardReset).unwrap();
- /// ```
- HardReset,
-
- /// Untested
- ///
- /// Slowly decrease brightness until off or something like that?
- ///
- /// # Examples
- ///
- /// ```rust
- /// # use servicepoint::{Command, Connection};
- /// # let connection = Connection::open("127.0.0.1:2342").unwrap();
- /// connection.send(Command::FadeOut).unwrap();
- /// ```
- FadeOut,
-
- /// Legacy command code, gets ignored by the real display.
- ///
- /// Might be useful as a noop package.
- ///
- /// # Examples
- ///
- /// ```rust
- /// # use servicepoint::{Command, Connection};
- /// # let connection = Connection::open("127.0.0.1:2342").unwrap();
- /// // this sends a packet that does nothing
- /// # #[allow(deprecated)]
- /// connection.send(Command::BitmapLegacy).unwrap();
- /// ```
- #[deprecated]
- BitmapLegacy,
-}
-
-/// Err values for [Command::try_from].
-#[derive(Debug, PartialEq, thiserror::Error)]
-pub enum TryFromPacketError {
- /// the contained command code does not correspond to a known command
- #[error("The command code {0:?} does not correspond to a known command")]
- InvalidCommand(u16),
- /// the expected payload size was n, but size m was found
- #[error("the expected payload size was {0}, but size {1} was found")]
- UnexpectedPayloadSize(usize, usize),
- /// Header fields not needed for the command have been used.
- ///
- /// Note that these commands would usually still work on the actual display.
- #[error("Header fields not needed for the command have been used")]
- ExtraneousHeaderValues,
- /// The contained compression code is not known. This could be of disabled features.
- #[error("The compression code {0:?} does not correspond to a known compression algorithm.")]
- InvalidCompressionCode(u16),
- /// Decompression of the payload failed. This can be caused by corrupted packets.
- #[error("The decompression of the payload failed")]
- DecompressionFailed,
- /// The given brightness value is out of bounds
- #[error("The given brightness value {0} is out of bounds.")]
- InvalidBrightness(u8),
- #[error(transparent)]
- InvalidUtf8(#[from] std::string::FromUtf8Error),
-}
-
-impl TryFrom for Command {
- type Error = TryFromPacketError;
-
- /// Try to interpret the [Packet] as one containing a [Command]
- fn try_from(packet: Packet) -> Result {
- let Packet {
- header: Header {
- command_code, a, ..
- },
- ..
- } = packet;
- let command_code = match CommandCode::try_from(command_code) {
- Err(()) => {
- return Err(TryFromPacketError::InvalidCommand(command_code));
- }
- Ok(value) => value,
- };
-
- match command_code {
- CommandCode::Clear => {
- Self::packet_into_command_only(packet, Command::Clear)
- }
- CommandCode::Brightness => Self::packet_into_brightness(&packet),
- CommandCode::HardReset => {
- Self::packet_into_command_only(packet, Command::HardReset)
- }
- CommandCode::FadeOut => {
- Self::packet_into_command_only(packet, Command::FadeOut)
- }
- CommandCode::Cp437Data => Self::packet_into_cp437(&packet),
- CommandCode::CharBrightness => {
- Self::packet_into_char_brightness(&packet)
- }
- CommandCode::Utf8Data => Self::packet_into_utf8(&packet),
- #[allow(deprecated)]
- CommandCode::BitmapLegacy => Ok(Command::BitmapLegacy),
- CommandCode::BitmapLinear => {
- let (vec, compression) =
- Self::packet_into_linear_bitmap(packet)?;
- Ok(Command::BitmapLinear(a as Offset, vec, compression))
- }
- CommandCode::BitmapLinearAnd => {
- let (vec, compression) =
- Self::packet_into_linear_bitmap(packet)?;
- Ok(Command::BitmapLinearAnd(a as Offset, vec, compression))
- }
- CommandCode::BitmapLinearOr => {
- let (vec, compression) =
- Self::packet_into_linear_bitmap(packet)?;
- Ok(Command::BitmapLinearOr(a as Offset, vec, compression))
- }
- CommandCode::BitmapLinearXor => {
- let (vec, compression) =
- Self::packet_into_linear_bitmap(packet)?;
- Ok(Command::BitmapLinearXor(a as Offset, vec, compression))
- }
- CommandCode::BitmapLinearWinUncompressed => {
- Self::packet_into_bitmap_win(
- packet,
- CompressionCode::Uncompressed,
- )
- }
- #[cfg(feature = "compression_zlib")]
- CommandCode::BitmapLinearWinZlib => {
- Self::packet_into_bitmap_win(packet, CompressionCode::Zlib)
- }
- #[cfg(feature = "compression_bzip2")]
- CommandCode::BitmapLinearWinBzip2 => {
- Self::packet_into_bitmap_win(packet, CompressionCode::Bzip2)
- }
- #[cfg(feature = "compression_lzma")]
- CommandCode::BitmapLinearWinLzma => {
- Self::packet_into_bitmap_win(packet, CompressionCode::Lzma)
- }
- #[cfg(feature = "compression_zstd")]
- CommandCode::BitmapLinearWinZstd => {
- Self::packet_into_bitmap_win(packet, CompressionCode::Zstd)
- }
- }
- }
-}
-
-impl Command {
- fn packet_into_bitmap_win(
- packet: Packet,
- compression: CompressionCode,
- ) -> Result {
- let Packet {
- header:
- Header {
- command_code: _,
- a: tiles_x,
- b: pixels_y,
- c: tile_w,
- d: pixel_h,
- },
- payload,
- } = packet;
-
- let payload = match into_decompressed(compression, payload) {
- None => return Err(TryFromPacketError::DecompressionFailed),
- Some(decompressed) => decompressed,
- };
-
- Ok(Command::BitmapLinearWin(
- Origin::new(tiles_x as usize * TILE_SIZE, pixels_y as usize),
- Bitmap::load(
- tile_w as usize * TILE_SIZE,
- pixel_h as usize,
- &payload,
- ),
- compression,
- ))
- }
-
- /// Helper method for checking that a packet is empty and only contains a command code
- fn packet_into_command_only(
- packet: Packet,
- command: Command,
- ) -> Result {
- let Packet {
- header:
- Header {
- command_code: _,
- a,
- b,
- c,
- d,
- },
- payload,
- } = packet;
- if !payload.is_empty() {
- Err(TryFromPacketError::UnexpectedPayloadSize(0, payload.len()))
- } else if a != 0 || b != 0 || c != 0 || d != 0 {
- Err(TryFromPacketError::ExtraneousHeaderValues)
- } else {
- Ok(command)
- }
- }
-
- /// Helper method for Packets into `BitmapLinear*`-Commands
- fn packet_into_linear_bitmap(
- packet: Packet,
- ) -> Result<(BitVec, CompressionCode), TryFromPacketError> {
- let Packet {
- header:
- Header {
- b: length,
- c: sub,
- d: reserved,
- ..
- },
- payload,
- } = packet;
- if reserved != 0 {
- return Err(TryFromPacketError::ExtraneousHeaderValues);
- }
- let sub = match CompressionCode::try_from(sub) {
- Err(()) => {
- return Err(TryFromPacketError::InvalidCompressionCode(sub));
- }
- Ok(value) => value,
- };
- let payload = match into_decompressed(sub, payload) {
- None => return Err(TryFromPacketError::DecompressionFailed),
- Some(value) => value,
- };
- if payload.len() != length as usize {
- return Err(TryFromPacketError::UnexpectedPayloadSize(
- length as usize,
- payload.len(),
- ));
- }
- Ok((BitVec::from_vec(payload), sub))
- }
-
- fn packet_into_char_brightness(
- packet: &Packet,
- ) -> Result {
- let Packet {
- header:
- Header {
- command_code: _,
- a: x,
- b: y,
- c: width,
- d: height,
- },
- payload,
- } = packet;
-
- let grid = ByteGrid::load(*width as usize, *height as usize, payload);
- let grid = match BrightnessGrid::try_from(grid) {
- Ok(grid) => grid,
- Err(val) => return Err(TryFromPacketError::InvalidBrightness(val)),
- };
-
- Ok(Command::CharBrightness(
- Origin::new(*x as usize, *y as usize),
- grid,
- ))
- }
-
- fn packet_into_brightness(
- packet: &Packet,
- ) -> Result {
- let Packet {
- header:
- Header {
- command_code: _,
- a,
- b,
- c,
- d,
- },
- payload,
- } = packet;
- if payload.len() != 1 {
- return Err(TryFromPacketError::UnexpectedPayloadSize(
- 1,
- payload.len(),
- ));
- }
-
- if *a != 0 || *b != 0 || *c != 0 || *d != 0 {
- return Err(TryFromPacketError::ExtraneousHeaderValues);
- }
-
- match Brightness::try_from(payload[0]) {
- Ok(b) => Ok(Command::Brightness(b)),
- Err(_) => Err(TryFromPacketError::InvalidBrightness(payload[0])),
- }
- }
-
- fn packet_into_cp437(
- packet: &Packet,
- ) -> Result {
- let Packet {
- header:
- Header {
- command_code: _,
- a,
- b,
- c,
- d,
- },
- payload,
- } = packet;
- Ok(Command::Cp437Data(
- Origin::new(*a as usize, *b as usize),
- Cp437Grid::load(*c as usize, *d as usize, payload),
- ))
- }
-
- fn packet_into_utf8(
- packet: &Packet,
- ) -> Result {
- let Packet {
- header:
- Header {
- command_code: _,
- a,
- b,
- c,
- d,
- },
- payload,
- } = packet;
- let payload: Vec<_> =
- String::from_utf8(payload.clone())?.chars().collect();
- Ok(Command::Utf8Data(
- Origin::new(*a as usize, *b as usize),
- CharGrid::load(*c as usize, *d as usize, &payload),
- ))
- }
-}
-
-#[cfg(test)]
-mod tests {
- use crate::command::TryFromPacketError;
- use crate::command_code::CommandCode;
- use crate::{
- BitVec, Bitmap, Brightness, BrightnessGrid, CharGrid, Command,
- CompressionCode, Cp437Grid, Header, Origin, Packet, Pixels,
- };
-
- fn round_trip(original: Command) {
- let packet: Packet = original.clone().into();
- let copy: Command = match Command::try_from(packet) {
- Ok(command) => command,
- Err(err) => panic!("could not reload {original:?}: {err:?}"),
- };
- assert_eq!(copy, original);
- }
-
- fn all_compressions<'t>() -> &'t [CompressionCode] {
- &[
- CompressionCode::Uncompressed,
- #[cfg(feature = "compression_lzma")]
- CompressionCode::Lzma,
- #[cfg(feature = "compression_bzip2")]
- CompressionCode::Bzip2,
- #[cfg(feature = "compression_zlib")]
- CompressionCode::Zlib,
- #[cfg(feature = "compression_zstd")]
- CompressionCode::Zstd,
- ]
- }
-
- #[test]
- fn round_trip_clear() {
- round_trip(Command::Clear);
- }
-
- #[test]
- fn round_trip_hard_reset() {
- round_trip(Command::HardReset);
- }
-
- #[test]
- fn round_trip_fade_out() {
- round_trip(Command::FadeOut);
- }
-
- #[test]
- fn round_trip_brightness() {
- round_trip(Command::Brightness(Brightness::try_from(6).unwrap()));
- }
-
- #[test]
- #[allow(deprecated)]
- fn round_trip_bitmap_legacy() {
- round_trip(Command::BitmapLegacy);
- }
-
- #[test]
- fn round_trip_char_brightness() {
- round_trip(Command::CharBrightness(
- Origin::new(5, 2),
- BrightnessGrid::new(7, 5),
- ));
- }
-
- #[test]
- fn round_trip_cp437_data() {
- round_trip(Command::Cp437Data(Origin::new(5, 2), Cp437Grid::new(7, 5)));
- }
-
- #[test]
- fn round_trip_utf8_data() {
- round_trip(Command::Utf8Data(Origin::new(5, 2), CharGrid::new(7, 5)));
- }
-
- #[test]
- fn round_trip_bitmap_linear() {
- for compression in all_compressions().iter().copied() {
- round_trip(Command::BitmapLinear(
- 23,
- BitVec::repeat(false, 40),
- compression,
- ));
- round_trip(Command::BitmapLinearAnd(
- 23,
- BitVec::repeat(false, 40),
- compression,
- ));
- round_trip(Command::BitmapLinearOr(
- 23,
- BitVec::repeat(false, 40),
- compression,
- ));
- round_trip(Command::BitmapLinearXor(
- 23,
- BitVec::repeat(false, 40),
- compression,
- ));
- round_trip(Command::BitmapLinearWin(
- Origin::ZERO,
- Bitmap::max_sized(),
- compression,
- ));
- }
- }
-
- #[test]
- fn error_invalid_command() {
- let p = Packet {
- header: Header {
- command_code: 0xFF,
- a: 0x00,
- b: 0x00,
- c: 0x00,
- d: 0x00,
- },
- payload: vec![],
- };
- let result = Command::try_from(p);
- assert!(matches!(
- result,
- Err(TryFromPacketError::InvalidCommand(0xFF))
- ))
- }
-
- #[test]
- fn error_extraneous_header_values_clear() {
- let p = Packet {
- header: Header {
- command_code: CommandCode::Clear.into(),
- a: 0x05,
- b: 0x00,
- c: 0x00,
- d: 0x00,
- },
- payload: vec![],
- };
- let result = Command::try_from(p);
- assert!(matches!(
- result,
- Err(TryFromPacketError::ExtraneousHeaderValues)
- ))
- }
-
- #[test]
- fn error_extraneous_header_values_brightness() {
- let p = Packet {
- header: Header {
- command_code: CommandCode::Brightness.into(),
- a: 0x00,
- b: 0x13,
- c: 0x37,
- d: 0x00,
- },
- payload: vec![5],
- };
- let result = Command::try_from(p);
- assert!(matches!(
- result,
- Err(TryFromPacketError::ExtraneousHeaderValues)
- ))
- }
-
- #[test]
- fn error_extraneous_header_hard_reset() {
- let p = Packet {
- header: Header {
- command_code: CommandCode::HardReset.into(),
- a: 0x00,
- b: 0x00,
- c: 0x00,
- d: 0x01,
- },
- payload: vec![],
- };
- let result = Command::try_from(p);
- assert!(matches!(
- result,
- Err(TryFromPacketError::ExtraneousHeaderValues)
- ))
- }
-
- #[test]
- fn error_extraneous_header_fade_out() {
- let p = Packet {
- header: Header {
- command_code: CommandCode::FadeOut.into(),
- a: 0x10,
- b: 0x00,
- c: 0x00,
- d: 0x01,
- },
- payload: vec![],
- };
- let result = Command::try_from(p);
- assert!(matches!(
- result,
- Err(TryFromPacketError::ExtraneousHeaderValues)
- ))
- }
-
- #[test]
- fn error_unexpected_payload() {
- let p = Packet {
- header: Header {
- command_code: CommandCode::FadeOut.into(),
- a: 0x00,
- b: 0x00,
- c: 0x00,
- d: 0x00,
- },
- payload: vec![5, 7],
- };
- let result = Command::try_from(p);
- assert!(matches!(
- result,
- Err(TryFromPacketError::UnexpectedPayloadSize(0, 2))
- ))
- }
-
- #[test]
- fn error_decompression_failed_win() {
- for compression in all_compressions().iter().copied() {
- let p: Packet = Command::BitmapLinearWin(
- Origin::new(16, 8),
- Bitmap::new(8, 8),
- compression,
- )
- .into();
-
- let Packet {
- header,
- mut payload,
- } = p;
-
- // mangle it
- for byte in payload.iter_mut() {
- *byte -= *byte / 2;
- }
-
- let p = Packet { header, payload };
- let result = Command::try_from(p);
- if compression != CompressionCode::Uncompressed {
- assert_eq!(result, Err(TryFromPacketError::DecompressionFailed))
- } else {
- assert!(result.is_ok());
- }
- }
- }
-
- #[test]
- fn error_decompression_failed_and() {
- for compression in all_compressions().iter().copied() {
- let p: Packet = Command::BitmapLinearAnd(
- 0,
- BitVec::repeat(false, 8),
- compression,
- )
- .into();
- let Packet {
- header,
- mut payload,
- } = p;
-
- // mangle it
- for byte in payload.iter_mut() {
- *byte -= *byte / 2;
- }
-
- let p = Packet { header, payload };
- let result = Command::try_from(p);
- if compression != CompressionCode::Uncompressed {
- assert_eq!(result, Err(TryFromPacketError::DecompressionFailed))
- } else {
- // when not compressing, there is no way to detect corrupted data
- assert!(result.is_ok());
- }
- }
- }
-
- #[test]
- fn unexpected_payload_size_brightness() {
- assert_eq!(
- Command::try_from(Packet {
- header: Header {
- command_code: CommandCode::Brightness.into(),
- a: 0,
- b: 0,
- c: 0,
- d: 0,
- },
- payload: vec!()
- }),
- Err(TryFromPacketError::UnexpectedPayloadSize(1, 0))
- );
-
- assert_eq!(
- Command::try_from(Packet {
- header: Header {
- command_code: CommandCode::Brightness.into(),
- a: 0,
- b: 0,
- c: 0,
- d: 0,
- },
- payload: vec!(0, 0)
- }),
- Err(TryFromPacketError::UnexpectedPayloadSize(1, 2))
- );
- }
-
- #[test]
- fn error_reserved_used() {
- let Packet { header, payload } = Command::BitmapLinear(
- 0,
- BitVec::repeat(false, 8),
- CompressionCode::Uncompressed,
- )
- .into();
- let Header {
- command_code: command,
- a: offset,
- b: length,
- c: sub,
- d: _reserved,
- } = header;
- let p = Packet {
- header: Header {
- command_code: command,
- a: offset,
- b: length,
- c: sub,
- d: 69,
- },
- payload,
- };
- assert_eq!(
- Command::try_from(p),
- Err(TryFromPacketError::ExtraneousHeaderValues)
- );
- }
-
- #[test]
- fn error_invalid_compression() {
- let Packet { header, payload } = Command::BitmapLinear(
- 0,
- BitVec::repeat(false, 8),
- CompressionCode::Uncompressed,
- )
- .into();
- let Header {
- command_code: command,
- a: offset,
- b: length,
- c: _sub,
- d: reserved,
- } = header;
- let p = Packet {
- header: Header {
- command_code: command,
- a: offset,
- b: length,
- c: 42,
- d: reserved,
- },
- payload,
- };
- assert_eq!(
- Command::try_from(p),
- Err(TryFromPacketError::InvalidCompressionCode(42))
- );
- }
-
- #[test]
- fn error_unexpected_size() {
- let Packet { header, payload } = Command::BitmapLinear(
- 0,
- BitVec::repeat(false, 8),
- CompressionCode::Uncompressed,
- )
- .into();
- let Header {
- command_code: command,
- a: offset,
- b: length,
- c: compression,
- d: reserved,
- } = header;
- let p = Packet {
- header: Header {
- command_code: command,
- a: offset,
- b: 420,
- c: compression,
- d: reserved,
- },
- payload,
- };
- assert_eq!(
- Command::try_from(p),
- Err(TryFromPacketError::UnexpectedPayloadSize(
- 420,
- length as usize,
- ))
- );
- }
-
- #[test]
- fn origin_add() {
- assert_eq!(
- Origin::::new(4, 2),
- Origin::new(1, 0) + Origin::new(3, 2)
- );
- }
-
- #[test]
- fn packet_into_char_brightness_invalid() {
- let grid = BrightnessGrid::new(2, 2);
- let command = Command::CharBrightness(Origin::ZERO, grid);
- let mut packet: Packet = command.into();
- let slot = packet.payload.get_mut(1).unwrap();
- *slot = 23;
- assert_eq!(
- Command::try_from(packet),
- Err(TryFromPacketError::InvalidBrightness(23))
- );
- }
-
- #[test]
- fn packet_into_brightness_invalid() {
- let mut packet: Packet = Command::Brightness(Brightness::MAX).into();
- let slot = packet.payload.get_mut(0).unwrap();
- *slot = 42;
- assert_eq!(
- Command::try_from(packet),
- Err(TryFromPacketError::InvalidBrightness(42))
- );
- }
-}
diff --git a/crates/servicepoint/src/command_code.rs b/crates/servicepoint/src/command_code.rs
deleted file mode 100644
index a105522..0000000
--- a/crates/servicepoint/src/command_code.rs
+++ /dev/null
@@ -1,214 +0,0 @@
-/// The u16 command codes used for the [Command]s.
-#[repr(u16)]
-#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
-pub(crate) enum CommandCode {
- Clear = 0x0002,
- Cp437Data = 0x0003,
- CharBrightness = 0x0005,
- Brightness = 0x0007,
- HardReset = 0x000b,
- FadeOut = 0x000d,
- #[deprecated]
- BitmapLegacy = 0x0010,
- BitmapLinear = 0x0012,
- BitmapLinearWinUncompressed = 0x0013,
- BitmapLinearAnd = 0x0014,
- BitmapLinearOr = 0x0015,
- BitmapLinearXor = 0x0016,
- #[cfg(feature = "compression_zlib")]
- BitmapLinearWinZlib = 0x0017,
- #[cfg(feature = "compression_bzip2")]
- BitmapLinearWinBzip2 = 0x0018,
- #[cfg(feature = "compression_lzma")]
- BitmapLinearWinLzma = 0x0019,
- Utf8Data = 0x0020,
- #[cfg(feature = "compression_zstd")]
- BitmapLinearWinZstd = 0x001A,
-}
-
-impl From for u16 {
- /// returns the u16 command code corresponding to the enum value
- fn from(value: CommandCode) -> Self {
- value as u16
- }
-}
-
-impl TryFrom for CommandCode {
- type Error = ();
-
- /// Returns the enum value for the specified `u16` or `Error` if the code is unknown.
- fn try_from(value: u16) -> Result {
- match value {
- value if value == CommandCode::Clear as u16 => {
- Ok(CommandCode::Clear)
- }
- value if value == CommandCode::Cp437Data as u16 => {
- Ok(CommandCode::Cp437Data)
- }
- value if value == CommandCode::CharBrightness as u16 => {
- Ok(CommandCode::CharBrightness)
- }
- value if value == CommandCode::Brightness as u16 => {
- Ok(CommandCode::Brightness)
- }
- value if value == CommandCode::HardReset as u16 => {
- Ok(CommandCode::HardReset)
- }
- value if value == CommandCode::FadeOut as u16 => {
- Ok(CommandCode::FadeOut)
- }
- #[allow(deprecated)]
- value if value == CommandCode::BitmapLegacy as u16 => {
- Ok(CommandCode::BitmapLegacy)
- }
- value if value == CommandCode::BitmapLinear as u16 => {
- Ok(CommandCode::BitmapLinear)
- }
- value
- if value == CommandCode::BitmapLinearWinUncompressed as u16 =>
- {
- Ok(CommandCode::BitmapLinearWinUncompressed)
- }
- value if value == CommandCode::BitmapLinearAnd as u16 => {
- Ok(CommandCode::BitmapLinearAnd)
- }
- value if value == CommandCode::BitmapLinearOr as u16 => {
- Ok(CommandCode::BitmapLinearOr)
- }
- value if value == CommandCode::BitmapLinearXor as u16 => {
- Ok(CommandCode::BitmapLinearXor)
- }
- #[cfg(feature = "compression_zstd")]
- value if value == CommandCode::BitmapLinearWinZstd as u16 => {
- Ok(CommandCode::BitmapLinearWinZstd)
- }
- #[cfg(feature = "compression_lzma")]
- value if value == CommandCode::BitmapLinearWinLzma as u16 => {
- Ok(CommandCode::BitmapLinearWinLzma)
- }
- #[cfg(feature = "compression_zlib")]
- value if value == CommandCode::BitmapLinearWinZlib as u16 => {
- Ok(CommandCode::BitmapLinearWinZlib)
- }
- #[cfg(feature = "compression_bzip2")]
- value if value == CommandCode::BitmapLinearWinBzip2 as u16 => {
- Ok(CommandCode::BitmapLinearWinBzip2)
- }
- value if value == CommandCode::Utf8Data as u16 => {
- Ok(CommandCode::Utf8Data)
- }
- _ => Err(()),
- }
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- #[test]
- fn clear() {
- assert_eq!(CommandCode::try_from(0x0002), Ok(CommandCode::Clear));
- assert_eq!(u16::from(CommandCode::Clear), 0x0002);
- }
-
- #[test]
- fn cp437_data() {
- assert_eq!(CommandCode::try_from(0x0003), Ok(CommandCode::Cp437Data));
- assert_eq!(u16::from(CommandCode::Cp437Data), 0x0003);
- }
-
- #[test]
- fn char_brightness() {
- assert_eq!(CommandCode::try_from(0x0005), Ok(CommandCode::CharBrightness));
- assert_eq!(u16::from(CommandCode::CharBrightness), 0x0005);
- }
-
- #[test]
- fn brightness() {
- assert_eq!(CommandCode::try_from(0x0007), Ok(CommandCode::Brightness));
- assert_eq!(u16::from(CommandCode::Brightness), 0x0007);
- }
-
- #[test]
- fn hard_reset() {
- assert_eq!(CommandCode::try_from(0x000b), Ok(CommandCode::HardReset));
- assert_eq!(u16::from(CommandCode::HardReset), 0x000b);
- }
-
- #[test]
- fn fade_out() {
- assert_eq!(CommandCode::try_from(0x000d), Ok(CommandCode::FadeOut));
- assert_eq!(u16::from(CommandCode::FadeOut), 0x000d);
- }
-
- #[test]
- #[allow(deprecated)]
- fn bitmap_legacy() {
- assert_eq!(CommandCode::try_from(0x0010), Ok(CommandCode::BitmapLegacy));
- assert_eq!(u16::from(CommandCode::BitmapLegacy), 0x0010);
- }
-
- #[test]
- fn linear() {
- assert_eq!(CommandCode::try_from(0x0012), Ok(CommandCode::BitmapLinear));
- assert_eq!(u16::from(CommandCode::BitmapLinear), 0x0012);
- }
-
- #[test]
- fn linear_and() {
- assert_eq!(CommandCode::try_from(0x0014), Ok(CommandCode::BitmapLinearAnd));
- assert_eq!(u16::from(CommandCode::BitmapLinearAnd), 0x0014);
- }
-
- #[test]
- fn linear_xor() {
- assert_eq!(CommandCode::try_from(0x0016), Ok(CommandCode::BitmapLinearXor));
- assert_eq!(u16::from(CommandCode::BitmapLinearXor), 0x0016);
- }
-
- #[test]
- #[cfg(feature = "compression_zlib")]
- fn bitmap_win_zlib() {
- assert_eq!(CommandCode::try_from(0x0017), Ok(CommandCode::BitmapLinearWinZlib));
- assert_eq!(u16::from(CommandCode::BitmapLinearWinZlib), 0x0017);
- }
-
- #[test]
- #[cfg(feature = "compression_bzip2")]
- fn bitmap_win_bzip2() {
- assert_eq!(CommandCode::try_from(0x0018), Ok(CommandCode::BitmapLinearWinBzip2));
- assert_eq!(u16::from(CommandCode::BitmapLinearWinBzip2), 0x0018);
- }
-
- #[test]
- #[cfg(feature = "compression_lzma")]
- fn bitmap_win_lzma() {
- assert_eq!(CommandCode::try_from(0x0019), Ok(CommandCode::BitmapLinearWinLzma));
- assert_eq!(u16::from(CommandCode::BitmapLinearWinLzma), 0x0019);
- }
-
- #[test]
- #[cfg(feature = "compression_zstd")]
- fn bitmap_win_zstd() {
- assert_eq!(CommandCode::try_from(0x001A), Ok(CommandCode::BitmapLinearWinZstd));
- assert_eq!(u16::from(CommandCode::BitmapLinearWinZstd), 0x001A);
- }
-
- #[test]
- fn bitmap_win_uncompressed() {
- assert_eq!(CommandCode::try_from(0x0013), Ok(CommandCode::BitmapLinearWinUncompressed));
- assert_eq!(u16::from(CommandCode::BitmapLinearWinUncompressed), 0x0013);
- }
-
- #[test]
- fn utf8_data() {
- assert_eq!(CommandCode::try_from(0x0020), Ok(CommandCode::Utf8Data));
- assert_eq!(u16::from(CommandCode::Utf8Data), 0x0020);
- }
-
- #[test]
- fn linear_or() {
- assert_eq!(CommandCode::try_from(0x0015), Ok(CommandCode::BitmapLinearOr));
- assert_eq!(u16::from(CommandCode::BitmapLinearOr), 0x0015);
- }
-}
\ No newline at end of file
diff --git a/crates/servicepoint/src/compression.rs b/crates/servicepoint/src/compression.rs
deleted file mode 100644
index 2e78073..0000000
--- a/crates/servicepoint/src/compression.rs
+++ /dev/null
@@ -1,115 +0,0 @@
-#[allow(unused)]
-use std::io::{Read, Write};
-
-#[cfg(feature = "compression_bzip2")]
-use bzip2::read::{BzDecoder, BzEncoder};
-#[cfg(feature = "compression_zlib")]
-use flate2::{FlushCompress, FlushDecompress, Status};
-#[cfg(feature = "compression_zstd")]
-use zstd::{Decoder as ZstdDecoder, Encoder as ZstdEncoder};
-
-use crate::{CompressionCode, Payload};
-
-pub(crate) fn into_decompressed(
- kind: CompressionCode,
- payload: Payload,
-) -> Option {
- match kind {
- CompressionCode::Uncompressed => Some(payload),
- #[cfg(feature = "compression_zlib")]
- CompressionCode::Zlib => {
- let mut decompress = flate2::Decompress::new(true);
- let mut buffer = [0u8; 10000];
-
- let status = match decompress.decompress(
- &payload,
- &mut buffer,
- FlushDecompress::Finish,
- ) {
- Err(_) => return None,
- Ok(status) => status,
- };
-
- match status {
- Status::Ok => None,
- Status::BufError => None,
- Status::StreamEnd => Some(
- buffer[0..(decompress.total_out() as usize)].to_owned(),
- ),
- }
- }
- #[cfg(feature = "compression_bzip2")]
- CompressionCode::Bzip2 => {
- let mut decoder = BzDecoder::new(&*payload);
- let mut decompressed = vec![];
- match decoder.read_to_end(&mut decompressed) {
- Err(_) => None,
- Ok(_) => Some(decompressed),
- }
- }
- #[cfg(feature = "compression_lzma")]
- CompressionCode::Lzma => match lzma::decompress(&payload) {
- Err(_) => None,
- Ok(decompressed) => Some(decompressed),
- },
- #[cfg(feature = "compression_zstd")]
- CompressionCode::Zstd => {
- let mut decoder = match ZstdDecoder::new(&*payload) {
- Err(_) => return None,
- Ok(value) => value,
- };
- let mut decompressed = vec![];
- match decoder.read_to_end(&mut decompressed) {
- Err(_) => None,
- Ok(_) => Some(decompressed),
- }
- }
- }
-}
-
-pub(crate) fn into_compressed(
- kind: CompressionCode,
- payload: Payload,
-) -> Payload {
- match kind {
- CompressionCode::Uncompressed => payload,
- #[cfg(feature = "compression_zlib")]
- CompressionCode::Zlib => {
- let mut compress =
- flate2::Compress::new(flate2::Compression::fast(), true);
- let mut buffer = [0u8; 10000];
-
- match compress
- .compress(&payload, &mut buffer, FlushCompress::Finish)
- .expect("compress failed")
- {
- Status::Ok => panic!("buffer should be big enough"),
- Status::BufError => panic!("BufError"),
- Status::StreamEnd => {}
- };
- buffer[..compress.total_out() as usize].to_owned()
- }
- #[cfg(feature = "compression_bzip2")]
- CompressionCode::Bzip2 => {
- let mut encoder =
- BzEncoder::new(&*payload, bzip2::Compression::fast());
- let mut compressed = vec![];
- match encoder.read_to_end(&mut compressed) {
- Err(err) => panic!("could not compress payload: {}", err),
- Ok(_) => compressed,
- }
- }
- #[cfg(feature = "compression_lzma")]
- CompressionCode::Lzma => lzma::compress(&payload, 6).unwrap(),
- #[cfg(feature = "compression_zstd")]
- CompressionCode::Zstd => {
- let mut encoder =
- ZstdEncoder::new(vec![], zstd::DEFAULT_COMPRESSION_LEVEL)
- .expect("could not create encoder");
- encoder
- .write_all(&payload)
- .expect("could not compress payload");
- encoder.finish().expect("could not finish encoding")
- }
- }
-}
diff --git a/crates/servicepoint/src/compression_code.rs b/crates/servicepoint/src/compression_code.rs
deleted file mode 100644
index db25221..0000000
--- a/crates/servicepoint/src/compression_code.rs
+++ /dev/null
@@ -1,120 +0,0 @@
-/// Specifies the kind of compression to use. Availability depends on features.
-///
-/// # Examples
-///
-/// ```rust
-/// # use servicepoint::{Command, CompressionCode, Origin, Bitmap};
-/// // create command without payload compression
-/// # let pixels = Bitmap::max_sized();
-/// _ = Command::BitmapLinearWin(Origin::ZERO, pixels, CompressionCode::Uncompressed);
-///
-/// // create command with payload compressed with lzma and appropriate header flags
-/// # let pixels = Bitmap::max_sized();
-/// _ = Command::BitmapLinearWin(Origin::ZERO, pixels, CompressionCode::Lzma);
-/// ```
-#[repr(u16)]
-#[derive(Debug, Clone, Copy, PartialEq)]
-pub enum CompressionCode {
- /// no compression
- Uncompressed = 0x0,
- #[cfg(feature = "compression_zlib")]
- /// compress using flate2 with zlib header
- Zlib = 0x677a,
- #[cfg(feature = "compression_bzip2")]
- /// compress using bzip2
- Bzip2 = 0x627a,
- #[cfg(feature = "compression_lzma")]
- /// compress using lzma
- Lzma = 0x6c7a,
- #[cfg(feature = "compression_zstd")]
- /// compress using Zstandard
- Zstd = 0x7a73,
-}
-
-impl From for u16 {
- fn from(value: CompressionCode) -> Self {
- value as u16
- }
-}
-
-impl TryFrom for CompressionCode {
- type Error = ();
-
- fn try_from(value: u16) -> Result {
- match value {
- value if value == CompressionCode::Uncompressed as u16 => {
- Ok(CompressionCode::Uncompressed)
- }
- #[cfg(feature = "compression_zlib")]
- value if value == CompressionCode::Zlib as u16 => {
- Ok(CompressionCode::Zlib)
- }
- #[cfg(feature = "compression_bzip2")]
- value if value == CompressionCode::Bzip2 as u16 => {
- Ok(CompressionCode::Bzip2)
- }
- #[cfg(feature = "compression_lzma")]
- value if value == CompressionCode::Lzma as u16 => {
- Ok(CompressionCode::Lzma)
- }
- #[cfg(feature = "compression_zstd")]
- value if value == CompressionCode::Zstd as u16 => {
- Ok(CompressionCode::Zstd)
- }
- _ => Err(()),
- }
- }
-}
-
-#[cfg(test)]
-mod test {
- use super::*;
- #[test]
- fn uncompressed() {
- assert_eq!(
- CompressionCode::try_from(0x0000),
- Ok(CompressionCode::Uncompressed)
- );
- assert_eq!(u16::from(CompressionCode::Uncompressed), 0x0000);
- }
-
- #[test]
- #[cfg(feature = "compression_zlib")]
- fn zlib() {
- assert_eq!(
- CompressionCode::try_from(0x677a),
- Ok(CompressionCode::Zlib)
- );
- assert_eq!(u16::from(CompressionCode::Zlib), 0x677a);
- }
-
- #[test]
- #[cfg(feature = "compression_bzip2")]
- fn bzip2() {
- assert_eq!(
- CompressionCode::try_from(0x627a),
- Ok(CompressionCode::Bzip2)
- );
- assert_eq!(u16::from(CompressionCode::Bzip2), 0x627a);
- }
-
- #[test]
- #[cfg(feature = "compression_lzma")]
- fn lzma() {
- assert_eq!(
- CompressionCode::try_from(0x6c7a),
- Ok(CompressionCode::Lzma)
- );
- assert_eq!(u16::from(CompressionCode::Lzma), 0x6c7a);
- }
-
- #[test]
- #[cfg(feature = "compression_zstd")]
- fn zstd() {
- assert_eq!(
- CompressionCode::try_from(0x7a73),
- Ok(CompressionCode::Zstd)
- );
- assert_eq!(u16::from(CompressionCode::Zstd), 0x7a73);
- }
-}
diff --git a/crates/servicepoint/src/connection.rs b/crates/servicepoint/src/connection.rs
deleted file mode 100644
index 417fd1d..0000000
--- a/crates/servicepoint/src/connection.rs
+++ /dev/null
@@ -1,175 +0,0 @@
-use crate::packet::Packet;
-use std::fmt::Debug;
-
-/// A connection to the display.
-///
-/// Used to send [Packets][Packet] or [Commands][crate::Command].
-///
-/// # Examples
-/// ```rust
-/// let connection = servicepoint::Connection::open("127.0.0.1:2342")
-/// .expect("connection failed");
-/// connection.send(servicepoint::Command::Clear)
-/// .expect("send failed");
-/// ```
-#[derive(Debug)]
-pub enum Connection {
- /// A connection using the UDP protocol.
- ///
- /// Use this when sending commands directly to the display.
- ///
- /// Requires the feature "protocol_udp" which is enabled by default.
- #[cfg(feature = "protocol_udp")]
- Udp(std::net::UdpSocket),
-
- /// A connection using the WebSocket protocol.
- ///
- /// Note that you will need to forward the WebSocket messages via UDP to the display.
- /// You can use [servicepoint-websocket-relay] for this.
- ///
- /// To create a new WebSocket automatically, use [Connection::open_websocket].
- ///
- /// Requires the feature "protocol_websocket" which is disabled by default.
- ///
- /// [servicepoint-websocket-relay]: https://github.com/kaesaecracker/servicepoint-websocket-relay
- #[cfg(feature = "protocol_websocket")]
- WebSocket(
- std::sync::Mutex<
- tungstenite::WebSocket<
- tungstenite::stream::MaybeTlsStream,
- >,
- >,
- ),
-
- /// A fake connection for testing that does not actually send anything.
- Fake,
-}
-
-#[derive(Debug, thiserror::Error)]
-pub enum SendError {
- #[error("IO error occurred while sending")]
- IoError(#[from] std::io::Error),
- #[cfg(feature = "protocol_websocket")]
- #[error("WebSocket error occurred while sending")]
- WebsocketError(#[from] tungstenite::Error),
-}
-
-impl Connection {
- /// Open a new UDP socket and connect to the provided host.
- ///
- /// Note that this is UDP, which means that the open call can succeed even if the display is unreachable.
- ///
- /// The address of the display in CCCB is `172.23.42.29:2342`.
- ///
- /// # Errors
- ///
- /// Any errors resulting from binding the udp socket.
- ///
- /// # Examples
- /// ```rust
- /// let connection = servicepoint::Connection::open("127.0.0.1:2342")
- /// .expect("connection failed");
- /// ```
- #[cfg(feature = "protocol_udp")]
- pub fn open(
- addr: impl std::net::ToSocketAddrs + Debug,
- ) -> std::io::Result {
- log::info!("connecting to {addr:?}");
- let socket = std::net::UdpSocket::bind("0.0.0.0:0")?;
- socket.connect(addr)?;
- Ok(Self::Udp(socket))
- }
-
- /// Open a new WebSocket and connect to the provided host.
- ///
- /// Requires the feature "protocol_websocket" which is disabled by default.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use tungstenite::http::Uri;
- /// use servicepoint::{Command, Connection};
- /// let uri = "ws://localhost:8080".parse().unwrap();
- /// let mut connection = Connection::open_websocket(uri)
- /// .expect("could not connect");
- /// connection.send(Command::Clear)
- /// .expect("send failed");
- /// ```
- #[cfg(feature = "protocol_websocket")]
- pub fn open_websocket(
- uri: tungstenite::http::Uri,
- ) -> tungstenite::Result {
- use tungstenite::{
- client::IntoClientRequest, connect, ClientRequestBuilder,
- };
-
- log::info!("connecting to {uri:?}");
-
- let request = ClientRequestBuilder::new(uri).into_client_request()?;
- let (sock, _) = connect(request)?;
- Ok(Self::WebSocket(std::sync::Mutex::new(sock)))
- }
-
- /// Send something packet-like to the display. Usually this is in the form of a Command.
- ///
- /// # Arguments
- ///
- /// - `packet`: the packet-like to send
- ///
- /// returns: true if packet was sent, otherwise false
- ///
- /// # Examples
- ///
- /// ```rust
- /// let connection = servicepoint::Connection::Fake;
- /// // turn off all pixels on display
- /// connection.send(servicepoint::Command::Clear)
- /// .expect("send failed");
- /// ```
- pub fn send(&self, packet: impl Into) -> Result<(), SendError> {
- let packet = packet.into();
- log::debug!("sending {packet:?}");
- let data: Vec = packet.into();
- match self {
- #[cfg(feature = "protocol_udp")]
- Connection::Udp(socket) => {
- socket
- .send(&data)
- .map_err(SendError::IoError)
- .map(move |_| ()) // ignore Ok value
- }
- #[cfg(feature = "protocol_websocket")]
- Connection::WebSocket(socket) => {
- let mut socket = socket.lock().unwrap();
- socket
- .send(tungstenite::Message::Binary(data.into()))
- .map_err(SendError::WebsocketError)
- }
- Connection::Fake => {
- let _ = data;
- Ok(())
- }
- }
- }
-}
-
-impl Drop for Connection {
- fn drop(&mut self) {
- #[cfg(feature = "protocol_websocket")]
- if let Connection::WebSocket(sock) = self {
- _ = sock.try_lock().map(move |mut sock| sock.close(None));
- }
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- #[test]
- fn send_fake() {
- let data: &[u8] = &[0u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
- let packet = Packet::try_from(data).unwrap();
- Connection::Fake.send(packet).unwrap()
- }
-}
diff --git a/crates/servicepoint/src/constants.rs b/crates/servicepoint/src/constants.rs
deleted file mode 100644
index 95c8684..0000000
--- a/crates/servicepoint/src/constants.rs
+++ /dev/null
@@ -1,75 +0,0 @@
-use std::time::Duration;
-
-/// size of a single tile in one dimension
-pub const TILE_SIZE: usize = 8;
-
-/// Display tile count in the x-direction
-///
-/// # Examples
-///
-/// ```rust
-/// # use servicepoint::{Cp437Grid, TILE_HEIGHT, TILE_WIDTH};
-/// let grid = Cp437Grid::new(TILE_WIDTH, TILE_HEIGHT);
-/// ```
-pub const TILE_WIDTH: usize = 56;
-
-/// Display tile count in the y-direction
-///
-/// # Examples
-///
-/// ```rust
-/// # use servicepoint::{Cp437Grid, TILE_HEIGHT, TILE_WIDTH};
-/// let grid = Cp437Grid::new(TILE_WIDTH, TILE_HEIGHT);
-/// ```
-pub const TILE_HEIGHT: usize = 20;
-
-/// Display width in pixels
-///
-/// # Examples
-///
-/// ```rust
-/// # use servicepoint::{PIXEL_HEIGHT, PIXEL_WIDTH, Bitmap};
-/// let grid = Bitmap::new(PIXEL_WIDTH, PIXEL_HEIGHT);
-/// ```
-pub const PIXEL_WIDTH: usize = TILE_WIDTH * TILE_SIZE;
-
-/// Display height in pixels
-///
-/// # Examples
-///
-/// ```rust
-/// # use servicepoint::{PIXEL_HEIGHT, PIXEL_WIDTH, Bitmap};
-/// let grid = Bitmap::new(PIXEL_WIDTH, PIXEL_HEIGHT);
-/// ```
-pub const PIXEL_HEIGHT: usize = TILE_HEIGHT * TILE_SIZE;
-
-/// pixel count on whole screen
-pub const PIXEL_COUNT: usize = PIXEL_WIDTH * PIXEL_HEIGHT;
-
-/// Actual hardware limit is around 28-29ms/frame. Rounded up for less dropped packets.
-///
-/// # Examples
-///
-/// ```rust
-/// # use std::time::Instant;
-/// # use servicepoint::{Command, CompressionCode, FRAME_PACING, Origin, Bitmap};
-/// # let connection = servicepoint::Connection::Fake;
-/// # let pixels = Bitmap::max_sized();
-/// loop {
-/// let start = Instant::now();
-///
-/// // Change pixels here
-///
-/// connection.send(Command::BitmapLinearWin(
-/// Origin::new(0,0),
-/// pixels,
-/// CompressionCode::Lzma
-/// ))
-/// .expect("send failed");
-///
-/// // warning: will crash if resulting duration is negative, e.g. when resuming from standby
-/// std::thread::sleep(FRAME_PACING - start.elapsed());
-/// # break; // prevent doctest from hanging
-/// }
-/// ```
-pub const FRAME_PACING: Duration = Duration::from_millis(30);
diff --git a/crates/servicepoint/src/cp437.rs b/crates/servicepoint/src/cp437.rs
deleted file mode 100644
index cb9b945..0000000
--- a/crates/servicepoint/src/cp437.rs
+++ /dev/null
@@ -1,115 +0,0 @@
-use std::collections::HashMap;
-
-/// Contains functions to convert between UTF-8 and Codepage 437.
-///
-/// See
-pub struct Cp437Converter;
-
-/// An array of 256 elements, mapping most of the CP437 values to UTF-8 characters
-///
-/// Mostly follows CP437, except 0x0A, which is kept for use as line ending.
-///
-/// See
-///
-/// Mostly copied from . License: GPL-3.0
-#[rustfmt::skip]
-const CP437_TO_UTF8: [char; 256] = [
- /* 0X */ '\0', '☺', '☻', '♥', '♦', '♣', '♠', '•', '◘', '○', '\n', '♂', '♀', '♪', '♫', '☼',
- /* 1X */ '►', '◄', '↕', '‼', '¶', '§', '▬', '↨', '↑', '↓', '→', '←', '∟', '↔', '▲', '▼',
- /* 2X */ ' ', '!', '"', '#', '$', '%', '&', '\'','(', ')', '*', '+', ',', '-', '.', '/',
- /* 3X */ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?',
- /* 4X */ '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
- /* 5X */ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\',']', '^', '_',
- /* 6X */ '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
- /* 7X */ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', '⌂',
- /* 8X */ 'Ç', 'ü', 'é', 'â', 'ä', 'à', 'å', 'ç', 'ê', 'ë', 'è', 'ï', 'î', 'ì', 'Ä', 'Å',
- /* 9X */ 'É', 'æ', 'Æ', 'ô', 'ö', 'ò', 'û', 'ù', 'ÿ', 'Ö', 'Ü', '¢', '£', '¥', '₧', 'ƒ',
- /* AX */ 'á', 'í', 'ó', 'ú', 'ñ', 'Ñ', 'ª', 'º', '¿', '⌐', '¬', '½', '¼', '¡', '«', '»',
- /* BX */ '░', '▒', '▓', '│', '┤', '╡', '╢', '╖', '╕', '╣', '║', '╗', '╝', '╜', '╛', '┐',
- /* CX */ '└', '┴', '┬', '├', '─', '┼', '╞', '╟', '╚', '╔', '╩', '╦', '╠', '═', '╬', '╧',
- /* DX */ '╨', '╤', '╥', '╙', '╘', '╒', '╓', '╫', '╪', '┘', '┌', '█', '▄', '▌', '▐', '▀',
- /* EX */ 'α', 'ß', 'Γ', 'π', 'Σ', 'σ', 'µ', 'τ', 'Φ', 'Θ', 'Ω', 'δ', '∞', 'φ', 'ε', '∩',
- /* FX */ '≡', '±', '≥', '≤', '⌠', '⌡', '÷', '≈', '°', '∙', '·', '√', 'ⁿ', '²', '■', ' ',
-];
-static UTF8_TO_CP437: once_cell::sync::Lazy> =
- once_cell::sync::Lazy::new(|| {
- let pairs = CP437_TO_UTF8
- .iter()
- .enumerate()
- .map(move |(index, char)| (*char, index as u8));
- HashMap::from_iter(pairs)
- });
-
-impl Cp437Converter {
- const MISSING_CHAR_CP437: u8 = 0x3F; // '?'
-
- /// Convert the provided bytes to UTF-8.
- pub fn cp437_to_str(cp437: &[u8]) -> String {
- cp437
- .iter()
- .map(move |char| Self::cp437_to_char(*char))
- .collect()
- }
-
- /// Convert a single CP-437 character to UTF-8.
- pub fn cp437_to_char(cp437: u8) -> char {
- CP437_TO_UTF8[cp437 as usize]
- }
-
- /// Convert the provided text to CP-437 bytes.
- ///
- /// Characters that are not available are mapped to '?'.
- pub fn str_to_cp437(utf8: &str) -> Vec {
- utf8.chars().map(Self::char_to_cp437).collect()
- }
-
- /// Convert a single UTF-8 character to CP-437.
- pub fn char_to_cp437(utf8: char) -> u8 {
- *UTF8_TO_CP437
- .get(&utf8)
- .unwrap_or(&Self::MISSING_CHAR_CP437)
- }
-}
-
-#[cfg(test)]
-mod tests_feature_cp437 {
- use super::*;
-
- #[test]
- fn convert_str() {
- // test text from https://int10h.org/oldschool-pc-fonts/fontlist/font?ibm_bios
- let utf8 = r#"A quick brown fox jumps over the lazy dog.
- 0123456789 ¿?¡!`'"., <>()[]{} &@%*^#$\/
-
- * Wieniläinen sioux'ta puhuva ökyzombie diggaa Åsan roquefort-tacoja.
- * Ça me fait peur de fêter noël là, sur cette île bizarroïde où une mère et sa môme essaient de me tuer avec un gâteau à la cigüe brûlé.
- * Zwölf Boxkämpfer jagten Eva quer über den Sylter Deich.
- * El pingüino Wenceslao hizo kilómetros bajo exhaustiva lluvia y frío, añoraba a su querido cachorro.
-
- ┌─┬─┐ ╔═╦═╗ ╒═╤═╕ ╓─╥─╖
- │ │ │ ║ ║ ║ │ │ │ ║ ║ ║
- ├─┼─┤ ╠═╬═╣ ╞═╪═╡ ╟─╫─╢
- └─┴─┘ ╚═╩═╝ ╘═╧═╛ ╙─╨─╜
-
- ░░░░░ ▐▀█▀▌ .·∙•○°○•∙·.
- ▒▒▒▒▒ ▐ █ ▌ ☺☻ ♥♦♣♠ ♪♫☼
- ▓▓▓▓▓ ▐▀█▀▌ $ ¢ £ ¥ ₧
- █████ ▐▄█▄▌ ◄►▲▼ ←→↑↓↕↨
-
- ⌠
- │dx ≡ Σ √x²ⁿ·δx
- ⌡"#;
-
- let cp437 = Cp437Converter::str_to_cp437(utf8);
- let actual = Cp437Converter::cp437_to_str(&cp437);
- assert_eq!(utf8, actual)
- }
-
- #[test]
- fn convert_invalid() {
- assert_eq!(
- Cp437Converter::cp437_to_char(Cp437Converter::char_to_cp437('😜')),
- '?'
- );
- }
-}
diff --git a/crates/servicepoint/src/cp437_grid.rs b/crates/servicepoint/src/cp437_grid.rs
deleted file mode 100644
index 99506bc..0000000
--- a/crates/servicepoint/src/cp437_grid.rs
+++ /dev/null
@@ -1,163 +0,0 @@
-/// A grid containing codepage 437 characters.
-///
-/// The encoding is currently not enforced.
-pub type Cp437Grid = crate::value_grid::ValueGrid;
-
-/// The error occurring when loading an invalid character
-#[derive(Debug, PartialEq, thiserror::Error)]
-#[error(
- "The character {char:?} at position {index} is not a valid CP437 character"
-)]
-pub struct InvalidCharError {
- /// invalid character is at this position in input
- index: usize,
- /// the invalid character
- char: char,
-}
-
-impl Cp437Grid {
- /// Load an ASCII-only [&str] into a [Cp437Grid] of specified width.
- ///
- /// # Panics
- ///
- /// - for width == 0
- /// - on empty strings
- pub fn load_ascii(
- value: &str,
- width: usize,
- wrap: bool,
- ) -> Result {
- assert!(width > 0);
- assert!(!value.is_empty());
-
- let mut chars = {
- let mut x = 0;
- let mut y = 0;
-
- for (index, char) in value.chars().enumerate() {
- if !char.is_ascii() {
- return Err(InvalidCharError { index, char });
- }
-
- let is_lf = char == '\n';
- if is_lf || (wrap && x == width) {
- y += 1;
- x = 0;
- if is_lf {
- continue;
- }
- }
-
- x += 1;
- }
-
- Cp437Grid::new(width, y + 1)
- };
-
- let mut x = 0;
- let mut y = 0;
- for char in value.chars().map(move |c| c as u8) {
- let is_lf = char == b'\n';
- if is_lf || (wrap && x == width) {
- y += 1;
- x = 0;
- if is_lf {
- continue;
- }
- }
-
- if wrap || x < width {
- chars.set(x, y, char);
- }
- x += 1;
- }
-
- Ok(chars)
- }
-}
-
-use crate::Grid;
-#[allow(unused)] // depends on features
-pub use feature_cp437::*;
-
-#[cfg(feature = "cp437")]
-mod feature_cp437 {
- use super::*;
- use crate::{CharGrid, Cp437Converter};
-
- impl From<&Cp437Grid> for CharGrid {
- fn from(value: &Cp437Grid) -> Self {
- value.map(Cp437Converter::cp437_to_char)
- }
- }
-
- impl From for CharGrid {
- fn from(value: Cp437Grid) -> Self {
- Self::from(&value)
- }
- }
-
- impl From<&CharGrid> for Cp437Grid {
- fn from(value: &CharGrid) -> Self {
- value.map(Cp437Converter::char_to_cp437)
- }
- }
-
- impl From for Cp437Grid {
- fn from(value: CharGrid) -> Self {
- Self::from(&value)
- }
- }
-}
-#[cfg(test)]
-mod tests {
- use super::*;
-
- #[test]
- fn load_ascii_nowrap() {
- let chars = ['H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd']
- .map(move |c| c as u8);
- let expected = Cp437Grid::load(5, 2, &chars);
-
- let actual = Cp437Grid::load_ascii("Hello,\nWorld!", 5, false).unwrap();
- // comma will be removed because line is too long and wrap is off
- assert_eq!(actual, expected);
- }
-
- #[test]
- fn load_ascii_wrap() {
- let chars = ['H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd']
- .map(move |c| c as u8);
- let expected = Cp437Grid::load(5, 2, &chars);
-
- let actual = Cp437Grid::load_ascii("HelloWorld", 5, true).unwrap();
- // line break will be added
- assert_eq!(actual, expected);
- }
-
- #[test]
- fn load_ascii_invalid() {
- assert_eq!(
- Err(InvalidCharError {
- char: '🥶',
- index: 2
- }),
- Cp437Grid::load_ascii("?#🥶42", 3, false)
- );
- }
-}
-
-#[cfg(test)]
-#[cfg(feature = "cp437")]
-mod tests_feature_cp437 {
- use super::*;
- use crate::CharGrid;
-
- #[test]
- fn round_trip_cp437() {
- let utf8 = CharGrid::load(2, 2, &['Ä', 'x', '\n', '$']);
- let cp437 = Cp437Grid::from(utf8.clone());
- let actual = CharGrid::from(cp437);
- assert_eq!(actual, utf8);
- }
-}
diff --git a/crates/servicepoint/src/data_ref.rs b/crates/servicepoint/src/data_ref.rs
deleted file mode 100644
index b8ff624..0000000
--- a/crates/servicepoint/src/data_ref.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-/// A trait for getting the underlying raw byte slices of data containers.
-///
-/// The expectation is that you can create an equal instance with this data given the additional
-/// metadata needed.
-pub trait DataRef {
- /// Get the underlying bytes writable.
- ///
- /// Note that depending on the struct this is implemented on, writing invalid values here might
- /// lead to panics later in the lifetime of the program or on the receiving side.
- fn data_ref_mut(&mut self) -> &mut [T];
-
- /// Get the underlying bytes read-only.
- fn data_ref(&self) -> &[T];
-}
diff --git a/crates/servicepoint/src/grid.rs b/crates/servicepoint/src/grid.rs
deleted file mode 100644
index 68fe102..0000000
--- a/crates/servicepoint/src/grid.rs
+++ /dev/null
@@ -1,84 +0,0 @@
-/// A two-dimensional grid of `T`
-pub trait Grid {
- /// Sets the value at the specified position
- ///
- /// # Arguments
- ///
- /// - `x` and `y`: position of the cell to read
- ///
- /// # Panics
- ///
- /// When accessing `x` or `y` out of bounds.
- fn set(&mut self, x: usize, y: usize, value: T);
-
- /// Get the current value at the specified position
- ///
- /// # Arguments
- ///
- /// - `x` and `y`: position of the cell to read
- ///
- /// # Panics
- ///
- /// When accessing `x` or `y` out of bounds.
- fn get(&self, x: usize, y: usize) -> T;
-
- /// Get the current value at the specified position if the position is inside of bounds
- ///
- /// # Arguments
- ///
- /// - `x` and `y`: position of the cell to read
- ///
- /// returns: Value at position or None
- fn get_optional(&self, x: isize, y: isize) -> Option {
- if self.is_in_bounds(x, y) {
- Some(self.get(x as usize, y as usize))
- } else {
- None
- }
- }
-
- /// Sets the value at the specified position if the position is inside of bounds
- ///
- /// # Arguments
- ///
- /// - `x` and `y`: position of the cell to read
- ///
- /// returns: the old value or None
- fn set_optional(&mut self, x: isize, y: isize, value: T) -> bool {
- if self.is_in_bounds(x, y) {
- self.set(x as usize, y as usize, value);
- true
- } else {
- false
- }
- }
-
- /// Sets all cells in the grid to the specified value
- fn fill(&mut self, value: T);
-
- /// the size in x-direction
- fn width(&self) -> usize;
-
- /// the height in y-direction
- fn height(&self) -> usize;
-
- /// Checks whether the specified signed position is in grid bounds
- fn is_in_bounds(&self, x: isize, y: isize) -> bool {
- x >= 0
- && x < self.width() as isize
- && y >= 0
- && y < self.height() as isize
- }
-
- /// Asserts that the specified unsigned position is in grid bounds.
- ///
- /// # Panics
- ///
- /// When the specified position is out of bounds for this grid.
- fn assert_in_bounds(&self, x: usize, y: usize) {
- let width = self.width();
- assert!(x < width, "cannot access index [{x}, {y}] because x is outside of bounds [0..{width})");
- let height = self.height();
- assert!(y < height, "cannot access index [{x}, {y}] because x is outside of bounds [0..{height})");
- }
-}
diff --git a/crates/servicepoint/src/lib.rs b/crates/servicepoint/src/lib.rs
deleted file mode 100644
index 790751a..0000000
--- a/crates/servicepoint/src/lib.rs
+++ /dev/null
@@ -1,103 +0,0 @@
-//! Abstractions for the UDP protocol of the CCCB servicepoint display.
-//!
-//! Your starting point is a [Connection] to the display.
-//! With a connection, you can send [Command]s.
-//! When received, the display will update the state of its pixels.
-//!
-//! # Examples
-//!
-//! ### Clear display
-//!
-//! ```rust
-//! use servicepoint::{Connection, Command};
-//!
-//! // establish a connection
-//! let connection = Connection::open("127.0.0.1:2342")
-//! .expect("connection failed");
-//!
-//! // turn off all pixels on display
-//! connection.send(Command::Clear)
-//! .expect("send failed");
-//! ```
-//!
-//! ### Set all pixels to on
-//!
-//! ```rust
-//! # use servicepoint::{Command, CompressionCode, Grid, Bitmap};
-//! # let connection = servicepoint::Connection::open("127.0.0.1:2342").expect("connection failed");
-//! // turn on all pixels in a grid
-//! let mut pixels = Bitmap::max_sized();
-//! pixels.fill(true);
-//!
-//! // create command to send pixels
-//! let command = Command::BitmapLinearWin(
-//! servicepoint::Origin::ZERO,
-//! pixels,
-//! CompressionCode::Uncompressed
-//! );
-//!
-//! // send command to display
-//! connection.send(command).expect("send failed");
-//! ```
-//!
-//! ### Send text
-//!
-//! ```rust
-//! # use servicepoint::{Command, CompressionCode, Grid, Bitmap, CharGrid};
-//! # let connection = servicepoint::Connection::open("127.0.0.1:2342").expect("connection failed");
-//! // create a text grid
-//! let mut grid = CharGrid::from("Hello\nCCCB?");
-//! // modify the grid
-//! grid.set(grid.width() - 1, 1, '!');
-//! // create the command to send the data
-//! let command = Command::Utf8Data(servicepoint::Origin::ZERO, grid);
-//! // send command to display
-//! connection.send(command).expect("send failed");
-//! ```
-
-pub use crate::bit_vec::{bitvec, BitVec};
-pub use crate::bitmap::Bitmap;
-pub use crate::brightness::Brightness;
-pub use crate::brightness_grid::BrightnessGrid;
-pub use crate::byte_grid::ByteGrid;
-pub use crate::char_grid::CharGrid;
-pub use crate::command::{Command, Offset};
-pub use crate::compression_code::CompressionCode;
-pub use crate::connection::Connection;
-pub use crate::constants::*;
-pub use crate::cp437::Cp437Converter;
-pub use crate::cp437_grid::Cp437Grid;
-pub use crate::data_ref::DataRef;
-pub use crate::grid::Grid;
-pub use crate::origin::{Origin, Pixels, Tiles};
-pub use crate::packet::{Header, Packet, Payload};
-pub use crate::value_grid::{
- IterGridRows, SetValueSeriesError, TryLoadValueGridError, Value, ValueGrid,
-};
-
-mod bit_vec;
-mod bitmap;
-mod brightness;
-mod brightness_grid;
-mod byte_grid;
-mod char_grid;
-mod command;
-mod command_code;
-mod compression;
-mod compression_code;
-mod connection;
-mod constants;
-mod cp437_grid;
-mod data_ref;
-mod grid;
-mod origin;
-mod packet;
-mod value_grid;
-
-#[cfg(feature = "cp437")]
-mod cp437;
-
-// include README.md in doctest
-#[doc = include_str!("../README.md")]
-#[cfg(doctest)]
-pub struct ReadmeDocTests;
diff --git a/crates/servicepoint/src/origin.rs b/crates/servicepoint/src/origin.rs
deleted file mode 100644
index 345b89e..0000000
--- a/crates/servicepoint/src/origin.rs
+++ /dev/null
@@ -1,122 +0,0 @@
-use crate::TILE_SIZE;
-use std::marker::PhantomData;
-
-/// An origin marks the top left position of a window sent to the display.
-#[derive(Debug, Copy, Clone, PartialEq)]
-pub struct Origin {
- /// position in the width direction
- pub x: usize,
- /// position in the height direction
- pub y: usize,
- phantom_data: PhantomData,
-}
-
-impl Origin {
- /// Top-left. Equivalent to `Origin::ZERO`.
- pub const ZERO: Self = Self {
- x: 0,
- y: 0,
- phantom_data: PhantomData,
- };
-
- /// Create a new [Origin] instance for the provided position.
- pub fn new(x: usize, y: usize) -> Self {
- Self {
- x,
- y,
- phantom_data: PhantomData,
- }
- }
-}
-
-impl std::ops::Add> for Origin {
- type Output = Origin;
-
- fn add(self, rhs: Origin) -> Self::Output {
- Origin {
- x: self.x + rhs.x,
- y: self.y + rhs.y,
- phantom_data: PhantomData,
- }
- }
-}
-
-pub trait DisplayUnit {}
-
-/// Marks something to be measured in number of pixels.
-#[derive(Debug, Copy, Clone, PartialEq)]
-pub struct Pixels();
-
-/// Marks something to be measured in number of iles.
-#[derive(Debug, Copy, Clone, PartialEq)]
-pub struct Tiles();
-
-impl DisplayUnit for Pixels {}
-
-impl DisplayUnit for Tiles {}
-
-impl From<&Origin> for Origin {
- fn from(value: &Origin) -> Self {
- Self {
- x: value.x * TILE_SIZE,
- y: value.y * TILE_SIZE,
- phantom_data: PhantomData,
- }
- }
-}
-
-impl TryFrom<&Origin> for Origin {
- type Error = ();
-
- fn try_from(value: &Origin) -> Result {
- let (x, x_rem) = (value.x / TILE_SIZE, value.x % TILE_SIZE);
- if x_rem != 0 {
- return Err(());
- }
- let (y, y_rem) = (value.y / TILE_SIZE, value.y % TILE_SIZE);
- if y_rem != 0 {
- return Err(());
- }
-
- Ok(Self {
- x,
- y,
- phantom_data: PhantomData,
- })
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- #[test]
- fn origin_tile_to_pixel() {
- let tile: Origin = Origin::new(1, 2);
- let actual: Origin = Origin::from(&tile);
- let expected: Origin = Origin::new(8, 16);
- assert_eq!(actual, expected);
- }
-
- #[test]
- fn origin_pixel_to_tile() {
- let pixel: Origin = Origin::new(8, 16);
- let actual: Origin = Origin::try_from(&pixel).unwrap();
- let expected: Origin = Origin::new(1, 2);
- assert_eq!(actual, expected);
- }
-
- #[test]
- #[should_panic]
- fn origin_pixel_to_tile_fail_y() {
- let pixel: Origin = Origin::new(8, 15);
- let _: Origin = Origin::try_from(&pixel).unwrap();
- }
-
- #[test]
- #[should_panic]
- fn origin_pixel_to_tile_fail_x() {
- let pixel: Origin = Origin::new(7, 16);
- let _: Origin = Origin::try_from(&pixel).unwrap();
- }
-}
diff --git a/crates/servicepoint/src/packet.rs b/crates/servicepoint/src/packet.rs
deleted file mode 100644
index 099c50c..0000000
--- a/crates/servicepoint/src/packet.rs
+++ /dev/null
@@ -1,358 +0,0 @@
-//! Raw packet manipulation.
-//!
-//! Should probably only be used directly to use features not exposed by the library.
-//!
-//! # Examples
-//!
-//! Converting a packet to a command and back:
-//!
-//! ```rust
-//! use servicepoint::{Command, Packet};
-//! # let command = Command::Clear;
-//! let packet: Packet = command.into();
-//! let command: Command = Command::try_from(packet).expect("could not read command from packet");
-//! ```
-//!
-//! Converting a packet to bytes and back:
-//!
-//! ```rust
-//! use servicepoint::{Command, Packet};
-//! # let command = Command::Clear;
-//! # let packet: Packet = command.into();
-//! let bytes: Vec = packet.into();
-//! let packet = Packet::try_from(bytes).expect("could not read packet from bytes");
-//! ```
-
-use crate::command_code::CommandCode;
-use crate::compression::into_compressed;
-use crate::{
- Bitmap, Command, CompressionCode, Grid, Offset, Origin, Pixels, Tiles,
- TILE_SIZE,
-};
-use std::mem::size_of;
-
-/// A raw header.
-///
-/// The header specifies the kind of command, the size of the payload and where to display the
-/// payload, where applicable.
-///
-/// Because the meaning of most fields depend on the command, there are no speaking names for them.
-#[derive(Copy, Clone, Debug, PartialEq)]
-pub struct Header {
- /// The first two bytes specify which command this packet represents.
- pub command_code: u16,
- /// First command-specific value
- pub a: u16,
- /// Second command-specific value
- pub b: u16,
- /// Third command-specific value
- pub c: u16,
- /// Fourth command-specific value
- pub d: u16,
-}
-
-/// The raw payload.
-///
-/// Should probably only be used directly to use features not exposed by the library.
-pub type Payload = Vec;
-
-/// The raw packet.
-///
-/// Contents should probably only be used directly to use features not exposed by the library.
-///
-/// You may want to use [Command] instead.
-///
-///
-#[derive(Clone, Debug, PartialEq)]
-pub struct Packet {
- /// Meta-information for the packed command
- pub header: Header,
- /// The data for the packed command
- pub payload: Payload,
-}
-
-impl From for Vec {
- /// Turn the packet into raw bytes ready to send
- fn from(value: Packet) -> Self {
- let Packet {
- header:
- Header {
- command_code: mode,
- a,
- b,
- c,
- d,
- },
- payload,
- } = value;
-
- let mut packet = vec![0u8; 10 + payload.len()];
- packet[0..=1].copy_from_slice(&u16::to_be_bytes(mode));
- packet[2..=3].copy_from_slice(&u16::to_be_bytes(a));
- packet[4..=5].copy_from_slice(&u16::to_be_bytes(b));
- packet[6..=7].copy_from_slice(&u16::to_be_bytes(c));
- packet[8..=9].copy_from_slice(&u16::to_be_bytes(d));
-
- packet[10..].copy_from_slice(&payload);
-
- packet
- }
-}
-
-impl TryFrom<&[u8]> for Packet {
- type Error = ();
-
- /// Tries to interpret the bytes as a [Packet].
- ///
- /// returns: `Error` if slice is not long enough to be a [Packet]
- fn try_from(value: &[u8]) -> Result {
- if value.len() < size_of::() {
- return Err(());
- }
-
- let header = {
- let command_code = Self::u16_from_be_slice(&value[0..=1]);
- let a = Self::u16_from_be_slice(&value[2..=3]);
- let b = Self::u16_from_be_slice(&value[4..=5]);
- let c = Self::u16_from_be_slice(&value[6..=7]);
- let d = Self::u16_from_be_slice(&value[8..=9]);
- Header {
- command_code,
- a,
- b,
- c,
- d,
- }
- };
- let payload = value[10..].to_vec();
-
- Ok(Packet { header, payload })
- }
-}
-
-impl TryFrom> for Packet {
- type Error = ();
-
- fn try_from(value: Vec) -> Result {
- Self::try_from(value.as_slice())
- }
-}
-
-impl From for Packet {
- /// Move the [Command] into a [Packet] instance for sending.
- #[allow(clippy::cast_possible_truncation)]
- fn from(value: Command) -> Self {
- match value {
- Command::Clear => Self::command_code_only(CommandCode::Clear),
- Command::FadeOut => Self::command_code_only(CommandCode::FadeOut),
- Command::HardReset => {
- Self::command_code_only(CommandCode::HardReset)
- }
- #[allow(deprecated)]
- Command::BitmapLegacy => {
- Self::command_code_only(CommandCode::BitmapLegacy)
- }
- Command::CharBrightness(origin, grid) => {
- Self::origin_grid_to_packet(
- origin,
- grid,
- CommandCode::CharBrightness,
- )
- }
- Command::Brightness(brightness) => Packet {
- header: Header {
- command_code: CommandCode::Brightness.into(),
- a: 0x00000,
- b: 0x0000,
- c: 0x0000,
- d: 0x0000,
- },
- payload: vec![brightness.into()],
- },
- Command::BitmapLinearWin(origin, pixels, compression) => {
- Self::bitmap_win_into_packet(origin, pixels, compression)
- }
- Command::BitmapLinear(offset, bits, compression) => {
- Self::bitmap_linear_into_packet(
- CommandCode::BitmapLinear,
- offset,
- compression,
- bits.into(),
- )
- }
- Command::BitmapLinearAnd(offset, bits, compression) => {
- Self::bitmap_linear_into_packet(
- CommandCode::BitmapLinearAnd,
- offset,
- compression,
- bits.into(),
- )
- }
- Command::BitmapLinearOr(offset, bits, compression) => {
- Self::bitmap_linear_into_packet(
- CommandCode::BitmapLinearOr,
- offset,
- compression,
- bits.into(),
- )
- }
- Command::BitmapLinearXor(offset, bits, compression) => {
- Self::bitmap_linear_into_packet(
- CommandCode::BitmapLinearXor,
- offset,
- compression,
- bits.into(),
- )
- }
- Command::Cp437Data(origin, grid) => Self::origin_grid_to_packet(
- origin,
- grid,
- CommandCode::Cp437Data,
- ),
- Command::Utf8Data(origin, grid) => {
- Self::origin_grid_to_packet(origin, grid, CommandCode::Utf8Data)
- }
- }
- }
-}
-
-impl Packet {
- /// Helper method for `BitmapLinear*`-Commands into [Packet]
- #[allow(clippy::cast_possible_truncation)]
- fn bitmap_linear_into_packet(
- command: CommandCode,
- offset: Offset,
- compression: CompressionCode,
- payload: Vec,
- ) -> Packet {
- let length = payload.len() as u16;
- let payload = into_compressed(compression, payload);
- Packet {
- header: Header {
- command_code: command.into(),
- a: offset as u16,
- b: length,
- c: compression.into(),
- d: 0,
- },
- payload,
- }
- }
-
- #[allow(clippy::cast_possible_truncation)]
- fn bitmap_win_into_packet(
- origin: Origin,
- pixels: Bitmap,
- compression: CompressionCode,
- ) -> Packet {
- debug_assert_eq!(origin.x % 8, 0);
- debug_assert_eq!(pixels.width() % 8, 0);
-
- let tile_x = (origin.x / TILE_SIZE) as u16;
- let tile_w = (pixels.width() / TILE_SIZE) as u16;
- let pixel_h = pixels.height() as u16;
- let payload = into_compressed(compression, pixels.into());
- let command = match compression {
- CompressionCode::Uncompressed => {
- CommandCode::BitmapLinearWinUncompressed
- }
- #[cfg(feature = "compression_zlib")]
- CompressionCode::Zlib => CommandCode::BitmapLinearWinZlib,
- #[cfg(feature = "compression_bzip2")]
- CompressionCode::Bzip2 => CommandCode::BitmapLinearWinBzip2,
- #[cfg(feature = "compression_lzma")]
- CompressionCode::Lzma => CommandCode::BitmapLinearWinLzma,
- #[cfg(feature = "compression_zstd")]
- CompressionCode::Zstd => CommandCode::BitmapLinearWinZstd,
- };
-
- Packet {
- header: Header {
- command_code: command.into(),
- a: tile_x,
- b: origin.y as u16,
- c: tile_w,
- d: pixel_h,
- },
- payload,
- }
- }
-
- /// Helper method for creating empty packets only containing the command code
- fn command_code_only(code: CommandCode) -> Packet {
- Packet {
- header: Header {
- command_code: code.into(),
- a: 0x0000,
- b: 0x0000,
- c: 0x0000,
- d: 0x0000,
- },
- payload: vec![],
- }
- }
-
- fn u16_from_be_slice(slice: &[u8]) -> u16 {
- let mut bytes = [0u8; 2];
- bytes[0] = slice[0];
- bytes[1] = slice[1];
- u16::from_be_bytes(bytes)
- }
-
- fn origin_grid_to_packet(
- origin: Origin,
- grid: impl Grid + Into,
- command_code: CommandCode,
- ) -> Packet {
- Packet {
- header: Header {
- command_code: command_code.into(),
- a: origin.x as u16,
- b: origin.y as u16,
- c: grid.width() as u16,
- d: grid.height() as u16,
- },
- payload: grid.into(),
- }
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- #[test]
- fn round_trip() {
- let p = Packet {
- header: Header {
- command_code: 0,
- a: 1,
- b: 2,
- c: 3,
- d: 4,
- },
- payload: vec![42u8; 23],
- };
- let data: Vec = p.into();
- let p = Packet::try_from(data).unwrap();
- assert_eq!(
- p,
- Packet {
- header: Header {
- command_code: 0,
- a: 1,
- b: 2,
- c: 3,
- d: 4
- },
- payload: vec![42u8; 23]
- }
- );
- }
-
- #[test]
- fn too_small() {
- let data = vec![0u8; 4];
- assert_eq!(Packet::try_from(data.as_slice()), Err(()))
- }
-}
diff --git a/crates/servicepoint/src/value_grid.rs b/crates/servicepoint/src/value_grid.rs
deleted file mode 100644
index b9cfea5..0000000
--- a/crates/servicepoint/src/value_grid.rs
+++ /dev/null
@@ -1,590 +0,0 @@
-use std::fmt::Debug;
-use std::slice::{Iter, IterMut};
-
-use crate::*;
-
-/// A type that can be stored in a [ValueGrid], e.g. [char], [u8].
-pub trait Value: Sized + Default + Copy + Clone + Debug {}
-impl Value for T {}
-
-/// A 2D grid of values.
-///
-/// The memory layout is the one the display expects in [Command]s.
-///
-/// This structure can be used with any type that implements the [Value] trait.
-/// You can also use the concrete type aliases provided in this crate, e.g. [CharGrid] and [ByteGrid].
-#[derive(Debug, Clone, PartialEq)]
-pub struct ValueGrid {
- width: usize,
- height: usize,
- data: Vec,
-}
-
-/// Error type for methods that change a whole column or row at once
-#[derive(thiserror::Error, Debug, PartialEq)]
-pub enum SetValueSeriesError {
- #[error("The index {index} was out of bounds for size {size}")]
- /// The index {index} was out of bounds for size {size}
- OutOfBounds {
- /// the index where access was tried
- index: usize,
- /// the size in that direction
- size: usize,
- },
- #[error("The provided series was expected to have a length of {expected}, but was {actual}")]
- /// The provided series was expected to have a length of {expected}, but was {actual}
- InvalidLength {
- /// actual size of the provided series
- actual: usize,
- /// expected size
- expected: usize,
- },
-}
-
-impl ValueGrid {
- /// Creates a new [ValueGrid] with the specified dimensions.
- ///
- /// # Arguments
- ///
- /// - width: size in x-direction
- /// - height: size in y-direction
- ///
- /// returns: [ValueGrid] initialized to default value.
- pub fn new(width: usize, height: usize) -> Self {
- Self {
- data: vec![Default::default(); width * height],
- width,
- height,
- }
- }
-
- /// Loads a [ValueGrid] with the specified dimensions from the provided data.
- ///
- /// returns: [ValueGrid] that contains a copy of the provided data
- ///
- /// # Panics
- ///
- /// - when the dimensions and data size do not match exactly.
- #[must_use]
- pub fn load(width: usize, height: usize, data: &[T]) -> Self {
- assert_eq!(
- width * height,
- data.len(),
- "dimension mismatch for data {data:?}"
- );
- Self {
- data: Vec::from(data),
- width,
- height,
- }
- }
-
- /// Creates a [ValueGrid] with the specified width from the provided data without copying it.
- ///
- /// returns: [ValueGrid] that contains the provided data.
- ///
- /// # Panics
- ///
- /// - when the data size is not dividable by the width.
- #[must_use]
- pub fn from_vec(width: usize, data: Vec) -> Self {
- let len = data.len();
- let height = len / width;
- assert_eq!(0, len % width, "dimension mismatch - len {len} is not dividable by {width}");
- Self { data, width, height }
- }
-
- /// Loads a [ValueGrid] with the specified width from the provided data, wrapping to as many rows as needed.
- ///
- /// returns: [ValueGrid] that contains a copy of the provided data or [TryLoadValueGridError].
- ///
- /// # Examples
- ///
- /// ```
- /// # use servicepoint::ValueGrid;
- /// let grid = ValueGrid::wrap(2, &[0, 1, 2, 3, 4, 5]).unwrap();
- /// ```
- pub fn wrap(
- width: usize,
- data: &[T],
- ) -> Result {
- let len = data.len();
- if len % width != 0 {
- return Err(TryLoadValueGridError::InvalidDimensions);
- }
- Ok(Self::load(width, len / width, data))
- }
-
- /// Loads a [ValueGrid] with the specified dimensions from the provided data.
- ///
- /// returns: [ValueGrid] that contains a copy of the provided data or [TryLoadValueGridError].
- pub fn try_load(
- width: usize,
- height: usize,
- data: Vec,
- ) -> Result {
- if width * height != data.len() {
- return Err(TryLoadValueGridError::InvalidDimensions);
- }
-
- Ok(Self {
- data,
- width,
- height,
- })
- }
-
- /// Iterate over all cells in [ValueGrid].
- ///
- /// Order is equivalent to the following loop:
- /// ```
- /// # use servicepoint::{ByteGrid, Grid};
- /// # let grid = ByteGrid::new(2,2);
- /// for y in 0..grid.height() {
- /// for x in 0..grid.width() {
- /// grid.get(x, y);
- /// }
- /// }
- /// ```
- pub fn iter(&self) -> Iter {
- self.data.iter()
- }
-
- /// Iterate over all rows in [ValueGrid] top to bottom.
- pub fn iter_rows(&self) -> IterGridRows {
- IterGridRows {
- byte_grid: self,
- row: 0,
- }
- }
-
- /// Returns an iterator that allows modifying each value.
- ///
- /// The iterator yields all cells from top left to bottom right.
- pub fn iter_mut(&mut self) -> IterMut {
- self.data.iter_mut()
- }
-
- /// Get a mutable reference to the current value at the specified position.
- ///
- /// # Arguments
- ///
- /// - `x` and `y`: position of the cell
- ///
- /// # Panics
- ///
- /// When accessing `x` or `y` out of bounds.
- pub fn get_ref_mut(&mut self, x: usize, y: usize) -> &mut T {
- self.assert_in_bounds(x, y);
- &mut self.data[x + y * self.width]
- }
-
- /// Get a mutable reference to the current value at the specified position if position is in bounds.
- ///
- /// # Arguments
- ///
- /// - `x` and `y`: position of the cell
- ///
- /// returns: Reference to cell or None
- pub fn get_ref_mut_optional(
- &mut self,
- x: isize,
- y: isize,
- ) -> Option<&mut T> {
- if self.is_in_bounds(x, y) {
- Some(&mut self.data[x as usize + y as usize * self.width])
- } else {
- None
- }
- }
-
- /// Convert between ValueGrid types.
- ///
- /// See also [Iterator::map].
- ///
- /// # Examples
- ///
- /// Use logic written for u8s and then convert to [Brightness] values for sending in a [Command].
- /// ```
- /// # fn foo(grid: &mut ByteGrid) {}
- /// # use servicepoint::{Brightness, BrightnessGrid, ByteGrid, Command, Origin, TILE_HEIGHT, TILE_WIDTH};
- /// let mut grid: ByteGrid = ByteGrid::new(TILE_WIDTH, TILE_HEIGHT);
- /// foo(&mut grid);
- /// let grid: BrightnessGrid = grid.map(Brightness::saturating_from);
- /// let command = Command::CharBrightness(Origin::ZERO, grid);
- /// ```
- /// [Brightness]: [crate::Brightness]
- /// [Command]: [crate::Command]
- pub fn map(&self, f: F) -> ValueGrid
- where
- TConverted: Value,
- F: Fn(T) -> TConverted,
- {
- let data = self
- .data_ref()
- .iter()
- .map(|elem| f(*elem))
- .collect::>();
- ValueGrid::load(self.width(), self.height(), &data)
- }
-
- /// Copies a row from the grid.
- ///
- /// Returns [None] if y is out of bounds.
- pub fn get_row(&self, y: usize) -> Option> {
- self.data
- .chunks_exact(self.width())
- .nth(y)
- .map(|row| row.to_vec())
- }
-
- /// Copies a column from the grid.
- ///
- /// Returns [None] if x is out of bounds.
- pub fn get_col(&self, x: usize) -> Option> {
- self.data
- .chunks_exact(self.width())
- .map(|row| row.get(x).copied())
- .collect()
- }
-
- /// Overwrites a column in the grid.
- ///
- /// Returns [Err] if x is out of bounds or `col` is not of the correct size.
- pub fn set_col(
- &mut self,
- x: usize,
- col: &[T],
- ) -> Result<(), SetValueSeriesError> {
- if col.len() != self.height() {
- return Err(SetValueSeriesError::InvalidLength {
- expected: self.height(),
- actual: col.len(),
- });
- }
- let width = self.width();
- if self
- .data
- .chunks_exact_mut(width)
- .zip(col.iter())
- .map(|(row, column_value)| {
- row.get_mut(x).map(move |cell| *cell = *column_value)
- })
- .all(|cell| cell.is_some())
- {
- Ok(())
- } else {
- Err(SetValueSeriesError::OutOfBounds {
- index: x,
- size: width,
- })
- }
- }
-
- /// Overwrites a row in the grid.
- ///
- /// Returns [Err] if y is out of bounds or `row` is not of the correct size.
- pub fn set_row(
- &mut self,
- y: usize,
- row: &[T],
- ) -> Result<(), SetValueSeriesError> {
- let width = self.width();
- if row.len() != width {
- return Err(SetValueSeriesError::InvalidLength {
- expected: width,
- actual: row.len(),
- });
- }
-
- let chunk = match self.data.chunks_exact_mut(width).nth(y) {
- Some(row) => row,
- None => {
- return Err(SetValueSeriesError::OutOfBounds {
- size: self.height(),
- index: y,
- })
- }
- };
-
- chunk.copy_from_slice(row);
- Ok(())
- }
-}
-
-/// Errors that can occur when loading a grid
-#[derive(Debug, thiserror::Error, PartialEq)]
-pub enum TryLoadValueGridError {
- #[error("The provided dimensions do not match with the data size")]
- /// The provided dimensions do not match with the data size
- InvalidDimensions,
-}
-
-impl Grid for ValueGrid {
- /// Sets the value of the cell at the specified position in the `ValueGrid.
- ///
- /// # Arguments
- ///
- /// - `x` and `y`: position of the cell
- /// - `value`: the value to write to the cell
- ///
- /// # Panics
- ///
- /// When accessing `x` or `y` out of bounds.
- fn set(&mut self, x: usize, y: usize, value: T) {
- self.assert_in_bounds(x, y);
- self.data[x + y * self.width] = value;
- }
-
- /// Gets the current value at the specified position.
- ///
- /// # Arguments
- ///
- /// - `x` and `y`: position of the cell to read
- ///
- /// # Panics
- ///
- /// When accessing `x` or `y` out of bounds.
- fn get(&self, x: usize, y: usize) -> T {
- self.assert_in_bounds(x, y);
- self.data[x + y * self.width]
- }
-
- fn fill(&mut self, value: T) {
- self.data.fill(value);
- }
-
- fn width(&self) -> usize {
- self.width
- }
-
- fn height(&self) -> usize {
- self.height
- }
-}
-
-impl DataRef for ValueGrid {
- /// Get the underlying byte rows mutable
- fn data_ref_mut(&mut self) -> &mut [T] {
- self.data.as_mut_slice()
- }
-
- /// Get the underlying byte rows read only
- fn data_ref(&self) -> &[T] {
- self.data.as_slice()
- }
-}
-
-impl From> for Vec {
- /// Turn into the underlying [`Vec`] containing the rows of bytes.
- fn from(value: ValueGrid) -> Self {
- value.data
- }
-}
-
-/// An iterator iver the rows in a [ValueGrid]
-pub struct IterGridRows<'t, T: Value> {
- byte_grid: &'t ValueGrid,
- row: usize,
-}
-
-impl<'t, T: Value> Iterator for IterGridRows<'t, T> {
- type Item = Iter<'t, T>;
-
- fn next(&mut self) -> Option {
- if self.row >= self.byte_grid.height {
- return None;
- }
-
- let start = self.row * self.byte_grid.width;
- let end = start + self.byte_grid.width;
- let result = self.byte_grid.data[start..end].iter();
- self.row += 1;
- Some(result)
- }
-}
-
-#[cfg(test)]
-mod tests {
- use crate::{
- value_grid::{SetValueSeriesError, ValueGrid},
- *,
- };
-
- #[test]
- fn fill() {
- let mut grid = ValueGrid::::new(2, 2);
- assert_eq!(grid.data, [0x00, 0x00, 0x00, 0x00]);
-
- grid.fill(42);
- assert_eq!(grid.data, [42; 4]);
- }
-
- #[test]
- fn get_set() {
- let mut grid = ValueGrid::new(2, 2);
- assert_eq!(grid.get(0, 0), 0);
- assert_eq!(grid.get(1, 1), 0);
-
- grid.set(0, 0, 42);
- grid.set(1, 0, 23);
- assert_eq!(grid.data, [42, 23, 0, 0]);
-
- assert_eq!(grid.get(0, 0), 42);
- assert_eq!(grid.get(1, 0), 23);
- assert_eq!(grid.get(1, 1), 0);
- }
-
- #[test]
- fn load() {
- let mut grid = ValueGrid::new(2, 3);
- for x in 0..grid.width {
- for y in 0..grid.height {
- grid.set(x, y, (x + y) as u8);
- }
- }
-
- assert_eq!(grid.data, [0, 1, 1, 2, 2, 3]);
-
- let data: Vec = grid.into();
-
- let grid = ValueGrid::load(2, 3, &data);
- assert_eq!(grid.data, [0, 1, 1, 2, 2, 3]);
- }
-
- #[test]
- fn mut_data_ref() {
- let mut vec = ValueGrid::new(2, 2);
-
- let data_ref = vec.data_ref_mut();
- data_ref.copy_from_slice(&[1, 2, 3, 4]);
-
- assert_eq!(vec.data, [1, 2, 3, 4]);
- assert_eq!(vec.get(1, 0), 2)
- }
-
- #[test]
- fn iter() {
- let mut vec = ValueGrid::new(2, 2);
- vec.set(1, 1, 5);
-
- let mut iter = vec.iter();
- assert_eq!(*iter.next().unwrap(), 0);
- assert_eq!(*iter.next().unwrap(), 0);
- assert_eq!(*iter.next().unwrap(), 0);
- assert_eq!(*iter.next().unwrap(), 5);
- }
-
- #[test]
- fn iter_mut() {
- let mut vec = ValueGrid::new(2, 3);
- for (index, cell) in vec.iter_mut().enumerate() {
- *cell = index as u8;
- }
-
- assert_eq!(vec.data_ref(), [0, 1, 2, 3, 4, 5]);
- }
-
- #[test]
- fn iter_rows() {
- let vec = ValueGrid::load(2, 3, &[0, 1, 1, 2, 2, 3]);
- for (y, row) in vec.iter_rows().enumerate() {
- for (x, val) in row.enumerate() {
- assert_eq!(*val, (x + y) as u8);
- }
- }
- }
-
- #[test]
- #[should_panic]
- fn out_of_bounds_x() {
- let mut vec = ValueGrid::load(2, 2, &[0, 1, 2, 3]);
- vec.set(2, 1, 5);
- }
-
- #[test]
- #[should_panic]
- fn out_of_bounds_y() {
- let vec = ValueGrid::load(2, 2, &[0, 1, 2, 3]);
- vec.get(1, 2);
- }
-
- #[test]
- fn ref_mut() {
- let mut vec = ValueGrid::from_vec(3, vec![0, 1, 2, 3,4,5,6,7,8]);
-
- let top_left = vec.get_ref_mut(0, 0);
- *top_left += 5;
- let somewhere = vec.get_ref_mut(2, 1);
- *somewhere = 42;
-
- assert_eq!(None, vec.get_ref_mut_optional(3, 2));
- assert_eq!(None, vec.get_ref_mut_optional(2, 3));
- assert_eq!(Some(&mut 5), vec.get_ref_mut_optional(0, 0));
- assert_eq!(Some(&mut 42), vec.get_ref_mut_optional(2, 1));
- assert_eq!(Some(&mut 8), vec.get_ref_mut_optional(2, 2));
- }
-
- #[test]
- fn optional() {
- let mut grid = ValueGrid::load(2, 2, &[0, 1, 2, 3]);
- grid.set_optional(0, 0, 5);
- grid.set_optional(-1, 0, 8);
- grid.set_optional(0, 8, 42);
- assert_eq!(grid.data, [5, 1, 2, 3]);
-
- assert_eq!(grid.get_optional(0, 0), Some(5));
- assert_eq!(grid.get_optional(0, 8), None);
- }
-
- #[test]
- fn col() {
- let mut grid = ValueGrid::load(2, 3, &[0, 1, 2, 3, 4, 5]);
- assert_eq!(grid.get_col(0), Some(vec![0, 2, 4]));
- assert_eq!(grid.get_col(1), Some(vec![1, 3, 5]));
- assert_eq!(grid.get_col(2), None);
- assert_eq!(grid.set_col(0, &[5, 7, 9]), Ok(()));
- assert_eq!(
- grid.set_col(2, &[5, 7, 9]),
- Err(SetValueSeriesError::OutOfBounds { size: 2, index: 2 })
- );
- assert_eq!(
- grid.set_col(0, &[5, 7]),
- Err(SetValueSeriesError::InvalidLength {
- expected: 3,
- actual: 2
- })
- );
- assert_eq!(grid.get_col(0), Some(vec![5, 7, 9]));
- }
-
- #[test]
- fn row() {
- let mut grid = ValueGrid::load(2, 3, &[0, 1, 2, 3, 4, 5]);
- assert_eq!(grid.get_row(0), Some(vec![0, 1]));
- assert_eq!(grid.get_row(2), Some(vec![4, 5]));
- assert_eq!(grid.get_row(3), None);
- assert_eq!(grid.set_row(0, &[5, 7]), Ok(()));
- assert_eq!(grid.get_row(0), Some(vec![5, 7]));
- assert_eq!(
- grid.set_row(3, &[5, 7]),
- Err(SetValueSeriesError::OutOfBounds { size: 3, index: 3 })
- );
- assert_eq!(
- grid.set_row(2, &[5, 7, 3]),
- Err(SetValueSeriesError::InvalidLength {
- expected: 2,
- actual: 3
- })
- );
- }
-
- #[test]
- fn wrap() {
- let grid = ValueGrid::wrap(2, &[0, 1, 2, 3, 4, 5]).unwrap();
- assert_eq!(grid.height(), 3);
-
- let grid = ValueGrid::wrap(4, &[0, 1, 2, 3, 4, 5]);
- assert_eq!(grid.err(), Some(TryLoadValueGridError::InvalidDimensions));
- }
-}
diff --git a/crates/servicepoint_binding_c/Cargo.toml b/crates/servicepoint_binding_c/Cargo.toml
deleted file mode 100644
index e93d2f1..0000000
--- a/crates/servicepoint_binding_c/Cargo.toml
+++ /dev/null
@@ -1,29 +0,0 @@
-[package]
-name = "servicepoint_binding_c"
-version.workspace = true
-publish = true
-edition = "2021"
-license = "GPL-3.0-or-later"
-description = "C bindings for the servicepoint crate."
-homepage = "https://docs.rs/crate/servicepoint_binding_c"
-repository = "https://git.berlin.ccc.de/servicepoint/servicepoint"
-readme = "README.md"
-links = "servicepoint"
-keywords = ["cccb", "cccb-servicepoint", "cbindgen"]
-
-[lib]
-crate-type = ["staticlib", "cdylib", "rlib"]
-
-[build-dependencies]
-cbindgen = "0.27.0"
-
-[dependencies.servicepoint]
-version = "0.13.1"
-path = "../servicepoint"
-features = ["all_compressions"]
-
-[lints]
-workspace = true
-
-[package.metadata.docs.rs]
-all-features = true
diff --git a/crates/servicepoint_binding_c/README.md b/crates/servicepoint_binding_c/README.md
deleted file mode 100644
index 892c9e5..0000000
--- a/crates/servicepoint_binding_c/README.md
+++ /dev/null
@@ -1,63 +0,0 @@
-# servicepoint_binding_c
-
-[](https://crates.io/crates/servicepoint)
-[](https://crates.io/crates/servicepoint)
-[](https://docs.rs/servicepoint/latest/servicepoint/)
-[](../../LICENSE)
-
-In [CCCB](https://berlin.ccc.de/), there is a big pixel matrix hanging on the wall.
-It is called "Service Point Display" or "Airport Display".
-
-This crate contains C bindings for the `servicepoint` library, enabling users to parse, encode and send packets to this display via UDP.
-
-## Examples
-
-```c++
-#include
-#include "servicepoint.h"
-
-int main(void) {
- SPConnection *connection = sp_connection_open("172.23.42.29:2342");
- if (connection == NULL)
- return 1;
-
- SPBitmap *pixels = sp_bitmap_new(SP_PIXEL_WIDTH, SP_PIXEL_HEIGHT);
- sp_bitmap_fill(pixels, true);
-
- SPCommand *command = sp_command_bitmap_linear_win(0, 0, pixels, Uncompressed);
- while (sp_connection_send_command(connection, sp_command_clone(command)));
-
- sp_command_free(command);
- sp_connection_free(connection);
- return 0;
-}
-```
-
-A full example including Makefile is available as part of this crate.
-
-## Note on stability
-
-This library is still in early development.
-You can absolutely use it, and it works, but expect minor breaking changes with every version bump.
-Please specify the full version including patch in your Cargo.toml until 1.0 is released.
-
-## Installation
-
-Copy the header to your project and compile against.
-
-You have the choice of linking statically (recommended) or dynamically.
-- The C example shows how to link statically against the `staticlib` variant.
-- When linked dynamically, you have to provide the `cdylib` at runtime in the _same_ version, as there are no API/ABI guarantees yet.
-
-## Notes on differences to rust library
-
-- function names are: `sp_` \ \.
-- Instances get consumed in the same way they do when writing rust code. Do not use an instance after an (implicit!) free.
-- Option or Result turn into nullable return values - check for NULL!
-- There are no specifics for C++ here yet. You might get a nicer header when generating directly for C++, but it should be usable.
-- Reading and writing to instances concurrently is not safe. Only reading concurrently is safe.
-- documentation is included in the header and available [online](https://docs.rs/servicepoint_binding_c/latest/servicepoint_binding_c/)
-
-## Everything else
-
-Look at the main project [README](https://git.berlin.ccc.de/servicepoint/servicepoint/src/branch/main/README.md) for further information.
diff --git a/crates/servicepoint_binding_c/build.rs b/crates/servicepoint_binding_c/build.rs
deleted file mode 100644
index 93bf703..0000000
--- a/crates/servicepoint_binding_c/build.rs
+++ /dev/null
@@ -1,33 +0,0 @@
-//! Build script generating the header for the `servicepoint` C library.
-//!
-//! When the environment variable `SERVICEPOINT_HEADER_OUT` is set, the header is copied there from
-//! the out directory. This can be used to use the build script as a command line tool from other
-//! build tools.
-
-use std::{env, fs::copy};
-
-use cbindgen::{generate_with_config, Config};
-
-fn main() {
- let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
- println!("cargo::rerun-if-changed={crate_dir}");
-
- let config =
- Config::from_file(crate_dir.clone() + "/cbindgen.toml").unwrap();
-
- let output_dir = env::var("OUT_DIR").unwrap();
- let header_file = output_dir.clone() + "/servicepoint.h";
-
- generate_with_config(crate_dir, config)
- .unwrap()
- .write_to_file(&header_file);
- println!("cargo:include={output_dir}");
-
- println!("cargo::rerun-if-env-changed=SERVICEPOINT_HEADER_OUT");
- if let Ok(header_out) = env::var("SERVICEPOINT_HEADER_OUT") {
- let header_copy = header_out + "/servicepoint.h";
- println!("cargo:warning=Copying header to {header_copy}");
- copy(header_file, &header_copy).unwrap();
- println!("cargo::rerun-if-changed={header_copy}");
- }
-}
diff --git a/crates/servicepoint_binding_c/cbindgen.toml b/crates/servicepoint_binding_c/cbindgen.toml
deleted file mode 100644
index 7fc0fdf..0000000
--- a/crates/servicepoint_binding_c/cbindgen.toml
+++ /dev/null
@@ -1,36 +0,0 @@
-language = "C"
-include_version = true
-cpp_compat = true
-
-autogen_warning = "/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */"
-
-############################ Code Style Options ################################
-
-braces = "SameLine"
-line_length = 80
-tab_width = 4
-documentation = true
-documentation_style = "auto"
-documentation_length = "full"
-line_endings = "LF"
-
-############################# Codegen Options ##################################
-
-style = "type"
-usize_is_size_t = true
-
-# this is needed because otherwise the order in the C# bindings is different on different machines
-sort_by = "Name"
-
-[parse]
-parse_deps = false
-
-[parse.expand]
-all_features = true
-
-[export]
-include = []
-exclude = []
-
-[enum]
-rename_variants = "QualifiedScreamingSnakeCase"
diff --git a/crates/servicepoint_binding_c/examples/lang_c/Cargo.toml b/crates/servicepoint_binding_c/examples/lang_c/Cargo.toml
deleted file mode 100644
index 2231f3c..0000000
--- a/crates/servicepoint_binding_c/examples/lang_c/Cargo.toml
+++ /dev/null
@@ -1,14 +0,0 @@
-[package]
-name = "lang_c"
-version = "0.1.0"
-edition = "2021"
-publish = false
-
-[lib]
-test = false
-
-[build-dependencies]
-cc = "1.2"
-
-[dependencies]
-servicepoint_binding_c = { path = "../.." }
diff --git a/crates/servicepoint_binding_c/examples/lang_c/Makefile b/crates/servicepoint_binding_c/examples/lang_c/Makefile
deleted file mode 100644
index 6b15722..0000000
--- a/crates/servicepoint_binding_c/examples/lang_c/Makefile
+++ /dev/null
@@ -1,34 +0,0 @@
-CC := gcc
-
-THIS_DIR := $(dir $(realpath $(lastword $(MAKEFILE_LIST))))
-REPO_ROOT := $(THIS_DIR)/../../../..
-
-build: out/lang_c
-
-clean:
- rm -r out || true
- rm include/servicepoint.h || true
- cargo clean
-
-run: out/lang_c
- out/lang_c
-
-PHONY: build clean dependencies run
-
-out/lang_c: dependencies src/main.c
- mkdir -p out || true
- ${CC} src/main.c \
- -I include \
- -L $(REPO_ROOT)/target/release \
- -Wl,-Bstatic -lservicepoint_binding_c \
- -Wl,-Bdynamic -llzma \
- -o out/lang_c
-
-dependencies: FORCE
- mkdir -p include || true
- # generate servicepoint header and binary to link against
- SERVICEPOINT_HEADER_OUT=$(THIS_DIR)/include cargo build \
- --manifest-path=$(REPO_ROOT)/crates/servicepoint_binding_c/Cargo.toml \
- --release
-
-FORCE: ;
diff --git a/crates/servicepoint_binding_c/examples/lang_c/build.rs b/crates/servicepoint_binding_c/examples/lang_c/build.rs
deleted file mode 100644
index 4f92e1d..0000000
--- a/crates/servicepoint_binding_c/examples/lang_c/build.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-const SP_INCLUDE: &str = "DEP_SERVICEPOINT_INCLUDE";
-
-fn main() {
- println!("cargo::rerun-if-changed=src/main.c");
- println!("cargo::rerun-if-changed=build.rs");
- println!("cargo::rerun-if-env-changed={SP_INCLUDE}");
-
- let sp_include =
- std::env::var_os(SP_INCLUDE).unwrap().into_string().unwrap();
-
- // this builds a lib, this is only to check that the example compiles
- let mut cc = cc::Build::new();
- cc.file("src/main.c");
- cc.include(&sp_include);
- cc.opt_level(2);
- cc.compile("lang_c");
-}
diff --git a/crates/servicepoint_binding_c/examples/lang_c/include/servicepoint.h b/crates/servicepoint_binding_c/examples/lang_c/include/servicepoint.h
deleted file mode 100644
index d9cbe57..0000000
--- a/crates/servicepoint_binding_c/examples/lang_c/include/servicepoint.h
+++ /dev/null
@@ -1,1867 +0,0 @@
-/* Generated with cbindgen:0.27.0 */
-
-/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */
-
-#include
-#include
-#include
-#include
-#include
-
-/**
- * Count of possible brightness values
- */
-#define SP_BRIGHTNESS_LEVELS 12
-
-/**
- * see [servicepoint::Brightness::MAX]
- */
-#define SP_BRIGHTNESS_MAX 11
-
-/**
- * see [servicepoint::Brightness::MIN]
- */
-#define SP_BRIGHTNESS_MIN 0
-
-/**
- * pixel count on whole screen
- */
-#define SP_PIXEL_COUNT (SP_PIXEL_WIDTH * SP_PIXEL_HEIGHT)
-
-/**
- * Display height in pixels
- */
-#define SP_PIXEL_HEIGHT (SP_TILE_HEIGHT * SP_TILE_SIZE)
-
-/**
- * Display width in pixels
- */
-#define SP_PIXEL_WIDTH (SP_TILE_WIDTH * SP_TILE_SIZE)
-
-/**
- * Display tile count in the y-direction
- */
-#define SP_TILE_HEIGHT 20
-
-/**
- * size of a single tile in one dimension
- */
-#define SP_TILE_SIZE 8
-
-/**
- * Display tile count in the x-direction
- */
-#define SP_TILE_WIDTH 56
-
-/**
- * Specifies the kind of compression to use.
- */
-enum SPCompressionCode
-#ifdef __cplusplus
- : uint16_t
-#endif // __cplusplus
- {
- /**
- * no compression
- */
- SP_COMPRESSION_CODE_UNCOMPRESSED = 0,
- /**
- * compress using flate2 with zlib header
- */
- SP_COMPRESSION_CODE_ZLIB = 26490,
- /**
- * compress using bzip2
- */
- SP_COMPRESSION_CODE_BZIP2 = 25210,
- /**
- * compress using lzma
- */
- SP_COMPRESSION_CODE_LZMA = 27770,
- /**
- * compress using Zstandard
- */
- SP_COMPRESSION_CODE_ZSTD = 31347,
-};
-#ifndef __cplusplus
-typedef uint16_t SPCompressionCode;
-#endif // __cplusplus
-
-/**
- * A vector of bits
- *
- * # Examples
- * ```C
- * SPBitVec vec = sp_bitvec_new(8);
- * sp_bitvec_set(vec, 5, true);
- * sp_bitvec_free(vec);
- * ```
- */
-typedef struct SPBitVec SPBitVec;
-
-/**
- * A grid of pixels.
- *
- * # Examples
- *
- * ```C
- * Cp437Grid grid = sp_bitmap_new(8, 3);
- * sp_bitmap_fill(grid, true);
- * sp_bitmap_set(grid, 0, 0, false);
- * sp_bitmap_free(grid);
- * ```
- */
-typedef struct SPBitmap SPBitmap;
-
-/**
- * A grid containing brightness values.
- *
- * # Examples
- * ```C
- * SPConnection connection = sp_connection_open("127.0.0.1:2342");
- * if (connection == NULL)
- * return 1;
- *
- * SPBrightnessGrid grid = sp_brightness_grid_new(2, 2);
- * sp_brightness_grid_set(grid, 0, 0, 0);
- * sp_brightness_grid_set(grid, 1, 1, 10);
- *
- * SPCommand command = sp_command_char_brightness(grid);
- * sp_connection_free(connection);
- * ```
- */
-typedef struct SPBrightnessGrid SPBrightnessGrid;
-
-/**
- * A C-wrapper for grid containing UTF-8 characters.
- *
- * As the rust [char] type is not FFI-safe, characters are passed in their UTF-32 form as 32bit unsigned integers.
- *
- * The encoding is enforced in most cases by the rust standard library
- * and will panic when provided with illegal characters.
- *
- * # Examples
- *
- * ```C
- * CharGrid grid = sp_char_grid_new(4, 3);
- * sp_char_grid_fill(grid, '?');
- * sp_char_grid_set(grid, 0, 0, '!');
- * sp_char_grid_free(grid);
- * ```
- */
-typedef struct SPCharGrid SPCharGrid;
-
-/**
- * A low-level display command.
- *
- * This struct and associated functions implement the UDP protocol for the display.
- *
- * To send a [SPCommand], use a [SPConnection].
- *
- * # Examples
- *
- * ```C
- * sp_connection_send_command(connection, sp_command_clear());
- * sp_connection_send_command(connection, sp_command_brightness(5));
- * ```
- *
- * [SPConnection]: [crate::SPConnection]
- */
-typedef struct SPCommand SPCommand;
-
-/**
- * A connection to the display.
- *
- * # Examples
- *
- * ```C
- * CConnection connection = sp_connection_open("172.23.42.29:2342");
- * if (connection != NULL)
- * sp_connection_send_command(connection, sp_command_clear());
- * ```
- */
-typedef struct SPConnection SPConnection;
-
-/**
- * A C-wrapper for grid containing codepage 437 characters.
- *
- * The encoding is currently not enforced.
- *
- * # Examples
- *
- * ```C
- * Cp437Grid grid = sp_cp437_grid_new(4, 3);
- * sp_cp437_grid_fill(grid, '?');
- * sp_cp437_grid_set(grid, 0, 0, '!');
- * sp_cp437_grid_free(grid);
- * ```
- */
-typedef struct SPCp437Grid SPCp437Grid;
-
-/**
- * The raw packet
- */
-typedef struct SPPacket SPPacket;
-
-/**
- * Represents a span of memory (`&mut [u8]` ) as a struct usable by C code.
- *
- * You should not create an instance of this type in your C code.
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - accesses to the memory pointed to with `start` is never accessed outside `length`
- * - the lifetime of the `CByteSlice` does not outlive the memory it points to, as described in
- * the function returning this type.
- * - an instance of this created from C is never passed to a consuming function, as the rust code
- * will try to free the memory of a potentially separate allocator.
- */
-typedef struct {
- /**
- * The start address of the memory
- */
- uint8_t *start;
- /**
- * The amount of memory in bytes
- */
- size_t length;
-} SPByteSlice;
-
-#ifdef __cplusplus
-extern "C" {
-#endif // __cplusplus
-
-/**
- * Clones a [SPBitmap].
- *
- * Will never return NULL.
- *
- * # Panics
- *
- * - when `bitmap` is NULL
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `bitmap` points to a valid [SPBitmap]
- * - `bitmap` is not written to concurrently
- * - the returned instance is freed in some way, either by using a consuming function or
- * by explicitly calling `sp_bitmap_free`.
- */
-SPBitmap *sp_bitmap_clone(const SPBitmap *bitmap);
-
-/**
- * Sets the state of all pixels in the [SPBitmap].
- *
- * # Arguments
- *
- * - `bitmap`: instance to write to
- * - `value`: the value to set all pixels to
- *
- * # Panics
- *
- * - when `bitmap` is NULL
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `bitmap` points to a valid [SPBitmap]
- * - `bitmap` is not written to or read from concurrently
- */
-void sp_bitmap_fill(SPBitmap *bitmap, bool value);
-
-/**
- * Deallocates a [SPBitmap].
- *
- * # Panics
- *
- * - when `bitmap` is NULL
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `bitmap` points to a valid [SPBitmap]
- * - `bitmap` is not used concurrently or after bitmap call
- * - `bitmap` was not passed to another consuming function, e.g. to create a [SPCommand]
- *
- * [SPCommand]: [crate::SPCommand]
- */
-void sp_bitmap_free(SPBitmap *bitmap);
-
-/**
- * Gets the current value at the specified position in the [SPBitmap].
- *
- * # Arguments
- *
- * - `bitmap`: instance to read from
- * - `x` and `y`: position of the cell to read
- *
- * # Panics
- *
- * - when `bitmap` is NULL
- * - when accessing `x` or `y` out of bounds
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `bitmap` points to a valid [SPBitmap]
- * - `bitmap` is not written to concurrently
- */
-bool sp_bitmap_get(const SPBitmap *bitmap, size_t x, size_t y);
-
-/**
- * Gets the height in pixels of the [SPBitmap] instance.
- *
- * # Arguments
- *
- * - `bitmap`: instance to read from
- *
- * # Panics
- *
- * - when `bitmap` is NULL
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `bitmap` points to a valid [SPBitmap]
- */
-size_t sp_bitmap_height(const SPBitmap *bitmap);
-
-/**
- * Loads a [SPBitmap] with the specified dimensions from the provided data.
- *
- * # Arguments
- *
- * - `width`: size in pixels in x-direction
- * - `height`: size in pixels in y-direction
- *
- * returns: [SPBitmap] that contains a copy of the provided data. Will never return NULL.
- *
- * # Panics
- *
- * - when `data` is NULL
- * - when the dimensions and data size do not match exactly.
- * - when the width is not dividable by 8
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `data` points to a valid memory location of at least `data_length` bytes in size.
- * - the returned instance is freed in some way, either by using a consuming function or
- * by explicitly calling `sp_bitmap_free`.
- */
-SPBitmap *sp_bitmap_load(size_t width,
- size_t height,
- const uint8_t *data,
- size_t data_length);
-
-/**
- * Creates a new [SPBitmap] with the specified dimensions.
- *
- * # Arguments
- *
- * - `width`: size in pixels in x-direction
- * - `height`: size in pixels in y-direction
- *
- * returns: [SPBitmap] initialized to all pixels off. Will never return NULL.
- *
- * # Panics
- *
- * - when the width is not dividable by 8
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - the returned instance is freed in some way, either by using a consuming function or
- * by explicitly calling `sp_bitmap_free`.
- */
-SPBitmap *sp_bitmap_new(size_t width,
- size_t height);
-
-/**
- * Creates a new [SPBitmap] with a size matching the screen.
- *
- * returns: [SPBitmap] initialized to all pixels off. Will never return NULL.
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - the returned instance is freed in some way, either by using a consuming function or
- * by explicitly calling [sp_bitmap_free].
- */
-SPBitmap *sp_bitmap_new_screen_sized(void);
-
-/**
- * Sets the value of the specified position in the [SPBitmap].
- *
- * # Arguments
- *
- * - `bitmap`: instance to write to
- * - `x` and `y`: position of the cell
- * - `value`: the value to write to the cell
- *
- * returns: old value of the cell
- *
- * # Panics
- *
- * - when `bitmap` is NULL
- * - when accessing `x` or `y` out of bounds
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `bitmap` points to a valid [SPBitmap]
- * - `bitmap` is not written to or read from concurrently
- */
-void sp_bitmap_set(SPBitmap *bitmap, size_t x, size_t y, bool value);
-
-/**
- * Gets an unsafe reference to the data of the [SPBitmap] instance.
- *
- * # Panics
- *
- * - when `bitmap` is NULL
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `bitmap` points to a valid [SPBitmap]
- * - the returned memory range is never accessed after the passed [SPBitmap] has been freed
- * - the returned memory range is never accessed concurrently, either via the [SPBitmap] or directly
- */
-SPByteSlice sp_bitmap_unsafe_data_ref(SPBitmap *bitmap);
-
-/**
- * Gets the width in pixels of the [SPBitmap] instance.
- *
- * # Arguments
- *
- * - `bitmap`: instance to read from
- *
- * # Panics
- *
- * - when `bitmap` is NULL
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `bitmap` points to a valid [SPBitmap]
- */
-size_t sp_bitmap_width(const SPBitmap *bitmap);
-
-/**
- * Clones a [SPBitVec].
- *
- * returns: new [SPBitVec] instance. Will never return NULL.
- *
- * # Panics
- *
- * - when `bit_vec` is NULL
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `bit_vec` points to a valid [SPBitVec]
- * - `bit_vec` is not written to concurrently
- * - the returned instance is freed in some way, either by using a consuming function or
- * by explicitly calling `sp_bitvec_free`.
- */
-SPBitVec *sp_bitvec_clone(const SPBitVec *bit_vec);
-
-/**
- * Sets the value of all bits in the [SPBitVec].
- *
- * # Arguments
- *
- * - `bit_vec`: instance to write to
- * - `value`: the value to set all bits to
- *
- * # Panics
- *
- * - when `bit_vec` is NULL
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `bit_vec` points to a valid [SPBitVec]
- * - `bit_vec` is not written to or read from concurrently
- */
-void sp_bitvec_fill(SPBitVec *bit_vec, bool value);
-
-/**
- * Deallocates a [SPBitVec].
- *
- * # Panics
- *
- * - when `but_vec` is NULL
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `bit_vec` points to a valid [SPBitVec]
- * - `bit_vec` is not used concurrently or after this call
- * - `bit_vec` was not passed to another consuming function, e.g. to create a [SPCommand]
- *
- * [SPCommand]: [crate::SPCommand]
- */
-void sp_bitvec_free(SPBitVec *bit_vec);
-
-/**
- * Gets the value of a bit from the [SPBitVec].
- *
- * # Arguments
- *
- * - `bit_vec`: instance to read from
- * - `index`: the bit index to read
- *
- * returns: value of the bit
- *
- * # Panics
- *
- * - when `bit_vec` is NULL
- * - when accessing `index` out of bounds
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `bit_vec` points to a valid [SPBitVec]
- * - `bit_vec` is not written to concurrently
- */
-bool sp_bitvec_get(const SPBitVec *bit_vec, size_t index);
-
-/**
- * Returns true if length is 0.
- *
- * # Arguments
- *
- * - `bit_vec`: instance to write to
- *
- * # Panics
- *
- * - when `bit_vec` is NULL
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `bit_vec` points to a valid [SPBitVec]
- */
-bool sp_bitvec_is_empty(const SPBitVec *bit_vec);
-
-/**
- * Gets the length of the [SPBitVec] in bits.
- *
- * # Arguments
- *
- * - `bit_vec`: instance to write to
- *
- * # Panics
- *
- * - when `bit_vec` is NULL
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `bit_vec` points to a valid [SPBitVec]
- */
-size_t sp_bitvec_len(const SPBitVec *bit_vec);
-
-/**
- * Interpret the data as a series of bits and load then into a new [SPBitVec] instance.
- *
- * returns: [SPBitVec] instance containing data. Will never return NULL.
- *
- * # Panics
- *
- * - when `data` is NULL
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `data` points to a valid memory location of at least `data_length`
- * bytes in size.
- * - the returned instance is freed in some way, either by using a consuming function or
- * by explicitly calling `sp_bitvec_free`.
- */
-SPBitVec *sp_bitvec_load(const uint8_t *data,
- size_t data_length);
-
-/**
- * Creates a new [SPBitVec] instance.
- *
- * # Arguments
- *
- * - `size`: size in bits.
- *
- * returns: [SPBitVec] with all bits set to false. Will never return NULL.
- *
- * # Panics
- *
- * - when `size` is not divisible by 8.
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - the returned instance is freed in some way, either by using a consuming function or
- * by explicitly calling `sp_bitvec_free`.
- */
-SPBitVec *sp_bitvec_new(size_t size);
-
-/**
- * Sets the value of a bit in the [SPBitVec].
- *
- * # Arguments
- *
- * - `bit_vec`: instance to write to
- * - `index`: the bit index to edit
- * - `value`: the value to set the bit to
- *
- * # Panics
- *
- * - when `bit_vec` is NULL
- * - when accessing `index` out of bounds
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `bit_vec` points to a valid [SPBitVec]
- * - `bit_vec` is not written to or read from concurrently
- */
-void sp_bitvec_set(SPBitVec *bit_vec, size_t index, bool value);
-
-/**
- * Gets an unsafe reference to the data of the [SPBitVec] instance.
- *
- * # Arguments
- *
- * - `bit_vec`: instance to write to
- *
- * # Panics
- *
- * - when `bit_vec` is NULL
- *
- * ## Safety
- *
- * The caller has to make sure that:
- *
- * - `bit_vec` points to a valid [SPBitVec]
- * - the returned memory range is never accessed after the passed [SPBitVec] has been freed
- * - the returned memory range is never accessed concurrently, either via the [SPBitVec] or directly
- */
-SPByteSlice sp_bitvec_unsafe_data_ref(SPBitVec *bit_vec);
-
-/**
- * Clones a [SPBrightnessGrid].
- *
- * # Arguments
- *
- * - `brightness_grid`: instance to read from
- *
- * returns: new [SPBrightnessGrid] instance. Will never return NULL.
- *
- * # Panics
- *
- * - when `brightness_grid` is NULL
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `brightness_grid` points to a valid [SPBrightnessGrid]
- * - `brightness_grid` is not written to concurrently
- * - the returned instance is freed in some way, either by using a consuming function or
- * by explicitly calling `sp_brightness_grid_free`.
- */
-SPBrightnessGrid *sp_brightness_grid_clone(const SPBrightnessGrid *brightness_grid);
-
-/**
- * Sets the value of all cells in the [SPBrightnessGrid].
- *
- * # Arguments
- *
- * - `brightness_grid`: instance to write to
- * - `value`: the value to set all cells to
- *
- * # Panics
- *
- * - when `brightness_grid` is NULL
- * - When providing an invalid brightness value
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `brightness_grid` points to a valid [SPBrightnessGrid]
- * - `brightness_grid` is not written to or read from concurrently
- */
-void sp_brightness_grid_fill(SPBrightnessGrid *brightness_grid, uint8_t value);
-
-/**
- * Deallocates a [SPBrightnessGrid].
- *
- * # Arguments
- *
- * - `brightness_grid`: instance to read from
- *
- * # Panics
- *
- * - when `brightness_grid` is NULL
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `brightness_grid` points to a valid [SPBrightnessGrid]
- * - `brightness_grid` is not used concurrently or after this call
- * - `brightness_grid` was not passed to another consuming function, e.g. to create a [SPCommand]
- *
- * [SPCommand]: [crate::SPCommand]
- */
-void sp_brightness_grid_free(SPBrightnessGrid *brightness_grid);
-
-/**
- * Gets the current value at the specified position.
- *
- * # Arguments
- *
- * - `brightness_grid`: instance to read from
- * - `x` and `y`: position of the cell to read
- *
- * returns: value at position
- *
- * # Panics
- *
- * - when `brightness_grid` is NULL
- * - When accessing `x` or `y` out of bounds.
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `brightness_grid` points to a valid [SPBrightnessGrid]
- * - `brightness_grid` is not written to concurrently
- */
-uint8_t sp_brightness_grid_get(const SPBrightnessGrid *brightness_grid,
- size_t x,
- size_t y);
-
-/**
- * Gets the height of the [SPBrightnessGrid] instance.
- *
- * # Arguments
- *
- * - `brightness_grid`: instance to read from
- *
- * returns: height
- *
- * # Panics
- *
- * - when `brightness_grid` is NULL
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `brightness_grid` points to a valid [SPBrightnessGrid]
- */
-size_t sp_brightness_grid_height(const SPBrightnessGrid *brightness_grid);
-
-/**
- * Loads a [SPBrightnessGrid] with the specified dimensions from the provided data.
- *
- * returns: new [SPBrightnessGrid] instance. Will never return NULL.
- *
- * # Panics
- *
- * - when `data` is NULL
- * - when the provided `data_length` does not match `height` and `width`
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `data` points to a valid memory location of at least `data_length`
- * bytes in size.
- * - the returned instance is freed in some way, either by using a consuming function or
- * by explicitly calling `sp_brightness_grid_free`.
- */
-SPBrightnessGrid *sp_brightness_grid_load(size_t width,
- size_t height,
- const uint8_t *data,
- size_t data_length);
-
-/**
- * Creates a new [SPBrightnessGrid] with the specified dimensions.
- *
- * returns: [SPBrightnessGrid] initialized to 0. Will never return NULL.
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - the returned instance is freed in some way, either by using a consuming function or
- * by explicitly calling `sp_brightness_grid_free`.
- */
-SPBrightnessGrid *sp_brightness_grid_new(size_t width,
- size_t height);
-
-/**
- * Sets the value of the specified position in the [SPBrightnessGrid].
- *
- * # Arguments
- *
- * - `brightness_grid`: instance to write to
- * - `x` and `y`: position of the cell
- * - `value`: the value to write to the cell
- *
- * returns: old value of the cell
- *
- * # Panics
- *
- * - when `brightness_grid` is NULL
- * - When accessing `x` or `y` out of bounds.
- * - When providing an invalid brightness value
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `brightness_grid` points to a valid [SPBrightnessGrid]
- * - `brightness_grid` is not written to or read from concurrently
- */
-void sp_brightness_grid_set(SPBrightnessGrid *brightness_grid,
- size_t x,
- size_t y,
- uint8_t value);
-
-/**
- * Gets an unsafe reference to the data of the [SPBrightnessGrid] instance.
- *
- * # Arguments
- *
- * - `brightness_grid`: instance to read from
- *
- * returns: slice of bytes underlying the `brightness_grid`.
- *
- * # Panics
- *
- * - when `brightness_grid` is NULL
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `brightness_grid` points to a valid [SPBrightnessGrid]
- * - the returned memory range is never accessed after the passed [SPBrightnessGrid] has been freed
- * - the returned memory range is never accessed concurrently, either via the [SPBrightnessGrid] or directly
- */
-SPByteSlice sp_brightness_grid_unsafe_data_ref(SPBrightnessGrid *brightness_grid);
-
-/**
- * Gets the width of the [SPBrightnessGrid] instance.
- *
- * # Arguments
- *
- * - `brightness_grid`: instance to read from
- *
- * returns: width
- *
- * # Panics
- *
- * - when `brightness_grid` is NULL
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `brightness_grid` points to a valid [SPBrightnessGrid]
- */
-size_t sp_brightness_grid_width(const SPBrightnessGrid *brightness_grid);
-
-/**
- * Clones a [SPCharGrid].
- *
- * Will never return NULL.
- *
- * # Panics
- *
- * - when `char_grid` is NULL
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `char_grid` points to a valid [SPCharGrid]
- * - `char_grid` is not written to concurrently
- * - the returned instance is freed in some way, either by using a consuming function or
- * by explicitly calling `sp_char_grid_free`.
- */
-SPCharGrid *sp_char_grid_clone(const SPCharGrid *char_grid);
-
-/**
- * Sets the value of all cells in the [SPCharGrid].
- *
- * # Arguments
- *
- * - `char_grid`: instance to write to
- * - `value`: the value to set all cells to
- *
- * # Panics
- *
- * - when `char_grid` is NULL
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `char_grid` points to a valid [SPCharGrid]
- * - `char_grid` is not written to or read from concurrently
- */
-void sp_char_grid_fill(SPCharGrid *char_grid, uint32_t value);
-
-/**
- * Deallocates a [SPCharGrid].
- *
- * # Panics
- *
- * - when `char_grid` is NULL
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `char_grid` points to a valid [SPCharGrid]
- * - `char_grid` is not used concurrently or after char_grid call
- * - `char_grid` was not passed to another consuming function, e.g. to create a [SPCommand]
- *
- * [SPCommand]: [crate::SPCommand]
- */
-void sp_char_grid_free(SPCharGrid *char_grid);
-
-/**
- * Gets the current value at the specified position.
- *
- * # Arguments
- *
- * - `char_grid`: instance to read from
- * - `x` and `y`: position of the cell to read
- *
- * # Panics
- *
- * - when `char_grid` is NULL
- * - when accessing `x` or `y` out of bounds
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `char_grid` points to a valid [SPCharGrid]
- * - `char_grid` is not written to concurrently
- */
-uint32_t sp_char_grid_get(const SPCharGrid *char_grid, size_t x, size_t y);
-
-/**
- * Gets the height of the [SPCharGrid] instance.
- *
- * # Arguments
- *
- * - `char_grid`: instance to read from
- *
- * # Panics
- *
- * - when `char_grid` is NULL
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `char_grid` points to a valid [SPCharGrid]
- */
-size_t sp_char_grid_height(const SPCharGrid *char_grid);
-
-/**
- * Loads a [SPCharGrid] with the specified dimensions from the provided data.
- *
- * Will never return NULL.
- *
- * # Panics
- *
- * - when `data` is NULL
- * - when the provided `data_length` does not match `height` and `width`
- * - when `data` is not valid UTF-8
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `data` points to a valid memory location of at least `data_length`
- * bytes in size.
- * - the returned instance is freed in some way, either by using a consuming function or
- * by explicitly calling `sp_char_grid_free`.
- */
-SPCharGrid *sp_char_grid_load(size_t width,
- size_t height,
- const uint8_t *data,
- size_t data_length);
-
-/**
- * Creates a new [SPCharGrid] with the specified dimensions.
- *
- * returns: [SPCharGrid] initialized to 0. Will never return NULL.
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - the returned instance is freed in some way, either by using a consuming function or
- * by explicitly calling `sp_char_grid_free`.
- */
-SPCharGrid *sp_char_grid_new(size_t width,
- size_t height);
-
-/**
- * Sets the value of the specified position in the [SPCharGrid].
- *
- * # Arguments
- *
- * - `char_grid`: instance to write to
- * - `x` and `y`: position of the cell
- * - `value`: the value to write to the cell
- *
- * returns: old value of the cell
- *
- * # Panics
- *
- * - when `char_grid` is NULL
- * - when accessing `x` or `y` out of bounds
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `char_grid` points to a valid [SPBitVec]
- * - `char_grid` is not written to or read from concurrently
- *
- * [SPBitVec]: [crate::SPBitVec]
- */
-void sp_char_grid_set(SPCharGrid *char_grid,
- size_t x,
- size_t y,
- uint32_t value);
-
-/**
- * Gets the width of the [SPCharGrid] instance.
- *
- * # Arguments
- *
- * - `char_grid`: instance to read from
- *
- * # Panics
- *
- * - when `char_grid` is NULL
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `char_grid` points to a valid [SPCharGrid]
- */
-size_t sp_char_grid_width(const SPCharGrid *char_grid);
-
-/**
- * Set pixel data starting at the pixel offset on screen.
- *
- * The screen will continuously overwrite more pixel data without regarding the offset, meaning
- * once the starting row is full, overwriting will continue on column 0.
- *
- * The contained [SPBitVec] is always uncompressed.
- *
- * The passed [SPBitVec] gets consumed.
- *
- * Returns: a new [servicepoint::Command::BitmapLinear] instance. Will never return NULL.
- *
- * # Panics
- *
- * - when `bit_vec` is null
- * - when `compression_code` is not a valid value
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `bit_vec` points to a valid instance of [SPBitVec]
- * - `bit_vec` is not used concurrently or after this call
- * - `compression` matches one of the allowed enum values
- * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
- * by explicitly calling `sp_command_free`.
- */
-SPCommand *sp_command_bitmap_linear(size_t offset,
- SPBitVec *bit_vec,
- SPCompressionCode compression);
-
-/**
- * Set pixel data according to an and-mask starting at the offset.
- *
- * The screen will continuously overwrite more pixel data without regarding the offset, meaning
- * once the starting row is full, overwriting will continue on column 0.
- *
- * The contained [SPBitVec] is always uncompressed.
- *
- * The passed [SPBitVec] gets consumed.
- *
- * Returns: a new [servicepoint::Command::BitmapLinearAnd] instance. Will never return NULL.
- *
- * # Panics
- *
- * - when `bit_vec` is null
- * - when `compression_code` is not a valid value
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `bit_vec` points to a valid instance of [SPBitVec]
- * - `bit_vec` is not used concurrently or after this call
- * - `compression` matches one of the allowed enum values
- * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
- * by explicitly calling `sp_command_free`.
- */
-SPCommand *sp_command_bitmap_linear_and(size_t offset,
- SPBitVec *bit_vec,
- SPCompressionCode compression);
-
-/**
- * Set pixel data according to an or-mask starting at the offset.
- *
- * The screen will continuously overwrite more pixel data without regarding the offset, meaning
- * once the starting row is full, overwriting will continue on column 0.
- *
- * The contained [SPBitVec] is always uncompressed.
- *
- * The passed [SPBitVec] gets consumed.
- *
- * Returns: a new [servicepoint::Command::BitmapLinearOr] instance. Will never return NULL.
- *
- * # Panics
- *
- * - when `bit_vec` is null
- * - when `compression_code` is not a valid value
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `bit_vec` points to a valid instance of [SPBitVec]
- * - `bit_vec` is not used concurrently or after this call
- * - `compression` matches one of the allowed enum values
- * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
- * by explicitly calling `sp_command_free`.
- */
-SPCommand *sp_command_bitmap_linear_or(size_t offset,
- SPBitVec *bit_vec,
- SPCompressionCode compression);
-
-/**
- * Sets a window of pixels to the specified values.
- *
- * The passed [SPBitmap] gets consumed.
- *
- * Returns: a new [servicepoint::Command::BitmapLinearWin] instance. Will never return NULL.
- *
- * # Panics
- *
- * - when `bitmap` is null
- * - when `compression_code` is not a valid value
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `bitmap` points to a valid instance of [SPBitmap]
- * - `bitmap` is not used concurrently or after this call
- * - `compression` matches one of the allowed enum values
- * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
- * by explicitly calling `sp_command_free`.
- */
-SPCommand *sp_command_bitmap_linear_win(size_t x,
- size_t y,
- SPBitmap *bitmap,
- SPCompressionCode compression_code);
-
-/**
- * Set pixel data according to a xor-mask starting at the offset.
- *
- * The screen will continuously overwrite more pixel data without regarding the offset, meaning
- * once the starting row is full, overwriting will continue on column 0.
- *
- * The contained [SPBitVec] is always uncompressed.
- *
- * The passed [SPBitVec] gets consumed.
- *
- * Returns: a new [servicepoint::Command::BitmapLinearXor] instance. Will never return NULL.
- *
- * # Panics
- *
- * - when `bit_vec` is null
- * - when `compression_code` is not a valid value
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `bit_vec` points to a valid instance of [SPBitVec]
- * - `bit_vec` is not used concurrently or after this call
- * - `compression` matches one of the allowed enum values
- * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
- * by explicitly calling `sp_command_free`.
- */
-SPCommand *sp_command_bitmap_linear_xor(size_t offset,
- SPBitVec *bit_vec,
- SPCompressionCode compression);
-
-/**
- * Set the brightness of all tiles to the same value.
- *
- * Returns: a new [servicepoint::Command::Brightness] instance. Will never return NULL.
- *
- * # Panics
- *
- * - When the provided brightness value is out of range (0-11).
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
- * by explicitly calling `sp_command_free`.
- */
-SPCommand *sp_command_brightness(uint8_t brightness);
-
-/**
- * Set the brightness of individual tiles in a rectangular area of the display.
- *
- * The passed [SPBrightnessGrid] gets consumed.
- *
- * Returns: a new [servicepoint::Command::CharBrightness] instance. Will never return NULL.
- *
- * # Panics
- *
- * - when `grid` is NULL
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `grid` points to a valid instance of [SPBrightnessGrid]
- * - `grid` is not used concurrently or after this call
- * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
- * by explicitly calling `sp_command_free`.
- */
-SPCommand *sp_command_char_brightness(size_t x,
- size_t y,
- SPBrightnessGrid *grid);
-
-/**
- * Set all pixels to the off state.
- *
- * Does not affect brightness.
- *
- * Returns: a new [servicepoint::Command::Clear] instance. Will never return NULL.
- *
- * # Examples
- *
- * ```C
- * sp_connection_send_command(connection, sp_command_clear());
- * ```
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
- * by explicitly calling `sp_command_free`.
- */
-SPCommand *sp_command_clear(void);
-
-/**
- * Clones a [SPCommand] instance.
- *
- * returns: new [SPCommand] instance. Will never return NULL.
- *
- * # Panics
- *
- * - when `command` is NULL
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `command` points to a valid instance of [SPCommand]
- * - `command` is not written to concurrently
- * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
- * by explicitly calling `sp_command_free`.
- */
-SPCommand *sp_command_clone(const SPCommand *command);
-
-/**
- * Show codepage 437 encoded text on the screen.
- *
- * The passed [SPCp437Grid] gets consumed.
- *
- * Returns: a new [servicepoint::Command::Cp437Data] instance. Will never return NULL.
- *
- * # Panics
- *
- * - when `grid` is null
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `grid` points to a valid instance of [SPCp437Grid]
- * - `grid` is not used concurrently or after this call
- * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
- * by explicitly calling `sp_command_free`.
- */
-SPCommand *sp_command_cp437_data(size_t x,
- size_t y,
- SPCp437Grid *grid);
-
-/**
- * A yet-to-be-tested command.
- *
- * Returns: a new [servicepoint::Command::FadeOut] instance. Will never return NULL.
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
- * by explicitly calling `sp_command_free`.
- */
-SPCommand *sp_command_fade_out(void);
-
-/**
- * Deallocates a [SPCommand].
- *
- * # Examples
- *
- * ```C
- * SPCommand c = sp_command_clear();
- * sp_command_free(c);
- * ```
- *
- * # Panics
- *
- * - when `command` is NULL
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `command` points to a valid [SPCommand]
- * - `command` is not used concurrently or after this call
- * - `command` was not passed to another consuming function, e.g. to create a [SPPacket]
- */
-void sp_command_free(SPCommand *command);
-
-/**
- * Kills the udp daemon on the display, which usually results in a restart.
- *
- * Please do not send this in your normal program flow.
- *
- * Returns: a new [servicepoint::Command::HardReset] instance. Will never return NULL.
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
- * by explicitly calling `sp_command_free`.
- */
-SPCommand *sp_command_hard_reset(void);
-
-/**
- * Tries to turn a [SPPacket] into a [SPCommand].
- *
- * The packet is deallocated in the process.
- *
- * Returns: pointer to new [SPCommand] instance or NULL if parsing failed.
- *
- * # Panics
- *
- * - when `packet` is NULL
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - [SPPacket] points to a valid instance of [SPPacket]
- * - [SPPacket] is not used concurrently or after this call
- * - the result is checked for NULL
- * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
- * by explicitly calling `sp_command_free`.
- */
-SPCommand *sp_command_try_from_packet(SPPacket *packet);
-
-/**
- * Show UTF-8 encoded text on the screen.
- *
- * The passed [SPCharGrid] gets consumed.
- *
- * Returns: a new [servicepoint::Command::Utf8Data] instance. Will never return NULL.
- *
- * # Panics
- *
- * - when `grid` is null
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `grid` points to a valid instance of [SPCharGrid]
- * - `grid` is not used concurrently or after this call
- * - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
- * by explicitly calling `sp_command_free`.
- */
-SPCommand *sp_command_utf8_data(size_t x,
- size_t y,
- SPCharGrid *grid);
-
-/**
- * Creates a new instance of [SPConnection] for testing that does not actually send anything.
- *
- * returns: a new instance. Will never return NULL.
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - the returned instance is freed in some way, either by using a consuming function or
- * by explicitly calling `sp_connection_free`.
- */
-SPConnection *sp_connection_fake(void);
-
-/**
- * Closes and deallocates a [SPConnection].
- *
- * # Panics
- *
- * - when `connection` is NULL
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `connection` points to a valid [SPConnection]
- * - `connection` is not used concurrently or after this call
- */
-void sp_connection_free(SPConnection *connection);
-
-/**
- * Creates a new instance of [SPConnection].
- *
- * returns: NULL if connection fails, or connected instance
- *
- * # Panics
- *
- * - when `host` is null or an invalid host
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - the returned instance is freed in some way, either by using a consuming function or
- * by explicitly calling `sp_connection_free`.
- */
-SPConnection *sp_connection_open(const char *host);
-
-/**
- * Sends a [SPCommand] to the display using the [SPConnection].
- *
- * The passed `command` gets consumed.
- *
- * returns: true in case of success
- *
- * # Panics
- *
- * - when `connection` is NULL
- * - when `command` is NULL
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `connection` points to a valid instance of [SPConnection]
- * - `command` points to a valid instance of [SPPacket]
- * - `command` is not used concurrently or after this call
- */
-bool sp_connection_send_command(const SPConnection *connection,
- SPCommand *command);
-
-/**
- * Sends a [SPPacket] to the display using the [SPConnection].
- *
- * The passed `packet` gets consumed.
- *
- * returns: true in case of success
- *
- * # Panics
- *
- * - when `connection` is NULL
- * - when `packet` is NULL
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `connection` points to a valid instance of [SPConnection]
- * - `packet` points to a valid instance of [SPPacket]
- * - `packet` is not used concurrently or after this call
- */
-bool sp_connection_send_packet(const SPConnection *connection,
- SPPacket *packet);
-
-/**
- * Clones a [SPCp437Grid].
- *
- * Will never return NULL.
- *
- * # Panics
- *
- * - when `cp437_grid` is NULL
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `cp437_grid` points to a valid [SPCp437Grid]
- * - `cp437_grid` is not written to concurrently
- * - the returned instance is freed in some way, either by using a consuming function or
- * by explicitly calling `sp_cp437_grid_free`.
- */
-SPCp437Grid *sp_cp437_grid_clone(const SPCp437Grid *cp437_grid);
-
-/**
- * Sets the value of all cells in the [SPCp437Grid].
- *
- * # Arguments
- *
- * - `cp437_grid`: instance to write to
- * - `value`: the value to set all cells to
- *
- * # Panics
- *
- * - when `cp437_grid` is NULL
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `cp437_grid` points to a valid [SPCp437Grid]
- * - `cp437_grid` is not written to or read from concurrently
- */
-void sp_cp437_grid_fill(SPCp437Grid *cp437_grid, uint8_t value);
-
-/**
- * Deallocates a [SPCp437Grid].
- *
- * # Panics
- *
- * - when `cp437_grid` is NULL
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `cp437_grid` points to a valid [SPCp437Grid]
- * - `cp437_grid` is not used concurrently or after cp437_grid call
- * - `cp437_grid` was not passed to another consuming function, e.g. to create a [SPCommand]
- *
- * [SPCommand]: [crate::SPCommand]
- */
-void sp_cp437_grid_free(SPCp437Grid *cp437_grid);
-
-/**
- * Gets the current value at the specified position.
- *
- * # Arguments
- *
- * - `cp437_grid`: instance to read from
- * - `x` and `y`: position of the cell to read
- *
- * # Panics
- *
- * - when `cp437_grid` is NULL
- * - when accessing `x` or `y` out of bounds
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `cp437_grid` points to a valid [SPCp437Grid]
- * - `cp437_grid` is not written to concurrently
- */
-uint8_t sp_cp437_grid_get(const SPCp437Grid *cp437_grid, size_t x, size_t y);
-
-/**
- * Gets the height of the [SPCp437Grid] instance.
- *
- * # Arguments
- *
- * - `cp437_grid`: instance to read from
- *
- * # Panics
- *
- * - when `cp437_grid` is NULL
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `cp437_grid` points to a valid [SPCp437Grid]
- */
-size_t sp_cp437_grid_height(const SPCp437Grid *cp437_grid);
-
-/**
- * Loads a [SPCp437Grid] with the specified dimensions from the provided data.
- *
- * Will never return NULL.
- *
- * # Panics
- *
- * - when `data` is NULL
- * - when the provided `data_length` does not match `height` and `width`
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `data` points to a valid memory location of at least `data_length`
- * bytes in size.
- * - the returned instance is freed in some way, either by using a consuming function or
- * by explicitly calling `sp_cp437_grid_free`.
- */
-SPCp437Grid *sp_cp437_grid_load(size_t width,
- size_t height,
- const uint8_t *data,
- size_t data_length);
-
-/**
- * Creates a new [SPCp437Grid] with the specified dimensions.
- *
- * returns: [SPCp437Grid] initialized to 0. Will never return NULL.
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - the returned instance is freed in some way, either by using a consuming function or
- * by explicitly calling `sp_cp437_grid_free`.
- */
-SPCp437Grid *sp_cp437_grid_new(size_t width,
- size_t height);
-
-/**
- * Sets the value of the specified position in the [SPCp437Grid].
- *
- * # Arguments
- *
- * - `cp437_grid`: instance to write to
- * - `x` and `y`: position of the cell
- * - `value`: the value to write to the cell
- *
- * returns: old value of the cell
- *
- * # Panics
- *
- * - when `cp437_grid` is NULL
- * - when accessing `x` or `y` out of bounds
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `cp437_grid` points to a valid [SPBitVec]
- * - `cp437_grid` is not written to or read from concurrently
- *
- * [SPBitVec]: [crate::SPBitVec]
- */
-void sp_cp437_grid_set(SPCp437Grid *cp437_grid,
- size_t x,
- size_t y,
- uint8_t value);
-
-/**
- * Gets an unsafe reference to the data of the [SPCp437Grid] instance.
- *
- * Will never return NULL.
- *
- * # Panics
- *
- * - when `cp437_grid` is NULL
- *
- * ## Safety
- *
- * The caller has to make sure that:
- *
- * - `cp437_grid` points to a valid [SPCp437Grid]
- * - the returned memory range is never accessed after the passed [SPCp437Grid] has been freed
- * - the returned memory range is never accessed concurrently, either via the [SPCp437Grid] or directly
- */
-SPByteSlice sp_cp437_grid_unsafe_data_ref(SPCp437Grid *cp437_grid);
-
-/**
- * Gets the width of the [SPCp437Grid] instance.
- *
- * # Arguments
- *
- * - `cp437_grid`: instance to read from
- *
- * # Panics
- *
- * - when `cp437_grid` is NULL
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `cp437_grid` points to a valid [SPCp437Grid]
- */
-size_t sp_cp437_grid_width(const SPCp437Grid *cp437_grid);
-
-/**
- * Clones a [SPPacket].
- *
- * Will never return NULL.
- *
- * # Panics
- *
- * - when `packet` is NULL
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `packet` points to a valid [SPPacket]
- * - `packet` is not written to concurrently
- * - the returned instance is freed in some way, either by using a consuming function or
- * by explicitly calling `sp_packet_free`.
- */
-SPPacket *sp_packet_clone(const SPPacket *packet);
-
-/**
- * Deallocates a [SPPacket].
- *
- * # Panics
- *
- * - when `packet` is NULL
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `packet` points to a valid [SPPacket]
- * - `packet` is not used concurrently or after this call
- */
-void sp_packet_free(SPPacket *packet);
-
-/**
- * Turns a [SPCommand] into a [SPPacket].
- * The [SPCommand] gets consumed.
- *
- * Will never return NULL.
- *
- * # Panics
- *
- * - when `command` is NULL
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - [SPCommand] points to a valid instance of [SPCommand]
- * - [SPCommand] is not used concurrently or after this call
- * - the returned [SPPacket] instance is freed in some way, either by using a consuming function or
- * by explicitly calling `sp_packet_free`.
- */
-SPPacket *sp_packet_from_command(SPCommand *command);
-
-/**
- * Creates a raw [SPPacket] from parts.
- *
- * # Arguments
- *
- * - `command_code` specifies which command this packet contains
- * - `a`, `b`, `c` and `d` are command-specific header values
- * - `payload` is the optional data that is part of the command
- * - `payload_len` is the size of the payload
- *
- * returns: new instance. Will never return null.
- *
- * # Panics
- *
- * - when `payload` is null, but `payload_len` is not zero
- * - when `payload_len` is zero, but `payload` is nonnull
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `payload` points to a valid memory region of at least `payload_len` bytes
- * - `payload` is not written to concurrently
- * - the returned [SPPacket] instance is freed in some way, either by using a consuming function or
- * by explicitly calling [sp_packet_free].
- */
-SPPacket *sp_packet_from_parts(uint16_t command_code,
- uint16_t a,
- uint16_t b,
- uint16_t c,
- uint16_t d,
- const uint8_t *payload,
- size_t payload_len);
-
-/**
- * Tries to load a [SPPacket] from the passed array with the specified length.
- *
- * returns: NULL in case of an error, pointer to the allocated packet otherwise
- *
- * # Panics
- *
- * - when `data` is NULL
- *
- * # Safety
- *
- * The caller has to make sure that:
- *
- * - `data` points to a valid memory region of at least `length` bytes
- * - `data` is not written to concurrently
- * - the returned [SPPacket] instance is freed in some way, either by using a consuming function or
- * by explicitly calling `sp_packet_free`.
- */
-SPPacket *sp_packet_try_load(const uint8_t *data,
- size_t length);
-
-#ifdef __cplusplus
-} // extern "C"
-#endif // __cplusplus
diff --git a/crates/servicepoint_binding_c/examples/lang_c/src/lib.rs b/crates/servicepoint_binding_c/examples/lang_c/src/lib.rs
deleted file mode 100644
index 8b13789..0000000
--- a/crates/servicepoint_binding_c/examples/lang_c/src/lib.rs
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/crates/servicepoint_binding_c/examples/lang_c/src/main.c b/crates/servicepoint_binding_c/examples/lang_c/src/main.c
deleted file mode 100644
index 1454804..0000000
--- a/crates/servicepoint_binding_c/examples/lang_c/src/main.c
+++ /dev/null
@@ -1,17 +0,0 @@
-#include
-#include "servicepoint.h"
-
-int main(void) {
- SPConnection *connection = sp_connection_open("localhost:2342");
- if (connection == NULL)
- return 1;
-
- SPBitmap *pixels = sp_bitmap_new(SP_PIXEL_WIDTH, SP_PIXEL_HEIGHT);
- sp_bitmap_fill(pixels, true);
-
- SPCommand *command = sp_command_bitmap_linear_win(0, 0, pixels, SP_COMPRESSION_CODE_UNCOMPRESSED);
- sp_connection_send_command(connection, command);
-
- sp_connection_free(connection);
- return 0;
-}
diff --git a/crates/servicepoint_binding_c/src/bitmap.rs b/crates/servicepoint_binding_c/src/bitmap.rs
deleted file mode 100644
index 3313385..0000000
--- a/crates/servicepoint_binding_c/src/bitmap.rs
+++ /dev/null
@@ -1,296 +0,0 @@
-//! C functions for interacting with [SPBitmap]s
-//!
-//! prefix `sp_bitmap_`
-
-use servicepoint::{DataRef, Grid};
-use std::ptr::NonNull;
-
-use crate::byte_slice::SPByteSlice;
-
-/// A grid of pixels.
-///
-/// # Examples
-///
-/// ```C
-/// Cp437Grid grid = sp_bitmap_new(8, 3);
-/// sp_bitmap_fill(grid, true);
-/// sp_bitmap_set(grid, 0, 0, false);
-/// sp_bitmap_free(grid);
-/// ```
-pub struct SPBitmap(pub(crate) servicepoint::Bitmap);
-
-/// Creates a new [SPBitmap] with the specified dimensions.
-///
-/// # Arguments
-///
-/// - `width`: size in pixels in x-direction
-/// - `height`: size in pixels in y-direction
-///
-/// returns: [SPBitmap] initialized to all pixels off. Will never return NULL.
-///
-/// # Panics
-///
-/// - when the width is not dividable by 8
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - the returned instance is freed in some way, either by using a consuming function or
-/// by explicitly calling `sp_bitmap_free`.
-#[no_mangle]
-pub unsafe extern "C" fn sp_bitmap_new(
- width: usize,
- height: usize,
-) -> NonNull {
- let result = Box::new(SPBitmap(servicepoint::Bitmap::new(width, height)));
- NonNull::from(Box::leak(result))
-}
-
-/// Creates a new [SPBitmap] with a size matching the screen.
-///
-/// returns: [SPBitmap] initialized to all pixels off. Will never return NULL.
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - the returned instance is freed in some way, either by using a consuming function or
-/// by explicitly calling [sp_bitmap_free].
-#[no_mangle]
-pub unsafe extern "C" fn sp_bitmap_new_screen_sized() -> NonNull {
- let result = Box::new(SPBitmap(servicepoint::Bitmap::max_sized()));
- NonNull::from(Box::leak(result))
-}
-
-/// Loads a [SPBitmap] with the specified dimensions from the provided data.
-///
-/// # Arguments
-///
-/// - `width`: size in pixels in x-direction
-/// - `height`: size in pixels in y-direction
-///
-/// returns: [SPBitmap] that contains a copy of the provided data. Will never return NULL.
-///
-/// # Panics
-///
-/// - when `data` is NULL
-/// - when the dimensions and data size do not match exactly.
-/// - when the width is not dividable by 8
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `data` points to a valid memory location of at least `data_length` bytes in size.
-/// - the returned instance is freed in some way, either by using a consuming function or
-/// by explicitly calling `sp_bitmap_free`.
-#[no_mangle]
-pub unsafe extern "C" fn sp_bitmap_load(
- width: usize,
- height: usize,
- data: *const u8,
- data_length: usize,
-) -> NonNull {
- assert!(!data.is_null());
- let data = std::slice::from_raw_parts(data, data_length);
- let result =
- Box::new(SPBitmap(servicepoint::Bitmap::load(width, height, data)));
- NonNull::from(Box::leak(result))
-}
-
-/// Clones a [SPBitmap].
-///
-/// Will never return NULL.
-///
-/// # Panics
-///
-/// - when `bitmap` is NULL
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `bitmap` points to a valid [SPBitmap]
-/// - `bitmap` is not written to concurrently
-/// - the returned instance is freed in some way, either by using a consuming function or
-/// by explicitly calling `sp_bitmap_free`.
-#[no_mangle]
-pub unsafe extern "C" fn sp_bitmap_clone(
- bitmap: *const SPBitmap,
-) -> NonNull {
- assert!(!bitmap.is_null());
- let result = Box::new(SPBitmap((*bitmap).0.clone()));
- NonNull::from(Box::leak(result))
-}
-
-/// Deallocates a [SPBitmap].
-///
-/// # Panics
-///
-/// - when `bitmap` is NULL
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `bitmap` points to a valid [SPBitmap]
-/// - `bitmap` is not used concurrently or after bitmap call
-/// - `bitmap` was not passed to another consuming function, e.g. to create a [SPCommand]
-///
-/// [SPCommand]: [crate::SPCommand]
-#[no_mangle]
-pub unsafe extern "C" fn sp_bitmap_free(bitmap: *mut SPBitmap) {
- assert!(!bitmap.is_null());
- _ = Box::from_raw(bitmap);
-}
-
-/// Gets the current value at the specified position in the [SPBitmap].
-///
-/// # Arguments
-///
-/// - `bitmap`: instance to read from
-/// - `x` and `y`: position of the cell to read
-///
-/// # Panics
-///
-/// - when `bitmap` is NULL
-/// - when accessing `x` or `y` out of bounds
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `bitmap` points to a valid [SPBitmap]
-/// - `bitmap` is not written to concurrently
-#[no_mangle]
-pub unsafe extern "C" fn sp_bitmap_get(
- bitmap: *const SPBitmap,
- x: usize,
- y: usize,
-) -> bool {
- assert!(!bitmap.is_null());
- (*bitmap).0.get(x, y)
-}
-
-/// Sets the value of the specified position in the [SPBitmap].
-///
-/// # Arguments
-///
-/// - `bitmap`: instance to write to
-/// - `x` and `y`: position of the cell
-/// - `value`: the value to write to the cell
-///
-/// returns: old value of the cell
-///
-/// # Panics
-///
-/// - when `bitmap` is NULL
-/// - when accessing `x` or `y` out of bounds
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `bitmap` points to a valid [SPBitmap]
-/// - `bitmap` is not written to or read from concurrently
-#[no_mangle]
-pub unsafe extern "C" fn sp_bitmap_set(
- bitmap: *mut SPBitmap,
- x: usize,
- y: usize,
- value: bool,
-) {
- assert!(!bitmap.is_null());
- (*bitmap).0.set(x, y, value);
-}
-
-/// Sets the state of all pixels in the [SPBitmap].
-///
-/// # Arguments
-///
-/// - `bitmap`: instance to write to
-/// - `value`: the value to set all pixels to
-///
-/// # Panics
-///
-/// - when `bitmap` is NULL
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `bitmap` points to a valid [SPBitmap]
-/// - `bitmap` is not written to or read from concurrently
-#[no_mangle]
-pub unsafe extern "C" fn sp_bitmap_fill(bitmap: *mut SPBitmap, value: bool) {
- assert!(!bitmap.is_null());
- (*bitmap).0.fill(value);
-}
-
-/// Gets the width in pixels of the [SPBitmap] instance.
-///
-/// # Arguments
-///
-/// - `bitmap`: instance to read from
-///
-/// # Panics
-///
-/// - when `bitmap` is NULL
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `bitmap` points to a valid [SPBitmap]
-#[no_mangle]
-pub unsafe extern "C" fn sp_bitmap_width(bitmap: *const SPBitmap) -> usize {
- assert!(!bitmap.is_null());
- (*bitmap).0.width()
-}
-
-/// Gets the height in pixels of the [SPBitmap] instance.
-///
-/// # Arguments
-///
-/// - `bitmap`: instance to read from
-///
-/// # Panics
-///
-/// - when `bitmap` is NULL
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `bitmap` points to a valid [SPBitmap]
-#[no_mangle]
-pub unsafe extern "C" fn sp_bitmap_height(bitmap: *const SPBitmap) -> usize {
- assert!(!bitmap.is_null());
- (*bitmap).0.height()
-}
-
-/// Gets an unsafe reference to the data of the [SPBitmap] instance.
-///
-/// # Panics
-///
-/// - when `bitmap` is NULL
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `bitmap` points to a valid [SPBitmap]
-/// - the returned memory range is never accessed after the passed [SPBitmap] has been freed
-/// - the returned memory range is never accessed concurrently, either via the [SPBitmap] or directly
-#[no_mangle]
-pub unsafe extern "C" fn sp_bitmap_unsafe_data_ref(
- bitmap: *mut SPBitmap,
-) -> SPByteSlice {
- assert!(!bitmap.is_null());
- let data = (*bitmap).0.data_ref_mut();
- SPByteSlice {
- start: NonNull::new(data.as_mut_ptr_range().start).unwrap(),
- length: data.len(),
- }
-}
diff --git a/crates/servicepoint_binding_c/src/bitvec.rs b/crates/servicepoint_binding_c/src/bitvec.rs
deleted file mode 100644
index 484e849..0000000
--- a/crates/servicepoint_binding_c/src/bitvec.rs
+++ /dev/null
@@ -1,283 +0,0 @@
-//! C functions for interacting with [SPBitVec]s
-//!
-//! prefix `sp_bitvec_`
-
-use crate::SPByteSlice;
-use std::ptr::NonNull;
-
-/// A vector of bits
-///
-/// # Examples
-/// ```C
-/// SPBitVec vec = sp_bitvec_new(8);
-/// sp_bitvec_set(vec, 5, true);
-/// sp_bitvec_free(vec);
-/// ```
-pub struct SPBitVec(servicepoint::BitVec);
-
-impl From for SPBitVec {
- fn from(actual: servicepoint::BitVec) -> Self {
- Self(actual)
- }
-}
-
-impl From for servicepoint::BitVec {
- fn from(value: SPBitVec) -> Self {
- value.0
- }
-}
-
-impl Clone for SPBitVec {
- fn clone(&self) -> Self {
- SPBitVec(self.0.clone())
- }
-}
-
-/// Creates a new [SPBitVec] instance.
-///
-/// # Arguments
-///
-/// - `size`: size in bits.
-///
-/// returns: [SPBitVec] with all bits set to false. Will never return NULL.
-///
-/// # Panics
-///
-/// - when `size` is not divisible by 8.
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - the returned instance is freed in some way, either by using a consuming function or
-/// by explicitly calling `sp_bitvec_free`.
-#[no_mangle]
-pub unsafe extern "C" fn sp_bitvec_new(size: usize) -> NonNull {
- let result = Box::new(SPBitVec(servicepoint::BitVec::repeat(false, size)));
- NonNull::from(Box::leak(result))
-}
-
-/// Interpret the data as a series of bits and load then into a new [SPBitVec] instance.
-///
-/// returns: [SPBitVec] instance containing data. Will never return NULL.
-///
-/// # Panics
-///
-/// - when `data` is NULL
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `data` points to a valid memory location of at least `data_length`
-/// bytes in size.
-/// - the returned instance is freed in some way, either by using a consuming function or
-/// by explicitly calling `sp_bitvec_free`.
-#[no_mangle]
-pub unsafe extern "C" fn sp_bitvec_load(
- data: *const u8,
- data_length: usize,
-) -> NonNull {
- assert!(!data.is_null());
- let data = std::slice::from_raw_parts(data, data_length);
- let result = Box::new(SPBitVec(servicepoint::BitVec::from_slice(data)));
- NonNull::from(Box::leak(result))
-}
-
-/// Clones a [SPBitVec].
-///
-/// returns: new [SPBitVec] instance. Will never return NULL.
-///
-/// # Panics
-///
-/// - when `bit_vec` is NULL
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `bit_vec` points to a valid [SPBitVec]
-/// - `bit_vec` is not written to concurrently
-/// - the returned instance is freed in some way, either by using a consuming function or
-/// by explicitly calling `sp_bitvec_free`.
-#[no_mangle]
-pub unsafe extern "C" fn sp_bitvec_clone(
- bit_vec: *const SPBitVec,
-) -> NonNull {
- assert!(!bit_vec.is_null());
- let result = Box::new((*bit_vec).clone());
- NonNull::from(Box::leak(result))
-}
-
-/// Deallocates a [SPBitVec].
-///
-/// # Panics
-///
-/// - when `but_vec` is NULL
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `bit_vec` points to a valid [SPBitVec]
-/// - `bit_vec` is not used concurrently or after this call
-/// - `bit_vec` was not passed to another consuming function, e.g. to create a [SPCommand]
-///
-/// [SPCommand]: [crate::SPCommand]
-#[no_mangle]
-pub unsafe extern "C" fn sp_bitvec_free(bit_vec: *mut SPBitVec) {
- assert!(!bit_vec.is_null());
- _ = Box::from_raw(bit_vec);
-}
-
-/// Gets the value of a bit from the [SPBitVec].
-///
-/// # Arguments
-///
-/// - `bit_vec`: instance to read from
-/// - `index`: the bit index to read
-///
-/// returns: value of the bit
-///
-/// # Panics
-///
-/// - when `bit_vec` is NULL
-/// - when accessing `index` out of bounds
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `bit_vec` points to a valid [SPBitVec]
-/// - `bit_vec` is not written to concurrently
-#[no_mangle]
-pub unsafe extern "C" fn sp_bitvec_get(
- bit_vec: *const SPBitVec,
- index: usize,
-) -> bool {
- assert!(!bit_vec.is_null());
- *(*bit_vec).0.get(index).unwrap()
-}
-
-/// Sets the value of a bit in the [SPBitVec].
-///
-/// # Arguments
-///
-/// - `bit_vec`: instance to write to
-/// - `index`: the bit index to edit
-/// - `value`: the value to set the bit to
-///
-/// # Panics
-///
-/// - when `bit_vec` is NULL
-/// - when accessing `index` out of bounds
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `bit_vec` points to a valid [SPBitVec]
-/// - `bit_vec` is not written to or read from concurrently
-#[no_mangle]
-pub unsafe extern "C" fn sp_bitvec_set(
- bit_vec: *mut SPBitVec,
- index: usize,
- value: bool,
-) {
- assert!(!bit_vec.is_null());
- (*bit_vec).0.set(index, value)
-}
-
-/// Sets the value of all bits in the [SPBitVec].
-///
-/// # Arguments
-///
-/// - `bit_vec`: instance to write to
-/// - `value`: the value to set all bits to
-///
-/// # Panics
-///
-/// - when `bit_vec` is NULL
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `bit_vec` points to a valid [SPBitVec]
-/// - `bit_vec` is not written to or read from concurrently
-#[no_mangle]
-pub unsafe extern "C" fn sp_bitvec_fill(bit_vec: *mut SPBitVec, value: bool) {
- assert!(!bit_vec.is_null());
- (*bit_vec).0.fill(value)
-}
-
-/// Gets the length of the [SPBitVec] in bits.
-///
-/// # Arguments
-///
-/// - `bit_vec`: instance to write to
-///
-/// # Panics
-///
-/// - when `bit_vec` is NULL
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `bit_vec` points to a valid [SPBitVec]
-#[no_mangle]
-pub unsafe extern "C" fn sp_bitvec_len(bit_vec: *const SPBitVec) -> usize {
- assert!(!bit_vec.is_null());
- (*bit_vec).0.len()
-}
-
-/// Returns true if length is 0.
-///
-/// # Arguments
-///
-/// - `bit_vec`: instance to write to
-///
-/// # Panics
-///
-/// - when `bit_vec` is NULL
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `bit_vec` points to a valid [SPBitVec]
-#[no_mangle]
-pub unsafe extern "C" fn sp_bitvec_is_empty(bit_vec: *const SPBitVec) -> bool {
- assert!(!bit_vec.is_null());
- (*bit_vec).0.is_empty()
-}
-
-/// Gets an unsafe reference to the data of the [SPBitVec] instance.
-///
-/// # Arguments
-///
-/// - `bit_vec`: instance to write to
-///
-/// # Panics
-///
-/// - when `bit_vec` is NULL
-///
-/// ## Safety
-///
-/// The caller has to make sure that:
-///
-/// - `bit_vec` points to a valid [SPBitVec]
-/// - the returned memory range is never accessed after the passed [SPBitVec] has been freed
-/// - the returned memory range is never accessed concurrently, either via the [SPBitVec] or directly
-#[no_mangle]
-pub unsafe extern "C" fn sp_bitvec_unsafe_data_ref(
- bit_vec: *mut SPBitVec,
-) -> SPByteSlice {
- assert!(!bit_vec.is_null());
- let data = (*bit_vec).0.as_raw_mut_slice();
- SPByteSlice {
- start: NonNull::new(data.as_mut_ptr_range().start).unwrap(),
- length: data.len(),
- }
-}
diff --git a/crates/servicepoint_binding_c/src/brightness_grid.rs b/crates/servicepoint_binding_c/src/brightness_grid.rs
deleted file mode 100644
index 83af008..0000000
--- a/crates/servicepoint_binding_c/src/brightness_grid.rs
+++ /dev/null
@@ -1,322 +0,0 @@
-//! C functions for interacting with [SPBrightnessGrid]s
-//!
-//! prefix `sp_brightness_grid_`
-
-use crate::SPByteSlice;
-use servicepoint::{DataRef, Grid};
-use std::convert::Into;
-use std::intrinsics::transmute;
-use std::ptr::NonNull;
-
-/// see [servicepoint::Brightness::MIN]
-pub const SP_BRIGHTNESS_MIN: u8 = 0;
-/// see [servicepoint::Brightness::MAX]
-pub const SP_BRIGHTNESS_MAX: u8 = 11;
-/// Count of possible brightness values
-pub const SP_BRIGHTNESS_LEVELS: u8 = 12;
-
-/// A grid containing brightness values.
-///
-/// # Examples
-/// ```C
-/// SPConnection connection = sp_connection_open("127.0.0.1:2342");
-/// if (connection == NULL)
-/// return 1;
-///
-/// SPBrightnessGrid grid = sp_brightness_grid_new(2, 2);
-/// sp_brightness_grid_set(grid, 0, 0, 0);
-/// sp_brightness_grid_set(grid, 1, 1, 10);
-///
-/// SPCommand command = sp_command_char_brightness(grid);
-/// sp_connection_free(connection);
-/// ```
-#[derive(Clone)]
-pub struct SPBrightnessGrid(pub(crate) servicepoint::BrightnessGrid);
-
-/// Creates a new [SPBrightnessGrid] with the specified dimensions.
-///
-/// returns: [SPBrightnessGrid] initialized to 0. Will never return NULL.
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - the returned instance is freed in some way, either by using a consuming function or
-/// by explicitly calling `sp_brightness_grid_free`.
-#[no_mangle]
-pub unsafe extern "C" fn sp_brightness_grid_new(
- width: usize,
- height: usize,
-) -> NonNull {
- let result = Box::new(SPBrightnessGrid(servicepoint::BrightnessGrid::new(
- width, height,
- )));
- NonNull::from(Box::leak(result))
-}
-
-/// Loads a [SPBrightnessGrid] with the specified dimensions from the provided data.
-///
-/// returns: new [SPBrightnessGrid] instance. Will never return NULL.
-///
-/// # Panics
-///
-/// - when `data` is NULL
-/// - when the provided `data_length` does not match `height` and `width`
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `data` points to a valid memory location of at least `data_length`
-/// bytes in size.
-/// - the returned instance is freed in some way, either by using a consuming function or
-/// by explicitly calling `sp_brightness_grid_free`.
-#[no_mangle]
-pub unsafe extern "C" fn sp_brightness_grid_load(
- width: usize,
- height: usize,
- data: *const u8,
- data_length: usize,
-) -> NonNull {
- assert!(!data.is_null());
- let data = std::slice::from_raw_parts(data, data_length);
- let grid = servicepoint::ByteGrid::load(width, height, data);
- let grid = servicepoint::BrightnessGrid::try_from(grid)
- .expect("invalid brightness value");
- let result = Box::new(SPBrightnessGrid(grid));
- NonNull::from(Box::leak(result))
-}
-
-/// Clones a [SPBrightnessGrid].
-///
-/// # Arguments
-///
-/// - `brightness_grid`: instance to read from
-///
-/// returns: new [SPBrightnessGrid] instance. Will never return NULL.
-///
-/// # Panics
-///
-/// - when `brightness_grid` is NULL
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `brightness_grid` points to a valid [SPBrightnessGrid]
-/// - `brightness_grid` is not written to concurrently
-/// - the returned instance is freed in some way, either by using a consuming function or
-/// by explicitly calling `sp_brightness_grid_free`.
-#[no_mangle]
-pub unsafe extern "C" fn sp_brightness_grid_clone(
- brightness_grid: *const SPBrightnessGrid,
-) -> NonNull {
- assert!(!brightness_grid.is_null());
- let result = Box::new((*brightness_grid).clone());
- NonNull::from(Box::leak(result))
-}
-
-/// Deallocates a [SPBrightnessGrid].
-///
-/// # Arguments
-///
-/// - `brightness_grid`: instance to read from
-///
-/// # Panics
-///
-/// - when `brightness_grid` is NULL
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `brightness_grid` points to a valid [SPBrightnessGrid]
-/// - `brightness_grid` is not used concurrently or after this call
-/// - `brightness_grid` was not passed to another consuming function, e.g. to create a [SPCommand]
-///
-/// [SPCommand]: [crate::SPCommand]
-#[no_mangle]
-pub unsafe extern "C" fn sp_brightness_grid_free(
- brightness_grid: *mut SPBrightnessGrid,
-) {
- assert!(!brightness_grid.is_null());
- _ = Box::from_raw(brightness_grid);
-}
-
-/// Gets the current value at the specified position.
-///
-/// # Arguments
-///
-/// - `brightness_grid`: instance to read from
-/// - `x` and `y`: position of the cell to read
-///
-/// returns: value at position
-///
-/// # Panics
-///
-/// - when `brightness_grid` is NULL
-/// - When accessing `x` or `y` out of bounds.
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `brightness_grid` points to a valid [SPBrightnessGrid]
-/// - `brightness_grid` is not written to concurrently
-#[no_mangle]
-pub unsafe extern "C" fn sp_brightness_grid_get(
- brightness_grid: *const SPBrightnessGrid,
- x: usize,
- y: usize,
-) -> u8 {
- assert!(!brightness_grid.is_null());
- (*brightness_grid).0.get(x, y).into()
-}
-
-/// Sets the value of the specified position in the [SPBrightnessGrid].
-///
-/// # Arguments
-///
-/// - `brightness_grid`: instance to write to
-/// - `x` and `y`: position of the cell
-/// - `value`: the value to write to the cell
-///
-/// returns: old value of the cell
-///
-/// # Panics
-///
-/// - when `brightness_grid` is NULL
-/// - When accessing `x` or `y` out of bounds.
-/// - When providing an invalid brightness value
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `brightness_grid` points to a valid [SPBrightnessGrid]
-/// - `brightness_grid` is not written to or read from concurrently
-#[no_mangle]
-pub unsafe extern "C" fn sp_brightness_grid_set(
- brightness_grid: *mut SPBrightnessGrid,
- x: usize,
- y: usize,
- value: u8,
-) {
- assert!(!brightness_grid.is_null());
- let brightness = servicepoint::Brightness::try_from(value)
- .expect("invalid brightness value");
- (*brightness_grid).0.set(x, y, brightness);
-}
-
-/// Sets the value of all cells in the [SPBrightnessGrid].
-///
-/// # Arguments
-///
-/// - `brightness_grid`: instance to write to
-/// - `value`: the value to set all cells to
-///
-/// # Panics
-///
-/// - when `brightness_grid` is NULL
-/// - When providing an invalid brightness value
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `brightness_grid` points to a valid [SPBrightnessGrid]
-/// - `brightness_grid` is not written to or read from concurrently
-#[no_mangle]
-pub unsafe extern "C" fn sp_brightness_grid_fill(
- brightness_grid: *mut SPBrightnessGrid,
- value: u8,
-) {
- assert!(!brightness_grid.is_null());
- let brightness = servicepoint::Brightness::try_from(value)
- .expect("invalid brightness value");
- (*brightness_grid).0.fill(brightness);
-}
-
-/// Gets the width of the [SPBrightnessGrid] instance.
-///
-/// # Arguments
-///
-/// - `brightness_grid`: instance to read from
-///
-/// returns: width
-///
-/// # Panics
-///
-/// - when `brightness_grid` is NULL
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `brightness_grid` points to a valid [SPBrightnessGrid]
-#[no_mangle]
-pub unsafe extern "C" fn sp_brightness_grid_width(
- brightness_grid: *const SPBrightnessGrid,
-) -> usize {
- assert!(!brightness_grid.is_null());
- (*brightness_grid).0.width()
-}
-
-/// Gets the height of the [SPBrightnessGrid] instance.
-///
-/// # Arguments
-///
-/// - `brightness_grid`: instance to read from
-///
-/// returns: height
-///
-/// # Panics
-///
-/// - when `brightness_grid` is NULL
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `brightness_grid` points to a valid [SPBrightnessGrid]
-#[no_mangle]
-pub unsafe extern "C" fn sp_brightness_grid_height(
- brightness_grid: *const SPBrightnessGrid,
-) -> usize {
- assert!(!brightness_grid.is_null());
- (*brightness_grid).0.height()
-}
-
-/// Gets an unsafe reference to the data of the [SPBrightnessGrid] instance.
-///
-/// # Arguments
-///
-/// - `brightness_grid`: instance to read from
-///
-/// returns: slice of bytes underlying the `brightness_grid`.
-///
-/// # Panics
-///
-/// - when `brightness_grid` is NULL
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `brightness_grid` points to a valid [SPBrightnessGrid]
-/// - the returned memory range is never accessed after the passed [SPBrightnessGrid] has been freed
-/// - the returned memory range is never accessed concurrently, either via the [SPBrightnessGrid] or directly
-#[no_mangle]
-pub unsafe extern "C" fn sp_brightness_grid_unsafe_data_ref(
- brightness_grid: *mut SPBrightnessGrid,
-) -> SPByteSlice {
- assert!(!brightness_grid.is_null());
- assert_eq!(core::mem::size_of::(), 1);
- let data = (*brightness_grid).0.data_ref_mut();
- // this assumes more about the memory layout than rust guarantees. yikes!
- let data: &mut [u8] = transmute(data);
- SPByteSlice {
- start: NonNull::new(data.as_mut_ptr_range().start).unwrap(),
- length: data.len(),
- }
-}
diff --git a/crates/servicepoint_binding_c/src/byte_slice.rs b/crates/servicepoint_binding_c/src/byte_slice.rs
deleted file mode 100644
index 678a5d7..0000000
--- a/crates/servicepoint_binding_c/src/byte_slice.rs
+++ /dev/null
@@ -1,24 +0,0 @@
-//! FFI slice helper
-
-use std::ptr::NonNull;
-
-#[repr(C)]
-/// Represents a span of memory (`&mut [u8]` ) as a struct usable by C code.
-///
-/// You should not create an instance of this type in your C code.
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - accesses to the memory pointed to with `start` is never accessed outside `length`
-/// - the lifetime of the `CByteSlice` does not outlive the memory it points to, as described in
-/// the function returning this type.
-/// - an instance of this created from C is never passed to a consuming function, as the rust code
-/// will try to free the memory of a potentially separate allocator.
-pub struct SPByteSlice {
- /// The start address of the memory
- pub start: NonNull,
- /// The amount of memory in bytes
- pub length: usize,
-}
diff --git a/crates/servicepoint_binding_c/src/char_grid.rs b/crates/servicepoint_binding_c/src/char_grid.rs
deleted file mode 100644
index dfaf225..0000000
--- a/crates/servicepoint_binding_c/src/char_grid.rs
+++ /dev/null
@@ -1,263 +0,0 @@
-//! C functions for interacting with [SPCharGrid]s
-//!
-//! prefix `sp_char_grid_`
-
-use servicepoint::Grid;
-use std::ptr::NonNull;
-
-/// A C-wrapper for grid containing UTF-8 characters.
-///
-/// As the rust [char] type is not FFI-safe, characters are passed in their UTF-32 form as 32bit unsigned integers.
-///
-/// The encoding is enforced in most cases by the rust standard library
-/// and will panic when provided with illegal characters.
-///
-/// # Examples
-///
-/// ```C
-/// CharGrid grid = sp_char_grid_new(4, 3);
-/// sp_char_grid_fill(grid, '?');
-/// sp_char_grid_set(grid, 0, 0, '!');
-/// sp_char_grid_free(grid);
-/// ```
-pub struct SPCharGrid(pub(crate) servicepoint::CharGrid);
-
-impl Clone for SPCharGrid {
- fn clone(&self) -> Self {
- SPCharGrid(self.0.clone())
- }
-}
-
-/// Creates a new [SPCharGrid] with the specified dimensions.
-///
-/// returns: [SPCharGrid] initialized to 0. Will never return NULL.
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - the returned instance is freed in some way, either by using a consuming function or
-/// by explicitly calling `sp_char_grid_free`.
-#[no_mangle]
-pub unsafe extern "C" fn sp_char_grid_new(
- width: usize,
- height: usize,
-) -> NonNull {
- let result =
- Box::new(SPCharGrid(servicepoint::CharGrid::new(width, height)));
- NonNull::from(Box::leak(result))
-}
-
-/// Loads a [SPCharGrid] with the specified dimensions from the provided data.
-///
-/// Will never return NULL.
-///
-/// # Panics
-///
-/// - when `data` is NULL
-/// - when the provided `data_length` does not match `height` and `width`
-/// - when `data` is not valid UTF-8
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `data` points to a valid memory location of at least `data_length`
-/// bytes in size.
-/// - the returned instance is freed in some way, either by using a consuming function or
-/// by explicitly calling `sp_char_grid_free`.
-#[no_mangle]
-pub unsafe extern "C" fn sp_char_grid_load(
- width: usize,
- height: usize,
- data: *const u8,
- data_length: usize,
-) -> NonNull {
- assert!(data.is_null());
- let data = std::slice::from_raw_parts(data, data_length);
- let result = Box::new(SPCharGrid(
- servicepoint::CharGrid::load_utf8(width, height, data.to_vec())
- .unwrap(),
- ));
- NonNull::from(Box::leak(result))
-}
-
-/// Clones a [SPCharGrid].
-///
-/// Will never return NULL.
-///
-/// # Panics
-///
-/// - when `char_grid` is NULL
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `char_grid` points to a valid [SPCharGrid]
-/// - `char_grid` is not written to concurrently
-/// - the returned instance is freed in some way, either by using a consuming function or
-/// by explicitly calling `sp_char_grid_free`.
-#[no_mangle]
-pub unsafe extern "C" fn sp_char_grid_clone(
- char_grid: *const SPCharGrid,
-) -> NonNull {
- assert!(!char_grid.is_null());
- let result = Box::new((*char_grid).clone());
- NonNull::from(Box::leak(result))
-}
-
-/// Deallocates a [SPCharGrid].
-///
-/// # Panics
-///
-/// - when `char_grid` is NULL
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `char_grid` points to a valid [SPCharGrid]
-/// - `char_grid` is not used concurrently or after char_grid call
-/// - `char_grid` was not passed to another consuming function, e.g. to create a [SPCommand]
-///
-/// [SPCommand]: [crate::SPCommand]
-#[no_mangle]
-pub unsafe extern "C" fn sp_char_grid_free(char_grid: *mut SPCharGrid) {
- assert!(!char_grid.is_null());
- _ = Box::from_raw(char_grid);
-}
-
-/// Gets the current value at the specified position.
-///
-/// # Arguments
-///
-/// - `char_grid`: instance to read from
-/// - `x` and `y`: position of the cell to read
-///
-/// # Panics
-///
-/// - when `char_grid` is NULL
-/// - when accessing `x` or `y` out of bounds
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `char_grid` points to a valid [SPCharGrid]
-/// - `char_grid` is not written to concurrently
-#[no_mangle]
-pub unsafe extern "C" fn sp_char_grid_get(
- char_grid: *const SPCharGrid,
- x: usize,
- y: usize,
-) -> u32 {
- assert!(!char_grid.is_null());
- (*char_grid).0.get(x, y) as u32
-}
-
-/// Sets the value of the specified position in the [SPCharGrid].
-///
-/// # Arguments
-///
-/// - `char_grid`: instance to write to
-/// - `x` and `y`: position of the cell
-/// - `value`: the value to write to the cell
-///
-/// returns: old value of the cell
-///
-/// # Panics
-///
-/// - when `char_grid` is NULL
-/// - when accessing `x` or `y` out of bounds
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `char_grid` points to a valid [SPBitVec]
-/// - `char_grid` is not written to or read from concurrently
-///
-/// [SPBitVec]: [crate::SPBitVec]
-#[no_mangle]
-pub unsafe extern "C" fn sp_char_grid_set(
- char_grid: *mut SPCharGrid,
- x: usize,
- y: usize,
- value: u32,
-) {
- assert!(!char_grid.is_null());
- (*char_grid).0.set(x, y, char::from_u32(value).unwrap());
-}
-
-/// Sets the value of all cells in the [SPCharGrid].
-///
-/// # Arguments
-///
-/// - `char_grid`: instance to write to
-/// - `value`: the value to set all cells to
-///
-/// # Panics
-///
-/// - when `char_grid` is NULL
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `char_grid` points to a valid [SPCharGrid]
-/// - `char_grid` is not written to or read from concurrently
-#[no_mangle]
-pub unsafe extern "C" fn sp_char_grid_fill(
- char_grid: *mut SPCharGrid,
- value: u32,
-) {
- assert!(!char_grid.is_null());
- (*char_grid).0.fill(char::from_u32(value).unwrap());
-}
-
-/// Gets the width of the [SPCharGrid] instance.
-///
-/// # Arguments
-///
-/// - `char_grid`: instance to read from
-///
-/// # Panics
-///
-/// - when `char_grid` is NULL
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `char_grid` points to a valid [SPCharGrid]
-#[no_mangle]
-pub unsafe extern "C" fn sp_char_grid_width(
- char_grid: *const SPCharGrid,
-) -> usize {
- assert!(!char_grid.is_null());
- (*char_grid).0.width()
-}
-
-/// Gets the height of the [SPCharGrid] instance.
-///
-/// # Arguments
-///
-/// - `char_grid`: instance to read from
-///
-/// # Panics
-///
-/// - when `char_grid` is NULL
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `char_grid` points to a valid [SPCharGrid]
-#[no_mangle]
-pub unsafe extern "C" fn sp_char_grid_height(
- char_grid: *const SPCharGrid,
-) -> usize {
- assert!(!char_grid.is_null());
- (*char_grid).0.height()
-}
diff --git a/crates/servicepoint_binding_c/src/command.rs b/crates/servicepoint_binding_c/src/command.rs
deleted file mode 100644
index f7e50ea..0000000
--- a/crates/servicepoint_binding_c/src/command.rs
+++ /dev/null
@@ -1,498 +0,0 @@
-//! C functions for interacting with [SPCommand]s
-//!
-//! prefix `sp_command_`
-
-use std::ptr::{null_mut, NonNull};
-
-use crate::{
- SPBitVec, SPBitmap, SPBrightnessGrid, SPCharGrid, SPCompressionCode,
- SPCp437Grid, SPPacket,
-};
-
-/// A low-level display command.
-///
-/// This struct and associated functions implement the UDP protocol for the display.
-///
-/// To send a [SPCommand], use a [SPConnection].
-///
-/// # Examples
-///
-/// ```C
-/// sp_connection_send_command(connection, sp_command_clear());
-/// sp_connection_send_command(connection, sp_command_brightness(5));
-/// ```
-///
-/// [SPConnection]: [crate::SPConnection]
-pub struct SPCommand(pub(crate) servicepoint::Command);
-
-impl Clone for SPCommand {
- fn clone(&self) -> Self {
- SPCommand(self.0.clone())
- }
-}
-
-/// Tries to turn a [SPPacket] into a [SPCommand].
-///
-/// The packet is deallocated in the process.
-///
-/// Returns: pointer to new [SPCommand] instance or NULL if parsing failed.
-///
-/// # Panics
-///
-/// - when `packet` is NULL
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - [SPPacket] points to a valid instance of [SPPacket]
-/// - [SPPacket] is not used concurrently or after this call
-/// - the result is checked for NULL
-/// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
-/// by explicitly calling `sp_command_free`.
-#[no_mangle]
-pub unsafe extern "C" fn sp_command_try_from_packet(
- packet: *mut SPPacket,
-) -> *mut SPCommand {
- let packet = *Box::from_raw(packet);
- match servicepoint::Command::try_from(packet.0) {
- Err(_) => null_mut(),
- Ok(command) => Box::into_raw(Box::new(SPCommand(command))),
- }
-}
-
-/// Clones a [SPCommand] instance.
-///
-/// returns: new [SPCommand] instance. Will never return NULL.
-///
-/// # Panics
-///
-/// - when `command` is NULL
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `command` points to a valid instance of [SPCommand]
-/// - `command` is not written to concurrently
-/// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
-/// by explicitly calling `sp_command_free`.
-#[no_mangle]
-pub unsafe extern "C" fn sp_command_clone(
- command: *const SPCommand,
-) -> NonNull {
- assert!(!command.is_null());
- let result = Box::new((*command).clone());
- NonNull::from(Box::leak(result))
-}
-
-/// Set all pixels to the off state.
-///
-/// Does not affect brightness.
-///
-/// Returns: a new [servicepoint::Command::Clear] instance. Will never return NULL.
-///
-/// # Examples
-///
-/// ```C
-/// sp_connection_send_command(connection, sp_command_clear());
-/// ```
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
-/// by explicitly calling `sp_command_free`.
-#[no_mangle]
-pub unsafe extern "C" fn sp_command_clear() -> NonNull {
- let result = Box::new(SPCommand(servicepoint::Command::Clear));
- NonNull::from(Box::leak(result))
-}
-
-/// Kills the udp daemon on the display, which usually results in a restart.
-///
-/// Please do not send this in your normal program flow.
-///
-/// Returns: a new [servicepoint::Command::HardReset] instance. Will never return NULL.
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
-/// by explicitly calling `sp_command_free`.
-#[no_mangle]
-pub unsafe extern "C" fn sp_command_hard_reset() -> NonNull {
- let result = Box::new(SPCommand(servicepoint::Command::HardReset));
- NonNull::from(Box::leak(result))
-}
-
-/// A yet-to-be-tested command.
-///
-/// Returns: a new [servicepoint::Command::FadeOut] instance. Will never return NULL.
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
-/// by explicitly calling `sp_command_free`.
-#[no_mangle]
-pub unsafe extern "C" fn sp_command_fade_out() -> NonNull {
- let result = Box::new(SPCommand(servicepoint::Command::FadeOut));
- NonNull::from(Box::leak(result))
-}
-
-/// Set the brightness of all tiles to the same value.
-///
-/// Returns: a new [servicepoint::Command::Brightness] instance. Will never return NULL.
-///
-/// # Panics
-///
-/// - When the provided brightness value is out of range (0-11).
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
-/// by explicitly calling `sp_command_free`.
-#[no_mangle]
-pub unsafe extern "C" fn sp_command_brightness(
- brightness: u8,
-) -> NonNull {
- let brightness = servicepoint::Brightness::try_from(brightness)
- .expect("invalid brightness");
- let result =
- Box::new(SPCommand(servicepoint::Command::Brightness(brightness)));
- NonNull::from(Box::leak(result))
-}
-
-/// Set the brightness of individual tiles in a rectangular area of the display.
-///
-/// The passed [SPBrightnessGrid] gets consumed.
-///
-/// Returns: a new [servicepoint::Command::CharBrightness] instance. Will never return NULL.
-///
-/// # Panics
-///
-/// - when `grid` is NULL
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `grid` points to a valid instance of [SPBrightnessGrid]
-/// - `grid` is not used concurrently or after this call
-/// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
-/// by explicitly calling `sp_command_free`.
-#[no_mangle]
-pub unsafe extern "C" fn sp_command_char_brightness(
- x: usize,
- y: usize,
- grid: *mut SPBrightnessGrid,
-) -> NonNull {
- assert!(!grid.is_null());
- let byte_grid = *Box::from_raw(grid);
- let result = Box::new(SPCommand(servicepoint::Command::CharBrightness(
- servicepoint::Origin::new(x, y),
- byte_grid.0,
- )));
- NonNull::from(Box::leak(result))
-}
-
-/// Set pixel data starting at the pixel offset on screen.
-///
-/// The screen will continuously overwrite more pixel data without regarding the offset, meaning
-/// once the starting row is full, overwriting will continue on column 0.
-///
-/// The contained [SPBitVec] is always uncompressed.
-///
-/// The passed [SPBitVec] gets consumed.
-///
-/// Returns: a new [servicepoint::Command::BitmapLinear] instance. Will never return NULL.
-///
-/// # Panics
-///
-/// - when `bit_vec` is null
-/// - when `compression_code` is not a valid value
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `bit_vec` points to a valid instance of [SPBitVec]
-/// - `bit_vec` is not used concurrently or after this call
-/// - `compression` matches one of the allowed enum values
-/// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
-/// by explicitly calling `sp_command_free`.
-#[no_mangle]
-pub unsafe extern "C" fn sp_command_bitmap_linear(
- offset: usize,
- bit_vec: *mut SPBitVec,
- compression: SPCompressionCode,
-) -> NonNull {
- assert!(!bit_vec.is_null());
- let bit_vec = *Box::from_raw(bit_vec);
- let result = Box::new(SPCommand(servicepoint::Command::BitmapLinear(
- offset,
- bit_vec.into(),
- compression.try_into().expect("invalid compression code"),
- )));
- NonNull::from(Box::leak(result))
-}
-
-/// Set pixel data according to an and-mask starting at the offset.
-///
-/// The screen will continuously overwrite more pixel data without regarding the offset, meaning
-/// once the starting row is full, overwriting will continue on column 0.
-///
-/// The contained [SPBitVec] is always uncompressed.
-///
-/// The passed [SPBitVec] gets consumed.
-///
-/// Returns: a new [servicepoint::Command::BitmapLinearAnd] instance. Will never return NULL.
-///
-/// # Panics
-///
-/// - when `bit_vec` is null
-/// - when `compression_code` is not a valid value
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `bit_vec` points to a valid instance of [SPBitVec]
-/// - `bit_vec` is not used concurrently or after this call
-/// - `compression` matches one of the allowed enum values
-/// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
-/// by explicitly calling `sp_command_free`.
-#[no_mangle]
-pub unsafe extern "C" fn sp_command_bitmap_linear_and(
- offset: usize,
- bit_vec: *mut SPBitVec,
- compression: SPCompressionCode,
-) -> NonNull {
- assert!(!bit_vec.is_null());
- let bit_vec = *Box::from_raw(bit_vec);
- let result = Box::new(SPCommand(servicepoint::Command::BitmapLinearAnd(
- offset,
- bit_vec.into(),
- compression.try_into().expect("invalid compression code"),
- )));
- NonNull::from(Box::leak(result))
-}
-
-/// Set pixel data according to an or-mask starting at the offset.
-///
-/// The screen will continuously overwrite more pixel data without regarding the offset, meaning
-/// once the starting row is full, overwriting will continue on column 0.
-///
-/// The contained [SPBitVec] is always uncompressed.
-///
-/// The passed [SPBitVec] gets consumed.
-///
-/// Returns: a new [servicepoint::Command::BitmapLinearOr] instance. Will never return NULL.
-///
-/// # Panics
-///
-/// - when `bit_vec` is null
-/// - when `compression_code` is not a valid value
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `bit_vec` points to a valid instance of [SPBitVec]
-/// - `bit_vec` is not used concurrently or after this call
-/// - `compression` matches one of the allowed enum values
-/// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
-/// by explicitly calling `sp_command_free`.
-#[no_mangle]
-pub unsafe extern "C" fn sp_command_bitmap_linear_or(
- offset: usize,
- bit_vec: *mut SPBitVec,
- compression: SPCompressionCode,
-) -> NonNull {
- assert!(!bit_vec.is_null());
- let bit_vec = *Box::from_raw(bit_vec);
- let result = Box::new(SPCommand(servicepoint::Command::BitmapLinearOr(
- offset,
- bit_vec.into(),
- compression.try_into().expect("invalid compression code"),
- )));
- NonNull::from(Box::leak(result))
-}
-
-/// Set pixel data according to a xor-mask starting at the offset.
-///
-/// The screen will continuously overwrite more pixel data without regarding the offset, meaning
-/// once the starting row is full, overwriting will continue on column 0.
-///
-/// The contained [SPBitVec] is always uncompressed.
-///
-/// The passed [SPBitVec] gets consumed.
-///
-/// Returns: a new [servicepoint::Command::BitmapLinearXor] instance. Will never return NULL.
-///
-/// # Panics
-///
-/// - when `bit_vec` is null
-/// - when `compression_code` is not a valid value
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `bit_vec` points to a valid instance of [SPBitVec]
-/// - `bit_vec` is not used concurrently or after this call
-/// - `compression` matches one of the allowed enum values
-/// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
-/// by explicitly calling `sp_command_free`.
-#[no_mangle]
-pub unsafe extern "C" fn sp_command_bitmap_linear_xor(
- offset: usize,
- bit_vec: *mut SPBitVec,
- compression: SPCompressionCode,
-) -> NonNull {
- assert!(!bit_vec.is_null());
- let bit_vec = *Box::from_raw(bit_vec);
- let result = Box::new(SPCommand(servicepoint::Command::BitmapLinearXor(
- offset,
- bit_vec.into(),
- compression.try_into().expect("invalid compression code"),
- )));
- NonNull::from(Box::leak(result))
-}
-
-/// Show codepage 437 encoded text on the screen.
-///
-/// The passed [SPCp437Grid] gets consumed.
-///
-/// Returns: a new [servicepoint::Command::Cp437Data] instance. Will never return NULL.
-///
-/// # Panics
-///
-/// - when `grid` is null
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `grid` points to a valid instance of [SPCp437Grid]
-/// - `grid` is not used concurrently or after this call
-/// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
-/// by explicitly calling `sp_command_free`.
-#[no_mangle]
-pub unsafe extern "C" fn sp_command_cp437_data(
- x: usize,
- y: usize,
- grid: *mut SPCp437Grid,
-) -> NonNull {
- assert!(!grid.is_null());
- let grid = *Box::from_raw(grid);
- let result = Box::new(SPCommand(servicepoint::Command::Cp437Data(
- servicepoint::Origin::new(x, y),
- grid.0,
- )));
- NonNull::from(Box::leak(result))
-}
-
-/// Show UTF-8 encoded text on the screen.
-///
-/// The passed [SPCharGrid] gets consumed.
-///
-/// Returns: a new [servicepoint::Command::Utf8Data] instance. Will never return NULL.
-///
-/// # Panics
-///
-/// - when `grid` is null
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `grid` points to a valid instance of [SPCharGrid]
-/// - `grid` is not used concurrently or after this call
-/// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
-/// by explicitly calling `sp_command_free`.
-#[no_mangle]
-pub unsafe extern "C" fn sp_command_utf8_data(
- x: usize,
- y: usize,
- grid: *mut SPCharGrid,
-) -> NonNull {
- assert!(!grid.is_null());
- let grid = *Box::from_raw(grid);
- let result = Box::new(SPCommand(servicepoint::Command::Utf8Data(
- servicepoint::Origin::new(x, y),
- grid.0,
- )));
- NonNull::from(Box::leak(result))
-}
-
-/// Sets a window of pixels to the specified values.
-///
-/// The passed [SPBitmap] gets consumed.
-///
-/// Returns: a new [servicepoint::Command::BitmapLinearWin] instance. Will never return NULL.
-///
-/// # Panics
-///
-/// - when `bitmap` is null
-/// - when `compression_code` is not a valid value
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `bitmap` points to a valid instance of [SPBitmap]
-/// - `bitmap` is not used concurrently or after this call
-/// - `compression` matches one of the allowed enum values
-/// - the returned [SPCommand] instance is freed in some way, either by using a consuming function or
-/// by explicitly calling `sp_command_free`.
-#[no_mangle]
-pub unsafe extern "C" fn sp_command_bitmap_linear_win(
- x: usize,
- y: usize,
- bitmap: *mut SPBitmap,
- compression_code: SPCompressionCode,
-) -> NonNull {
- assert!(!bitmap.is_null());
- let byte_grid = (*Box::from_raw(bitmap)).0;
- let result = Box::new(SPCommand(servicepoint::Command::BitmapLinearWin(
- servicepoint::Origin::new(x, y),
- byte_grid,
- compression_code
- .try_into()
- .expect("invalid compression code"),
- )));
- NonNull::from(Box::leak(result))
-}
-
-/// Deallocates a [SPCommand].
-///
-/// # Examples
-///
-/// ```C
-/// SPCommand c = sp_command_clear();
-/// sp_command_free(c);
-/// ```
-///
-/// # Panics
-///
-/// - when `command` is NULL
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `command` points to a valid [SPCommand]
-/// - `command` is not used concurrently or after this call
-/// - `command` was not passed to another consuming function, e.g. to create a [SPPacket]
-#[no_mangle]
-pub unsafe extern "C" fn sp_command_free(command: *mut SPCommand) {
- assert!(!command.is_null());
- _ = Box::from_raw(command);
-}
diff --git a/crates/servicepoint_binding_c/src/connection.rs b/crates/servicepoint_binding_c/src/connection.rs
deleted file mode 100644
index 8b31243..0000000
--- a/crates/servicepoint_binding_c/src/connection.rs
+++ /dev/null
@@ -1,139 +0,0 @@
-//! C functions for interacting with [SPConnection]s
-//!
-//! prefix `sp_connection_`
-
-use std::ffi::{c_char, CStr};
-use std::ptr::{null_mut, NonNull};
-
-use crate::{SPCommand, SPPacket};
-
-/// A connection to the display.
-///
-/// # Examples
-///
-/// ```C
-/// CConnection connection = sp_connection_open("172.23.42.29:2342");
-/// if (connection != NULL)
-/// sp_connection_send_command(connection, sp_command_clear());
-/// ```
-pub struct SPConnection(pub(crate) servicepoint::Connection);
-
-/// Creates a new instance of [SPConnection].
-///
-/// returns: NULL if connection fails, or connected instance
-///
-/// # Panics
-///
-/// - when `host` is null or an invalid host
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - the returned instance is freed in some way, either by using a consuming function or
-/// by explicitly calling `sp_connection_free`.
-#[no_mangle]
-pub unsafe extern "C" fn sp_connection_open(
- host: *const c_char,
-) -> *mut SPConnection {
- assert!(!host.is_null());
- let host = CStr::from_ptr(host).to_str().expect("Bad encoding");
- let connection = match servicepoint::Connection::open(host) {
- Err(_) => return null_mut(),
- Ok(value) => value,
- };
-
- Box::into_raw(Box::new(SPConnection(connection)))
-}
-
-/// Creates a new instance of [SPConnection] for testing that does not actually send anything.
-///
-/// returns: a new instance. Will never return NULL.
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - the returned instance is freed in some way, either by using a consuming function or
-/// by explicitly calling `sp_connection_free`.
-#[no_mangle]
-pub unsafe extern "C" fn sp_connection_fake() -> NonNull {
- let result = Box::new(SPConnection(servicepoint::Connection::Fake));
- NonNull::from(Box::leak(result))
-}
-
-/// Sends a [SPPacket] to the display using the [SPConnection].
-///
-/// The passed `packet` gets consumed.
-///
-/// returns: true in case of success
-///
-/// # Panics
-///
-/// - when `connection` is NULL
-/// - when `packet` is NULL
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `connection` points to a valid instance of [SPConnection]
-/// - `packet` points to a valid instance of [SPPacket]
-/// - `packet` is not used concurrently or after this call
-#[no_mangle]
-pub unsafe extern "C" fn sp_connection_send_packet(
- connection: *const SPConnection,
- packet: *mut SPPacket,
-) -> bool {
- assert!(!connection.is_null());
- assert!(!packet.is_null());
- let packet = Box::from_raw(packet);
- (*connection).0.send((*packet).0).is_ok()
-}
-
-/// Sends a [SPCommand] to the display using the [SPConnection].
-///
-/// The passed `command` gets consumed.
-///
-/// returns: true in case of success
-///
-/// # Panics
-///
-/// - when `connection` is NULL
-/// - when `command` is NULL
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `connection` points to a valid instance of [SPConnection]
-/// - `command` points to a valid instance of [SPPacket]
-/// - `command` is not used concurrently or after this call
-#[no_mangle]
-pub unsafe extern "C" fn sp_connection_send_command(
- connection: *const SPConnection,
- command: *mut SPCommand,
-) -> bool {
- assert!(!connection.is_null());
- assert!(!command.is_null());
- let command = (*Box::from_raw(command)).0;
- (*connection).0.send(command).is_ok()
-}
-
-/// Closes and deallocates a [SPConnection].
-///
-/// # Panics
-///
-/// - when `connection` is NULL
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `connection` points to a valid [SPConnection]
-/// - `connection` is not used concurrently or after this call
-#[no_mangle]
-pub unsafe extern "C" fn sp_connection_free(connection: *mut SPConnection) {
- assert!(!connection.is_null());
- _ = Box::from_raw(connection);
-}
diff --git a/crates/servicepoint_binding_c/src/constants.rs b/crates/servicepoint_binding_c/src/constants.rs
deleted file mode 100644
index 1a268f4..0000000
--- a/crates/servicepoint_binding_c/src/constants.rs
+++ /dev/null
@@ -1,48 +0,0 @@
-//! re-exported constants for use in C
-
-use servicepoint::CompressionCode;
-use std::time::Duration;
-
-/// size of a single tile in one dimension
-pub const SP_TILE_SIZE: usize = 8;
-
-/// Display tile count in the x-direction
-pub const SP_TILE_WIDTH: usize = 56;
-
-/// Display tile count in the y-direction
-pub const SP_TILE_HEIGHT: usize = 20;
-
-/// Display width in pixels
-pub const SP_PIXEL_WIDTH: usize = SP_TILE_WIDTH * SP_TILE_SIZE;
-
-/// Display height in pixels
-pub const SP_PIXEL_HEIGHT: usize = SP_TILE_HEIGHT * SP_TILE_SIZE;
-
-/// pixel count on whole screen
-pub const SP_PIXEL_COUNT: usize = SP_PIXEL_WIDTH * SP_PIXEL_HEIGHT;
-
-/// Actual hardware limit is around 28-29ms/frame. Rounded up for less dropped packets.
-pub const SP_FRAME_PACING_MS: u128 = Duration::from_millis(30).as_millis();
-
-/// Specifies the kind of compression to use.
-#[repr(u16)]
-pub enum SPCompressionCode {
- /// no compression
- Uncompressed = 0x0,
- /// compress using flate2 with zlib header
- Zlib = 0x677a,
- /// compress using bzip2
- Bzip2 = 0x627a,
- /// compress using lzma
- Lzma = 0x6c7a,
- /// compress using Zstandard
- Zstd = 0x7a73,
-}
-
-impl TryFrom for CompressionCode {
- type Error = ();
-
- fn try_from(value: SPCompressionCode) -> Result {
- CompressionCode::try_from(value as u16)
- }
-}
diff --git a/crates/servicepoint_binding_c/src/cp437_grid.rs b/crates/servicepoint_binding_c/src/cp437_grid.rs
deleted file mode 100644
index 9b366c8..0000000
--- a/crates/servicepoint_binding_c/src/cp437_grid.rs
+++ /dev/null
@@ -1,285 +0,0 @@
-//! C functions for interacting with [SPCp437Grid]s
-//!
-//! prefix `sp_cp437_grid_`
-
-use crate::SPByteSlice;
-use servicepoint::{DataRef, Grid};
-use std::ptr::NonNull;
-
-/// A C-wrapper for grid containing codepage 437 characters.
-///
-/// The encoding is currently not enforced.
-///
-/// # Examples
-///
-/// ```C
-/// Cp437Grid grid = sp_cp437_grid_new(4, 3);
-/// sp_cp437_grid_fill(grid, '?');
-/// sp_cp437_grid_set(grid, 0, 0, '!');
-/// sp_cp437_grid_free(grid);
-/// ```
-pub struct SPCp437Grid(pub(crate) servicepoint::Cp437Grid);
-
-impl Clone for SPCp437Grid {
- fn clone(&self) -> Self {
- SPCp437Grid(self.0.clone())
- }
-}
-
-/// Creates a new [SPCp437Grid] with the specified dimensions.
-///
-/// returns: [SPCp437Grid] initialized to 0. Will never return NULL.
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - the returned instance is freed in some way, either by using a consuming function or
-/// by explicitly calling `sp_cp437_grid_free`.
-#[no_mangle]
-pub unsafe extern "C" fn sp_cp437_grid_new(
- width: usize,
- height: usize,
-) -> NonNull {
- let result =
- Box::new(SPCp437Grid(servicepoint::Cp437Grid::new(width, height)));
- NonNull::from(Box::leak(result))
-}
-
-/// Loads a [SPCp437Grid] with the specified dimensions from the provided data.
-///
-/// Will never return NULL.
-///
-/// # Panics
-///
-/// - when `data` is NULL
-/// - when the provided `data_length` does not match `height` and `width`
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `data` points to a valid memory location of at least `data_length`
-/// bytes in size.
-/// - the returned instance is freed in some way, either by using a consuming function or
-/// by explicitly calling `sp_cp437_grid_free`.
-#[no_mangle]
-pub unsafe extern "C" fn sp_cp437_grid_load(
- width: usize,
- height: usize,
- data: *const u8,
- data_length: usize,
-) -> NonNull {
- assert!(data.is_null());
- let data = std::slice::from_raw_parts(data, data_length);
- let result = Box::new(SPCp437Grid(servicepoint::Cp437Grid::load(
- width, height, data,
- )));
- NonNull::from(Box::leak(result))
-}
-
-/// Clones a [SPCp437Grid].
-///
-/// Will never return NULL.
-///
-/// # Panics
-///
-/// - when `cp437_grid` is NULL
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `cp437_grid` points to a valid [SPCp437Grid]
-/// - `cp437_grid` is not written to concurrently
-/// - the returned instance is freed in some way, either by using a consuming function or
-/// by explicitly calling `sp_cp437_grid_free`.
-#[no_mangle]
-pub unsafe extern "C" fn sp_cp437_grid_clone(
- cp437_grid: *const SPCp437Grid,
-) -> NonNull {
- assert!(!cp437_grid.is_null());
- let result = Box::new((*cp437_grid).clone());
- NonNull::from(Box::leak(result))
-}
-
-/// Deallocates a [SPCp437Grid].
-///
-/// # Panics
-///
-/// - when `cp437_grid` is NULL
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `cp437_grid` points to a valid [SPCp437Grid]
-/// - `cp437_grid` is not used concurrently or after cp437_grid call
-/// - `cp437_grid` was not passed to another consuming function, e.g. to create a [SPCommand]
-///
-/// [SPCommand]: [crate::SPCommand]
-#[no_mangle]
-pub unsafe extern "C" fn sp_cp437_grid_free(cp437_grid: *mut SPCp437Grid) {
- assert!(!cp437_grid.is_null());
- _ = Box::from_raw(cp437_grid);
-}
-
-/// Gets the current value at the specified position.
-///
-/// # Arguments
-///
-/// - `cp437_grid`: instance to read from
-/// - `x` and `y`: position of the cell to read
-///
-/// # Panics
-///
-/// - when `cp437_grid` is NULL
-/// - when accessing `x` or `y` out of bounds
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `cp437_grid` points to a valid [SPCp437Grid]
-/// - `cp437_grid` is not written to concurrently
-#[no_mangle]
-pub unsafe extern "C" fn sp_cp437_grid_get(
- cp437_grid: *const SPCp437Grid,
- x: usize,
- y: usize,
-) -> u8 {
- assert!(!cp437_grid.is_null());
- (*cp437_grid).0.get(x, y)
-}
-
-/// Sets the value of the specified position in the [SPCp437Grid].
-///
-/// # Arguments
-///
-/// - `cp437_grid`: instance to write to
-/// - `x` and `y`: position of the cell
-/// - `value`: the value to write to the cell
-///
-/// returns: old value of the cell
-///
-/// # Panics
-///
-/// - when `cp437_grid` is NULL
-/// - when accessing `x` or `y` out of bounds
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `cp437_grid` points to a valid [SPBitVec]
-/// - `cp437_grid` is not written to or read from concurrently
-///
-/// [SPBitVec]: [crate::SPBitVec]
-#[no_mangle]
-pub unsafe extern "C" fn sp_cp437_grid_set(
- cp437_grid: *mut SPCp437Grid,
- x: usize,
- y: usize,
- value: u8,
-) {
- assert!(!cp437_grid.is_null());
- (*cp437_grid).0.set(x, y, value);
-}
-
-/// Sets the value of all cells in the [SPCp437Grid].
-///
-/// # Arguments
-///
-/// - `cp437_grid`: instance to write to
-/// - `value`: the value to set all cells to
-///
-/// # Panics
-///
-/// - when `cp437_grid` is NULL
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `cp437_grid` points to a valid [SPCp437Grid]
-/// - `cp437_grid` is not written to or read from concurrently
-#[no_mangle]
-pub unsafe extern "C" fn sp_cp437_grid_fill(
- cp437_grid: *mut SPCp437Grid,
- value: u8,
-) {
- assert!(!cp437_grid.is_null());
- (*cp437_grid).0.fill(value);
-}
-
-/// Gets the width of the [SPCp437Grid] instance.
-///
-/// # Arguments
-///
-/// - `cp437_grid`: instance to read from
-///
-/// # Panics
-///
-/// - when `cp437_grid` is NULL
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `cp437_grid` points to a valid [SPCp437Grid]
-#[no_mangle]
-pub unsafe extern "C" fn sp_cp437_grid_width(
- cp437_grid: *const SPCp437Grid,
-) -> usize {
- assert!(!cp437_grid.is_null());
- (*cp437_grid).0.width()
-}
-
-/// Gets the height of the [SPCp437Grid] instance.
-///
-/// # Arguments
-///
-/// - `cp437_grid`: instance to read from
-///
-/// # Panics
-///
-/// - when `cp437_grid` is NULL
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `cp437_grid` points to a valid [SPCp437Grid]
-#[no_mangle]
-pub unsafe extern "C" fn sp_cp437_grid_height(
- cp437_grid: *const SPCp437Grid,
-) -> usize {
- assert!(!cp437_grid.is_null());
- (*cp437_grid).0.height()
-}
-
-/// Gets an unsafe reference to the data of the [SPCp437Grid] instance.
-///
-/// Will never return NULL.
-///
-/// # Panics
-///
-/// - when `cp437_grid` is NULL
-///
-/// ## Safety
-///
-/// The caller has to make sure that:
-///
-/// - `cp437_grid` points to a valid [SPCp437Grid]
-/// - the returned memory range is never accessed after the passed [SPCp437Grid] has been freed
-/// - the returned memory range is never accessed concurrently, either via the [SPCp437Grid] or directly
-#[no_mangle]
-pub unsafe extern "C" fn sp_cp437_grid_unsafe_data_ref(
- cp437_grid: *mut SPCp437Grid,
-) -> SPByteSlice {
- let data = (*cp437_grid).0.data_ref_mut();
- SPByteSlice {
- start: NonNull::new(data.as_mut_ptr_range().start).unwrap(),
- length: data.len(),
- }
-}
diff --git a/crates/servicepoint_binding_c/src/lib.rs b/crates/servicepoint_binding_c/src/lib.rs
deleted file mode 100644
index 887fb40..0000000
--- a/crates/servicepoint_binding_c/src/lib.rs
+++ /dev/null
@@ -1,48 +0,0 @@
-//! C API wrapper for the [servicepoint](https://docs.rs/servicepoint/latest/servicepoint/) crate.
-//!
-//! # Examples
-//!
-//! Make sure to check out [this GitHub repo](https://github.com/arfst23/ServicePoint) as well!
-//!
-//! ```C
-//! #include
-//! #include "servicepoint.h"
-//!
-//! int main(void) {
-//! SPConnection *connection = sp_connection_open("172.23.42.29:2342");
-//! if (connection == NULL)
-//! return 1;
-//!
-//! SPBitmap *pixels = sp_bitmap_new(SP_PIXEL_WIDTH, SP_PIXEL_HEIGHT);
-//! sp_bitmap_fill(pixels, true);
-//!
-//! SPCommand *command = sp_command_bitmap_linear_win(0, 0, pixels, Uncompressed);
-//! while (sp_connection_send_command(connection, sp_command_clone(command)));
-//!
-//! sp_command_free(command);
-//! sp_connection_free(connection);
-//! return 0;
-//! }
-//! ```
-
-pub use crate::bitmap::*;
-pub use crate::bitvec::*;
-pub use crate::brightness_grid::*;
-pub use crate::byte_slice::*;
-pub use crate::char_grid::*;
-pub use crate::command::*;
-pub use crate::connection::*;
-pub use crate::constants::*;
-pub use crate::cp437_grid::*;
-pub use crate::packet::*;
-
-mod bitmap;
-mod bitvec;
-mod brightness_grid;
-mod byte_slice;
-mod char_grid;
-mod command;
-mod connection;
-mod constants;
-mod cp437_grid;
-mod packet;
diff --git a/crates/servicepoint_binding_c/src/packet.rs b/crates/servicepoint_binding_c/src/packet.rs
deleted file mode 100644
index 9293a8a..0000000
--- a/crates/servicepoint_binding_c/src/packet.rs
+++ /dev/null
@@ -1,166 +0,0 @@
-//! C functions for interacting with [SPPacket]s
-//!
-//! prefix `sp_packet_`
-
-use std::ptr::{null_mut, NonNull};
-
-use crate::SPCommand;
-
-/// The raw packet
-pub struct SPPacket(pub(crate) servicepoint::Packet);
-
-/// Turns a [SPCommand] into a [SPPacket].
-/// The [SPCommand] gets consumed.
-///
-/// Will never return NULL.
-///
-/// # Panics
-///
-/// - when `command` is NULL
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - [SPCommand] points to a valid instance of [SPCommand]
-/// - [SPCommand] is not used concurrently or after this call
-/// - the returned [SPPacket] instance is freed in some way, either by using a consuming function or
-/// by explicitly calling `sp_packet_free`.
-#[no_mangle]
-pub unsafe extern "C" fn sp_packet_from_command(
- command: *mut SPCommand,
-) -> NonNull {
- assert!(!command.is_null());
- let command = *Box::from_raw(command);
- let result = Box::new(SPPacket(command.0.into()));
- NonNull::from(Box::leak(result))
-}
-
-/// Tries to load a [SPPacket] from the passed array with the specified length.
-///
-/// returns: NULL in case of an error, pointer to the allocated packet otherwise
-///
-/// # Panics
-///
-/// - when `data` is NULL
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `data` points to a valid memory region of at least `length` bytes
-/// - `data` is not written to concurrently
-/// - the returned [SPPacket] instance is freed in some way, either by using a consuming function or
-/// by explicitly calling `sp_packet_free`.
-#[no_mangle]
-pub unsafe extern "C" fn sp_packet_try_load(
- data: *const u8,
- length: usize,
-) -> *mut SPPacket {
- assert!(!data.is_null());
- let data = std::slice::from_raw_parts(data, length);
- match servicepoint::Packet::try_from(data) {
- Err(_) => null_mut(),
- Ok(packet) => Box::into_raw(Box::new(SPPacket(packet))),
- }
-}
-
-/// Creates a raw [SPPacket] from parts.
-///
-/// # Arguments
-///
-/// - `command_code` specifies which command this packet contains
-/// - `a`, `b`, `c` and `d` are command-specific header values
-/// - `payload` is the optional data that is part of the command
-/// - `payload_len` is the size of the payload
-///
-/// returns: new instance. Will never return null.
-///
-/// # Panics
-///
-/// - when `payload` is null, but `payload_len` is not zero
-/// - when `payload_len` is zero, but `payload` is nonnull
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `payload` points to a valid memory region of at least `payload_len` bytes
-/// - `payload` is not written to concurrently
-/// - the returned [SPPacket] instance is freed in some way, either by using a consuming function or
-/// by explicitly calling [sp_packet_free].
-#[no_mangle]
-pub unsafe extern "C" fn sp_packet_from_parts(
- command_code: u16,
- a: u16,
- b: u16,
- c: u16,
- d: u16,
- payload: *const u8,
- payload_len: usize,
-) -> NonNull {
- assert_eq!(payload.is_null(), payload_len == 0);
-
- let payload = if payload.is_null() {
- vec![]
- } else {
- let payload = std::slice::from_raw_parts(payload, payload_len);
- Vec::from(payload)
- };
-
- let packet = servicepoint::Packet {
- header: servicepoint::Header {
- command_code,
- a,
- b,
- c,
- d,
- },
- payload,
- };
- let result = Box::new(SPPacket(packet));
- NonNull::from(Box::leak(result))
-}
-
-/// Clones a [SPPacket].
-///
-/// Will never return NULL.
-///
-/// # Panics
-///
-/// - when `packet` is NULL
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `packet` points to a valid [SPPacket]
-/// - `packet` is not written to concurrently
-/// - the returned instance is freed in some way, either by using a consuming function or
-/// by explicitly calling `sp_packet_free`.
-#[no_mangle]
-pub unsafe extern "C" fn sp_packet_clone(
- packet: *const SPPacket,
-) -> NonNull {
- assert!(!packet.is_null());
- let result = Box::new(SPPacket((*packet).0.clone()));
- NonNull::from(Box::leak(result))
-}
-
-/// Deallocates a [SPPacket].
-///
-/// # Panics
-///
-/// - when `packet` is NULL
-///
-/// # Safety
-///
-/// The caller has to make sure that:
-///
-/// - `packet` points to a valid [SPPacket]
-/// - `packet` is not used concurrently or after this call
-#[no_mangle]
-pub unsafe extern "C" fn sp_packet_free(packet: *mut SPPacket) {
- assert!(!packet.is_null());
- _ = Box::from_raw(packet)
-}
diff --git a/crates/servicepoint_binding_uniffi/Cargo.toml b/crates/servicepoint_binding_uniffi/Cargo.toml
deleted file mode 100644
index 0af1af9..0000000
--- a/crates/servicepoint_binding_uniffi/Cargo.toml
+++ /dev/null
@@ -1,61 +0,0 @@
-[package]
-name = "servicepoint_binding_uniffi"
-version.workspace = true
-publish = false
-edition = "2021"
-license = "GPL-3.0-or-later"
-description = "C bindings for the servicepoint crate."
-homepage = "https://docs.rs/crate/servicepoint_binding_c"
-repository = "https://git.berlin.ccc.de/servicepoint/servicepoint"
-#readme = "README.md"
-keywords = ["cccb", "cccb-servicepoint", "uniffi"]
-
-[lib]
-crate-type = ["cdylib"]
-
-[build-dependencies]
-uniffi = { version = "0.25.3", features = ["build"] }
-
-[dependencies]
-uniffi = { version = "0.25.3" }
-thiserror.workspace = true
-
-[dependencies.servicepoint]
-version = "0.13.1"
-path = "../servicepoint"
-features = ["all_compressions"]
-
-[dependencies.uniffi-bindgen-cs]
-git = "https://github.com/NordSecurity/uniffi-bindgen-cs"
-# tag="v0.8.3+v0.25.0"
-rev = "f68639fbc720b50ebe561ba75c66c84dc456bdce"
-optional = true
-
-[dependencies.uniffi-bindgen-go]
-git = "https://github.com/NordSecurity/uniffi-bindgen-go.git"
-# tag = "0.2.2+v0.25.0"
-rev = "ba23bab72f1a9bcc39ce81924d3d9265598e017c"
-optional = true
-
-[lints]
-#workspace = true
-
-[package.metadata.docs.rs]
-all-features = true
-
-[[bin]]
-name = "uniffi-bindgen"
-required-features = ["uniffi/cli"]
-
-[[bin]]
-name = "uniffi-bindgen-cs"
-required-features = ["cs"]
-
-[[bin]]
-name = "uniffi-bindgen-go"
-required-features = ["go"]
-
-[features]
-default = []
-cs = ["dep:uniffi-bindgen-cs"]
-go = ["dep:uniffi-bindgen-go"]
diff --git a/crates/servicepoint_binding_uniffi/README.md b/crates/servicepoint_binding_uniffi/README.md
deleted file mode 100644
index 27d05ed..0000000
--- a/crates/servicepoint_binding_uniffi/README.md
+++ /dev/null
@@ -1,90 +0,0 @@
-# ServicePoint
-
-In [CCCB](https://berlin.ccc.de/), there is a big pixel matrix hanging on the wall. It is called "Service Point
-Display" or "Airport Display".
-
-This crate contains bindings for multiple programming languages, enabling non-rust-developers to use the library.
-
-Also take a look at the main project [README](https://git.berlin.ccc.de/servicepoint/servicepoint/src/branch/main/README.md) for more
-information.
-
-## Note on stability
-
-This library is still in early development.
-You can absolutely use it, and it works, but expect minor breaking changes with every version bump.
-
-## Notes on differences to rust library
-
-- Performance will not be as good as the rust version:
- - most objects are reference counted.
- - objects with mutating methods will also have a MRSW lock
-- You will not get rust backtraces in release builds of the native code
-- Panic messages will work (PanicException)
-
-## Supported languages
-
-| Language | Support level | Notes |
-|-----------|---------------|-------------------------------------------------------------------------------------------------|
-| .NET (C#) | Full | see dedicated section |
-| Ruby | Working | LD_LIBRARY_PATH has to be set, see example project |
-| Python | Tested once | Required project file not included. The shared library will be loaded from the script location. |
-| Go | untested | |
-| Kotlin | untested | |
-| Swift | untested | |
-
-## Installation
-
-Including this repository as a submodule and building from source is the recommended way of using the library.
-
-```bash
-git submodule add https://git.berlin.ccc.de/servicepoint/servicepoint.git
-git commit -m "add servicepoint submodule"
-```
-
-Run `generate-bindings.sh` to regenerate all bindings. This will also build `libservicepoint.so` (or equivalent on your
-platform).
-
-For languages not fully supported, there will be no project file for the library, just the naked source file(s).
-If you successfully use a language, please open an issue or PR to add the missing ones.
-
-## .NET (C#)
-
-This is the best supported language.
-
-F# is not tested. If there are usability or functionality problems, please open an issue.
-
-Currently, the project file is hard-coded for Linux and will need tweaks for other platforms (e.g. `.dylib` instead of `.so`).
-
-You do not have to compile or copy the rust crate manually, as building `ServicePoint.csproj` also builds it.
-
-### Example
-
-```csharp
-using System.Threading;
-using ServicePoint;
-
-var connection = new Connection("127.0.0.1:2342");
-connection.Send(Command.Clear());
-
-connection.Send(Command.Brightness(5));
-
-var pixels = Bitmap.NewMaxSized();
-for (ulong offset = 0; offset < ulong.MaxValue; offset++)
-{
- pixels.Fill(false);
-
- for (ulong y = 0; y < pixels.Height(); y++)
- pixels.Set((y + offset) % pixels.Width(), y, true);
-
- connection.Send(Command.BitmapLinearWin(0, 0, pixels));
- Thread.Sleep(14);
-}
-```
-
-A full example including project files is available as part of this crate.
-
-### Why is there no NuGet-Package?
-
-NuGet packages are not a good way to distribute native
-binaries ([relevant issue](https://github.com/dotnet/sdk/issues/33845)).
-Because of that, there is no NuGet package you can use directly.
diff --git a/crates/servicepoint_binding_uniffi/generate-bindings.sh b/crates/servicepoint_binding_uniffi/generate-bindings.sh
deleted file mode 100755
index bfb571c..0000000
--- a/crates/servicepoint_binding_uniffi/generate-bindings.sh
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/usr/bin/env bash
-set -e
-
-cargo build --release
-
-SCRIPT_PATH="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"
-TARGET_PATH="$(realpath "$SCRIPT_PATH"/../../target/release)"
-SERVICEPOINT_SO="$TARGET_PATH/libservicepoint_binding_uniffi.so"
-LIBRARIES_PATH="$SCRIPT_PATH/libraries"
-
-echo "Source: $SERVICEPOINT_SO"
-echo "Output: $LIBRARIES_PATH"
-
-BINDGEN="cargo run --features=uniffi/cli --bin uniffi-bindgen -- "
-BINDGEN_CS="cargo run --features=cs --bin uniffi-bindgen-cs -- "
-BINDGEN_GO="cargo run --features=go --bin uniffi-bindgen-go -- "
-COMMON_ARGS="--library $SERVICEPOINT_SO"
-
-${BINDGEN} generate $COMMON_ARGS --language python --out-dir "$LIBRARIES_PATH/python"
-${BINDGEN} generate $COMMON_ARGS --language kotlin --out-dir "$LIBRARIES_PATH/kotlin"
-${BINDGEN} generate $COMMON_ARGS --language swift --out-dir "$LIBRARIES_PATH/swift"
-${BINDGEN} generate $COMMON_ARGS --language ruby --out-dir "$LIBRARIES_PATH/ruby/lib"
-${BINDGEN_CS} $COMMON_ARGS --out-dir "$LIBRARIES_PATH/csharp/ServicePoint"
-${BINDGEN_GO} $COMMON_ARGS --out-dir "$LIBRARIES_PATH/go/"
diff --git a/crates/servicepoint_binding_uniffi/libraries/.gitignore b/crates/servicepoint_binding_uniffi/libraries/.gitignore
deleted file mode 100644
index a875c72..0000000
--- a/crates/servicepoint_binding_uniffi/libraries/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-go
-kotlin
-python
-swift
\ No newline at end of file
diff --git a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Example/.gitignore b/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Example/.gitignore
deleted file mode 100644
index 1746e32..0000000
--- a/crates/servicepoint_binding_uniffi/libraries/csharp/ServicePoint.Example/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-bin
-obj
diff --git a/crates/servicepoint_binding_uniffi/libraries/ruby/example/Gemfile b/crates/servicepoint_binding_uniffi/libraries/ruby/example/Gemfile
deleted file mode 100644
index f44ed21..0000000
--- a/crates/servicepoint_binding_uniffi/libraries/ruby/example/Gemfile
+++ /dev/null
@@ -1,3 +0,0 @@
-source 'https://rubygems.org'
-
-gem 'servicepoint', path: '..'
diff --git a/crates/servicepoint_binding_uniffi/libraries/ruby/example/Gemfile.lock b/crates/servicepoint_binding_uniffi/libraries/ruby/example/Gemfile.lock
deleted file mode 100644
index 2b6d5f7..0000000
--- a/crates/servicepoint_binding_uniffi/libraries/ruby/example/Gemfile.lock
+++ /dev/null
@@ -1,19 +0,0 @@
-PATH
- remote: ..
- specs:
- servicepoint (0.0.0)
- ffi
-
-GEM
- remote: https://rubygems.org/
- specs:
- ffi (1.17.0-x86_64-linux-gnu)
-
-PLATFORMS
- x86_64-linux
-
-DEPENDENCIES
- servicepoint!
-
-BUNDLED WITH
- 2.3.27
diff --git a/crates/servicepoint_binding_uniffi/libraries/ruby/example/example.rb b/crates/servicepoint_binding_uniffi/libraries/ruby/example/example.rb
deleted file mode 100644
index 8d212f2..0000000
--- a/crates/servicepoint_binding_uniffi/libraries/ruby/example/example.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-require_relative "../lib/servicepoint_binding_uniffi"
-
-include ServicepointBindingUniffi
-
-connection = Connection.new("172.23.42.29:2342")
-
-pixels = Bitmap.new_max_sized
-x_offset = 0
-loop do
-
- pixels.fill(false)
-
- (0..((pixels.height) -1)).each do |y|
- pixels.set((y + x_offset) % pixels.width, y, true);
- end
-
- command = Command.bitmap_linear_win(0, 0, pixels, CompressionCode::UNCOMPRESSED)
-
- connection.send(command)
- sleep 0.0005
-
- x_offset += 1
-end
-
-
diff --git a/crates/servicepoint_binding_uniffi/libraries/ruby/example/example.sh b/crates/servicepoint_binding_uniffi/libraries/ruby/example/example.sh
deleted file mode 100755
index 25ed29e..0000000
--- a/crates/servicepoint_binding_uniffi/libraries/ruby/example/example.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env bash
-
-LD_LIBRARY_PATH="../../../../../target/release:$LD_LIBRARY_PATH" ruby example.rb
diff --git a/crates/servicepoint_binding_uniffi/libraries/ruby/lib/servicepoint_binding_uniffi.rb b/crates/servicepoint_binding_uniffi/libraries/ruby/lib/servicepoint_binding_uniffi.rb
deleted file mode 100644
index d097798..0000000
--- a/crates/servicepoint_binding_uniffi/libraries/ruby/lib/servicepoint_binding_uniffi.rb
+++ /dev/null
@@ -1,2003 +0,0 @@
-# This file was autogenerated by some hot garbage in the `uniffi` crate.
-# Trust me, you don't want to mess with it!
-
-# Common helper code.
-#
-# Ideally this would live in a separate .rb file where it can be unittested etc
-# in isolation, and perhaps even published as a re-useable package.
-#
-# However, it's important that the details of how this helper code works (e.g. the
-# way that different builtin types are passed across the FFI) exactly match what's
-# expected by the rust code on the other side of the interface. In practice right
-# now that means coming from the exact some version of `uniffi` that was used to
-# compile the rust component. The easiest way to ensure this is to bundle the Ruby
-# helpers directly inline like we're doing here.
-
-require 'ffi'
-
-
-module ServicepointBindingUniffi
- def self.uniffi_in_range(i, type_name, min, max)
- raise TypeError, "no implicit conversion of #{i} into Integer" unless i.respond_to?(:to_int)
- i = i.to_int
- raise RangeError, "#{type_name} requires #{min} <= value < #{max}" unless (min <= i && i < max)
- i
-end
-
-def self.uniffi_utf8(v)
- raise TypeError, "no implicit conversion of #{v} into String" unless v.respond_to?(:to_str)
- v = v.to_str.encode(Encoding::UTF_8)
- raise Encoding::InvalidByteSequenceError, "not a valid UTF-8 encoded string" unless v.valid_encoding?
- v
-end
-
-def self.uniffi_bytes(v)
- raise TypeError, "no implicit conversion of #{v} into String" unless v.respond_to?(:to_str)
- v.to_str
-end
-
- class RustBuffer < FFI::Struct
- layout :capacity, :int32,
- :len, :int32,
- :data, :pointer
-
- def self.alloc(size)
- return ServicepointBindingUniffi.rust_call(:ffi_servicepoint_binding_uniffi_rustbuffer_alloc, size)
- end
-
- def self.reserve(rbuf, additional)
- return ServicepointBindingUniffi.rust_call(:ffi_servicepoint_binding_uniffi_rustbuffer_reserve, rbuf, additional)
- end
-
- def free
- ServicepointBindingUniffi.rust_call(:ffi_servicepoint_binding_uniffi_rustbuffer_free, self)
- end
-
- def capacity
- self[:capacity]
- end
-
- def len
- self[:len]
- end
-
- def len=(value)
- self[:len] = value
- end
-
- def data
- self[:data]
- end
-
- def to_s
- "RustBuffer(capacity=#{capacity}, len=#{len}, data=#{data.read_bytes len})"
- end
-
- # The allocated buffer will be automatically freed if an error occurs, ensuring that
- # we don't accidentally leak it.
- def self.allocWithBuilder
- builder = RustBufferBuilder.new
-
- begin
- yield builder
- rescue => e
- builder.discard
- raise e
- end
- end
-
- # The RustBuffer will be freed once the context-manager exits, ensuring that we don't
- # leak it even if an error occurs.
- def consumeWithStream
- stream = RustBufferStream.new self
-
- yield stream
-
- raise RuntimeError, 'junk data left in buffer after consuming' if stream.remaining != 0
- ensure
- free
- end# The primitive String type.
-
- def self.allocFromString(value)
- RustBuffer.allocWithBuilder do |builder|
- builder.write value.encode('utf-8')
- return builder.finalize
- end
- end
-
- def consumeIntoString
- consumeWithStream do |stream|
- return stream.read(stream.remaining).force_encoding(Encoding::UTF_8)
- end
- end
-
- # The primitive Bytes type.
-
- def self.allocFromBytes(value)
- RustBuffer.allocWithBuilder do |builder|
- builder.write_Bytes(value)
- return builder.finalize
- end
- end
-
- def consumeIntoBytes
- consumeWithStream do |stream|
- return stream.readBytes
- end
- end
-
- # The Record type Constants.
-
- def self.alloc_from_TypeConstants(v)
- RustBuffer.allocWithBuilder do |builder|
- builder.write_TypeConstants(v)
- return builder.finalize
- end
- end
-
- def consumeIntoTypeConstants
- consumeWithStream do |stream|
- return stream.readTypeConstants
- end
- end
-
-
-
- # The Enum type CompressionCode.
-
- def self.alloc_from_TypeCompressionCode(v)
- RustBuffer.allocWithBuilder do |builder|
- builder.write_TypeCompressionCode(v)
- return builder.finalize
- end
- end
-
- def consumeIntoTypeCompressionCode
- consumeWithStream do |stream|
- return stream.readTypeCompressionCode
- end
- end
-
-
-
-
-
-end
-
-module UniFFILib
- class ForeignBytes < FFI::Struct
- layout :len, :int32,
- :data, :pointer
-
- def len
- self[:len]
- end
-
- def data
- self[:data]
- end
-
- def to_s
- "ForeignBytes(len=#{len}, data=#{data.read_bytes(len)})"
- end
- end
-end
-
-private_constant :UniFFILib
-
-# Helper for structured reading of values from a RustBuffer.
-class RustBufferStream
-
- def initialize(rbuf)
- @rbuf = rbuf
- @offset = 0
- end
-
- def remaining
- @rbuf.len - @offset
- end
-
- def read(size)
- raise InternalError, 'read past end of rust buffer' if @offset + size > @rbuf.len
-
- data = @rbuf.data.get_bytes @offset, size
-
- @offset += size
-
- data
- end
-
- def readU8
- unpack_from 1, 'c'
- end
-
- def readU64
- unpack_from 8, 'Q>'
- end
-
- def readBool
- v = unpack_from 1, 'c'
-
- return false if v == 0
- return true if v == 1
-
- raise InternalError, 'Unexpected byte for Boolean type'
- end
-
- def readString
- size = unpack_from 4, 'l>'
-
- raise InternalError, 'Unexpected negative string length' if size.negative?
-
- read(size).force_encoding(Encoding::UTF_8)
- end
-
- def readBytes
- size = unpack_from 4, 'l>'
-
- raise InternalError, 'Unexpected negative byte string length' if size.negative?
-
- read(size).force_encoding(Encoding::BINARY)
- end
-
- # The Object type BitVec.
-
- def readTypeBitVec
- pointer = FFI::Pointer.new unpack_from 8, 'Q>'
- return BitVec._uniffi_allocate(pointer)
- end
-
- # The Object type Bitmap.
-
- def readTypeBitmap
- pointer = FFI::Pointer.new unpack_from 8, 'Q>'
- return Bitmap._uniffi_allocate(pointer)
- end
-
- # The Object type BrightnessGrid.
-
- def readTypeBrightnessGrid
- pointer = FFI::Pointer.new unpack_from 8, 'Q>'
- return BrightnessGrid._uniffi_allocate(pointer)
- end
-
- # The Object type CharGrid.
-
- def readTypeCharGrid
- pointer = FFI::Pointer.new unpack_from 8, 'Q>'
- return CharGrid._uniffi_allocate(pointer)
- end
-
- # The Object type Command.
-
- def readTypeCommand
- pointer = FFI::Pointer.new unpack_from 8, 'Q>'
- return Command._uniffi_allocate(pointer)
- end
-
- # The Object type Connection.
-
- def readTypeConnection
- pointer = FFI::Pointer.new unpack_from 8, 'Q>'
- return Connection._uniffi_allocate(pointer)
- end
-
- # The Object type Cp437Grid.
-
- def readTypeCp437Grid
- pointer = FFI::Pointer.new unpack_from 8, 'Q>'
- return Cp437Grid._uniffi_allocate(pointer)
- end
-
- # The Record type Constants.
-
- def readTypeConstants
- Constants.new(
- readU64,
- readU64,
- readU64,
- readU64,
- readU64,
- readU64
- )
- end
-
-
-
-
-
- # The Error type CharGridError
-
- def readTypeCharGridError
- variant = unpack_from 4, 'l>'
-
- if variant == 1
- return CharGridError::StringNotOneChar.new(
- readString()
- )
- end
- if variant == 2
- return CharGridError::InvalidSeriesLength.new(
- readU64(),
- readU64()
- )
- end
- if variant == 3
- return CharGridError::OutOfBounds.new(
- readU64(),
- readU64()
- )
- end
-
- raise InternalError, 'Unexpected variant tag for TypeCharGridError'
- end
-
-
-
-
- # The Enum type CompressionCode.
-
- def readTypeCompressionCode
- variant = unpack_from 4, 'l>'
-
- if variant == 1
- return CompressionCode::UNCOMPRESSED
- end
- if variant == 2
- return CompressionCode::ZLIB
- end
- if variant == 3
- return CompressionCode::BZIP2
- end
- if variant == 4
- return CompressionCode::LZMA
- end
- if variant == 5
- return CompressionCode::ZSTD
- end
-
- raise InternalError, 'Unexpected variant tag for TypeCompressionCode'
- end
-
-
-
-
-
-
-
- # The Error type ServicePointError
-
- def readTypeServicePointError
- variant = unpack_from 4, 'l>'
-
- if variant == 1
- return ServicePointError::IoError.new(
- readString()
- )
- end
- if variant == 2
- return ServicePointError::InvalidBrightness.new(
- readU8()
- )
- end
-
- raise InternalError, 'Unexpected variant tag for TypeServicePointError'
- end
-
-
-
-
- def unpack_from(size, format)
- raise InternalError, 'read past end of rust buffer' if @offset + size > @rbuf.len
-
- value = @rbuf.data.get_bytes(@offset, size).unpack format
-
- @offset += size
-
- # TODO: verify this
- raise 'more than one element!!!' if value.size > 1
-
- value[0]
- end
-end
-
-private_constant :RustBufferStream
-
-# Helper for structured writing of values into a RustBuffer.
-class RustBufferBuilder
- def initialize
- @rust_buf = RustBuffer.alloc 16
- @rust_buf.len = 0
- end
-
- def finalize
- rbuf = @rust_buf
-
- @rust_buf = nil
-
- rbuf
- end
-
- def discard
- return if @rust_buf.nil?
-
- rbuf = finalize
- rbuf.free
- end
-
- def write(value)
- reserve(value.bytes.size) do
- @rust_buf.data.put_array_of_char @rust_buf.len, value.bytes
- end
- end
-
- def write_U8(v)
- v = ServicepointBindingUniffi::uniffi_in_range(v, "u8", 0, 2**8)
- pack_into(1, 'c', v)
- end
-
- def write_U64(v)
- v = ServicepointBindingUniffi::uniffi_in_range(v, "u64", 0, 2**64)
- pack_into(8, 'Q>', v)
- end
-
- def write_Bool(v)
- pack_into(1, 'c', v ? 1 : 0)
- end
-
- def write_String(v)
- v = ServicepointBindingUniffi::uniffi_utf8(v)
- pack_into 4, 'l>', v.bytes.size
- write v
- end
-
- def write_Bytes(v)
- v = ServicepointBindingUniffi::uniffi_bytes(v)
- pack_into 4, 'l>', v.bytes.size
- write v
- end
-
- # The Object type BitVec.
-
- def write_TypeBitVec(obj)
- pointer = BitVec._uniffi_lower obj
- pack_into(8, 'Q>', pointer.address)
- end
-
- # The Object type Bitmap.
-
- def write_TypeBitmap(obj)
- pointer = Bitmap._uniffi_lower obj
- pack_into(8, 'Q>', pointer.address)
- end
-
- # The Object type BrightnessGrid.
-
- def write_TypeBrightnessGrid(obj)
- pointer = BrightnessGrid._uniffi_lower obj
- pack_into(8, 'Q>', pointer.address)
- end
-
- # The Object type CharGrid.
-
- def write_TypeCharGrid(obj)
- pointer = CharGrid._uniffi_lower obj
- pack_into(8, 'Q>', pointer.address)
- end
-
- # The Object type Command.
-
- def write_TypeCommand(obj)
- pointer = Command._uniffi_lower obj
- pack_into(8, 'Q>', pointer.address)
- end
-
- # The Object type Connection.
-
- def write_TypeConnection(obj)
- pointer = Connection._uniffi_lower obj
- pack_into(8, 'Q>', pointer.address)
- end
-
- # The Object type Cp437Grid.
-
- def write_TypeCp437Grid(obj)
- pointer = Cp437Grid._uniffi_lower obj
- pack_into(8, 'Q>', pointer.address)
- end
-
- # The Record type Constants.
-
- def write_TypeConstants(v)
- self.write_U64(v.tile_size)
- self.write_U64(v.tile_width)
- self.write_U64(v.tile_height)
- self.write_U64(v.pixel_width)
- self.write_U64(v.pixel_height)
- self.write_U64(v.pixel_count)
- end
-
-
-
- # The Enum type CompressionCode.
-
- def write_TypeCompressionCode(v)
- pack_into(4, 'l>', v)
- end
-
-
-
-
-
-
- private
-
- def reserve(num_bytes)
- if @rust_buf.len + num_bytes > @rust_buf.capacity
- @rust_buf = RustBuffer.reserve(@rust_buf, num_bytes)
- end
-
- yield
-
- @rust_buf.len += num_bytes
- end
-
- def pack_into(size, format, value)
- reserve(size) do
- @rust_buf.data.put_array_of_char @rust_buf.len, [value].pack(format).bytes
- end
- end
-end
-
-private_constant :RustBufferBuilder
-
- # Error definitions
- class RustCallStatus < FFI::Struct
- layout :code, :int8,
- :error_buf, RustBuffer
-
- def code
- self[:code]
- end
-
- def error_buf
- self[:error_buf]
- end
-
- def to_s
- "RustCallStatus(code=#{self[:code]})"
- end
-end
-
-# These match the values from the uniffi::rustcalls module
-CALL_SUCCESS = 0
-CALL_ERROR = 1
-CALL_PANIC = 2
-
-
-module CharGridError
- class StringNotOneChar < StandardError
- def initialize(value)
- @value = value
- super()
- end
-
- attr_reader :value
-
-
- def to_s
- "#{self.class.name}(value=#{@value.inspect})"
- end
- end
- class InvalidSeriesLength < StandardError
- def initialize(actual, expected)
- @actual = actual
- @expected = expected
- super()
- end
-
- attr_reader :actual, :expected
-
-
- def to_s
- "#{self.class.name}(actual=#{@actual.inspect}, expected=#{@expected.inspect})"
- end
- end
- class OutOfBounds < StandardError
- def initialize(index, size)
- @index = index
- @size = size
- super()
- end
-
- attr_reader :index, :size
-
-
- def to_s
- "#{self.class.name}(index=#{@index.inspect}, size=#{@size.inspect})"
- end
- end
-
-end
-
-
-
-
-module ServicePointError
- class IoError < StandardError
- def initialize(error)
- @error = error
- super()
- end
-
- attr_reader :error
-
-
- def to_s
- "#{self.class.name}(error=#{@error.inspect})"
- end
- end
- class InvalidBrightness < StandardError
- def initialize(value)
- @value = value
- super()
- end
-
- attr_reader :value
-
-
- def to_s
- "#{self.class.name}(value=#{@value.inspect})"
- end
- end
-
-end
-
-
-# Map error modules to the RustBuffer method name that reads them
-ERROR_MODULE_TO_READER_METHOD = {
-
- CharGridError => :readTypeCharGridError,
-
-
-
- ServicePointError => :readTypeServicePointError,
-
-}
-
-private_constant :ERROR_MODULE_TO_READER_METHOD, :CALL_SUCCESS, :CALL_ERROR, :CALL_PANIC,
- :RustCallStatus
-
-def self.consume_buffer_into_error(error_module, rust_buffer)
- rust_buffer.consumeWithStream do |stream|
- reader_method = ERROR_MODULE_TO_READER_METHOD[error_module]
- return stream.send(reader_method)
- end
-end
-
-class InternalError < StandardError
-end
-
-def self.rust_call(fn_name, *args)
- # Call a rust function
- rust_call_with_error(nil, fn_name, *args)
-end
-
-def self.rust_call_with_error(error_module, fn_name, *args)
- # Call a rust function and handle errors
- #
- # Use this when the rust function returns a Result<>. error_module must be the error_module that corresponds to that Result.
-
-
- # Note: RustCallStatus.new zeroes out the struct, which is exactly what we
- # want to pass to Rust (code=0, error_buf=RustBuffer(len=0, capacity=0,
- # data=NULL))
- status = RustCallStatus.new
- args << status
-
- result = UniFFILib.public_send(fn_name, *args)
-
- case status.code
- when CALL_SUCCESS
- result
- when CALL_ERROR
- if error_module.nil?
- status.error_buf.free
- raise InternalError, "CALL_ERROR with no error_module set"
- else
- raise consume_buffer_into_error(error_module, status.error_buf)
- end
- when CALL_PANIC
- # When the rust code sees a panic, it tries to construct a RustBuffer
- # with the message. But if that code panics, then it just sends back
- # an empty buffer.
- if status.error_buf.len > 0
- raise InternalError, status.error_buf.consumeIntoString()
- else
- raise InternalError, "Rust panic"
- end
- else
- raise InternalError, "Unknown call status: #{status.code}"
- end
-end
-
-private_class_method :consume_buffer_into_error
-
- # This is how we find and load the dynamic library provided by the component.
-# For now we just look it up by name.
-module UniFFILib
- extend FFI::Library
-
-
- ffi_lib 'servicepoint_binding_uniffi'
-
-
- attach_function :uniffi_servicepoint_binding_uniffi_fn_free_bitvec,
- [:pointer, RustCallStatus.by_ref],
- :void
- attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_bitvec_clone,
- [:pointer, RustCallStatus.by_ref],
- :pointer
- attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_bitvec_load,
- [RustBuffer.by_value, RustCallStatus.by_ref],
- :pointer
- attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_bitvec_new,
- [:uint64, RustCallStatus.by_ref],
- :pointer
- attach_function :uniffi_servicepoint_binding_uniffi_fn_method_bitvec_copy_raw,
- [:pointer, RustCallStatus.by_ref],
- RustBuffer.by_value
- attach_function :uniffi_servicepoint_binding_uniffi_fn_method_bitvec_equals,
- [:pointer, :pointer, RustCallStatus.by_ref],
- :int8
- attach_function :uniffi_servicepoint_binding_uniffi_fn_method_bitvec_fill,
- [:pointer, :int8, RustCallStatus.by_ref],
- :void
- attach_function :uniffi_servicepoint_binding_uniffi_fn_method_bitvec_get,
- [:pointer, :uint64, RustCallStatus.by_ref],
- :int8
- attach_function :uniffi_servicepoint_binding_uniffi_fn_method_bitvec_len,
- [:pointer, RustCallStatus.by_ref],
- :uint64
- attach_function :uniffi_servicepoint_binding_uniffi_fn_method_bitvec_set,
- [:pointer, :uint64, :int8, RustCallStatus.by_ref],
- :void
- attach_function :uniffi_servicepoint_binding_uniffi_fn_free_bitmap,
- [:pointer, RustCallStatus.by_ref],
- :void
- attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_bitmap_clone,
- [:pointer, RustCallStatus.by_ref],
- :pointer
- attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_bitmap_load,
- [:uint64, :uint64, RustBuffer.by_value, RustCallStatus.by_ref],
- :pointer
- attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_bitmap_new,
- [:uint64, :uint64, RustCallStatus.by_ref],
- :pointer
- attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_bitmap_new_max_sized,
- [RustCallStatus.by_ref],
- :pointer
- attach_function :uniffi_servicepoint_binding_uniffi_fn_method_bitmap_copy_raw,
- [:pointer, RustCallStatus.by_ref],
- RustBuffer.by_value
- attach_function :uniffi_servicepoint_binding_uniffi_fn_method_bitmap_equals,
- [:pointer, :pointer, RustCallStatus.by_ref],
- :int8
- attach_function :uniffi_servicepoint_binding_uniffi_fn_method_bitmap_fill,
- [:pointer, :int8, RustCallStatus.by_ref],
- :void
- attach_function :uniffi_servicepoint_binding_uniffi_fn_method_bitmap_get,
- [:pointer, :uint64, :uint64, RustCallStatus.by_ref],
- :int8
- attach_function :uniffi_servicepoint_binding_uniffi_fn_method_bitmap_height,
- [:pointer, RustCallStatus.by_ref],
- :uint64
- attach_function :uniffi_servicepoint_binding_uniffi_fn_method_bitmap_set,
- [:pointer, :uint64, :uint64, :int8, RustCallStatus.by_ref],
- :void
- attach_function :uniffi_servicepoint_binding_uniffi_fn_method_bitmap_width,
- [:pointer, RustCallStatus.by_ref],
- :uint64
- attach_function :uniffi_servicepoint_binding_uniffi_fn_free_brightnessgrid,
- [:pointer, RustCallStatus.by_ref],
- :void
- attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_brightnessgrid_clone,
- [:pointer, RustCallStatus.by_ref],
- :pointer
- attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_brightnessgrid_load,
- [:uint64, :uint64, RustBuffer.by_value, RustCallStatus.by_ref],
- :pointer
- attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_brightnessgrid_new,
- [:uint64, :uint64, RustCallStatus.by_ref],
- :pointer
- attach_function :uniffi_servicepoint_binding_uniffi_fn_method_brightnessgrid_copy_raw,
- [:pointer, RustCallStatus.by_ref],
- RustBuffer.by_value
- attach_function :uniffi_servicepoint_binding_uniffi_fn_method_brightnessgrid_equals,
- [:pointer, :pointer, RustCallStatus.by_ref],
- :int8
- attach_function :uniffi_servicepoint_binding_uniffi_fn_method_brightnessgrid_fill,
- [:pointer, :uint8, RustCallStatus.by_ref],
- :void
- attach_function :uniffi_servicepoint_binding_uniffi_fn_method_brightnessgrid_get,
- [:pointer, :uint64, :uint64, RustCallStatus.by_ref],
- :uint8
- attach_function :uniffi_servicepoint_binding_uniffi_fn_method_brightnessgrid_height,
- [:pointer, RustCallStatus.by_ref],
- :uint64
- attach_function :uniffi_servicepoint_binding_uniffi_fn_method_brightnessgrid_set,
- [:pointer, :uint64, :uint64, :uint8, RustCallStatus.by_ref],
- :void
- attach_function :uniffi_servicepoint_binding_uniffi_fn_method_brightnessgrid_width,
- [:pointer, RustCallStatus.by_ref],
- :uint64
- attach_function :uniffi_servicepoint_binding_uniffi_fn_free_chargrid,
- [:pointer, RustCallStatus.by_ref],
- :void
- attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_chargrid_clone,
- [:pointer, RustCallStatus.by_ref],
- :pointer
- attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_chargrid_load,
- [RustBuffer.by_value, RustCallStatus.by_ref],
- :pointer
- attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_chargrid_new,
- [:uint64, :uint64, RustCallStatus.by_ref],
- :pointer
- attach_function :uniffi_servicepoint_binding_uniffi_fn_method_chargrid_as_string,
- [:pointer, RustCallStatus.by_ref],
- RustBuffer.by_value
- attach_function :uniffi_servicepoint_binding_uniffi_fn_method_chargrid_equals,
- [:pointer, :pointer, RustCallStatus.by_ref],
- :int8
- attach_function :uniffi_servicepoint_binding_uniffi_fn_method_chargrid_fill,
- [:pointer, RustBuffer.by_value, RustCallStatus.by_ref],
- :void
- attach_function :uniffi_servicepoint_binding_uniffi_fn_method_chargrid_get,
- [:pointer, :uint64, :uint64, RustCallStatus.by_ref],
- RustBuffer.by_value
- attach_function :uniffi_servicepoint_binding_uniffi_fn_method_chargrid_get_col,
- [:pointer, :uint64, RustCallStatus.by_ref],
- RustBuffer.by_value
- attach_function :uniffi_servicepoint_binding_uniffi_fn_method_chargrid_get_row,
- [:pointer, :uint64, RustCallStatus.by_ref],
- RustBuffer.by_value
- attach_function :uniffi_servicepoint_binding_uniffi_fn_method_chargrid_height,
- [:pointer, RustCallStatus.by_ref],
- :uint64
- attach_function :uniffi_servicepoint_binding_uniffi_fn_method_chargrid_set,
- [:pointer, :uint64, :uint64, RustBuffer.by_value, RustCallStatus.by_ref],
- :void
- attach_function :uniffi_servicepoint_binding_uniffi_fn_method_chargrid_set_col,
- [:pointer, :uint64, RustBuffer.by_value, RustCallStatus.by_ref],
- :void
- attach_function :uniffi_servicepoint_binding_uniffi_fn_method_chargrid_set_row,
- [:pointer, :uint64, RustBuffer.by_value, RustCallStatus.by_ref],
- :void
- attach_function :uniffi_servicepoint_binding_uniffi_fn_method_chargrid_to_cp437,
- [:pointer, RustCallStatus.by_ref],
- :pointer
- attach_function :uniffi_servicepoint_binding_uniffi_fn_method_chargrid_width,
- [:pointer, RustCallStatus.by_ref],
- :uint64
- attach_function :uniffi_servicepoint_binding_uniffi_fn_free_command,
- [:pointer, RustCallStatus.by_ref],
- :void
- attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear,
- [:uint64, :pointer, RustBuffer.by_value, RustCallStatus.by_ref],
- :pointer
- attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_and,
- [:uint64, :pointer, RustBuffer.by_value, RustCallStatus.by_ref],
- :pointer
- attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_or,
- [:uint64, :pointer, RustBuffer.by_value, RustCallStatus.by_ref],
- :pointer
- attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_win,
- [:uint64, :uint64, :pointer, RustBuffer.by_value, RustCallStatus.by_ref],
- :pointer
- attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_xor,
- [:uint64, :pointer, RustBuffer.by_value, RustCallStatus.by_ref],
- :pointer
- attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_command_brightness,
- [:uint8, RustCallStatus.by_ref],
- :pointer
- attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_command_char_brightness,
- [:uint64, :uint64, :pointer, RustCallStatus.by_ref],
- :pointer
- attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_command_clear,
- [RustCallStatus.by_ref],
- :pointer
- attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_command_clone,
- [:pointer, RustCallStatus.by_ref],
- :pointer
- attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_command_cp437_data,
- [:uint64, :uint64, :pointer, RustCallStatus.by_ref],
- :pointer
- attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_command_fade_out,
- [RustCallStatus.by_ref],
- :pointer
- attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_command_hard_reset,
- [RustCallStatus.by_ref],
- :pointer
- attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_command_utf8_data,
- [:uint64, :uint64, :pointer, RustCallStatus.by_ref],
- :pointer
- attach_function :uniffi_servicepoint_binding_uniffi_fn_method_command_equals,
- [:pointer, :pointer, RustCallStatus.by_ref],
- :int8
- attach_function :uniffi_servicepoint_binding_uniffi_fn_free_connection,
- [:pointer, RustCallStatus.by_ref],
- :void
- attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_connection_new,
- [RustBuffer.by_value, RustCallStatus.by_ref],
- :pointer
- attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_connection_new_fake,
- [RustCallStatus.by_ref],
- :pointer
- attach_function :uniffi_servicepoint_binding_uniffi_fn_method_connection_send,
- [:pointer, :pointer, RustCallStatus.by_ref],
- :void
- attach_function :uniffi_servicepoint_binding_uniffi_fn_free_cp437grid,
- [:pointer, RustCallStatus.by_ref],
- :void
- attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_cp437grid_clone,
- [:pointer, RustCallStatus.by_ref],
- :pointer
- attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_cp437grid_load,
- [:uint64, :uint64, RustBuffer.by_value, RustCallStatus.by_ref],
- :pointer
- attach_function :uniffi_servicepoint_binding_uniffi_fn_constructor_cp437grid_new,
- [:uint64, :uint64, RustCallStatus.by_ref],
- :pointer
- attach_function :uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_copy_raw,
- [:pointer, RustCallStatus.by_ref],
- RustBuffer.by_value
- attach_function :uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_equals,
- [:pointer, :pointer, RustCallStatus.by_ref],
- :int8
- attach_function :uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_fill,
- [:pointer, :uint8, RustCallStatus.by_ref],
- :void
- attach_function :uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_get,
- [:pointer, :uint64, :uint64, RustCallStatus.by_ref],
- :uint8
- attach_function :uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_height,
- [:pointer, RustCallStatus.by_ref],
- :uint64
- attach_function :uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_set,
- [:pointer, :uint64, :uint64, :uint8, RustCallStatus.by_ref],
- :void
- attach_function :uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_to_utf8,
- [:pointer, RustCallStatus.by_ref],
- :pointer
- attach_function :uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_width,
- [:pointer, RustCallStatus.by_ref],
- :uint64
- attach_function :uniffi_servicepoint_binding_uniffi_fn_func_get_constants,
- [RustCallStatus.by_ref],
- RustBuffer.by_value
- attach_function :ffi_servicepoint_binding_uniffi_rustbuffer_alloc,
- [:int32, RustCallStatus.by_ref],
- RustBuffer.by_value
- attach_function :ffi_servicepoint_binding_uniffi_rustbuffer_from_bytes,
- [ForeignBytes, RustCallStatus.by_ref],
- RustBuffer.by_value
- attach_function :ffi_servicepoint_binding_uniffi_rustbuffer_free,
- [RustBuffer.by_value, RustCallStatus.by_ref],
- :void
- attach_function :ffi_servicepoint_binding_uniffi_rustbuffer_reserve,
- [RustBuffer.by_value, :int32, RustCallStatus.by_ref],
- RustBuffer.by_value
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_func_get_constants,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_copy_raw,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_equals,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_fill,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_get,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_len,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_bitvec_set,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_bitmap_copy_raw,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_bitmap_equals,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_bitmap_fill,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_bitmap_get,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_bitmap_height,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_bitmap_set,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_bitmap_width,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_brightnessgrid_copy_raw,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_brightnessgrid_equals,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_brightnessgrid_fill,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_brightnessgrid_get,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_brightnessgrid_height,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_brightnessgrid_set,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_brightnessgrid_width,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_as_string,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_equals,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_fill,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_get,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_get_col,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_get_row,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_height,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_set,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_set_col,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_set_row,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_to_cp437,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_chargrid_width,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_command_equals,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_connection_send,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_cp437grid_copy_raw,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_cp437grid_equals,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_cp437grid_fill,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_cp437grid_get,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_cp437grid_height,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_cp437grid_set,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_cp437grid_to_utf8,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_method_cp437grid_width,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_bitvec_clone,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_bitvec_load,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_bitvec_new,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_bitmap_clone,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_bitmap_load,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_bitmap_new,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_bitmap_new_max_sized,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_brightnessgrid_clone,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_brightnessgrid_load,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_brightnessgrid_new,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_chargrid_clone,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_chargrid_load,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_chargrid_new,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_and,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_or,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_win,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_command_bitmap_linear_xor,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_command_brightness,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_command_char_brightness,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_command_clear,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_command_clone,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_command_cp437_data,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_command_fade_out,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_command_hard_reset,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_command_utf8_data,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_connection_new,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_connection_new_fake,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_cp437grid_clone,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_cp437grid_load,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :uniffi_servicepoint_binding_uniffi_checksum_constructor_cp437grid_new,
- [RustCallStatus.by_ref],
- :uint16
- attach_function :ffi_servicepoint_binding_uniffi_uniffi_contract_version,
- [RustCallStatus.by_ref],
- :uint32
-
-end
-
- # Public interface members begin here.
-
-
-
-
-
-
-class CompressionCode
- UNCOMPRESSED = 1
- ZLIB = 2
- BZIP2 = 3
- LZMA = 4
- ZSTD = 5
-
-end
-
-
-
-
- # Record type Constants
-class Constants
- attr_reader :tile_size, :tile_width, :tile_height, :pixel_width, :pixel_height, :pixel_count
-
- def initialize(tile_size, tile_width, tile_height, pixel_width, pixel_height, pixel_count)
- @tile_size = tile_size
- @tile_width = tile_width
- @tile_height = tile_height
- @pixel_width = pixel_width
- @pixel_height = pixel_height
- @pixel_count = pixel_count
- end
-
- def ==(other)
- if @tile_size != other.tile_size
- return false
- end
- if @tile_width != other.tile_width
- return false
- end
- if @tile_height != other.tile_height
- return false
- end
- if @pixel_width != other.pixel_width
- return false
- end
- if @pixel_height != other.pixel_height
- return false
- end
- if @pixel_count != other.pixel_count
- return false
- end
-
- true
- end
-end
-
-
-
-
-
-def self.get_constants()
- result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_func_get_constants,)
- return result.consumeIntoTypeConstants
-end
-
-
-
-
-
- class BitVec
-
- # A private helper for initializing instances of the class from a raw pointer,
- # bypassing any initialization logic and ensuring they are GC'd properly.
- def self._uniffi_allocate(pointer)
- pointer.autorelease = false
- inst = allocate
- inst.instance_variable_set :@pointer, pointer
- ObjectSpace.define_finalizer(inst, _uniffi_define_finalizer_by_pointer(pointer, inst.object_id))
- return inst
- end
-
- # A private helper for registering an object finalizer.
- # N.B. it's important that this does not capture a reference
- # to the actual instance, only its underlying pointer.
- def self._uniffi_define_finalizer_by_pointer(pointer, object_id)
- Proc.new do |_id|
- ServicepointBindingUniffi.rust_call(
- :uniffi_servicepoint_binding_uniffi_fn_free_bitvec,
- pointer
- )
- end
- end
-
- # A private helper for lowering instances into a raw pointer.
- # This does an explicit typecheck, because accidentally lowering a different type of
- # object in a place where this type is expected, could lead to memory unsafety.
- def self._uniffi_lower(inst)
- if not inst.is_a? self
- raise TypeError.new "Expected a BitVec instance, got #{inst}"
- end
- return inst.instance_variable_get :@pointer
- end
- def initialize(size)
- size = ServicepointBindingUniffi::uniffi_in_range(size, "u64", 0, 2**64)
- pointer = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_bitvec_new,size)
- @pointer = pointer
- ObjectSpace.define_finalizer(self, self.class._uniffi_define_finalizer_by_pointer(pointer, self.object_id))
- end
-
- def self.clone(other)
- other = other
- # Call the (fallible) function before creating any half-baked object instances.
- # Lightly yucky way to bypass the usual "initialize" logic
- # and just create a new instance with the required pointer.
- return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_bitvec_clone,(BitVec._uniffi_lower other)))
- end
- def self.load(data)
- data = ServicepointBindingUniffi::uniffi_bytes(data)
- # Call the (fallible) function before creating any half-baked object instances.
- # Lightly yucky way to bypass the usual "initialize" logic
- # and just create a new instance with the required pointer.
- return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_bitvec_load,RustBuffer.allocFromBytes(data)))
- end
-
-
- def copy_raw()
- result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_bitvec_copy_raw,@pointer,)
- return result.consumeIntoBytes
- end
- def equals(other)
- other = other
- result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_bitvec_equals,@pointer,(BitVec._uniffi_lower other))
- return 1 == result
- end
- def fill(value)
- value = value ? true : false
- ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_bitvec_fill,@pointer,(value ? 1 : 0))
- end
-
- def get(index)
- index = ServicepointBindingUniffi::uniffi_in_range(index, "u64", 0, 2**64)
- result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_bitvec_get,@pointer,index)
- return 1 == result
- end
- def len()
- result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_bitvec_len,@pointer,)
- return result.to_i
- end
- def set(index, value)
- index = ServicepointBindingUniffi::uniffi_in_range(index, "u64", 0, 2**64)
- value = value ? true : false
- ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_bitvec_set,@pointer,index,(value ? 1 : 0))
- end
-
-
-end
-
- class Bitmap
-
- # A private helper for initializing instances of the class from a raw pointer,
- # bypassing any initialization logic and ensuring they are GC'd properly.
- def self._uniffi_allocate(pointer)
- pointer.autorelease = false
- inst = allocate
- inst.instance_variable_set :@pointer, pointer
- ObjectSpace.define_finalizer(inst, _uniffi_define_finalizer_by_pointer(pointer, inst.object_id))
- return inst
- end
-
- # A private helper for registering an object finalizer.
- # N.B. it's important that this does not capture a reference
- # to the actual instance, only its underlying pointer.
- def self._uniffi_define_finalizer_by_pointer(pointer, object_id)
- Proc.new do |_id|
- ServicepointBindingUniffi.rust_call(
- :uniffi_servicepoint_binding_uniffi_fn_free_bitmap,
- pointer
- )
- end
- end
-
- # A private helper for lowering instances into a raw pointer.
- # This does an explicit typecheck, because accidentally lowering a different type of
- # object in a place where this type is expected, could lead to memory unsafety.
- def self._uniffi_lower(inst)
- if not inst.is_a? self
- raise TypeError.new "Expected a Bitmap instance, got #{inst}"
- end
- return inst.instance_variable_get :@pointer
- end
- def initialize(width, height)
- width = ServicepointBindingUniffi::uniffi_in_range(width, "u64", 0, 2**64)
- height = ServicepointBindingUniffi::uniffi_in_range(height, "u64", 0, 2**64)
- pointer = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_bitmap_new,width,height)
- @pointer = pointer
- ObjectSpace.define_finalizer(self, self.class._uniffi_define_finalizer_by_pointer(pointer, self.object_id))
- end
-
- def self.clone(other)
- other = other
- # Call the (fallible) function before creating any half-baked object instances.
- # Lightly yucky way to bypass the usual "initialize" logic
- # and just create a new instance with the required pointer.
- return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_bitmap_clone,(Bitmap._uniffi_lower other)))
- end
- def self.load(width, height, data)
- width = ServicepointBindingUniffi::uniffi_in_range(width, "u64", 0, 2**64)
- height = ServicepointBindingUniffi::uniffi_in_range(height, "u64", 0, 2**64)
- data = ServicepointBindingUniffi::uniffi_bytes(data)
- # Call the (fallible) function before creating any half-baked object instances.
- # Lightly yucky way to bypass the usual "initialize" logic
- # and just create a new instance with the required pointer.
- return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_bitmap_load,width,height,RustBuffer.allocFromBytes(data)))
- end
- def self.new_max_sized()
- # Call the (fallible) function before creating any half-baked object instances.
- # Lightly yucky way to bypass the usual "initialize" logic
- # and just create a new instance with the required pointer.
- return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_bitmap_new_max_sized,))
- end
-
-
- def copy_raw()
- result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_bitmap_copy_raw,@pointer,)
- return result.consumeIntoBytes
- end
- def equals(other)
- other = other
- result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_bitmap_equals,@pointer,(Bitmap._uniffi_lower other))
- return 1 == result
- end
- def fill(value)
- value = value ? true : false
- ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_bitmap_fill,@pointer,(value ? 1 : 0))
- end
-
- def get(x, y)
- x = ServicepointBindingUniffi::uniffi_in_range(x, "u64", 0, 2**64)
- y = ServicepointBindingUniffi::uniffi_in_range(y, "u64", 0, 2**64)
- result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_bitmap_get,@pointer,x,y)
- return 1 == result
- end
- def height()
- result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_bitmap_height,@pointer,)
- return result.to_i
- end
- def set(x, y, value)
- x = ServicepointBindingUniffi::uniffi_in_range(x, "u64", 0, 2**64)
- y = ServicepointBindingUniffi::uniffi_in_range(y, "u64", 0, 2**64)
- value = value ? true : false
- ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_bitmap_set,@pointer,x,y,(value ? 1 : 0))
- end
-
- def width()
- result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_bitmap_width,@pointer,)
- return result.to_i
- end
-
-end
-
- class BrightnessGrid
-
- # A private helper for initializing instances of the class from a raw pointer,
- # bypassing any initialization logic and ensuring they are GC'd properly.
- def self._uniffi_allocate(pointer)
- pointer.autorelease = false
- inst = allocate
- inst.instance_variable_set :@pointer, pointer
- ObjectSpace.define_finalizer(inst, _uniffi_define_finalizer_by_pointer(pointer, inst.object_id))
- return inst
- end
-
- # A private helper for registering an object finalizer.
- # N.B. it's important that this does not capture a reference
- # to the actual instance, only its underlying pointer.
- def self._uniffi_define_finalizer_by_pointer(pointer, object_id)
- Proc.new do |_id|
- ServicepointBindingUniffi.rust_call(
- :uniffi_servicepoint_binding_uniffi_fn_free_brightnessgrid,
- pointer
- )
- end
- end
-
- # A private helper for lowering instances into a raw pointer.
- # This does an explicit typecheck, because accidentally lowering a different type of
- # object in a place where this type is expected, could lead to memory unsafety.
- def self._uniffi_lower(inst)
- if not inst.is_a? self
- raise TypeError.new "Expected a BrightnessGrid instance, got #{inst}"
- end
- return inst.instance_variable_get :@pointer
- end
- def initialize(width, height)
- width = ServicepointBindingUniffi::uniffi_in_range(width, "u64", 0, 2**64)
- height = ServicepointBindingUniffi::uniffi_in_range(height, "u64", 0, 2**64)
- pointer = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_brightnessgrid_new,width,height)
- @pointer = pointer
- ObjectSpace.define_finalizer(self, self.class._uniffi_define_finalizer_by_pointer(pointer, self.object_id))
- end
-
- def self.clone(other)
- other = other
- # Call the (fallible) function before creating any half-baked object instances.
- # Lightly yucky way to bypass the usual "initialize" logic
- # and just create a new instance with the required pointer.
- return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_brightnessgrid_clone,(BrightnessGrid._uniffi_lower other)))
- end
- def self.load(width, height, data)
- width = ServicepointBindingUniffi::uniffi_in_range(width, "u64", 0, 2**64)
- height = ServicepointBindingUniffi::uniffi_in_range(height, "u64", 0, 2**64)
- data = ServicepointBindingUniffi::uniffi_bytes(data)
- # Call the (fallible) function before creating any half-baked object instances.
- # Lightly yucky way to bypass the usual "initialize" logic
- # and just create a new instance with the required pointer.
- return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_brightnessgrid_load,width,height,RustBuffer.allocFromBytes(data)))
- end
-
-
- def copy_raw()
- result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_brightnessgrid_copy_raw,@pointer,)
- return result.consumeIntoBytes
- end
- def equals(other)
- other = other
- result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_brightnessgrid_equals,@pointer,(BrightnessGrid._uniffi_lower other))
- return 1 == result
- end
- def fill(value)
- value = ServicepointBindingUniffi::uniffi_in_range(value, "u8", 0, 2**8)
- ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_brightnessgrid_fill,@pointer,value)
- end
-
- def get(x, y)
- x = ServicepointBindingUniffi::uniffi_in_range(x, "u64", 0, 2**64)
- y = ServicepointBindingUniffi::uniffi_in_range(y, "u64", 0, 2**64)
- result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_brightnessgrid_get,@pointer,x,y)
- return result.to_i
- end
- def height()
- result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_brightnessgrid_height,@pointer,)
- return result.to_i
- end
- def set(x, y, value)
- x = ServicepointBindingUniffi::uniffi_in_range(x, "u64", 0, 2**64)
- y = ServicepointBindingUniffi::uniffi_in_range(y, "u64", 0, 2**64)
- value = ServicepointBindingUniffi::uniffi_in_range(value, "u8", 0, 2**8)
- ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_brightnessgrid_set,@pointer,x,y,value)
- end
-
- def width()
- result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_brightnessgrid_width,@pointer,)
- return result.to_i
- end
-
-end
-
- class CharGrid
-
- # A private helper for initializing instances of the class from a raw pointer,
- # bypassing any initialization logic and ensuring they are GC'd properly.
- def self._uniffi_allocate(pointer)
- pointer.autorelease = false
- inst = allocate
- inst.instance_variable_set :@pointer, pointer
- ObjectSpace.define_finalizer(inst, _uniffi_define_finalizer_by_pointer(pointer, inst.object_id))
- return inst
- end
-
- # A private helper for registering an object finalizer.
- # N.B. it's important that this does not capture a reference
- # to the actual instance, only its underlying pointer.
- def self._uniffi_define_finalizer_by_pointer(pointer, object_id)
- Proc.new do |_id|
- ServicepointBindingUniffi.rust_call(
- :uniffi_servicepoint_binding_uniffi_fn_free_chargrid,
- pointer
- )
- end
- end
-
- # A private helper for lowering instances into a raw pointer.
- # This does an explicit typecheck, because accidentally lowering a different type of
- # object in a place where this type is expected, could lead to memory unsafety.
- def self._uniffi_lower(inst)
- if not inst.is_a? self
- raise TypeError.new "Expected a CharGrid instance, got #{inst}"
- end
- return inst.instance_variable_get :@pointer
- end
- def initialize(width, height)
- width = ServicepointBindingUniffi::uniffi_in_range(width, "u64", 0, 2**64)
- height = ServicepointBindingUniffi::uniffi_in_range(height, "u64", 0, 2**64)
- pointer = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_chargrid_new,width,height)
- @pointer = pointer
- ObjectSpace.define_finalizer(self, self.class._uniffi_define_finalizer_by_pointer(pointer, self.object_id))
- end
-
- def self.clone(other)
- other = other
- # Call the (fallible) function before creating any half-baked object instances.
- # Lightly yucky way to bypass the usual "initialize" logic
- # and just create a new instance with the required pointer.
- return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_chargrid_clone,(CharGrid._uniffi_lower other)))
- end
- def self.load(data)
- data = ServicepointBindingUniffi::uniffi_utf8(data)
- # Call the (fallible) function before creating any half-baked object instances.
- # Lightly yucky way to bypass the usual "initialize" logic
- # and just create a new instance with the required pointer.
- return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_chargrid_load,RustBuffer.allocFromString(data)))
- end
-
-
- def as_string()
- result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_chargrid_as_string,@pointer,)
- return result.consumeIntoString
- end
- def equals(other)
- other = other
- result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_chargrid_equals,@pointer,(CharGrid._uniffi_lower other))
- return 1 == result
- end
- def fill(value)
- value = ServicepointBindingUniffi::uniffi_utf8(value)
- ServicepointBindingUniffi.rust_call_with_error(CharGridError,:uniffi_servicepoint_binding_uniffi_fn_method_chargrid_fill,@pointer,RustBuffer.allocFromString(value))
- end
-
- def get(x, y)
- x = ServicepointBindingUniffi::uniffi_in_range(x, "u64", 0, 2**64)
- y = ServicepointBindingUniffi::uniffi_in_range(y, "u64", 0, 2**64)
- result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_chargrid_get,@pointer,x,y)
- return result.consumeIntoString
- end
- def get_col(x)
- x = ServicepointBindingUniffi::uniffi_in_range(x, "u64", 0, 2**64)
- result = ServicepointBindingUniffi.rust_call_with_error(CharGridError,:uniffi_servicepoint_binding_uniffi_fn_method_chargrid_get_col,@pointer,x)
- return result.consumeIntoString
- end
- def get_row(y)
- y = ServicepointBindingUniffi::uniffi_in_range(y, "u64", 0, 2**64)
- result = ServicepointBindingUniffi.rust_call_with_error(CharGridError,:uniffi_servicepoint_binding_uniffi_fn_method_chargrid_get_row,@pointer,y)
- return result.consumeIntoString
- end
- def height()
- result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_chargrid_height,@pointer,)
- return result.to_i
- end
- def set(x, y, value)
- x = ServicepointBindingUniffi::uniffi_in_range(x, "u64", 0, 2**64)
- y = ServicepointBindingUniffi::uniffi_in_range(y, "u64", 0, 2**64)
- value = ServicepointBindingUniffi::uniffi_utf8(value)
- ServicepointBindingUniffi.rust_call_with_error(CharGridError,:uniffi_servicepoint_binding_uniffi_fn_method_chargrid_set,@pointer,x,y,RustBuffer.allocFromString(value))
- end
-
- def set_col(x, col)
- x = ServicepointBindingUniffi::uniffi_in_range(x, "u64", 0, 2**64)
- col = ServicepointBindingUniffi::uniffi_utf8(col)
- ServicepointBindingUniffi.rust_call_with_error(CharGridError,:uniffi_servicepoint_binding_uniffi_fn_method_chargrid_set_col,@pointer,x,RustBuffer.allocFromString(col))
- end
-
- def set_row(y, row)
- y = ServicepointBindingUniffi::uniffi_in_range(y, "u64", 0, 2**64)
- row = ServicepointBindingUniffi::uniffi_utf8(row)
- ServicepointBindingUniffi.rust_call_with_error(CharGridError,:uniffi_servicepoint_binding_uniffi_fn_method_chargrid_set_row,@pointer,y,RustBuffer.allocFromString(row))
- end
-
- def to_cp437()
- result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_chargrid_to_cp437,@pointer,)
- return Cp437Grid._uniffi_allocate(result)
- end
- def width()
- result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_chargrid_width,@pointer,)
- return result.to_i
- end
-
-end
-
- class Command
-
- # A private helper for initializing instances of the class from a raw pointer,
- # bypassing any initialization logic and ensuring they are GC'd properly.
- def self._uniffi_allocate(pointer)
- pointer.autorelease = false
- inst = allocate
- inst.instance_variable_set :@pointer, pointer
- ObjectSpace.define_finalizer(inst, _uniffi_define_finalizer_by_pointer(pointer, inst.object_id))
- return inst
- end
-
- # A private helper for registering an object finalizer.
- # N.B. it's important that this does not capture a reference
- # to the actual instance, only its underlying pointer.
- def self._uniffi_define_finalizer_by_pointer(pointer, object_id)
- Proc.new do |_id|
- ServicepointBindingUniffi.rust_call(
- :uniffi_servicepoint_binding_uniffi_fn_free_command,
- pointer
- )
- end
- end
-
- # A private helper for lowering instances into a raw pointer.
- # This does an explicit typecheck, because accidentally lowering a different type of
- # object in a place where this type is expected, could lead to memory unsafety.
- def self._uniffi_lower(inst)
- if not inst.is_a? self
- raise TypeError.new "Expected a Command instance, got #{inst}"
- end
- return inst.instance_variable_get :@pointer
- end
-
- def self.bitmap_linear(offset, bitmap, compression)
- offset = ServicepointBindingUniffi::uniffi_in_range(offset, "u64", 0, 2**64)
- bitmap = bitmap
- compression = compression
- # Call the (fallible) function before creating any half-baked object instances.
- # Lightly yucky way to bypass the usual "initialize" logic
- # and just create a new instance with the required pointer.
- return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear,offset,(BitVec._uniffi_lower bitmap),RustBuffer.alloc_from_TypeCompressionCode(compression)))
- end
- def self.bitmap_linear_and(offset, bitmap, compression)
- offset = ServicepointBindingUniffi::uniffi_in_range(offset, "u64", 0, 2**64)
- bitmap = bitmap
- compression = compression
- # Call the (fallible) function before creating any half-baked object instances.
- # Lightly yucky way to bypass the usual "initialize" logic
- # and just create a new instance with the required pointer.
- return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_and,offset,(BitVec._uniffi_lower bitmap),RustBuffer.alloc_from_TypeCompressionCode(compression)))
- end
- def self.bitmap_linear_or(offset, bitmap, compression)
- offset = ServicepointBindingUniffi::uniffi_in_range(offset, "u64", 0, 2**64)
- bitmap = bitmap
- compression = compression
- # Call the (fallible) function before creating any half-baked object instances.
- # Lightly yucky way to bypass the usual "initialize" logic
- # and just create a new instance with the required pointer.
- return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_or,offset,(BitVec._uniffi_lower bitmap),RustBuffer.alloc_from_TypeCompressionCode(compression)))
- end
- def self.bitmap_linear_win(offset_x, offset_y, bitmap, compression)
- offset_x = ServicepointBindingUniffi::uniffi_in_range(offset_x, "u64", 0, 2**64)
- offset_y = ServicepointBindingUniffi::uniffi_in_range(offset_y, "u64", 0, 2**64)
- bitmap = bitmap
- compression = compression
- # Call the (fallible) function before creating any half-baked object instances.
- # Lightly yucky way to bypass the usual "initialize" logic
- # and just create a new instance with the required pointer.
- return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_win,offset_x,offset_y,(Bitmap._uniffi_lower bitmap),RustBuffer.alloc_from_TypeCompressionCode(compression)))
- end
- def self.bitmap_linear_xor(offset, bitmap, compression)
- offset = ServicepointBindingUniffi::uniffi_in_range(offset, "u64", 0, 2**64)
- bitmap = bitmap
- compression = compression
- # Call the (fallible) function before creating any half-baked object instances.
- # Lightly yucky way to bypass the usual "initialize" logic
- # and just create a new instance with the required pointer.
- return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_command_bitmap_linear_xor,offset,(BitVec._uniffi_lower bitmap),RustBuffer.alloc_from_TypeCompressionCode(compression)))
- end
- def self.brightness(brightness)
- brightness = ServicepointBindingUniffi::uniffi_in_range(brightness, "u8", 0, 2**8)
- # Call the (fallible) function before creating any half-baked object instances.
- # Lightly yucky way to bypass the usual "initialize" logic
- # and just create a new instance with the required pointer.
- return _uniffi_allocate(ServicepointBindingUniffi.rust_call_with_error(ServicePointError,:uniffi_servicepoint_binding_uniffi_fn_constructor_command_brightness,brightness))
- end
- def self.char_brightness(offset_x, offset_y, grid)
- offset_x = ServicepointBindingUniffi::uniffi_in_range(offset_x, "u64", 0, 2**64)
- offset_y = ServicepointBindingUniffi::uniffi_in_range(offset_y, "u64", 0, 2**64)
- grid = grid
- # Call the (fallible) function before creating any half-baked object instances.
- # Lightly yucky way to bypass the usual "initialize" logic
- # and just create a new instance with the required pointer.
- return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_command_char_brightness,offset_x,offset_y,(BrightnessGrid._uniffi_lower grid)))
- end
- def self.clear()
- # Call the (fallible) function before creating any half-baked object instances.
- # Lightly yucky way to bypass the usual "initialize" logic
- # and just create a new instance with the required pointer.
- return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_command_clear,))
- end
- def self.clone(other)
- other = other
- # Call the (fallible) function before creating any half-baked object instances.
- # Lightly yucky way to bypass the usual "initialize" logic
- # and just create a new instance with the required pointer.
- return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_command_clone,(Command._uniffi_lower other)))
- end
- def self.cp437_data(offset_x, offset_y, grid)
- offset_x = ServicepointBindingUniffi::uniffi_in_range(offset_x, "u64", 0, 2**64)
- offset_y = ServicepointBindingUniffi::uniffi_in_range(offset_y, "u64", 0, 2**64)
- grid = grid
- # Call the (fallible) function before creating any half-baked object instances.
- # Lightly yucky way to bypass the usual "initialize" logic
- # and just create a new instance with the required pointer.
- return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_command_cp437_data,offset_x,offset_y,(Cp437Grid._uniffi_lower grid)))
- end
- def self.fade_out()
- # Call the (fallible) function before creating any half-baked object instances.
- # Lightly yucky way to bypass the usual "initialize" logic
- # and just create a new instance with the required pointer.
- return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_command_fade_out,))
- end
- def self.hard_reset()
- # Call the (fallible) function before creating any half-baked object instances.
- # Lightly yucky way to bypass the usual "initialize" logic
- # and just create a new instance with the required pointer.
- return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_command_hard_reset,))
- end
- def self.utf8_data(offset_x, offset_y, grid)
- offset_x = ServicepointBindingUniffi::uniffi_in_range(offset_x, "u64", 0, 2**64)
- offset_y = ServicepointBindingUniffi::uniffi_in_range(offset_y, "u64", 0, 2**64)
- grid = grid
- # Call the (fallible) function before creating any half-baked object instances.
- # Lightly yucky way to bypass the usual "initialize" logic
- # and just create a new instance with the required pointer.
- return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_command_utf8_data,offset_x,offset_y,(CharGrid._uniffi_lower grid)))
- end
-
-
- def equals(other)
- other = other
- result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_command_equals,@pointer,(Command._uniffi_lower other))
- return 1 == result
- end
-
-end
-
- class Connection
-
- # A private helper for initializing instances of the class from a raw pointer,
- # bypassing any initialization logic and ensuring they are GC'd properly.
- def self._uniffi_allocate(pointer)
- pointer.autorelease = false
- inst = allocate
- inst.instance_variable_set :@pointer, pointer
- ObjectSpace.define_finalizer(inst, _uniffi_define_finalizer_by_pointer(pointer, inst.object_id))
- return inst
- end
-
- # A private helper for registering an object finalizer.
- # N.B. it's important that this does not capture a reference
- # to the actual instance, only its underlying pointer.
- def self._uniffi_define_finalizer_by_pointer(pointer, object_id)
- Proc.new do |_id|
- ServicepointBindingUniffi.rust_call(
- :uniffi_servicepoint_binding_uniffi_fn_free_connection,
- pointer
- )
- end
- end
-
- # A private helper for lowering instances into a raw pointer.
- # This does an explicit typecheck, because accidentally lowering a different type of
- # object in a place where this type is expected, could lead to memory unsafety.
- def self._uniffi_lower(inst)
- if not inst.is_a? self
- raise TypeError.new "Expected a Connection instance, got #{inst}"
- end
- return inst.instance_variable_get :@pointer
- end
- def initialize(host)
- host = ServicepointBindingUniffi::uniffi_utf8(host)
- pointer = ServicepointBindingUniffi.rust_call_with_error(ServicePointError,:uniffi_servicepoint_binding_uniffi_fn_constructor_connection_new,RustBuffer.allocFromString(host))
- @pointer = pointer
- ObjectSpace.define_finalizer(self, self.class._uniffi_define_finalizer_by_pointer(pointer, self.object_id))
- end
-
- def self.new_fake()
- # Call the (fallible) function before creating any half-baked object instances.
- # Lightly yucky way to bypass the usual "initialize" logic
- # and just create a new instance with the required pointer.
- return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_connection_new_fake,))
- end
-
-
- def send(command)
- command = command
- ServicepointBindingUniffi.rust_call_with_error(ServicePointError,:uniffi_servicepoint_binding_uniffi_fn_method_connection_send,@pointer,(Command._uniffi_lower command))
- end
-
-
-end
-
- class Cp437Grid
-
- # A private helper for initializing instances of the class from a raw pointer,
- # bypassing any initialization logic and ensuring they are GC'd properly.
- def self._uniffi_allocate(pointer)
- pointer.autorelease = false
- inst = allocate
- inst.instance_variable_set :@pointer, pointer
- ObjectSpace.define_finalizer(inst, _uniffi_define_finalizer_by_pointer(pointer, inst.object_id))
- return inst
- end
-
- # A private helper for registering an object finalizer.
- # N.B. it's important that this does not capture a reference
- # to the actual instance, only its underlying pointer.
- def self._uniffi_define_finalizer_by_pointer(pointer, object_id)
- Proc.new do |_id|
- ServicepointBindingUniffi.rust_call(
- :uniffi_servicepoint_binding_uniffi_fn_free_cp437grid,
- pointer
- )
- end
- end
-
- # A private helper for lowering instances into a raw pointer.
- # This does an explicit typecheck, because accidentally lowering a different type of
- # object in a place where this type is expected, could lead to memory unsafety.
- def self._uniffi_lower(inst)
- if not inst.is_a? self
- raise TypeError.new "Expected a Cp437Grid instance, got #{inst}"
- end
- return inst.instance_variable_get :@pointer
- end
- def initialize(width, height)
- width = ServicepointBindingUniffi::uniffi_in_range(width, "u64", 0, 2**64)
- height = ServicepointBindingUniffi::uniffi_in_range(height, "u64", 0, 2**64)
- pointer = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_cp437grid_new,width,height)
- @pointer = pointer
- ObjectSpace.define_finalizer(self, self.class._uniffi_define_finalizer_by_pointer(pointer, self.object_id))
- end
-
- def self.clone(other)
- other = other
- # Call the (fallible) function before creating any half-baked object instances.
- # Lightly yucky way to bypass the usual "initialize" logic
- # and just create a new instance with the required pointer.
- return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_cp437grid_clone,(Cp437Grid._uniffi_lower other)))
- end
- def self.load(width, height, data)
- width = ServicepointBindingUniffi::uniffi_in_range(width, "u64", 0, 2**64)
- height = ServicepointBindingUniffi::uniffi_in_range(height, "u64", 0, 2**64)
- data = ServicepointBindingUniffi::uniffi_bytes(data)
- # Call the (fallible) function before creating any half-baked object instances.
- # Lightly yucky way to bypass the usual "initialize" logic
- # and just create a new instance with the required pointer.
- return _uniffi_allocate(ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_constructor_cp437grid_load,width,height,RustBuffer.allocFromBytes(data)))
- end
-
-
- def copy_raw()
- result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_copy_raw,@pointer,)
- return result.consumeIntoBytes
- end
- def equals(other)
- other = other
- result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_equals,@pointer,(Cp437Grid._uniffi_lower other))
- return 1 == result
- end
- def fill(value)
- value = ServicepointBindingUniffi::uniffi_in_range(value, "u8", 0, 2**8)
- ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_fill,@pointer,value)
- end
-
- def get(x, y)
- x = ServicepointBindingUniffi::uniffi_in_range(x, "u64", 0, 2**64)
- y = ServicepointBindingUniffi::uniffi_in_range(y, "u64", 0, 2**64)
- result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_get,@pointer,x,y)
- return result.to_i
- end
- def height()
- result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_height,@pointer,)
- return result.to_i
- end
- def set(x, y, value)
- x = ServicepointBindingUniffi::uniffi_in_range(x, "u64", 0, 2**64)
- y = ServicepointBindingUniffi::uniffi_in_range(y, "u64", 0, 2**64)
- value = ServicepointBindingUniffi::uniffi_in_range(value, "u8", 0, 2**8)
- ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_set,@pointer,x,y,value)
- end
-
- def to_utf8()
- result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_to_utf8,@pointer,)
- return CharGrid._uniffi_allocate(result)
- end
- def width()
- result = ServicepointBindingUniffi.rust_call(:uniffi_servicepoint_binding_uniffi_fn_method_cp437grid_width,@pointer,)
- return result.to_i
- end
-
-end
-
-end
-
diff --git a/crates/servicepoint_binding_uniffi/libraries/ruby/servicepoint.gemspec b/crates/servicepoint_binding_uniffi/libraries/ruby/servicepoint.gemspec
deleted file mode 100644
index f558ad5..0000000
--- a/crates/servicepoint_binding_uniffi/libraries/ruby/servicepoint.gemspec
+++ /dev/null
@@ -1,13 +0,0 @@
-Gem::Specification.new do |s|
- s.name = "servicepoint"
- s.version = "0.13.1"
- s.summary = ""
- s.description = ""
- s.authors = ["kaesaecracker"]
- s.email = ""
- s.files = ["lib/servicepoint_binding_uniffi.rb"]
- s.homepage =
- "https://rubygems.org/gems/hola"
- s.license = "MIT"
- s.add_dependency 'ffi'
-end
diff --git a/crates/servicepoint_binding_uniffi/src/bin/uniffi-bindgen-go.rs b/crates/servicepoint_binding_uniffi/src/bin/uniffi-bindgen-go.rs
deleted file mode 100644
index 5f01856..0000000
--- a/crates/servicepoint_binding_uniffi/src/bin/uniffi-bindgen-go.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-fn main() {
- uniffi_bindgen_go::main().unwrap();
-}
diff --git a/crates/servicepoint_binding_uniffi/src/bin/uniffi-bindgen.rs b/crates/servicepoint_binding_uniffi/src/bin/uniffi-bindgen.rs
deleted file mode 100644
index f6cff6c..0000000
--- a/crates/servicepoint_binding_uniffi/src/bin/uniffi-bindgen.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-fn main() {
- uniffi::uniffi_bindgen_main()
-}
diff --git a/crates/servicepoint_binding_uniffi/src/bitmap.rs b/crates/servicepoint_binding_uniffi/src/bitmap.rs
deleted file mode 100644
index 1291f7b..0000000
--- a/crates/servicepoint_binding_uniffi/src/bitmap.rs
+++ /dev/null
@@ -1,77 +0,0 @@
-use servicepoint::{DataRef, Grid};
-use std::sync::{Arc, RwLock};
-
-#[derive(uniffi::Object)]
-pub struct Bitmap {
- pub(crate) actual: RwLock,
-}
-
-impl Bitmap {
- fn internal_new(actual: servicepoint::Bitmap) -> Arc {
- Arc::new(Self {
- actual: RwLock::new(actual),
- })
- }
-}
-
-#[uniffi::export]
-impl Bitmap {
- #[uniffi::constructor]
- pub fn new(width: u64, height: u64) -> Arc {
- Self::internal_new(servicepoint::Bitmap::new(
- width as usize,
- height as usize,
- ))
- }
-
- #[uniffi::constructor]
- pub fn new_max_sized() -> Arc {
- Self::internal_new(servicepoint::Bitmap::max_sized())
- }
-
- #[uniffi::constructor]
- pub fn load(width: u64, height: u64, data: Vec) -> Arc {
- Self::internal_new(servicepoint::Bitmap::load(
- width as usize,
- height as usize,
- &data,
- ))
- }
-
- #[uniffi::constructor]
- pub fn clone(other: &Arc) -> Arc {
- Self::internal_new(other.actual.read().unwrap().clone())
- }
-
- pub fn set(&self, x: u64, y: u64, value: bool) {
- self.actual
- .write()
- .unwrap()
- .set(x as usize, y as usize, value)
- }
-
- pub fn get(&self, x: u64, y: u64) -> bool {
- self.actual.read().unwrap().get(x as usize, y as usize)
- }
-
- pub fn fill(&self, value: bool) {
- self.actual.write().unwrap().fill(value)
- }
- pub fn width(&self) -> u64 {
- self.actual.read().unwrap().width() as u64
- }
-
- pub fn height(&self) -> u64 {
- self.actual.read().unwrap().height() as u64
- }
-
- pub fn equals(&self, other: &Bitmap) -> bool {
- let a = self.actual.read().unwrap();
- let b = other.actual.read().unwrap();
- *a == *b
- }
-
- pub fn copy_raw(&self) -> Vec {
- self.actual.read().unwrap().data_ref().to_vec()
- }
-}
diff --git a/crates/servicepoint_binding_uniffi/src/bitvec.rs b/crates/servicepoint_binding_uniffi/src/bitvec.rs
deleted file mode 100644
index 1ad7751..0000000
--- a/crates/servicepoint_binding_uniffi/src/bitvec.rs
+++ /dev/null
@@ -1,61 +0,0 @@
-use std::sync::{Arc, RwLock};
-
-#[derive(uniffi::Object)]
-pub struct BitVec {
- pub(crate) actual: RwLock,
-}
-
-impl BitVec {
- fn internal_new(actual: servicepoint::BitVec) -> Arc {
- Arc::new(Self {
- actual: RwLock::new(actual),
- })
- }
-}
-
-#[uniffi::export]
-impl BitVec {
- #[uniffi::constructor]
- pub fn new(size: u64) -> Arc {
- Self::internal_new(servicepoint::BitVec::repeat(false, size as usize))
- }
- #[uniffi::constructor]
- pub fn load(data: Vec) -> Arc {
- Self::internal_new(servicepoint::BitVec::from_slice(&data))
- }
-
- #[uniffi::constructor]
- pub fn clone(other: &Arc) -> Arc {
- Self::internal_new(other.actual.read().unwrap().clone())
- }
-
- pub fn set(&self, index: u64, value: bool) {
- self.actual.write().unwrap().set(index as usize, value)
- }
-
- pub fn get(&self, index: u64) -> bool {
- self.actual
- .read()
- .unwrap()
- .get(index as usize)
- .is_some_and(move |bit| *bit)
- }
-
- pub fn fill(&self, value: bool) {
- self.actual.write().unwrap().fill(value)
- }
-
- pub fn len(&self) -> u64 {
- self.actual.read().unwrap().len() as u64
- }
-
- pub fn equals(&self, other: &BitVec) -> bool {
- let a = self.actual.read().unwrap();
- let b = other.actual.read().unwrap();
- *a == *b
- }
-
- pub fn copy_raw(&self) -> Vec {
- self.actual.read().unwrap().clone().into_vec()
- }
-}
diff --git a/crates/servicepoint_binding_uniffi/src/brightness_grid.rs b/crates/servicepoint_binding_uniffi/src/brightness_grid.rs
deleted file mode 100644
index afa0e3f..0000000
--- a/crates/servicepoint_binding_uniffi/src/brightness_grid.rs
+++ /dev/null
@@ -1,86 +0,0 @@
-use servicepoint::{Brightness, DataRef, Grid};
-use std::sync::{Arc, RwLock};
-
-#[derive(uniffi::Object)]
-pub struct BrightnessGrid {
- pub(crate) actual: RwLock,
-}
-
-impl BrightnessGrid {
- fn internal_new(actual: servicepoint::BrightnessGrid) -> Arc {
- Arc::new(Self {
- actual: RwLock::new(actual),
- })
- }
-}
-
-#[uniffi::export]
-impl BrightnessGrid {
- #[uniffi::constructor]
- pub fn new(width: u64, height: u64) -> Arc {
- Self::internal_new(servicepoint::BrightnessGrid::new(
- width as usize,
- height as usize,
- ))
- }
-
- #[uniffi::constructor]
- pub fn load(width: u64, height: u64, data: Vec) -> Arc {
- Self::internal_new(servicepoint::BrightnessGrid::saturating_load(
- width as usize,
- height as usize,
- &data,
- ))
- }
-
- #[uniffi::constructor]
- pub fn clone(other: &Arc) -> Arc {
- Self::internal_new(other.actual.read().unwrap().clone())
- }
-
- pub fn set(&self, x: u64, y: u64, value: u8) {
- self.actual.write().unwrap().set(
- x as usize,
- y as usize,
- Brightness::saturating_from(value),
- )
- }
-
- pub fn get(&self, x: u64, y: u64) -> u8 {
- self.actual
- .read()
- .unwrap()
- .get(x as usize, y as usize)
- .into()
- }
-
- pub fn fill(&self, value: u8) {
- self.actual
- .write()
- .unwrap()
- .fill(Brightness::saturating_from(value))
- }
- pub fn width(&self) -> u64 {
- self.actual.read().unwrap().width() as u64
- }
-
- pub fn height(&self) -> u64 {
- self.actual.read().unwrap().height() as u64
- }
-
- pub fn equals(&self, other: &BrightnessGrid) -> bool {
- let a = self.actual.read().unwrap();
- let b = other.actual.read().unwrap();
- *a == *b
- }
-
- pub fn copy_raw(&self) -> Vec {
- self.actual
- .read()
- .unwrap()
- .data_ref()
- .iter()
- .map(u8::from)
- .collect()
- }
-}
diff --git a/crates/servicepoint_binding_uniffi/src/char_grid.rs b/crates/servicepoint_binding_uniffi/src/char_grid.rs
deleted file mode 100644
index e5d59a8..0000000
--- a/crates/servicepoint_binding_uniffi/src/char_grid.rs
+++ /dev/null
@@ -1,169 +0,0 @@
-use crate::cp437_grid::Cp437Grid;
-use servicepoint::{Grid, SetValueSeriesError};
-use std::convert::Into;
-use std::sync::{Arc, RwLock};
-
-#[derive(uniffi::Object)]
-pub struct CharGrid {
- pub(crate) actual: RwLock,
-}
-
-#[derive(uniffi::Error, thiserror::Error, Debug)]
-pub enum CharGridError {
- #[error("Exactly one character was expected, but {value:?} was provided")]
- StringNotOneChar { value: String },
- #[error("The provided series was expected to have a length of {expected}, but was {actual}")]
- InvalidSeriesLength { actual: u64, expected: u64 },
- #[error("The index {index} was out of bounds for size {size}")]
- OutOfBounds { index: u64, size: u64 },
-}
-
-#[uniffi::export]
-impl CharGrid {
- #[uniffi::constructor]
- pub fn new(width: u64, height: u64) -> Arc {
- Self::internal_new(servicepoint::CharGrid::new(
- width as usize,
- height as usize,
- ))
- }
-
- #[uniffi::constructor]
- pub fn load(data: String) -> Arc {
- Self::internal_new(servicepoint::CharGrid::from(&*data))
- }
-
- #[uniffi::constructor]
- pub fn clone(other: &Arc) -> Arc {
- Self::internal_new(other.actual.read().unwrap().clone())
- }
-
- pub fn set(
- &self,
- x: u64,
- y: u64,
- value: String,
- ) -> Result<(), CharGridError> {
- let value = Self::str_to_char(value)?;
- self.actual
- .write()
- .unwrap()
- .set(x as usize, y as usize, value);
- Ok(())
- }
-
- pub fn get(&self, x: u64, y: u64) -> String {
- self.actual
- .read()
- .unwrap()
- .get(x as usize, y as usize)
- .into()
- }
-
- pub fn fill(&self, value: String) -> Result<(), CharGridError> {
- let value = Self::str_to_char(value)?;
- self.actual.write().unwrap().fill(value);
- Ok(())
- }
-
- pub fn width(&self) -> u64 {
- self.actual.read().unwrap().width() as u64
- }
-
- pub fn height(&self) -> u64 {
- self.actual.read().unwrap().height() as u64
- }
-
- pub fn equals(&self, other: &CharGrid) -> bool {
- let a = self.actual.read().unwrap();
- let b = other.actual.read().unwrap();
- *a == *b
- }
-
- pub fn as_string(&self) -> String {
- let grid = self.actual.read().unwrap();
- String::from(&*grid)
- }
-
- pub fn set_row(&self, y: u64, row: String) -> Result<(), CharGridError> {
- self.actual
- .write()
- .unwrap()
- .set_row(y as usize, &row.chars().collect::>())
- .map_err(CharGridError::from)
- }
-
- pub fn set_col(&self, x: u64, col: String) -> Result<(), CharGridError> {
- self.actual
- .write()
- .unwrap()
- .set_row(x as usize, &col.chars().collect::>())
- .map_err(CharGridError::from)
- }
-
- pub fn get_row(&self, y: u64) -> Result {
- self.actual
- .read()
- .unwrap()
- .get_row(y as usize)
- .map(String::from_iter)
- .ok_or(CharGridError::OutOfBounds {
- index: y,
- size: self.height(),
- })
- }
-
- pub fn get_col(&self, x: u64) -> Result {
- self.actual
- .read()
- .unwrap()
- .get_col(x as usize)
- .map(String::from_iter)
- .ok_or(CharGridError::OutOfBounds {
- index: x,
- size: self.width(),
- })
- }
-
- pub fn to_cp437(&self) -> Arc {
- Cp437Grid::internal_new(servicepoint::Cp437Grid::from(
- &*self.actual.read().unwrap(),
- ))
- }
-}
-
-impl CharGrid {
- pub(crate) fn internal_new(actual: servicepoint::CharGrid) -> Arc {
- Arc::new(Self {
- actual: RwLock::new(actual),
- })
- }
-
- fn str_to_char(value: String) -> Result {
- if value.len() != 1 {
- return Err(CharGridError::StringNotOneChar { value });
- }
-
- let value = value.chars().nth(0).unwrap();
- Ok(value)
- }
-}
-
-impl From for CharGridError {
- fn from(e: SetValueSeriesError) -> Self {
- match e {
- SetValueSeriesError::OutOfBounds { index, size } => {
- CharGridError::OutOfBounds {
- index: index as u64,
- size: size as u64,
- }
- }
- SetValueSeriesError::InvalidLength { actual, expected } => {
- CharGridError::InvalidSeriesLength {
- actual: actual as u64,
- expected: expected as u64,
- }
- }
- }
- }
-}
diff --git a/crates/servicepoint_binding_uniffi/src/command.rs b/crates/servicepoint_binding_uniffi/src/command.rs
deleted file mode 100644
index bb479ae..0000000
--- a/crates/servicepoint_binding_uniffi/src/command.rs
+++ /dev/null
@@ -1,175 +0,0 @@
-use crate::bitmap::Bitmap;
-use crate::bitvec::BitVec;
-use crate::brightness_grid::BrightnessGrid;
-use crate::char_grid::CharGrid;
-use crate::compression_code::CompressionCode;
-use crate::cp437_grid::Cp437Grid;
-use crate::errors::ServicePointError;
-use servicepoint::Origin;
-use std::sync::Arc;
-
-#[derive(uniffi::Object)]
-pub struct Command {
- pub(crate) actual: servicepoint::Command,
-}
-
-impl Command {
- fn internal_new(actual: servicepoint::Command) -> Arc {
- Arc::new(Command { actual })
- }
-}
-
-#[uniffi::export]
-impl Command {
- #[uniffi::constructor]
- pub fn clear() -> Arc