Skip to content

Commit

Permalink
Merge pull request #5 from n0-computer/175
Browse files Browse the repository at this point in the history
convert to impl Future in trait
  • Loading branch information
rklaehn authored Feb 12, 2024
2 parents 1de2016 + 3d493ff commit 3c4665c
Show file tree
Hide file tree
Showing 8 changed files with 229 additions and 475 deletions.
22 changes: 11 additions & 11 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ on:
- main

env:
MSRV: "1.63"
MSRV: "1.75"
RUST_BACKTRACE: 1
RUSTFLAGS: -Dwarnings

Expand Down Expand Up @@ -100,13 +100,13 @@ jobs:
- name: cargo check
run: cargo check --workspace --all-features --lib --bins

minimal-crates:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: dtolnay/rust-toolchain@nightly
- uses: swatinem/rust-cache@v2
- name: cargo check
run: |
rm -f Cargo.lock
cargo +nightly check -Z minimal-versions --workspace --all-features --lib --bins
# minimal-crates:
# runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@v2
# - uses: dtolnay/rust-toolchain@nightly
# - uses: swatinem/rust-cache@v2
# - name: cargo check
# run: |
# rm -f Cargo.lock
# cargo +nightly check -Z minimal-versions --workspace --all-features --lib --bins
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
[package]
name = "iroh-io"
version = "0.3.0"
version = "0.4.0"
edition = "2021"
license = "Apache-2.0 OR MIT"
authors = ["rklaehn <[email protected]>", "n0 team"]
repository = "https://github.com/n0-computer/iroh"
description = "async local io"
keywords = ["io", "async", "http"]
categories = ["asynchronous"]
rust-version = "1.75"

[dependencies]
bytes = "1.4.0"
Expand Down
105 changes: 32 additions & 73 deletions src/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//! Uses the [reqwest](https://docs.rs/reqwest) crate. Somewhat inspired by
//! <https://github.com/fasterthanlime/ubio/blob/main/src/http/mod.rs>
use super::*;
use futures::{future::LocalBoxFuture, FutureExt, Stream, StreamExt, TryStreamExt};
use futures::{Stream, StreamExt, TryStreamExt};
use reqwest::{
header::{HeaderMap, HeaderValue},
Method, StatusCode, Url,
Expand Down Expand Up @@ -121,88 +121,47 @@ pub mod http_adapter {

use super::*;

newtype_future!(
/// The future returned by [`HttpAdapter::read_at`]
ReadAtFuture,
LocalBoxFuture<'a, io::Result<Bytes>>,
io::Result<Bytes>
);

impl fmt::Debug for ReadAtFuture<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("ReadAtFuture").finish_non_exhaustive()
}
}

newtype_future!(
/// The future returned by [`HttpAdapter::len`]
LenFuture,
LocalBoxFuture<'a, io::Result<u64>>,
io::Result<u64>
);

impl fmt::Debug for LenFuture<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("LenFuture").finish_non_exhaustive()
}
}

/// Options for [HttpAdapter]
#[derive(Debug, Clone, Default)]
pub struct Opts {
pub(crate) headers: Option<HeaderMap<HeaderValue>>,
}

impl AsyncSliceReader for HttpAdapter {
type ReadAtFuture<'a> = ReadAtFuture<'a>;

fn read_at(&mut self, offset: u64, len: usize) -> Self::ReadAtFuture<'_> {
ReadAtFuture(
async move {
let mut stream = self.get_stream_at(offset, len).await?;
let mut res = BytesMut::with_capacity(len.min(1024));
while let Some(chunk) = stream.next().await {
let chunk = chunk?;
res.extend_from_slice(&chunk);
if BytesMut::len(&res) >= len {
break;
}
}
// we do not want to rely on the server sending the exact amount of bytes
res.truncate(len);
Ok(res.freeze())
async fn read_at(&mut self, offset: u64, len: usize) -> io::Result<Bytes> {
let mut stream = self.get_stream_at(offset, len).await?;
let mut res = BytesMut::with_capacity(len.min(1024));
while let Some(chunk) = stream.next().await {
let chunk = chunk?;
res.extend_from_slice(&chunk);
if BytesMut::len(&res) >= len {
break;
}
.boxed_local(),
)
}
// we do not want to rely on the server sending the exact amount of bytes
res.truncate(len);
Ok(res.freeze())
}

type LenFuture<'a> = LenFuture<'a>;

fn len(&mut self) -> Self::LenFuture<'_> {
LenFuture(
async move {
let io_err = |text: &str| io::Error::new(io::ErrorKind::Other, text);
let head_response = self
.head_request()
.await
.map_err(|_| io_err("head request failed"))?;
if !head_response.status().is_success() {
return Err(io_err("head request failed"));
}
let size = head_response
.headers()
.get("content-length")
.ok_or_else(|| io_err("content-length header missing"))?;
let text = size
.to_str()
.map_err(|_| io_err("content-length malformed"))?;
let size =
u64::from_str(text).map_err(|_| io_err("content-length malformed"))?;
self.size = Some(size);
Ok(size)
}
.boxed_local(),
)
async fn len(&mut self) -> io::Result<u64> {
let io_err = |text: &str| io::Error::new(io::ErrorKind::Other, text);
let head_response = self
.head_request()
.await
.map_err(|_| io_err("head request failed"))?;
if !head_response.status().is_success() {
return Err(io_err("head request failed"));
}
let size = head_response
.headers()
.get("content-length")
.ok_or_else(|| io_err("content-length header missing"))?;
let text = size
.to_str()
.map_err(|_| io_err("content-length malformed"))?;
let size = u64::from_str(text).map_err(|_| io_err("content-length malformed"))?;
self.size = Some(size);
Ok(size)
}
}
}
Loading

0 comments on commit 3c4665c

Please sign in to comment.