mirror of
https://github.com/cccb/servicepoint.git
synced 2025-01-18 10:00:14 +01:00
add websocket binary message protocol
This commit is contained in:
parent
f434b5bf83
commit
c7764c49e1
151
Cargo.lock
generated
151
Cargo.lock
generated
|
@ -84,12 +84,27 @@ dependencies = [
|
||||||
"wyz",
|
"wyz",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "block-buffer"
|
||||||
|
version = "0.10.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
|
||||||
|
dependencies = [
|
||||||
|
"generic-array",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "byteorder"
|
name = "byteorder"
|
||||||
version = "1.5.0"
|
version = "1.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bytes"
|
||||||
|
version = "1.7.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bzip2"
|
name = "bzip2"
|
||||||
version = "0.4.4"
|
version = "0.4.4"
|
||||||
|
@ -193,6 +208,15 @@ version = "1.0.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0"
|
checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cpufeatures"
|
||||||
|
version = "0.2.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crc32fast"
|
name = "crc32fast"
|
||||||
version = "1.4.2"
|
version = "1.4.2"
|
||||||
|
@ -202,6 +226,16 @@ dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crypto-common"
|
||||||
|
version = "0.1.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
||||||
|
dependencies = [
|
||||||
|
"generic-array",
|
||||||
|
"typenum",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "csbindgen"
|
name = "csbindgen"
|
||||||
version = "1.9.3"
|
version = "1.9.3"
|
||||||
|
@ -212,6 +246,22 @@ dependencies = [
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "data-encoding"
|
||||||
|
version = "2.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "digest"
|
||||||
|
version = "0.10.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
|
||||||
|
dependencies = [
|
||||||
|
"block-buffer",
|
||||||
|
"crypto-common",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "equivalent"
|
name = "equivalent"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
|
@ -244,12 +294,28 @@ dependencies = [
|
||||||
"miniz_oxide",
|
"miniz_oxide",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fnv"
|
||||||
|
version = "1.0.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "funty"
|
name = "funty"
|
||||||
version = "2.0.0"
|
version = "2.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
|
checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "generic-array"
|
||||||
|
version = "0.14.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
|
||||||
|
dependencies = [
|
||||||
|
"typenum",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
version = "0.2.15"
|
version = "0.2.15"
|
||||||
|
@ -279,6 +345,23 @@ version = "0.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "http"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"fnv",
|
||||||
|
"itoa",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "httparse"
|
||||||
|
version = "1.9.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "2.6.0"
|
version = "2.6.0"
|
||||||
|
@ -536,6 +619,7 @@ dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"rand",
|
"rand",
|
||||||
"rust-lzma",
|
"rust-lzma",
|
||||||
|
"tungstenite",
|
||||||
"zstd",
|
"zstd",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -556,6 +640,17 @@ dependencies = [
|
||||||
"servicepoint_binding_c",
|
"servicepoint_binding_c",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sha1"
|
||||||
|
version = "0.10.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"cpufeatures",
|
||||||
|
"digest",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "shlex"
|
name = "shlex"
|
||||||
version = "1.3.0"
|
version = "1.3.0"
|
||||||
|
@ -598,6 +693,26 @@ dependencies = [
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror"
|
||||||
|
version = "1.0.64"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror-impl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror-impl"
|
||||||
|
version = "1.0.64"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml"
|
name = "toml"
|
||||||
version = "0.8.19"
|
version = "0.8.19"
|
||||||
|
@ -632,12 +747,42 @@ dependencies = [
|
||||||
"winnow",
|
"winnow",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tungstenite"
|
||||||
|
version = "0.24.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "18e5b8366ee7a95b16d32197d0b2604b43a0be89dc5fac9f8e96ccafbaedda8a"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder",
|
||||||
|
"bytes",
|
||||||
|
"data-encoding",
|
||||||
|
"http",
|
||||||
|
"httparse",
|
||||||
|
"log",
|
||||||
|
"rand",
|
||||||
|
"sha1",
|
||||||
|
"thiserror",
|
||||||
|
"utf-8",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "typenum"
|
||||||
|
version = "1.17.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.13"
|
version = "1.0.13"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
|
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "utf-8"
|
||||||
|
version = "0.7.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "utf8parse"
|
name = "utf8parse"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
|
@ -650,6 +795,12 @@ version = "0.2.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "version_check"
|
||||||
|
version = "0.9.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasi"
|
name = "wasi"
|
||||||
version = "0.11.0+wasi-snapshot-preview1"
|
version = "0.11.0+wasi-snapshot-preview1"
|
||||||
|
|
|
@ -20,6 +20,7 @@ bzip2 = { version = "0.4", optional = true }
|
||||||
zstd = { version = "0.13", optional = true }
|
zstd = { version = "0.13", optional = true }
|
||||||
rust-lzma = { version = "0.6.0", optional = true }
|
rust-lzma = { version = "0.6.0", optional = true }
|
||||||
rand = { version = "0.8", optional = true }
|
rand = { version = "0.8", optional = true }
|
||||||
|
tungstenite = { version = "0.24.0", optional = true }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["compression_lzma", "protocol_udp"]
|
default = ["compression_lzma", "protocol_udp"]
|
||||||
|
@ -30,6 +31,7 @@ compression_zstd = ["dep:zstd"]
|
||||||
all_compressions = ["compression_zlib", "compression_bzip2", "compression_lzma", "compression_zstd"]
|
all_compressions = ["compression_zlib", "compression_bzip2", "compression_lzma", "compression_zstd"]
|
||||||
rand = ["dep:rand"]
|
rand = ["dep:rand"]
|
||||||
protocol_udp = []
|
protocol_udp = []
|
||||||
|
protocol_websocket = ["dep:tungstenite"]
|
||||||
|
|
||||||
[[example]]
|
[[example]]
|
||||||
name = "random_brightness"
|
name = "random_brightness"
|
||||||
|
|
|
@ -1,12 +1,5 @@
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
use log::debug;
|
|
||||||
|
|
||||||
#[cfg(feature = "protocol_udp")]
|
|
||||||
use log::info;
|
|
||||||
#[cfg(feature = "protocol_udp")]
|
|
||||||
use std::net::{ToSocketAddrs, UdpSocket};
|
|
||||||
|
|
||||||
use crate::packet::Packet;
|
use crate::packet::Packet;
|
||||||
|
|
||||||
/// A connection to the display.
|
/// A connection to the display.
|
||||||
|
@ -15,22 +8,54 @@ use crate::packet::Packet;
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// let connection = servicepoint::Connection::open("172.23.42.29:2342")
|
/// let connection = servicepoint::Connection::open("127.0.0.1:2342")
|
||||||
/// .expect("connection failed");
|
/// .expect("connection failed");
|
||||||
/// connection.send(servicepoint::Command::Clear)
|
/// connection.send(servicepoint::Command::Clear)
|
||||||
/// .expect("send failed");
|
/// .expect("send failed");
|
||||||
/// ```
|
/// ```
|
||||||
|
#[derive(Debug)]
|
||||||
pub enum Connection {
|
pub enum Connection {
|
||||||
/// A real connection using the UDP protocol
|
/// 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")]
|
#[cfg(feature = "protocol_udp")]
|
||||||
Udp(UdpSocket),
|
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(
|
||||||
|
tungstenite::WebSocket<
|
||||||
|
tungstenite::stream::MaybeTlsStream<std::net::TcpStream>,
|
||||||
|
>,
|
||||||
|
),
|
||||||
|
|
||||||
/// A fake connection for testing that does not actually send anything.
|
/// A fake connection for testing that does not actually send anything.
|
||||||
|
///
|
||||||
|
/// This variant allows immutable send.
|
||||||
Fake,
|
Fake,
|
||||||
|
|
||||||
|
/// A fake connection for testing that does not actually send anything.
|
||||||
|
///
|
||||||
|
/// This variant does not allow immutable send.
|
||||||
|
FakeMutableSend,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum SendError {
|
pub enum SendError {
|
||||||
IoError(std::io::Error),
|
IoError(std::io::Error),
|
||||||
|
#[cfg(feature = "protocol_websocket")]
|
||||||
|
WebsocketError(tungstenite::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Connection {
|
impl Connection {
|
||||||
|
@ -38,42 +63,85 @@ impl Connection {
|
||||||
///
|
///
|
||||||
/// Note that this is UDP, which means that the open call can succeed even if the display is unreachable.
|
/// 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
|
/// # Errors
|
||||||
///
|
///
|
||||||
/// Any errors resulting from binding the udp socket.
|
/// Any errors resulting from binding the udp socket.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// let connection = servicepoint::Connection::open("172.23.42.29:2342")
|
/// let connection = servicepoint::Connection::open("127.0.0.1:2342")
|
||||||
/// .expect("connection failed");
|
/// .expect("connection failed");
|
||||||
/// ```
|
/// ```
|
||||||
#[cfg(feature = "protocol_udp")]
|
#[cfg(feature = "protocol_udp")]
|
||||||
pub fn open(addr: impl ToSocketAddrs + Debug) -> std::io::Result<Self> {
|
pub fn open(
|
||||||
info!("connecting to {addr:?}");
|
addr: impl std::net::ToSocketAddrs + Debug,
|
||||||
let socket = UdpSocket::bind("0.0.0.0:0")?;
|
) -> std::io::Result<Self> {
|
||||||
|
log::info!("connecting to {addr:?}");
|
||||||
|
let socket = std::net::UdpSocket::bind("0.0.0.0:0")?;
|
||||||
socket.connect(addr)?;
|
socket.connect(addr)?;
|
||||||
Ok(Self::Udp(socket))
|
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
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// 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_mut(Command::Clear)
|
||||||
|
/// .expect("send failed");
|
||||||
|
/// ```
|
||||||
|
#[cfg(feature = "protocol_websocket")]
|
||||||
|
pub fn open_websocket(
|
||||||
|
uri: tungstenite::http::Uri,
|
||||||
|
) -> tungstenite::Result<Self> {
|
||||||
|
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(sock))
|
||||||
|
}
|
||||||
|
|
||||||
/// Send something packet-like to the display. Usually this is in the form of a Command.
|
/// Send something packet-like to the display. Usually this is in the form of a Command.
|
||||||
///
|
///
|
||||||
|
/// This variant can only be used for connections that support immutable send, e.g. [Connection::Udp].
|
||||||
|
///
|
||||||
|
/// If you want to be able to switch the protocol, you should use [Self::send_mut] instead.
|
||||||
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// - `packet`: the packet-like to send
|
/// - `packet`: the packet-like to send
|
||||||
///
|
///
|
||||||
/// returns: true if packet was sent, otherwise false
|
/// returns: true if packet was sent, otherwise false
|
||||||
///
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// If the connection does not support immutable send, e.g. for [Connection::WebSocket].
|
||||||
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # let connection = servicepoint::Connection::Fake;
|
/// let connection = servicepoint::Connection::Fake;
|
||||||
/// // turn off all pixels on display
|
/// // turn off all pixels on display
|
||||||
/// connection.send(servicepoint::Command::Clear)
|
/// connection.send(servicepoint::Command::Clear)
|
||||||
/// .expect("send failed");
|
/// .expect("send failed");
|
||||||
/// ```
|
/// ```
|
||||||
pub fn send(&self, packet: impl Into<Packet>) -> Result<(), SendError> {
|
pub fn send(&self, packet: impl Into<Packet>) -> Result<(), SendError> {
|
||||||
let packet = packet.into();
|
let packet = packet.into();
|
||||||
debug!("sending {packet:?}");
|
log::debug!("sending {packet:?}");
|
||||||
let data: Vec<u8> = packet.into();
|
let data: Vec<u8> = packet.into();
|
||||||
match self {
|
match self {
|
||||||
#[cfg(feature = "protocol_udp")]
|
#[cfg(feature = "protocol_udp")]
|
||||||
|
@ -87,6 +155,55 @@ impl Connection {
|
||||||
let _ = data;
|
let _ = data;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
#[allow(unreachable_patterns)] // depends on features
|
||||||
|
_ => {
|
||||||
|
panic!("Connection {:?} does not support immutable send", self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Send something packet-like to the display. Usually this is in the form of a Command.
|
||||||
|
///
|
||||||
|
/// This variant has to be used for connections that do not support immutable send, e.g. [Connection::WebSocket].
|
||||||
|
///
|
||||||
|
/// If you want to be able to switch the protocol, you should use this variant.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// - `packet`: the packet-like to send
|
||||||
|
///
|
||||||
|
/// returns: true if packet was sent, otherwise false
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// let mut connection = servicepoint::Connection::FakeMutableSend;
|
||||||
|
/// // turn off all pixels on display
|
||||||
|
/// connection.send_mut(servicepoint::Command::Clear)
|
||||||
|
/// .expect("send failed");
|
||||||
|
/// ```
|
||||||
|
pub fn send_mut(
|
||||||
|
&mut self,
|
||||||
|
packet: impl Into<Packet>,
|
||||||
|
) -> Result<(), SendError> {
|
||||||
|
match self {
|
||||||
|
#[cfg(feature = "protocol_websocket")]
|
||||||
|
Connection::WebSocket(socket) => {
|
||||||
|
let packet = packet.into();
|
||||||
|
log::debug!("sending {packet:?}");
|
||||||
|
let data: Vec<u8> = packet.into();
|
||||||
|
socket
|
||||||
|
.send(tungstenite::Message::Binary(data))
|
||||||
|
.map_err(SendError::WebsocketError)
|
||||||
|
}
|
||||||
|
Connection::FakeMutableSend => {
|
||||||
|
let packet = packet.into();
|
||||||
|
log::debug!("sending {packet:?}");
|
||||||
|
let data: Vec<u8> = packet.into();
|
||||||
|
let _ = data;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
_ => self.send(packet),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -102,4 +219,19 @@ mod tests {
|
||||||
let packet = Packet::try_from(data).unwrap();
|
let packet = Packet::try_from(data).unwrap();
|
||||||
Connection::Fake.send(packet).unwrap()
|
Connection::Fake.send(packet).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn send_fake_mutable() {
|
||||||
|
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::FakeMutableSend.send_mut(packet).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn send_fake_mutable_panic() {
|
||||||
|
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::FakeMutableSend.send(packet).unwrap()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue