Skip to content

Commit 80347df

Browse files
committed
feat: add serde to peer_id
Signed-off-by: Sacha Froment <[email protected]>
1 parent dd07e0f commit 80347df

File tree

7 files changed

+551
-72
lines changed

7 files changed

+551
-72
lines changed

Cargo.lock

Lines changed: 55 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sf-peer-id/Cargo.toml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,18 @@ version = "0.1.0"
44
edition = "2024"
55

66
[dependencies]
7+
unsigned-varint = { version = "0.8.0", default-features = false }
8+
serde = { version = "1.0.116", optional = true, default-features = false }
9+
10+
[dev-dependencies]
11+
serde_json = "1.0.140"
12+
serde_bytes = "0.11"
13+
bincode = { version = "2.0.0-rc.3", features = ["serde"] }
714

815
[features]
9-
default = ["std"]
10-
std = []
16+
default = ["std", "serde"]
17+
std = ["unsigned-varint/std"]
18+
serde = ["dep:serde"]
1119

1220
[package.metadata.docs.rs]
1321
all-features = true

sf-peer-id/src/error.rs

Lines changed: 148 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,96 @@
11
use core::fmt;
2+
use unsigned_varint::decode;
3+
4+
#[cfg(not(feature = "std"))]
5+
use core2::io;
6+
#[cfg(feature = "std")]
7+
use std::io;
28

