Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

links in docs, Cp437::load_ascii, WebSocket sending, Encoding conversion #12

Merged
merged 15 commits into from
Oct 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
242 changes: 197 additions & 45 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ members = [
]

[workspace.package]
version = "0.8.0"
version = "0.9.0"

[workspace.lints.rust]
missing-docs = "warn"
16 changes: 14 additions & 2 deletions crates/servicepoint/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,36 @@ bzip2 = { version = "0.4", optional = true }
zstd = { version = "0.13", optional = true }
rust-lzma = { version = "0.6.0", optional = true }
rand = { version = "0.8", optional = true }
tungstenite = { version = "0.24.0", optional = true }
once_cell = { version = "1.20.2", optional = true }

[features]
default = ["compression_lzma"]
default = ["compression_lzma", "protocol_udp", "cp437"]
compression_zlib = ["dep:flate2"]
compression_bzip2 = ["dep:bzip2"]
compression_lzma = ["dep:rust-lzma"]
compression_zstd = ["dep:zstd"]
all_compressions = ["compression_zlib", "compression_bzip2", "compression_lzma", "compression_zstd"]
rand = ["dep:rand"]
protocol_udp = []
protocol_websocket = ["dep:tungstenite"]
cp437 = ["dep:once_cell"]

[[example]]
name = "random_brightness"
required-features = ["rand"]

[[example]]
name = "game_of_life"
required-features = ["rand"]

[[example]]
name = "websocket"
required-features = ["protocol_websocket"]

[dev-dependencies]
# for examples
clap = { version = "4.5", features = ["derive"] }
rand = "0.8"

[lints]
workspace = true
38 changes: 24 additions & 14 deletions crates/servicepoint/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,17 @@ In [CCCB](https://berlin.ccc.de/), there is a big pixel matrix hanging on the wa
Display" or "Airport Display".
This crate contains a library for parsing, encoding and sending packets to this display via UDP.

## Installation

```bash
cargo add servicepoint
```
or
```toml
[dependencies]
servicepoint = "0.9.0"
```

## Examples

```rust
Expand All @@ -23,7 +34,7 @@ fn main() {
}
```

More examples are available in the crate.
More examples are available in the crate.
Execute `cargo run --example` for a list of available examples and `cargo run --example <name>` to run one.

## Note on stability
Expand All @@ -32,22 +43,21 @@ 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

```bash
cargo add servicepoint
```

## Features

This library has multiple compression libraries as optional dependencies.
If you do not need compression/decompression support you can disable those features.
In the likely case you only need one of them, you can include that one specifically.
This library has multiple optional dependencies.
You can choose to (not) include them by toggling the related features.

```toml
[dependencies]
servicepoint = { version = "0.8.0", default-features = false, features = ["compression-bz"] }
```
| Name | Default | Description |
|--------------------|---------|--------------------------------------------|
| compression_zlib | false | Enable additional compression algo |
| compression_bzip2 | false | Enable additional compression algo |
| compression_lzma | true | Enable additional compression algo |
| compression_zstd | false | Enable additional compression algo |
| protocol_udp | true | Connection::Udp |
| protocol_websocket | false | Connection::WebSocket |
| rand | false | impl Distribution<Brightness> for Standard |
| cp437 | true | Conversion to and from CP-437 |

## Everything else

Expand Down
20 changes: 8 additions & 12 deletions crates/servicepoint/examples/announce.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use clap::Parser;

use servicepoint::{Command, Connection, Cp437Grid, Grid, Origin};
use servicepoint::{CharGrid, Command, Connection, Cp437Grid, Origin};

#[derive(Parser, Debug)]
struct Cli {
Expand Down Expand Up @@ -31,19 +31,15 @@ fn main() {
.expect("sending clear failed");
}

let max_width = cli.text.iter().map(|t| t.len()).max().unwrap();
let text = cli.text.iter().fold(String::new(), move |str, line| {
let is_first = str.is_empty();
str + if is_first { "" } else { "\n" } + line
});

let mut chars = Cp437Grid::new(max_width, cli.text.len());
for y in 0..cli.text.len() {
let row = &cli.text[y];

for (x, char) in row.chars().enumerate() {
let char = char.try_into().expect("invalid input char");
chars.set(x, y, char);
}
}
let grid = CharGrid::from(&*text);
let cp437_grid = Cp437Grid::from(&grid);

connection
.send(Command::Cp437Data(Origin::new(0, 0), chars))
.send(Command::Cp437Data(Origin::new(0, 0), cp437_grid))
.expect("sending text failed");
}
27 changes: 27 additions & 0 deletions crates/servicepoint/examples/websocket.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//! Example for how to use the WebSocket connection

use servicepoint::{
Command, CompressionCode, Connection, Grid, Origin, PixelGrid,
};

fn main() {
// make connection mut
let mut connection =
Connection::open_websocket("ws://localhost:8080".parse().unwrap())
.unwrap();

// use send_mut instead of send
connection.send_mut(Command::Clear).unwrap();

let mut pixels = PixelGrid::max_sized();
pixels.fill(true);

// use send_mut instead of send
connection
.send_mut(Command::BitmapLinearWin(
Origin::ZERO,
pixels,
CompressionCode::Lzma,
))
.unwrap();
}
34 changes: 32 additions & 2 deletions crates/servicepoint/src/brightness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ impl From<BrightnessGrid> for Vec<u8> {
}
}

impl From<BrightnessGrid> for PrimitiveGrid<u8> {
fn from(value: PrimitiveGrid<Brightness>) -> Self {
impl From<&BrightnessGrid> for PrimitiveGrid<u8> {
fn from(value: &PrimitiveGrid<Brightness>) -> Self {
let u8s = value
.iter()
.map(|brightness| (*brightness).into())
Expand Down Expand Up @@ -109,3 +109,33 @@ impl Distribution<Brightness> for Standard {
Brightness(rng.gen_range(Brightness::MIN.0..=Brightness::MAX.0))
}
}

#[cfg(test)]
mod tests {
use super::*;
use crate::DataRef;

#[test]
fn brightness_from_u8() {
assert_eq!(Err(100), Brightness::try_from(100));
assert_eq!(Ok(Brightness(1)), Brightness::try_from(1))
}

#[test]
#[cfg(feature = "rand")]
fn rand_brightness() {
let mut rng = rand::thread_rng();
for _ in 0..100 {
let _: Brightness = rng.gen();
}
}

#[test]
fn to_u8_grid() {
let mut grid = BrightnessGrid::new(2, 2);
grid.set(1, 0, Brightness::MIN);
grid.set(0, 1, Brightness::MAX);
let actual = PrimitiveGrid::from(&grid);
assert_eq!(actual.data_ref(), &[11, 0, 11, 11]);
}
}
Loading