refactor(cliprdr-format): hand-implement Error trait

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
This commit is contained in:
Marc-André Lureau 2025-07-23 16:46:26 +04:00 committed by Benoît Cortier
parent fc8f8ee279
commit 83ad04dd56
5 changed files with 84 additions and 25 deletions

1
Cargo.lock generated
View file

@ -2474,7 +2474,6 @@ version = "0.1.3"
dependencies = [
"ironrdp-core",
"png",
"thiserror 1.0.69",
]
[[package]]

View file

@ -17,7 +17,6 @@ test = false
[dependencies]
ironrdp-core = { path = "../ironrdp-core", version = "0.1" } # public
thiserror = "1" # FIXME: handwrite the Error trait implementations.
png = "0.17"
[lints]

View file

@ -2,31 +2,65 @@ use ironrdp_core::{
cast_int, ensure_fixed_part_size, invalid_field_err, Decode, DecodeResult, Encode, EncodeResult, ReadCursor,
WriteCursor,
};
use thiserror::Error;
/// Maximum size of PNG image that could be placed on the clipboard.
const MAX_BUFFER_SIZE: usize = 64 * 1024 * 1024; // 64 MB
#[derive(Debug, Error)]
#[derive(Debug)]
pub enum BitmapError {
#[error("decoding error")]
Decode(ironrdp_core::DecodeError),
#[error("encoding error")]
Encode(ironrdp_core::EncodeError),
#[error("unsupported bitmap: {0}")]
Unsupported(&'static str),
#[error("one of bitmap's dimensions is invalid")]
InvalidSize,
#[error("buffer size required for allocation is too big")]
BufferTooBig,
#[error("image width is too big")]
WidthTooBig,
#[error("image height is too big")]
HeightTooBig,
#[error("PNG encoding error")]
PngEncode(#[from] png::EncodingError),
#[error("PNG decoding error")]
PngDecode(#[from] png::DecodingError),
PngEncode(png::EncodingError),
PngDecode(png::DecodingError),
}
impl core::fmt::Display for BitmapError {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
BitmapError::Decode(_error) => write!(f, "decoding error"),
BitmapError::Encode(_error) => write!(f, "encoding error"),
BitmapError::Unsupported(s) => write!(f, "unsupported bitmap: {s}"),
BitmapError::InvalidSize => write!(f, "one of bitmap's dimensions is invalid"),
BitmapError::BufferTooBig => write!(f, "buffer size required for allocation is too big"),
BitmapError::WidthTooBig => write!(f, "image width is too big"),
BitmapError::HeightTooBig => write!(f, "image height is too big"),
BitmapError::PngEncode(_error) => write!(f, "PNG encoding error"),
BitmapError::PngDecode(_error) => write!(f, "PNG decoding error"),
}
}
}
impl core::error::Error for BitmapError {
fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
match self {
BitmapError::Decode(error) => Some(error),
BitmapError::Encode(error) => Some(error),
BitmapError::Unsupported(_) => None,
BitmapError::InvalidSize => None,
BitmapError::BufferTooBig => None,
BitmapError::WidthTooBig => None,
BitmapError::HeightTooBig => None,
BitmapError::PngEncode(encoding_error) => Some(encoding_error),
BitmapError::PngDecode(decoding_error) => Some(decoding_error),
}
}
}
impl From<png::EncodingError> for BitmapError {
fn from(error: png::EncodingError) -> Self {
BitmapError::PngEncode(error)
}
}
impl From<png::DecodingError> for BitmapError {
fn from(error: png::DecodingError) -> Self {
BitmapError::PngDecode(error)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]

View file

@ -1,17 +1,45 @@
use thiserror::Error;
#[derive(Debug, Error)]
#[derive(Debug)]
pub enum HtmlError {
#[error("invalid CF_HTML format")]
InvalidFormat,
#[error("invalid UTF-8")]
InvalidUtf8(#[from] core::str::Utf8Error),
#[error("failed to parse integer")]
InvalidInteger(#[from] core::num::ParseIntError),
#[error("invalid integer conversion")]
InvalidUtf8(core::str::Utf8Error),
InvalidInteger(core::num::ParseIntError),
InvalidConversion,
}
impl core::fmt::Display for HtmlError {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
HtmlError::InvalidFormat => write!(f, "invalid CF_HTML format"),
HtmlError::InvalidUtf8(_error) => write!(f, "invalid UTF-8"),
HtmlError::InvalidInteger(_error) => write!(f, "failed to parse integer"),
HtmlError::InvalidConversion => write!(f, "invalid integer conversion"),
}
}
}
impl core::error::Error for HtmlError {
fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
match self {
HtmlError::InvalidFormat => None,
HtmlError::InvalidUtf8(utf8_error) => Some(utf8_error),
HtmlError::InvalidInteger(parse_int_error) => Some(parse_int_error),
HtmlError::InvalidConversion => None,
}
}
}
impl From<core::str::Utf8Error> for HtmlError {
fn from(error: core::str::Utf8Error) -> Self {
HtmlError::InvalidUtf8(error)
}
}
impl From<core::num::ParseIntError> for HtmlError {
fn from(error: core::num::ParseIntError) -> Self {
HtmlError::InvalidInteger(error)
}
}
/// Converts `CF_HTML` format to plain HTML text.
///
/// Note that the `CF_HTML` format is using UTF-8, and the input is expected to be valid UTF-8.

1
fuzz/Cargo.lock generated
View file

@ -302,7 +302,6 @@ version = "0.1.3"
dependencies = [
"ironrdp-core",
"png",
"thiserror",
]
[[package]]