Skip to content

Commit

Permalink
add reason enum to use instead of string value for error messages
Browse files Browse the repository at this point in the history
  • Loading branch information
knickish committed Jan 18, 2025
1 parent a7113a2 commit 45c6bbb
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 67 deletions.
55 changes: 32 additions & 23 deletions src/serde_bin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,28 +59,44 @@ pub trait DeBin: Sized {
fn de_bin(offset: &mut usize, bytes: &[u8]) -> Result<Self, DeBinErr>;
}

/// The error message when failing to deserialize from raw bytes.
#[derive(Clone)]
#[non_exhaustive]
pub enum DeBinErrReason {
Length {
/// Expected Length
l: usize,
/// Actual Length
s: usize,
},
}

/// The error message when failing to deserialize.
#[derive(Clone)]
pub struct DeBinErr {
/// Offset
pub o: usize,
pub l: usize,
pub s: usize,
pub msg: DeBinErrReason,
}

impl DeBinErr {
/// Helper for constructing [`DeBinErr`]
pub fn new(o: usize, l: usize, s: usize) -> Self {
Self { o, l, s }
Self {
o,
msg: DeBinErrReason::Length { l, s },
}
}
}

impl core::fmt::Debug for DeBinErr {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(
f,
"Bin deserialize error at:{} wanted:{} bytes but max size is {}",
self.o, self.l, self.s
)
match self.msg {
DeBinErrReason::Length { l, s } => write!(
f,
"Bin deserialize error at:{} wanted:{} bytes but max size is {}",
self.o, l, s
),
}
}
}

