Skip to content

Commit 630525d

Browse files
refactor!: enable unwrap_used clippy correctness lint (#965)
Co-authored-by: Benoît CORTIER <git.divisible626@passmail.com>
1 parent a8b6fb1 commit 630525d

File tree

49 files changed

+534
-366
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+534
-366
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ float_cmp = "warn"
102102
lossy_float_literal = "warn"
103103
float_cmp_const = "warn"
104104
as_underscore = "warn"
105-
# TODO: unwrap_used = "warn" # Let’s either handle `None`, `Err` or use `expect` to give a reason.
105+
unwrap_used = "warn"
106106
large_stack_frames = "warn"
107107
mem_forget = "warn"
108108
mixed_read_write_in_expression = "warn"

benches/src/perfenc.rs

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#![allow(clippy::print_stderr)]
33
#![allow(clippy::print_stdout)]
44

5-
use core::num::NonZero;
5+
use core::num::{NonZeroU16, NonZeroUsize};
66
use core::time::Duration;
77
use std::io::Write as _;
88
use std::time::Instant;
@@ -59,13 +59,14 @@ async fn main() -> Result<(), anyhow::Error> {
5959
OptCodec::QoiZ => update_codecs.set_qoiz(Some(0)),
6060
};
6161

62-
let mut encoder = UpdateEncoder::new(DesktopSize { width, height }, flags, update_codecs);
62+
let mut encoder = UpdateEncoder::new(DesktopSize { width, height }, flags, update_codecs)
63+
.context("failed to initialize update encoder")?;
6364

6465
let mut total_raw = 0u64;
6566
let mut total_enc = 0u64;
6667
let mut n_updates = 0u64;
6768
let mut updates = DisplayUpdates::new(file, DesktopSize { width, height }, fps);
68-
while let Some(up) = updates.next_update().await {
69+
while let Some(up) = updates.next_update().await? {
6970
if let DisplayUpdate::Bitmap(ref up) = up {
7071
total_raw += up.data.len() as u64;
7172
} else {
@@ -82,7 +83,7 @@ async fn main() -> Result<(), anyhow::Error> {
8283
}
8384
n_updates += 1;
8485
print!(".");
85-
std::io::stdout().flush().unwrap();
86+
std::io::stdout().flush()?;
8687
}
8788
println!();
8889

@@ -119,20 +120,21 @@ impl DisplayUpdates {
119120

120121
#[async_trait::async_trait]
121122
impl RdpServerDisplayUpdates for DisplayUpdates {
122-
async fn next_update(&mut self) -> Option<DisplayUpdate> {
123+
async fn next_update(&mut self) -> anyhow::Result<Option<DisplayUpdate>> {
123124
let stride = self.desktop_size.width as usize * 4;
124125
let frame_size = stride * self.desktop_size.height as usize;
125126
let mut buf = vec![0u8; frame_size];
126-
if self.file.read_exact(&mut buf).await.is_err() {
127-
return None;
128-
}
127+
// FIXME: AsyncReadExt::read_exact is not cancellation safe.
128+
self.file.read_exact(&mut buf).await.context("read exact")?;
129129

130130
let now = Instant::now();
131131
if let Some(last_update_time) = self.last_update_time {
132132
let elapsed = now - last_update_time;
133133
if self.fps > 0 && elapsed < Duration::from_millis(1000 / self.fps) {
134134
sleep(Duration::from_millis(
135-
1000 / self.fps - u64::try_from(elapsed.as_millis()).unwrap(),
135+
1000 / self.fps
136+
- u64::try_from(elapsed.as_millis())
137+
.context("invalid `elapsed millis`: out of range integral conversion")?,
136138
))
137139
.await;
138140
}
@@ -142,13 +144,13 @@ impl RdpServerDisplayUpdates for DisplayUpdates {
142144
let up = DisplayUpdate::Bitmap(BitmapUpdate {
143145
x: 0,
144146
y: 0,
145-
width: self.desktop_size.width.try_into().unwrap(),
146-
height: self.desktop_size.height.try_into().unwrap(),
147+
width: NonZeroU16::new(self.desktop_size.width).context("width cannot be zero")?,
148+
height: NonZeroU16::new(self.desktop_size.height).context("height cannot be zero")?,
147149
format: PixelFormat::RgbX32,
148150
data: buf.into(),
149-
stride: NonZero::new(stride).unwrap(),
151+
stride: NonZeroUsize::new(stride).context("stride cannot be zero")?,
150152
});
151-
Some(up)
153+
Ok(Some(up))
152154
}
153155
}
154156

clippy.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ semicolon-outside-block-ignore-multiline = true
33
accept-comment-above-statement = true
44
accept-comment-above-attributes = true
55
allow-panic-in-tests = true
6+
allow-unwrap-in-tests = true

crates/ironrdp-acceptor/src/connection.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,7 @@ impl Sequence for Acceptor {
404404
.into_iter()
405405
.enumerate()
406406
.map(|(i, channel)| {
407-
let channel_id = u16::try_from(i).unwrap() + self.io_channel_id + 1;
407+
let channel_id = u16::try_from(i).expect("always in the range") + self.io_channel_id + 1;
408408
if let Some((type_id, c)) = channel {
409409
self.static_channels.attach_channel_id(type_id, channel_id);
410410
(channel_id, Some(c))

crates/ironrdp-ainput/src/lib.rs

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ use ironrdp_core::{
66
ensure_fixed_part_size, invalid_field_err, Decode, DecodeResult, Encode, EncodeResult, ReadCursor, WriteCursor,
77
};
88
use ironrdp_dvc::DvcEncode;
9-
use num_derive::{FromPrimitive, ToPrimitive};
10-
use num_traits::{FromPrimitive as _, ToPrimitive as _};
9+
use num_derive::FromPrimitive;
10+
use num_traits::FromPrimitive as _;
1111
// Advanced Input channel as defined from Freerdp, [here]:
1212
//
1313
// [here]: https://github.com/FreeRDP/FreeRDP/blob/master/include/freerdp/channels/ainput.h
@@ -93,11 +93,22 @@ impl<'de> Decode<'de> for VersionPdu {
9393
}
9494
}
9595

96-
#[derive(Debug, Copy, Clone, PartialEq, Eq, FromPrimitive, ToPrimitive)]
96+
#[derive(Debug, Copy, Clone, PartialEq, Eq, FromPrimitive)]
97+
#[repr(u16)]
9798
pub enum ServerPduType {
9899
Version = 0x01,
99100
}
100101

102+
impl ServerPduType {
103+
#[expect(
104+
clippy::as_conversions,
105+
reason = "guarantees discriminant layout, and as is the only way to cast enum -> primitive"
106+
)]
107+
fn as_u16(&self) -> u16 {
108+
*self as u16
109+
}
110+
}
111+
101112
impl<'a> From<&'a ServerPdu> for ServerPduType {
102113
fn from(s: &'a ServerPdu) -> Self {
103114
match s {
@@ -121,7 +132,7 @@ impl Encode for ServerPdu {
121132
fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
122133
ensure_fixed_part_size!(in: dst);
123134

124-
dst.write_u16(ServerPduType::from(self).to_u16().unwrap());
135+
dst.write_u16(ServerPduType::from(self).as_u16());
125136
match self {
126137
ServerPdu::Version(pdu) => pdu.encode(dst),
127138
}
@@ -220,7 +231,7 @@ impl Encode for ClientPdu {
220231
fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
221232
ensure_fixed_part_size!(in: dst);
222233

223-
dst.write_u16(ClientPduType::from(self).to_u16().unwrap());
234+
dst.write_u16(ClientPduType::from(self).as_u16());
224235
match self {
225236
ClientPdu::Mouse(pdu) => pdu.encode(dst),
226237
}
@@ -254,11 +265,22 @@ impl<'de> Decode<'de> for ClientPdu {
254265
}
255266
}
256267

257-
#[derive(Debug, Copy, Clone, PartialEq, Eq, FromPrimitive, ToPrimitive)]
268+
#[derive(Debug, Copy, Clone, PartialEq, Eq, FromPrimitive)]
269+
#[repr(u16)]
258270
pub enum ClientPduType {
259271
Mouse = 0x02,
260272
}
261273

274+
impl ClientPduType {
275+
#[expect(
276+
clippy::as_conversions,
277+
reason = "guarantees discriminant layout, and as is the only way to cast enum -> primitive"
278+
)]
279+
fn as_u16(self) -> u16 {
280+
self as u16
281+
}
282+
}
283+
262284
impl<'a> From<&'a ClientPdu> for ClientPduType {
263285
fn from(s: &'a ClientPdu) -> Self {
264286
match s {

crates/ironrdp-bench/benches/bench.rs

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use core::num::NonZero;
1+
use core::num::{NonZeroU16, NonZeroUsize};
22

33
use criterion::{criterion_group, criterion_main, Criterion};
44
use ironrdp_graphics::color_conversion::to_64x64_ycbcr_tile;
@@ -7,46 +7,70 @@ use ironrdp_server::bench::encoder::rfx::{rfx_enc, rfx_enc_tile};
77
use ironrdp_server::BitmapUpdate;
88

99
pub fn rfx_enc_tile_bench(c: &mut Criterion) {
10+
const WIDTH: NonZeroU16 = NonZeroU16::new(64).expect("value is guaranteed to be non-zero");
11+
const HEIGHT: NonZeroU16 = NonZeroU16::new(64).expect("value is guaranteed to be non-zero");
12+
const STRIDE: NonZeroUsize = NonZeroUsize::new(64 * 4).expect("value is guaranteed to be non-zero");
13+
1014
let quant = rfx::Quant::default();
1115
let algo = rfx::EntropyAlgorithm::Rlgr3;
16+
1217
let bitmap = BitmapUpdate {
1318
x: 0,
1419
y: 0,
15-
width: NonZero::new(64).unwrap(),
16-
height: NonZero::new(64).unwrap(),
20+
width: WIDTH,
21+
height: HEIGHT,
1722
format: ironrdp_server::PixelFormat::ARgb32,
1823
data: vec![0; 64 * 64 * 4].into(),
19-
stride: NonZero::new(64 * 4).unwrap(),
24+
stride: STRIDE,
2025
};
2126
c.bench_function("rfx_enc_tile", |b| b.iter(|| rfx_enc_tile(&bitmap, &quant, algo, 0, 0)));
2227
}
2328

2429
pub fn rfx_enc_bench(c: &mut Criterion) {
30+
const WIDTH: NonZeroU16 = NonZeroU16::new(2048).expect("value is guaranteed to be non-zero");
31+
const HEIGHT: NonZeroU16 = NonZeroU16::new(2048).expect("value is guaranteed to be non-zero");
32+
// FIXME/QUESTION: It looks like we have a bug here, don't we? The stride value should be 2048 * 4.
33+
const STRIDE: NonZeroUsize = NonZeroUsize::new(64 * 4).expect("value is guaranteed to be non-zero");
34+
2535
let quant = rfx::Quant::default();
2636
let algo = rfx::EntropyAlgorithm::Rlgr3;
37+
2738
let bitmap = BitmapUpdate {
2839
x: 0,
2940
y: 0,
30-
width: NonZero::new(2048).unwrap(),
31-
height: NonZero::new(2048).unwrap(),
41+
width: WIDTH,
42+
height: HEIGHT,
3243
format: ironrdp_server::PixelFormat::ARgb32,
3344
data: vec![0; 2048 * 2048 * 4].into(),
34-
stride: NonZero::new(64 * 4).unwrap(),
45+
stride: STRIDE,
3546
};
3647
c.bench_function("rfx_enc", |b| b.iter(|| rfx_enc(&bitmap, &quant, algo)));
3748
}
3849

3950
pub fn to_ycbcr_bench(c: &mut Criterion) {
4051
const WIDTH: usize = 64;
4152
const HEIGHT: usize = 64;
53+
4254
let input = vec![0; WIDTH * HEIGHT * 4];
4355
let stride = WIDTH * 4;
4456
let mut y = [0i16; WIDTH * HEIGHT];
4557
let mut cb = [0i16; WIDTH * HEIGHT];
4658
let mut cr = [0i16; WIDTH * HEIGHT];
4759
let format = ironrdp_graphics::image_processing::PixelFormat::ARgb32;
60+
4861
c.bench_function("to_ycbcr", |b| {
49-
b.iter(|| to_64x64_ycbcr_tile(&input, WIDTH, HEIGHT, stride, format, &mut y, &mut cb, &mut cr))
62+
b.iter(|| {
63+
to_64x64_ycbcr_tile(
64+
&input,
65+
WIDTH.try_into().expect("can't panic"),
66+
HEIGHT.try_into().expect("can't panic"),
67+
stride.try_into().expect("can't panic"),
68+
format,
69+
&mut y,
70+
&mut cb,
71+
&mut cr,
72+
)
73+
})
5074
});
5175
}
5276

crates/ironrdp-blocking/src/connector.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,9 @@ fn resolve_generator(
100100
loop {
101101
match state {
102102
GeneratorState::Suspended(request) => {
103-
let response = network_client.send(&request).unwrap();
103+
let response = network_client.send(&request).map_err(|e| {
104+
ConnectorError::new("network client send", ironrdp_connector::ConnectorErrorKind::Credssp(e))
105+
})?;
104106
state = generator.resume(Ok(response));
105107
}
106108
GeneratorState::Completed(client_state) => {

crates/ironrdp-client/src/app.rs

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@ use core::time::Duration;
55
use std::sync::Arc;
66
use std::time::Instant;
77

8+
use anyhow::Context as _;
89
use raw_window_handle::{DisplayHandle, HasDisplayHandle as _};
910
use tokio::sync::mpsc;
10-
use tracing::{debug, error, trace};
11+
use tracing::{debug, error, trace, warn};
1112
use winit::application::ApplicationHandler;
1213
use winit::dpi::{LogicalPosition, PhysicalSize};
1314
use winit::event::{self, WindowEvent};
@@ -38,7 +39,9 @@ impl App {
3839
// SAFETY: We drop the softbuffer context right before the event loop is stopped, thus making this safe.
3940
// FIXME: This is not a sufficient proof and the API is actually unsound as-is.
4041
let display_handle = unsafe {
41-
core::mem::transmute::<DisplayHandle<'_>, DisplayHandle<'static>>(event_loop.display_handle().unwrap())
42+
core::mem::transmute::<DisplayHandle<'_>, DisplayHandle<'static>>(
43+
event_loop.display_handle().context("get display handle")?,
44+
)
4245
};
4346
let context = softbuffer::Context::new(display_handle)
4447
.map_err(|e| anyhow::anyhow!("unable to initialize softbuffer context: {e}"))?;
@@ -65,9 +68,12 @@ impl App {
6568
};
6669
let scale_factor = (window.scale_factor() * 100.0) as u32;
6770

71+
let width = u16::try_from(size.width).expect("reasonable width");
72+
let height = u16::try_from(size.height).expect("reasonable height");
73+
6874
let _ = self.input_event_sender.send(RdpInputEvent::Resize {
69-
width: u16::try_from(size.width).unwrap(),
70-
height: u16::try_from(size.height).unwrap(),
75+
width,
76+
height,
7177
scale_factor,
7278
// TODO: it should be possible to get the physical size here, however winit doesn't make it straightforward.
7379
// FreeRDP does it based on DPI reading grabbed via [`SDL_GetDisplayDPI`](https://wiki.libsdl.org/SDL2/SDL_GetDisplayDPI):
@@ -160,7 +166,14 @@ impl ApplicationHandler<RdpOutputEvent> for App {
160166
// }
161167
WindowEvent::KeyboardInput { event, .. } => {
162168
if let Some(scancode) = event.physical_key.to_scancode() {
163-
let scancode = ironrdp::input::Scancode::from_u16(u16::try_from(scancode).unwrap());
169+
let scancode = match u16::try_from(scancode) {
170+
Ok(scancode) => scancode,
171+
Err(_) => {
172+
warn!("Unsupported scancode: `{scancode:#X}`; ignored");
173+
return;
174+
}
175+
};
176+
let scancode = ironrdp::input::Scancode::from_u16(scancode);
164177

165178
let operation = match event.state {
166179
event::ElementState::Pressed => ironrdp::input::Operation::KeyPressed(scancode),
@@ -325,13 +338,10 @@ impl ApplicationHandler<RdpOutputEvent> for App {
325338
RdpOutputEvent::Image { buffer, width, height } => {
326339
trace!(width = ?width, height = ?height, "Received image with size");
327340
trace!(window_physical_size = ?window.inner_size(), "Drawing image to the window with size");
328-
self.buffer_size = (width, height);
341+
self.buffer_size = (width.get(), height.get());
329342
self.buffer = buffer;
330343
surface
331-
.resize(
332-
NonZeroU32::new(u32::from(width)).unwrap(),
333-
NonZeroU32::new(u32::from(height)).unwrap(),
334-
)
344+
.resize(NonZeroU32::from(width), NonZeroU32::from(height))
335345
.expect("surface resize");
336346

337347
window.request_redraw();

crates/ironrdp-client/src/config.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -439,10 +439,9 @@ impl Config {
439439
desktop_scale_factor: 0, // Default to 0 per FreeRDP
440440
bitmap: Some(bitmap),
441441
client_build: semver::Version::parse(env!("CARGO_PKG_VERSION"))
442-
.map(|version| version.major * 100 + version.minor * 10 + version.patch)
443-
.unwrap_or(0)
442+
.map_or(0, |version| version.major * 100 + version.minor * 10 + version.patch)
444443
.pipe(u32::try_from)
445-
.unwrap(),
444+
.context("cargo package version")?,
446445
client_name: whoami::fallible::hostname().unwrap_or_else(|_| "ironrdp".to_owned()),
447446
// NOTE: hardcode this value like in freerdp
448447
// https://github.com/FreeRDP/FreeRDP/blob/4e24b966c86fdf494a782f0dfcfc43a057a2ea60/libfreerdp/core/settings.c#LL49C34-L49C70

crates/ironrdp-client/src/main.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ fn main() -> anyhow::Result<()> {
2222
// TODO: get window size & scale factor from GUI/App
2323
let window_size = (1024, 768);
2424
config.connector.desktop_scale_factor = 0;
25-
config.connector.desktop_size.width = u16::try_from(window_size.0).unwrap();
26-
config.connector.desktop_size.height = u16::try_from(window_size.1).unwrap();
25+
config.connector.desktop_size.width = window_size.0;
26+
config.connector.desktop_size.height = window_size.1;
2727

2828
let rt = runtime::Builder::new_multi_thread()
2929
.enable_all()

0 commit comments

Comments
 (0)