39
/// Error type for parsing a PeerID from a string.
4-
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5-
pub enum ParsePeerIDError {
10+
#[derive(Debug)]
11+
pub enum Error {
612
/// The input string had an incorrect length.
713
InvalidLength { expected: usize, actual: usize },
814
/// The input string contained non-hexadecimal characters or had an odd number of digits.
915
InvalidHexEncoding { c: char, index: usize },
16+
/// Io error
17+
Io(io::Error),
18+
/// Varint error
19+
Varint(decode::Error),
1020
}
1121

12-
impl fmt::Display for ParsePeerIDError {
22+
impl PartialEq for Error {
23+
fn eq(&self, other: &Self) -> bool {
24+
match (self, other) {
25+
(
26+
Error::InvalidLength { expected, actual },
27+
Error::InvalidLength {
28+
expected: e,
29+
actual: a,
30+
},
31+
) => expected == e && actual == a,
32+
(
33+
Error::InvalidHexEncoding { c, index },
34+
Error::InvalidHexEncoding { c: cc, index: i },
35+
) => c == cc && index == i,
36+
(Error::Io(err), Error::Io(other_err)) => err.kind() == other_err.kind(),
37+
(Error::Varint(err), Error::Varint(other_err)) => err == other_err,
38+
_ => false,
39+
}
40+
}
41+
42+
fn ne(&self, other: &Self) -> bool {
43+
!self.eq(other)
44+
}
45+
}
46+
47+
impl fmt::Display for Error {
1348
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1449
match self {
15-
ParsePeerIDError::InvalidLength { expected, actual } => {
50+
Error::InvalidLength { expected, actual } => {
1651
write!(f, "Expected length: {}, but got: {}", expected, actual)
1752
}
18-
ParsePeerIDError::InvalidHexEncoding { c, index } => {
53+
Error::InvalidHexEncoding { c, index } => {
1954
write!(f, "Invalid hex character '{}' at index {}", c, index)
2055
}
56+
Error::Io(err) => {
57+
write!(f, "IO error: {}", err)
58+
}
59+
Error::Varint(err) => {
60+
write!(f, "Varint error: {}", err)
61+
}
62+
}
63+
}
64+
}
65+
66+
impl From<io::Error> for Error {
67+
fn from(err: io::Error) -> Self {
68+
Error::Io(err)
69+
}
70+
}
71+
72+
impl From<decode::Error> for Error {
73+
fn from(err: decode::Error) -> Self {
74+
Error::Varint(err)
75+
}
76+
}
77+
78+
#[cfg(feature = "std")]
79+
impl From<unsigned_varint::io::ReadError> for Error {
80+
fn from(err: unsigned_varint::io::ReadError) -> Self {
81+
match err {
82+
unsigned_varint::io::ReadError::Io(e) => Error::Io(e),
83+
unsigned_varint::io::ReadError::Decode(e) => Error::Varint(e),
84+
_ => {
85+
// This case should not happen, but if it does, we can convert it to a Varint error.
86+
Error::Varint(decode::Error::Insufficient)
87+
}
2188
}
2289
}
2390
}
2491

2592
#[cfg(feature = "std")]
26-
impl std::error::Error for ParsePeerIDError {}
93+
impl std::error::Error for Error {}
2794

2895
#[cfg(test)]
2996
#[cfg_attr(coverage_nightly, coverage(off))]
@@ -32,13 +99,86 @@ mod tests {
3299

33100
#[test]
34101
fn test_parse_id_error_display() {
35-
let error = ParsePeerIDError::InvalidLength {
102+
let error = Error::InvalidLength {
36103
expected: 16,
37104
actual: 20,
38105
};
39106
assert_eq!(format!("{}", error), "Expected length: 16, but got: 20");
40107

41-
let error = ParsePeerIDError::InvalidHexEncoding { c: 'g', index: 5 };
108+
let error = Error::InvalidHexEncoding { c: 'g', index: 5 };
42109
assert_eq!(format!("{}", error), "Invalid hex character 'g' at index 5");
110+
111+
let io_error = io::Error::new(io::ErrorKind::Other, "IO error");
112+
let error = Error::Io(io_error);
113+
assert_eq!(format!("{}", error), "IO error: IO error");
114+
115+
let varint_error = decode::Error::Insufficient;
116+
let error = Error::Varint(varint_error);
117+
assert_eq!(format!("{}", error), "Varint error: not enough input bytes");
118+
}
119+
120+
#[test]
121+
fn test_partial_eq() {
122+
let error1 = Error::InvalidLength {
123+
expected: 16,
124+
actual: 20,
125+
};
126+
let error2 = Error::InvalidLength {
127+
expected: 16,
128+
actual: 20,
129+
};
130+
assert_eq!(error1, error2);
131+
132+
let error3 = Error::InvalidHexEncoding { c: 'g', index: 5 };
133+
assert_ne!(error1, error3);
134+
135+
let io_error = io::Error::new(io::ErrorKind::Other, "IO error");
136+
let error4 = Error::Io(io_error);
137+
assert_ne!(error1, error4);
138+
139+
let varint_error = decode::Error::Insufficient;
140+
let error5 = Error::Varint(varint_error);
141+
assert_ne!(error1, error5);
142+
143+
let error6 = Error::Varint(decode::Error::Insufficient);
144+
assert_eq!(error5, error6);
145+
146+
let io_error = io::Error::new(io::ErrorKind::Other, "IO error");
147+
let error7 = Error::Io(io_error);
148+
assert_eq!(error4, error7);
149+
150+
assert!(error4 != error5);
151+
}
152+
153+
#[test]
154+
fn test_error_from_io() {
155+
let err = io::Error::new(io::ErrorKind::Other, "IO error");
156+
let error = Error::from(err);
157+
assert_eq!(
158+
error,
159+
Error::Io(io::Error::new(io::ErrorKind::Other, "IO error"))
160+
);
161+
}
162+
163+
#[test]
164+
fn test_error_from_varint() {
165+
let varint_error = decode::Error::Insufficient;
166+
let error: Error = Error::from(varint_error);
167+
assert_eq!(error, Error::Varint(decode::Error::Insufficient));
168+
}
169+
170+
#[test]
171+
fn test_error_from_unsigned_varint_io() {
172+
let read_error =
173+
unsigned_varint::io::ReadError::Io(io::Error::new(io::ErrorKind::Other, "IO error"));
174+
let error: Error = Error::from(read_error);
175+
assert_eq!(
176+
error,
177+
Error::Io(io::Error::new(io::ErrorKind::Other, "IO error"))
178+
);
179+
180+
let decode_error = unsigned_varint::io::ReadError::Decode(decode::Error::Insufficient);
181+
let error: Error = Error::from(decode_error);
182+
assert_eq!(error, Error::Varint(decode::Error::Insufficient));
43183
}
44184
}

sf-peer-id/src/hex.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
use crate::ParsePeerIDError;
1+
use crate::Error;
22

33
#[inline]
4-
pub(crate) fn hex_char_to_value(c: char, i: usize) -> Result<u8, ParsePeerIDError> {
4+
pub(crate) fn hex_char_to_value(c: char, i: usize) -> Result<u8, Error> {
55
match c {
66
'0'..='9' => Ok((c as u8) - b'0'),
77
'a'..='f' => Ok((c as u8) - b'a' + 10),
88
'A'..='F' => Ok((c as u8) - b'A' + 10),
9-
_ => Err(ParsePeerIDError::InvalidHexEncoding { c, index: i }),
9+
_ => Err(Error::InvalidHexEncoding { c, index: i }),
1010
}
1111
}
1212

@@ -25,7 +25,7 @@ mod tests {
2525
assert_eq!(hex_char_to_value('F', 0), Ok(15));
2626
assert_eq!(
2727
hex_char_to_value('g', 0),
28-
Err(ParsePeerIDError::InvalidHexEncoding { c: 'g', index: 0 })
28+
Err(Error::InvalidHexEncoding { c: 'g', index: 0 })
2929
);
3030
}
3131
}

sf-peer-id/src/lib.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@
44
mod error;
55
mod hex;
66
mod peer_id;
7+
#[cfg(feature = "serde")]
8+
mod serde;
79

810
pub(crate) use crate::hex::hex_char_to_value;
911

10-
pub use crate::{error::ParsePeerIDError, peer_id::PeerID};
12+
pub use crate::{
13+
error::Error,
14+
peer_id::{FixedSizePeerID, PeerID},
15+
};

0 commit comments

Comments
 (0)