Expand All @@ -107,8 +123,7 @@ macro_rules! impl_ser_de_bin_for {
if *o + l > d.len() {
return Err(DeBinErr {
o: *o,
l,
s: d.len(),
msg: DeBinErrReason::Length { l, s: d.len() },
});
}

Expand Down Expand Up @@ -152,8 +167,7 @@ impl DeBin for usize {
None => {
return Err(DeBinErr {
o: *o,
l,
s: d.len(),
msg: DeBinErrReason::Length { l, s: d.len() },
});
}
};
Expand All @@ -168,8 +182,7 @@ impl DeBin for u8 {
if *o + 1 > d.len() {
return Err(DeBinErr {
o: *o,
l: 1,
s: d.len(),
msg: DeBinErrReason::Length { l: 1, s: d.len() },
});
}
let m = d[*o];
Expand All @@ -195,8 +208,7 @@ impl DeBin for bool {
if *o + 1 > d.len() {
return Err(DeBinErr {
o: *o,
l: 1,
s: d.len(),
msg: DeBinErrReason::Length { l: 1, s: d.len() },
});
}
let m = d[*o];
Expand All @@ -223,17 +235,15 @@ impl DeBin for String {
if *o + len > d.len() {
return Err(DeBinErr {
o: *o,
l: 1,
s: d.len(),
msg: DeBinErrReason::Length { l: 1, s: d.len() },
});
}
let r = match core::str::from_utf8(&d[*o..(*o + len)]) {
Ok(r) => r.to_owned(),
Err(_) => {
return Err(DeBinErr {
o: *o,
l: len,
s: d.len(),
msg: DeBinErrReason::Length { l: len, s: d.len() },
})
}
};
Expand Down Expand Up @@ -374,8 +384,7 @@ where
if *o + 1 > d.len() {
return Err(DeBinErr {
o: *o,
l: 1,
s: d.len(),
msg: DeBinErrReason::Length { l: 1, s: d.len() },
});
}
let m = d[*o];
Expand Down
60 changes: 46 additions & 14 deletions src/serde_json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ pub trait DeJson: Sized {
}

/// A JSON parsed token.
#[derive(PartialEq, Debug, Default)]
#[derive(PartialEq, Debug, Default, Clone)]
#[non_exhaustive]
pub enum DeJsonTok {
Str,
Expand Down Expand Up @@ -142,23 +142,55 @@ pub struct DeJsonState {
pub col: usize,
}

/// The error message when failing to deserialize a JSON string.
#[derive(Clone)]
#[non_exhaustive]
pub enum DeJsonErrReason {
UnexpectedKey(String),
UnexpectedToken(DeJsonTok, String),
MissingKey(String),
NoSuchEnum(String),
OutOfRange(String),
WrongType(String),
CannotParse(String),
}

/// The error message when failing to deserialize a JSON string.
#[derive(Clone)]
pub struct DeJsonErr {
pub msg: String,
pub line: usize,
pub col: usize,
pub msg: DeJsonErrReason,
}

impl core::fmt::Debug for DeJsonErrReason {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::UnexpectedKey(name) => write!(f, "Unexpected key {}", name),
Self::MissingKey(name) => write!(f, "Key not found {}", name),
Self::NoSuchEnum(name) => write!(f, "Enum not defined {}", name),
Self::UnexpectedToken(token, name) => {
write!(f, "Unexpected token {:?} expected {} ", token, name)
}
Self::OutOfRange(value) => write!(f, "Value out of range {} ", value),
Self::WrongType(found) => write!(f, "Token wrong type {} ", found),
Self::CannotParse(unparseable) => write!(f, "Cannot parse {} ", unparseable),
}
}
}

impl core::fmt::Debug for DeJsonErr {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let DeJsonErr {
line,
col: column,
msg: reason,
} = self;
write!(
f,
"Json Deserialize error: {}, line:{} col:{}",
self.msg,
self.line + 1,
self.col + 1
"Json Deserialize error: {:?}, line:{} col:{}",
reason,
line + 1,
column + 1
)
}
}
Expand Down Expand Up @@ -188,55 +220,55 @@ impl DeJsonState {

pub fn err_exp(&self, name: &str) -> DeJsonErr {
DeJsonErr {
msg: format!("Unexpected key {}", name),
msg: DeJsonErrReason::UnexpectedKey(name.to_string()),
line: self.line,
col: self.col,
}
}

pub fn err_nf(&self, name: &str) -> DeJsonErr {
DeJsonErr {
msg: format!("Key not found {}", name),
msg: DeJsonErrReason::MissingKey(name.to_string()),
line: self.line,
col: self.col,
}
}

pub fn err_enum(&self, name: &str) -> DeJsonErr {
DeJsonErr {
msg: format!("Enum not defined {}", name),
msg: DeJsonErrReason::NoSuchEnum(name.to_string()),
line: self.line,
col: self.col,
}
}

pub fn err_token(&self, what: &str) -> DeJsonErr {
DeJsonErr {
msg: format!("Unexpected token {:?} expected {} ", self.tok, what),
msg: DeJsonErrReason::UnexpectedToken(self.tok.clone(), what.to_string()),
line: self.line,
col: self.col,
}
}

pub fn err_range(&self, what: &str) -> DeJsonErr {
DeJsonErr {
msg: format!("Value out of range {} ", what),
msg: DeJsonErrReason::OutOfRange(what.to_string()),
line: self.line,
col: self.col,
}
}

pub fn err_type(&self, what: &str) -> DeJsonErr {
DeJsonErr {
msg: format!("Token wrong type {} ", what),
msg: DeJsonErrReason::WrongType(what.to_string()),
line: self.line,
col: self.col,
}
}

pub fn err_parse(&self, what: &str) -> DeJsonErr {
DeJsonErr {
msg: format!("Cannot parse {} ", what),
msg: DeJsonErrReason::CannotParse(what.to_string()),
line: self.line,
col: self.col,
}
Expand Down
60 changes: 46 additions & 14 deletions src/serde_ron.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ pub trait DeRon: Sized {
}

/// A RON parsed token.
#[derive(PartialEq, Debug, Default)]
#[derive(PartialEq, Debug, Default, Clone)]
pub enum DeRonTok {
Ident,
Str,
Expand Down Expand Up @@ -133,23 +133,55 @@ pub struct DeRonState {
pub col: usize,
}

/// The error message when failing to deserialize a RON string.
#[derive(Clone)]
#[non_exhaustive]
pub enum DeRonErrReason {
UnexpectedKey(String),
UnexpectedToken(DeRonTok, String),
MissingKey(String),
NoSuchEnum(String),
OutOfRange(String),
WrongType(String),
CannotParse(String),
}

/// The error message when failing to deserialize a Ron string.
#[derive(Clone)]
pub struct DeRonErr {
pub msg: String,
pub line: usize,
pub col: usize,
pub msg: DeRonErrReason,
}

impl core::fmt::Debug for DeRonErrReason {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::UnexpectedKey(name) => write!(f, "Unexpected key {}", name),
Self::MissingKey(name) => write!(f, "Key not found {}", name),
Self::NoSuchEnum(name) => write!(f, "Enum not defined {}", name),
Self::UnexpectedToken(token, name) => {
write!(f, "Unexpected token {:?} expected {} ", token, name)
}
Self::OutOfRange(value) => write!(f, "Value out of range {} ", value),
Self::WrongType(found) => write!(f, "Token wrong type {} ", found),
Self::CannotParse(unparseable) => write!(f, "Cannot parse {} ", unparseable),
}
}
}

impl core::fmt::Debug for DeRonErr {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let DeRonErr {
line,
col: column,
msg: reason,
} = self;
write!(
f,
"Ron Deserialize error: {}, line:{} col:{}",
self.msg,
self.line + 1,
self.col + 1
"Ron Deserialize error: {:?}, line:{} col:{}",
reason,
line + 1,
column + 1
)
}
}
Expand Down Expand Up @@ -179,55 +211,55 @@ impl DeRonState {

pub fn err_exp(&self, name: &str) -> DeRonErr {
DeRonErr {
msg: format!("Unexpected key {}", name),
msg: DeRonErrReason::UnexpectedKey(name.to_string()),
line: self.line,
col: self.col,
}
}

pub fn err_nf(&self, name: &str) -> DeRonErr {
DeRonErr {
msg: format!("Key not found {}", name),
msg: DeRonErrReason::MissingKey(name.to_string()),
line: self.line,
col: self.col,
}
}

pub fn err_enum(&self, name: &str) -> DeRonErr {
DeRonErr {
msg: format!("Enum not defined {}", name),
msg: DeRonErrReason::NoSuchEnum(name.to_string()),
line: self.line,
col: self.col,
}
}

pub fn err_token(&self, what: &str) -> DeRonErr {
DeRonErr {
msg: format!("Unexpected token {:?} expected {} ", self.tok, what),
msg: DeRonErrReason::UnexpectedToken(self.tok.clone(), what.to_string()),
line: self.line,
col: self.col,
}
}

pub fn err_range(&self, what: &str) -> DeRonErr {
DeRonErr {
msg: format!("Value out of range {} ", what),
msg: DeRonErrReason::OutOfRange(what.to_string()),
line: self.line,
col: self.col,
}
}

pub fn err_type(&self, what: &str) -> DeRonErr {
DeRonErr {
msg: format!("Token wrong type {} ", what),
msg: DeRonErrReason::WrongType(what.to_string()),
line: self.line,
col: self.col,
}
}

pub fn err_parse(&self, what: &str) -> DeRonErr {
DeRonErr {
msg: format!("Cannot parse {} ", what),
msg: DeRonErrReason::CannotParse(what.to_string()),
line: self.line,
col: self.col,
}
Expand Down
Loading

0 comments on commit 45c6bbb

Please sign in to comment.