add a bunch of lints and change more panics to result/option
Some checks failed
Rust / build (pull_request) Failing after 1m7s
Some checks failed
Rust / build (pull_request) Failing after 1m7s
This commit is contained in:
parent
4ccbd57ba8
commit
08ed6a6fee
12 changed files with 145 additions and 39 deletions
18
Cargo.toml
18
Cargo.toml
|
|
@ -9,6 +9,7 @@ homepage = "https://docs.rs/crate/servicepoint"
|
|||
repository = "https://git.berlin.ccc.de/servicepoint/servicepoint"
|
||||
readme = "README.md"
|
||||
keywords = ["cccb", "cccb-servicepoint"]
|
||||
rust-version = "1.70.0"
|
||||
|
||||
[lib]
|
||||
crate-type = ["rlib"]
|
||||
|
|
@ -55,6 +56,23 @@ clap = { version = "4.5", features = ["derive"] }
|
|||
|
||||
[lints.rust]
|
||||
missing-docs = "warn"
|
||||
deprecated-safe = "warn"
|
||||
future-incompatible = "warn"
|
||||
keyword-idents = "warn"
|
||||
let-underscore = "warn"
|
||||
nonstandard-style = "warn"
|
||||
refining_impl_trait_reachable = "warn"
|
||||
rust-2024-compatibility = "warn"
|
||||
|
||||
[lints.clippy]
|
||||
unwrap_used = "warn"
|
||||
expect_used = "warn"
|
||||
panic = "warn"
|
||||
incompatible_msrv = "forbid"
|
||||
|
||||
[lints.rustdoc]
|
||||
private_doc_tests = "warn"
|
||||
unescaped_backticks = "warn"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
|
|
|
|||
|
|
@ -60,6 +60,8 @@ There should be no breaking changes in patch releases, but there may also be fea
|
|||
|
||||
All of this means for you: please specify the full version including patch in your Cargo.toml until 1.0 is released.
|
||||
|
||||
Release notes are published [here](https://git.berlin.ccc.de/servicepoint/servicepoint/releases), please check them before updating.
|
||||
|
||||
## Features
|
||||
|
||||
This library has multiple optional dependencies.
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ use rand::{
|
|||
///
|
||||
/// let b = Brightness::try_from(7).unwrap();
|
||||
/// # let connection = FakeConnection;
|
||||
/// let result = connection.send(b);
|
||||
/// let result = connection.send(BrightnessCommand::from(b));
|
||||
/// ```
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Ord, PartialOrd)]
|
||||
pub struct Brightness(u8);
|
||||
|
|
@ -90,7 +90,7 @@ mod tests {
|
|||
fn rand_brightness() {
|
||||
let mut rng = rand::thread_rng();
|
||||
for _ in 0..100 {
|
||||
let _: Brightness = rng.gen();
|
||||
let _: Brightness = rng.r#gen();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -104,6 +104,6 @@ mod tests {
|
|||
#[cfg(feature = "rand")]
|
||||
fn test() {
|
||||
let mut rng = rand::thread_rng();
|
||||
assert_ne!(rng.gen::<Brightness>(), rng.gen());
|
||||
assert_ne!(rng.r#gen::<Brightness>(), rng.r#gen());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{
|
||||
command_code::CommandCode, commands::TryFromPacketError, Brightness,
|
||||
Header, Packet, TypedCommand,
|
||||
command_code::CommandCode, commands::check_command_code,
|
||||
commands::TryFromPacketError, Brightness, Header, Packet, TypedCommand,
|
||||
};
|
||||
|
||||
/// Set the brightness of all tiles to the same value.
|
||||
|
|
@ -41,7 +41,7 @@ impl TryFrom<Packet> for BrightnessCommand {
|
|||
let Packet {
|
||||
header:
|
||||
Header {
|
||||
command_code: _,
|
||||
command_code,
|
||||
a,
|
||||
b,
|
||||
c,
|
||||
|
|
@ -49,6 +49,9 @@ impl TryFrom<Packet> for BrightnessCommand {
|
|||
},
|
||||
payload,
|
||||
} = packet;
|
||||
|
||||
check_command_code(command_code, CommandCode::Brightness)?;
|
||||
|
||||
if payload.len() != 1 {
|
||||
return Err(TryFromPacketError::UnexpectedPayloadSize(
|
||||
1,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use crate::{
|
||||
command_code::CommandCode, commands::TryFromPacketError, BrightnessGrid,
|
||||
ByteGrid, Header, Origin, Packet, Tiles, TypedCommand,
|
||||
command_code::CommandCode, commands::check_command_code,
|
||||
commands::TryFromPacketError, BrightnessGrid, ByteGrid, Header, Origin,
|
||||
Packet, Tiles, TypedCommand,
|
||||
};
|
||||
|
||||
/// Set the brightness of individual tiles in a rectangular area of the display.
|
||||
|
|
@ -29,7 +30,7 @@ impl TryFrom<Packet> for BrightnessGridCommand {
|
|||
let Packet {
|
||||
header:
|
||||
Header {
|
||||
command_code: _,
|
||||
command_code,
|
||||
a: x,
|
||||
b: y,
|
||||
c: width,
|
||||
|
|
@ -38,8 +39,21 @@ impl TryFrom<Packet> for BrightnessGridCommand {
|
|||
payload,
|
||||
} = packet;
|
||||
|
||||
let grid =
|
||||
ByteGrid::load(width as usize, height as usize, &payload).unwrap();
|
||||
check_command_code(command_code, CommandCode::CharBrightness)?;
|
||||
|
||||
let expected_size = width as usize * height as usize;
|
||||
if payload.len() != expected_size {
|
||||
return Err(TryFromPacketError::UnexpectedPayloadSize(
|
||||
payload.len(),
|
||||
expected_size,
|
||||
));
|
||||
}
|
||||
|
||||
let grid = ByteGrid::from_raw_parts_unchecked(
|
||||
width as usize,
|
||||
height as usize,
|
||||
payload,
|
||||
);
|
||||
let grid = match BrightnessGrid::try_from(grid) {
|
||||
Ok(grid) => grid,
|
||||
Err(val) => return Err(TryFromPacketError::InvalidBrightness(val)),
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use crate::{
|
||||
command_code::CommandCode, commands::TryFromPacketError, CharGrid, Header,
|
||||
Origin, Packet, Tiles, TypedCommand,
|
||||
command_code::CommandCode, commands::check_command_code,
|
||||
commands::TryFromPacketError, CharGrid, Header, Origin, Packet, Tiles,
|
||||
TypedCommand,
|
||||
};
|
||||
|
||||
/// Show text on the screen.
|
||||
|
|
@ -40,19 +41,35 @@ impl TryFrom<Packet> for CharGridCommand {
|
|||
let Packet {
|
||||
header:
|
||||
Header {
|
||||
command_code: _,
|
||||
a,
|
||||
b,
|
||||
c,
|
||||
d,
|
||||
command_code,
|
||||
a: origin_x,
|
||||
b: origin_y,
|
||||
c: width,
|
||||
d: height,
|
||||
},
|
||||
payload,
|
||||
} = packet;
|
||||
|
||||
check_command_code(command_code, CommandCode::Utf8Data)?;
|
||||
|
||||
let payload: Vec<_> =
|
||||
String::from_utf8(payload.clone())?.chars().collect();
|
||||
|
||||
let expected_size = width as usize * height as usize;
|
||||
if payload.len() != expected_size {
|
||||
return Err(TryFromPacketError::UnexpectedPayloadSize(
|
||||
expected_size,
|
||||
payload.len(),
|
||||
));
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
origin: Origin::new(a as usize, b as usize),
|
||||
grid: CharGrid::load(c as usize, d as usize, &payload).unwrap(),
|
||||
origin: Origin::new(origin_x as usize, origin_y as usize),
|
||||
grid: CharGrid::from_raw_parts_unchecked(
|
||||
width as usize,
|
||||
height as usize,
|
||||
payload,
|
||||
),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use crate::{
|
||||
command_code::CommandCode, commands::TryFromPacketError, Cp437Grid, Header,
|
||||
Origin, Packet, Tiles, TypedCommand,
|
||||
command_code::CommandCode, commands::check_command_code,
|
||||
commands::TryFromPacketError, Cp437Grid, Header, Origin, Packet, Tiles,
|
||||
TypedCommand,
|
||||
};
|
||||
|
||||
/// Show text on the screen.
|
||||
|
|
@ -51,17 +52,32 @@ impl TryFrom<Packet> for Cp437GridCommand {
|
|||
let Packet {
|
||||
header:
|
||||
Header {
|
||||
command_code: _,
|
||||
a,
|
||||
b,
|
||||
c,
|
||||
d,
|
||||
command_code,
|
||||
a: origin_x,
|
||||
b: origin_y,
|
||||
c: width,
|
||||
d: height,
|
||||
},
|
||||
payload,
|
||||
} = packet;
|
||||
|
||||
check_command_code(command_code, CommandCode::Cp437Data)?;
|
||||
|
||||
let expected_size = width as usize * height as usize;
|
||||
if payload.len() != expected_size {
|
||||
return Err(TryFromPacketError::UnexpectedPayloadSize(
|
||||
expected_size,
|
||||
payload.len(),
|
||||
));
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
origin: Origin::new(a as usize, b as usize),
|
||||
grid: Cp437Grid::load(c as usize, d as usize, &payload).unwrap(),
|
||||
origin: Origin::new(origin_x as usize, origin_y as usize),
|
||||
grid: Cp437Grid::from_raw_parts_unchecked(
|
||||
width as usize,
|
||||
height as usize,
|
||||
payload,
|
||||
),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -106,6 +106,17 @@ fn check_command_code_only(
|
|||
}
|
||||
}
|
||||
|
||||
fn check_command_code(
|
||||
actual: u16,
|
||||
expected: CommandCode,
|
||||
) -> Result<(), TryFromPacketError> {
|
||||
if actual != u16::from(expected) {
|
||||
Err(TryFromPacketError::InvalidCommand(actual))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::*;
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ pub(crate) fn into_decompressed(
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::unwrap_used)]
|
||||
pub(crate) fn into_compressed(
|
||||
kind: CompressionCode,
|
||||
payload: Payload,
|
||||
|
|
|
|||
|
|
@ -20,10 +20,13 @@ pub type BrightnessGrid = ValueGrid<Brightness>;
|
|||
|
||||
impl BrightnessGrid {
|
||||
/// Like [Self::load], but ignoring any out-of-range brightness values
|
||||
pub fn saturating_load(width: usize, height: usize, data: &[u8]) -> Self {
|
||||
pub fn saturating_load(
|
||||
width: usize,
|
||||
height: usize,
|
||||
data: &[u8],
|
||||
) -> Option<Self> {
|
||||
ValueGrid::load(width, height, data)
|
||||
.unwrap()
|
||||
.map(Brightness::saturating_from)
|
||||
.map(move |grid| grid.map(Brightness::saturating_from))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -42,7 +45,7 @@ impl From<&BrightnessGrid> for ByteGrid {
|
|||
.iter()
|
||||
.map(|brightness| (*brightness).into())
|
||||
.collect::<Vec<u8>>();
|
||||
ValueGrid::load(value.width(), value.height(), &u8s).unwrap()
|
||||
Self::from_raw_parts_unchecked(value.width(), value.height(), u8s)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -54,10 +57,11 @@ impl TryFrom<ByteGrid> for BrightnessGrid {
|
|||
.iter()
|
||||
.map(|b| Brightness::try_from(*b))
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
Ok(
|
||||
BrightnessGrid::load(value.width(), value.height(), &brightnesses)
|
||||
.unwrap(),
|
||||
)
|
||||
Ok(Self::from_raw_parts_unchecked(
|
||||
value.width(),
|
||||
value.height(),
|
||||
brightnesses,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -88,7 +92,7 @@ mod tests {
|
|||
]
|
||||
)
|
||||
.unwrap(),
|
||||
BrightnessGrid::saturating_load(2, 2, &[255u8, 23, 0, 42])
|
||||
BrightnessGrid::saturating_load(2, 2, &[255u8, 23, 0, 42]).unwrap()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@ impl CharGrid {
|
|||
let height = lines.len();
|
||||
let mut result = Self::new(width, height);
|
||||
for (row, text_line) in lines.iter().enumerate() {
|
||||
#[allow(clippy::unwrap_used)]
|
||||
// we calculated the width before setting
|
||||
result.set_row_str(row, text_line).unwrap()
|
||||
}
|
||||
result
|
||||
|
|
|
|||
|
|
@ -101,6 +101,20 @@ impl<T: Value> ValueGrid<T> {
|
|||
})
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub(crate) fn from_raw_parts_unchecked(
|
||||
width: usize,
|
||||
height: usize,
|
||||
data: Vec<T>,
|
||||
) -> Self {
|
||||
debug_assert_eq!(data.len(), width * height);
|
||||
Self {
|
||||
data,
|
||||
width,
|
||||
height,
|
||||
}
|
||||
}
|
||||
|
||||
/// Iterate over all cells in [ValueGrid].
|
||||
///
|
||||
/// Order is equivalent to the following loop:
|
||||
|
|
@ -189,7 +203,11 @@ impl<T: Value> ValueGrid<T> {
|
|||
.iter()
|
||||
.map(|elem| f(*elem))
|
||||
.collect::<Vec<_>>();
|
||||
ValueGrid::load(self.width(), self.height(), &data).unwrap()
|
||||
ValueGrid {
|
||||
width: self.width(),
|
||||
height: self.height(),
|
||||
data,
|
||||
}
|
||||
}
|
||||
|
||||
/// Copies a row from the grid.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue