mirror of
https://github.com/cccb/servicepoint.git
synced 2025-01-18 10:00:14 +01:00
add function to load Cp437Grid from str
This commit is contained in:
parent
21cc7e3f12
commit
03f7495695
|
@ -4,18 +4,13 @@ use crate::{
|
|||
command_code::CommandCode,
|
||||
compression::into_decompressed,
|
||||
packet::{Header, Packet},
|
||||
Brightness, BrightnessGrid, CompressionCode, Origin, PixelGrid, Pixels,
|
||||
PrimitiveGrid, SpBitVec, Tiles, TILE_SIZE,
|
||||
Brightness, BrightnessGrid, CompressionCode, Cp437Grid, Origin, PixelGrid,
|
||||
Pixels, PrimitiveGrid, SpBitVec, Tiles, TILE_SIZE,
|
||||
};
|
||||
|
||||
/// Type alias for documenting the meaning of the u16 in enum values
|
||||
pub type Offset = usize;
|
||||
|
||||
/// A grid containing codepage 437 characters.
|
||||
///
|
||||
/// The encoding is currently not enforced.
|
||||
pub type Cp437Grid = PrimitiveGrid<u8>;
|
||||
|
||||
/// A low-level display command.
|
||||
///
|
||||
/// This struct and associated functions implement the UDP protocol for the display.
|
||||
|
@ -92,9 +87,8 @@ pub enum Command {
|
|||
///
|
||||
/// ```rust
|
||||
/// # use servicepoint::{Command, Connection, Cp437Grid, Origin};
|
||||
/// # let connection = Connection::open("127.0.0.1:2342").unwrap();
|
||||
/// let chars = ['H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd'].map(move |c| c as u8);
|
||||
/// let grid = Cp437Grid::load(5, 2, &chars);
|
||||
/// # let connection = Connection::Fake;
|
||||
/// let grid = Cp437Grid::load_ascii("Hello\nWorld", 5, false).unwrap();
|
||||
/// connection.send(Command::Cp437Data(Origin::new(2, 2), grid)).unwrap();
|
||||
/// ```
|
||||
Cp437Data(Origin<Tiles>, Cp437Grid),
|
||||
|
|
100
crates/servicepoint/src/cp437.rs
Normal file
100
crates/servicepoint/src/cp437.rs
Normal file
|
@ -0,0 +1,100 @@
|
|||
use crate::cp437::Cp437LoadError::InvalidChar;
|
||||
use crate::{Grid, PrimitiveGrid};
|
||||
|
||||
/// A grid containing codepage 437 characters.
|
||||
///
|
||||
/// The encoding is currently not enforced.
|
||||
pub type Cp437Grid = PrimitiveGrid<u8>;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Cp437LoadError {
|
||||
InvalidChar { index: usize, 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<Self, Cp437LoadError> {
|
||||
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(InvalidChar { 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)
|
||||
}
|
||||
}
|
||||
|
||||
#[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);
|
||||
}
|
||||
}
|
|
@ -41,9 +41,10 @@ pub use bitvec;
|
|||
use bitvec::prelude::{BitVec, Msb0};
|
||||
|
||||
pub use crate::brightness::{Brightness, BrightnessGrid};
|
||||
pub use crate::command::{Command, Cp437Grid, Offset};
|
||||
pub use crate::command::{Command, Offset};
|
||||
pub use crate::compression_code::CompressionCode;
|
||||
pub use crate::connection::Connection;
|
||||
pub use crate::cp437::Cp437Grid;
|
||||
pub use crate::data_ref::DataRef;
|
||||
pub use crate::grid::Grid;
|
||||
pub use crate::origin::{Origin, Pixels, Tiles};
|
||||
|
@ -58,6 +59,7 @@ mod command_code;
|
|||
mod compression;
|
||||
mod compression_code;
|
||||
mod connection;
|
||||
mod cp437;
|
||||
mod data_ref;
|
||||
mod grid;
|
||||
mod origin;
|
||||
|
|
|
@ -40,7 +40,9 @@ pub unsafe extern "C" fn sp_cp437_grid_new(
|
|||
width: usize,
|
||||
height: usize,
|
||||
) -> *mut SPCp437Grid {
|
||||
Box::into_raw(Box::new(SPCp437Grid(servicepoint::Cp437Grid::new(width, height))))
|
||||
Box::into_raw(Box::new(SPCp437Grid(servicepoint::Cp437Grid::new(
|
||||
width, height,
|
||||
))))
|
||||
}
|
||||
|
||||
/// Loads a `SPCp437Grid` with the specified dimensions from the provided data.
|
||||
|
@ -67,7 +69,9 @@ pub unsafe extern "C" fn sp_cp437_grid_load(
|
|||
data_length: usize,
|
||||
) -> *mut SPCp437Grid {
|
||||
let data = std::slice::from_raw_parts(data, data_length);
|
||||
Box::into_raw(Box::new(SPCp437Grid(servicepoint::Cp437Grid::load(width, height, data))))
|
||||
Box::into_raw(Box::new(SPCp437Grid(servicepoint::Cp437Grid::load(
|
||||
width, height, data,
|
||||
))))
|
||||
}
|
||||
|
||||
/// Clones a `SPCp437Grid`.
|
||||
|
|
Loading…
Reference in a new issue