Skip to content

Commit 8004115

Browse files
committed
Merge branch 'main' into entity-manager
2 parents c26e555 + bc61e8e commit 8004115

File tree

6 files changed

+190
-24
lines changed

6 files changed

+190
-24
lines changed

examples/random_store.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ async fn provide(args: ProvideArgs) -> anyhow::Result<()> {
237237
.bind()
238238
.await?;
239239
let (dump_task, events_tx) = dump_provider_events(args.allow_push);
240-
let blobs = iroh_blobs::net_protocol::Blobs::new(&store, endpoint.clone(), Some(events_tx));
240+
let blobs = iroh_blobs::BlobsProtocol::new(&store, endpoint.clone(), Some(events_tx));
241241
let router = iroh::protocol::Router::builder(endpoint.clone())
242242
.accept(iroh_blobs::ALPN, blobs)
243243
.spawn();

src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ pub mod format;
77
pub mod get;
88
pub mod hashseq;
99
mod metrics;
10-
pub mod net_protocol;
10+
mod net_protocol;
11+
pub use net_protocol::BlobsProtocol;
1112
pub mod protocol;
1213
pub mod provider;
1314
pub mod test;

src/net_protocol.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
//! ```rust
88
//! # async fn example() -> anyhow::Result<()> {
99
//! use iroh::{protocol::Router, Endpoint};
10-
//! use iroh_blobs::{net_protocol::Blobs, store};
10+
//! use iroh_blobs::{store, BlobsProtocol};
1111
//!
1212
//! // create a store
1313
//! let store = store::fs::FsStore::load("blobs").await?;
@@ -19,7 +19,7 @@
1919
//! let endpoint = Endpoint::builder().discovery_n0().bind().await?;
2020
//!
2121
//! // create a blobs protocol handler
22-
//! let blobs = Blobs::new(&store, endpoint.clone(), None);
22+
//! let blobs = BlobsProtocol::new(&store, endpoint.clone(), None);
2323
//!
2424
//! // create a router and add the blobs protocol handler
2525
//! let router = Router::builder(endpoint)
@@ -62,11 +62,11 @@ pub(crate) struct BlobsInner {
6262

6363
/// A protocol handler for the blobs protocol.
6464
#[derive(Debug, Clone)]
65-
pub struct Blobs {
65+
pub struct BlobsProtocol {
6666
pub(crate) inner: Arc<BlobsInner>,
6767
}
6868

69-
impl Blobs {
69+
impl BlobsProtocol {
7070
pub fn new(store: &Store, endpoint: Endpoint, events: Option<mpsc::Sender<Event>>) -> Self {
7171
Self {
7272
inner: Arc::new(BlobsInner {
@@ -97,7 +97,7 @@ impl Blobs {
9797
}
9898
}
9999

100-
impl ProtocolHandler for Blobs {
100+
impl ProtocolHandler for BlobsProtocol {
101101
fn accept(
102102
&self,
103103
conn: Connection,

src/provider.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! The low level server side API
22
//!
33
//! Note that while using this API directly is fine, the standard way
4-
//! to provide data is to just register a [`crate::net_protocol`] protocol
4+
//! to provide data is to just register a [`crate::BlobsProtocol`] protocol
55
//! handler with an [`iroh::Endpoint`](iroh::protocol::Router).
66
use std::{
77
fmt::Debug,

src/tests.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use crate::{
1414
api::{blobs::Bitfield, Store},
1515
get,
1616
hashseq::HashSeq,
17-
net_protocol::Blobs,
17+
net_protocol::BlobsProtocol,
1818
protocol::{ChunkRangesSeq, GetManyRequest, ObserveRequest, PushRequest},
1919
provider::Event,
2020
store::{
@@ -490,7 +490,7 @@ pub async fn node_test_setup_with_events_fs(
490490
) -> TestResult<(Router, FsStore, PathBuf)> {
491491
let store = crate::store::fs::FsStore::load(&db_path).await?;
492492
let ep = Endpoint::builder().bind().await?;
493-
let blobs = Blobs::new(&store, ep.clone(), events);
493+
let blobs = BlobsProtocol::new(&store, ep.clone(), events);
494494
let router = Router::builder(ep).accept(crate::ALPN, blobs).spawn();
495495
Ok((router, store, db_path))
496496
}
@@ -504,7 +504,7 @@ pub async fn node_test_setup_with_events_mem(
504504
) -> TestResult<(Router, MemStore)> {
505505
let store = MemStore::new();
506506
let ep = Endpoint::builder().bind().await?;
507-
let blobs = Blobs::new(&store, ep.clone(), events);
507+
let blobs = BlobsProtocol::new(&store, ep.clone(), events);
508508
let router = Router::builder(ep).accept(crate::ALPN, blobs).spawn();
509509
Ok((router, store))
510510
}
@@ -601,7 +601,7 @@ async fn node_serve_hash_seq() -> TestResult<()> {
601601
let root_tt = store.add_bytes(hash_seq).await?;
602602
let root = root_tt.hash;
603603
let endpoint = Endpoint::builder().discovery_n0().bind().await?;
604-
let blobs = crate::net_protocol::Blobs::new(&store, endpoint.clone(), None);
604+
let blobs = crate::net_protocol::BlobsProtocol::new(&store, endpoint.clone(), None);
605605
let r1 = Router::builder(endpoint)
606606
.accept(crate::protocol::ALPN, blobs)
607607
.spawn();
@@ -632,7 +632,7 @@ async fn node_serve_blobs() -> TestResult<()> {
632632
tts.push(store.add_bytes(test_data(size)).await?);
633633
}
634634
let endpoint = Endpoint::builder().discovery_n0().bind().await?;
635-
let blobs = crate::net_protocol::Blobs::new(&store, endpoint.clone(), None);
635+
let blobs = crate::net_protocol::BlobsProtocol::new(&store, endpoint.clone(), None);
636636
let r1 = Router::builder(endpoint)
637637
.accept(crate::protocol::ALPN, blobs)
638638
.spawn();
@@ -674,7 +674,7 @@ async fn node_smoke(store: &Store) -> TestResult<()> {
674674
let tt = store.add_bytes(b"hello world".to_vec()).temp_tag().await?;
675675
let hash = *tt.hash();
676676
let endpoint = Endpoint::builder().discovery_n0().bind().await?;
677-
let blobs = crate::net_protocol::Blobs::new(store, endpoint.clone(), None);
677+
let blobs = crate::net_protocol::BlobsProtocol::new(store, endpoint.clone(), None);
678678
let r1 = Router::builder(endpoint)
679679
.accept(crate::protocol::ALPN, blobs)
680680
.spawn();

src/util.rs

Lines changed: 175 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,108 @@ pub mod serde {
1111
use std::{fmt, io};
1212

1313
use serde::{
14-
de::{self, Visitor},
14+
de::{self, SeqAccess, Visitor},
15+
ser::SerializeTuple,
1516
Deserializer, Serializer,
1617
};
1718

19+
fn error_kind_to_u8(kind: io::ErrorKind) -> u8 {
20+
match kind {
21+
io::ErrorKind::AddrInUse => 0,
22+
io::ErrorKind::AddrNotAvailable => 1,
23+
io::ErrorKind::AlreadyExists => 2,
24+
io::ErrorKind::ArgumentListTooLong => 3,
25+
io::ErrorKind::BrokenPipe => 4,
26+
io::ErrorKind::ConnectionAborted => 5,
27+
io::ErrorKind::ConnectionRefused => 6,
28+
io::ErrorKind::ConnectionReset => 7,
29+
io::ErrorKind::CrossesDevices => 8,
30+
io::ErrorKind::Deadlock => 9,
31+
io::ErrorKind::DirectoryNotEmpty => 10,
32+
io::ErrorKind::ExecutableFileBusy => 11,
33+
io::ErrorKind::FileTooLarge => 12,
34+
io::ErrorKind::HostUnreachable => 13,
35+
io::ErrorKind::Interrupted => 14,
36+
io::ErrorKind::InvalidData => 15,
37+
io::ErrorKind::InvalidInput => 17,
38+
io::ErrorKind::IsADirectory => 18,
39+
io::ErrorKind::NetworkDown => 19,
40+
io::ErrorKind::NetworkUnreachable => 20,
41+
io::ErrorKind::NotADirectory => 21,
42+
io::ErrorKind::NotConnected => 22,
43+
io::ErrorKind::NotFound => 23,
44+
io::ErrorKind::NotSeekable => 24,
45+
io::ErrorKind::Other => 25,
46+
io::ErrorKind::OutOfMemory => 26,
47+
io::ErrorKind::PermissionDenied => 27,
48+
io::ErrorKind::QuotaExceeded => 28,
49+
io::ErrorKind::ReadOnlyFilesystem => 29,
50+
io::ErrorKind::ResourceBusy => 30,
51+
io::ErrorKind::StaleNetworkFileHandle => 31,
52+
io::ErrorKind::StorageFull => 32,
53+
io::ErrorKind::TimedOut => 33,
54+
io::ErrorKind::TooManyLinks => 34,
55+
io::ErrorKind::UnexpectedEof => 35,
56+
io::ErrorKind::Unsupported => 36,
57+
io::ErrorKind::WouldBlock => 37,
58+
io::ErrorKind::WriteZero => 38,
59+
_ => 25,
60+
}
61+
}
62+
63+
fn u8_to_error_kind(num: u8) -> io::ErrorKind {
64+
match num {
65+
0 => io::ErrorKind::AddrInUse,
66+
1 => io::ErrorKind::AddrNotAvailable,
67+
2 => io::ErrorKind::AlreadyExists,
68+
3 => io::ErrorKind::ArgumentListTooLong,
69+
4 => io::ErrorKind::BrokenPipe,
70+
5 => io::ErrorKind::ConnectionAborted,
71+
6 => io::ErrorKind::ConnectionRefused,
72+
7 => io::ErrorKind::ConnectionReset,
73+
8 => io::ErrorKind::CrossesDevices,
74+
9 => io::ErrorKind::Deadlock,
75+
10 => io::ErrorKind::DirectoryNotEmpty,
76+
11 => io::ErrorKind::ExecutableFileBusy,
77+
12 => io::ErrorKind::FileTooLarge,
78+
13 => io::ErrorKind::HostUnreachable,
79+
14 => io::ErrorKind::Interrupted,
80+
15 => io::ErrorKind::InvalidData,
81+
// 16 => io::ErrorKind::InvalidFilename,
82+
17 => io::ErrorKind::InvalidInput,
83+
18 => io::ErrorKind::IsADirectory,
84+
19 => io::ErrorKind::NetworkDown,
85+
20 => io::ErrorKind::NetworkUnreachable,
86+
21 => io::ErrorKind::NotADirectory,
87+
22 => io::ErrorKind::NotConnected,
88+
23 => io::ErrorKind::NotFound,
89+
24 => io::ErrorKind::NotSeekable,
90+
25 => io::ErrorKind::Other,
91+
26 => io::ErrorKind::OutOfMemory,
92+
27 => io::ErrorKind::PermissionDenied,
93+
28 => io::ErrorKind::QuotaExceeded,
94+
29 => io::ErrorKind::ReadOnlyFilesystem,
95+
30 => io::ErrorKind::ResourceBusy,
96+
31 => io::ErrorKind::StaleNetworkFileHandle,
97+
32 => io::ErrorKind::StorageFull,
98+
33 => io::ErrorKind::TimedOut,
99+
34 => io::ErrorKind::TooManyLinks,
100+
35 => io::ErrorKind::UnexpectedEof,
101+
36 => io::ErrorKind::Unsupported,
102+
37 => io::ErrorKind::WouldBlock,
103+
38 => io::ErrorKind::WriteZero,
104+
_ => io::ErrorKind::Other,
105+
}
106+
}
107+
18108
pub fn serialize<S>(error: &io::Error, serializer: S) -> Result<S::Ok, S::Error>
19109
where
20110
S: Serializer,
21111
{
22-
// Serialize the error kind and message
23-
serializer.serialize_str(&format!("{:?}:{}", error.kind(), error))
112+
let mut tup = serializer.serialize_tuple(2)?;
113+
tup.serialize_element(&error_kind_to_u8(error.kind()))?;
114+
tup.serialize_element(&error.to_string())?;
115+
tup.end()
24116
}
25117

26118
pub fn deserialize<'de, D>(deserializer: D) -> Result<io::Error, D::Error>
@@ -33,20 +125,93 @@ pub mod serde {
33125
type Value = io::Error;
34126

35127
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
36-
formatter.write_str("an io::Error string representation")
128+
formatter.write_str("a tuple of (u32, String) representing io::Error")
37129
}
38130

39-
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
131+
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
40132
where
41-
E: de::Error,
133+
A: SeqAccess<'de>,
42134
{
43-
// For simplicity, create a generic error
44-
// In a real app, you might want to parse the kind from the string
45-
Ok(io::Error::other(value))
135+
let num: u8 = seq
136+
.next_element()?
137+
.ok_or_else(|| de::Error::invalid_length(0, &self))?;
138+
let message: String = seq
139+
.next_element()?
140+
.ok_or_else(|| de::Error::invalid_length(1, &self))?;
141+
let kind = u8_to_error_kind(num);
142+
Ok(io::Error::new(kind, message))
46143
}
47144
}
48145

49-
deserializer.deserialize_str(IoErrorVisitor)
146+
deserializer.deserialize_tuple(2, IoErrorVisitor)
147+
}
148+
}
149+
150+
#[cfg(test)]
151+
mod tests {
152+
use std::io::{self, ErrorKind};
153+
154+
use postcard;
155+
use serde::{Deserialize, Serialize};
156+
157+
use super::io_error_serde;
158+
159+
#[derive(Serialize, Deserialize)]
160+
struct TestError(#[serde(with = "io_error_serde")] io::Error);
161+
162+
#[test]
163+
fn test_roundtrip_error_kinds() {
164+
let message = "test error";
165+
let kinds = [
166+
ErrorKind::AddrInUse,
167+
ErrorKind::AddrNotAvailable,
168+
ErrorKind::AlreadyExists,
169+
ErrorKind::ArgumentListTooLong,
170+
ErrorKind::BrokenPipe,
171+
ErrorKind::ConnectionAborted,
172+
ErrorKind::ConnectionRefused,
173+
ErrorKind::ConnectionReset,
174+
ErrorKind::CrossesDevices,
175+
ErrorKind::Deadlock,
176+
ErrorKind::DirectoryNotEmpty,
177+
ErrorKind::ExecutableFileBusy,
178+
ErrorKind::FileTooLarge,
179+
ErrorKind::HostUnreachable,
180+
ErrorKind::Interrupted,
181+
ErrorKind::InvalidData,
182+
// ErrorKind::InvalidFilename,
183+
ErrorKind::InvalidInput,
184+
ErrorKind::IsADirectory,
185+
ErrorKind::NetworkDown,
186+
ErrorKind::NetworkUnreachable,
187+
ErrorKind::NotADirectory,
188+
ErrorKind::NotConnected,
189+
ErrorKind::NotFound,
190+
ErrorKind::NotSeekable,
191+
ErrorKind::Other,
192+
ErrorKind::OutOfMemory,
193+
ErrorKind::PermissionDenied,
194+
ErrorKind::QuotaExceeded,
195+
ErrorKind::ReadOnlyFilesystem,
196+
ErrorKind::ResourceBusy,
197+
ErrorKind::StaleNetworkFileHandle,
198+
ErrorKind::StorageFull,
199+
ErrorKind::TimedOut,
200+
ErrorKind::TooManyLinks,
201+
ErrorKind::UnexpectedEof,
202+
ErrorKind::Unsupported,
203+
ErrorKind::WouldBlock,
204+
ErrorKind::WriteZero,
205+
];
206+
207+
for kind in kinds {
208+
let err = TestError(io::Error::new(kind, message));
209+
let serialized = postcard::to_allocvec(&err).unwrap();
210+
let deserialized: TestError = postcard::from_bytes(&serialized).unwrap();
211+
212+
assert_eq!(err.0.kind(), deserialized.0.kind());
213+
assert_eq!(err.0.to_string(), deserialized.0.to_string());
214+
}
50215
}
51216
}
52217
}

0 commit comments

Comments
 (0)