mirror of
https://github.com/lune-org/lune.git
synced 2025-05-04 10:43:57 +01:00
Implement everything needed to integrate with hyper: executor + timer + sleep + io
This commit is contained in:
parent
89e8104bd4
commit
0911fcbf5b
4 changed files with 164 additions and 0 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -1831,6 +1831,7 @@ dependencies = [
|
|||
name = "lune-std-net"
|
||||
version = "0.2.0"
|
||||
dependencies = [
|
||||
"async-executor",
|
||||
"async-io",
|
||||
"async-lock",
|
||||
"async-net",
|
||||
|
@ -1843,6 +1844,7 @@ dependencies = [
|
|||
"lune-utils",
|
||||
"mlua",
|
||||
"mlua-luau-scheduler",
|
||||
"pin-project-lite",
|
||||
"rustls 0.23.26",
|
||||
"rustls-pki-types",
|
||||
"webpki",
|
||||
|
|
|
@ -16,6 +16,7 @@ workspace = true
|
|||
mlua = { version = "0.10.3", features = ["luau"] }
|
||||
mlua-luau-scheduler = { version = "0.1.0", path = "../mlua-luau-scheduler" }
|
||||
|
||||
async-executor = "1.13"
|
||||
async-io = "2.4"
|
||||
async-lock = "3.4"
|
||||
async-net = "2.0"
|
||||
|
@ -24,6 +25,7 @@ bstr = "1.9"
|
|||
futures-lite = "2.6"
|
||||
futures-rustls = "0.26"
|
||||
hyper = "1.6"
|
||||
pin-project-lite = "0.2"
|
||||
rustls = "0.23"
|
||||
rustls-pki-types = "1.11"
|
||||
webpki = "0.22"
|
||||
|
|
159
crates/lune-std-net/src/client/hyper.rs
Normal file
159
crates/lune-std-net/src/client/hyper.rs
Normal file
|
@ -0,0 +1,159 @@
|
|||
use std::{
|
||||
future::Future,
|
||||
io,
|
||||
pin::Pin,
|
||||
slice,
|
||||
task::{Context, Poll},
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
|
||||
use async_io::Timer;
|
||||
use futures_lite::prelude::*;
|
||||
use hyper::rt::{self, ReadBufCursor};
|
||||
use mlua::prelude::*;
|
||||
use mlua_luau_scheduler::LuaSpawnExt;
|
||||
|
||||
// Hyper executor that spawns futures onto our Lua scheduler
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct HyperExecutor {
|
||||
lua: Lua,
|
||||
}
|
||||
|
||||
impl From<Lua> for HyperExecutor {
|
||||
fn from(lua: Lua) -> Self {
|
||||
Self { lua }
|
||||
}
|
||||
}
|
||||
|
||||
impl<Fut: Future + Send + 'static> rt::Executor<Fut> for HyperExecutor
|
||||
where
|
||||
Fut::Output: Send + 'static,
|
||||
{
|
||||
fn execute(&self, fut: Fut) {
|
||||
self.lua.spawn(fut).detach();
|
||||
}
|
||||
}
|
||||
|
||||
// Hyper timer & sleep future wrapper for async-io
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct HyperTimer;
|
||||
|
||||
impl rt::Timer for HyperTimer {
|
||||
fn sleep(&self, duration: Duration) -> Pin<Box<dyn rt::Sleep>> {
|
||||
Box::pin(HyperSleep::from(Timer::after(duration)))
|
||||
}
|
||||
|
||||
fn sleep_until(&self, at: Instant) -> Pin<Box<dyn rt::Sleep>> {
|
||||
Box::pin(HyperSleep::from(Timer::at(at)))
|
||||
}
|
||||
|
||||
fn reset(&self, sleep: &mut Pin<Box<dyn rt::Sleep>>, new_deadline: Instant) {
|
||||
if let Some(mut sleep) = sleep.as_mut().downcast_mut_pin::<HyperSleep>() {
|
||||
sleep.inner.set_at(new_deadline);
|
||||
} else {
|
||||
*sleep = Box::pin(HyperSleep::from(Timer::at(new_deadline)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct HyperSleep {
|
||||
inner: Timer,
|
||||
}
|
||||
|
||||
impl From<Timer> for HyperSleep {
|
||||
fn from(inner: Timer) -> Self {
|
||||
Self { inner }
|
||||
}
|
||||
}
|
||||
|
||||
impl Future for HyperSleep {
|
||||
type Output = ();
|
||||
|
||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
|
||||
match Pin::new(&mut self.inner).poll(cx) {
|
||||
Poll::Ready(_) => Poll::Ready(()),
|
||||
Poll::Pending => Poll::Pending,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl rt::Sleep for HyperSleep {}
|
||||
|
||||
// Hyper I/O wrapper for futures-lite types
|
||||
|
||||
pin_project_lite::pin_project! {
|
||||
#[derive(Debug)]
|
||||
pub struct HyperIo<T> {
|
||||
#[pin]
|
||||
inner: T
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<T> for HyperIo<T> {
|
||||
fn from(inner: T) -> Self {
|
||||
Self { inner }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> HyperIo<T> {
|
||||
pub fn pin_mut(self: Pin<&mut Self>) -> Pin<&mut T> {
|
||||
self.project().inner
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: AsyncRead> rt::Read for HyperIo<T> {
|
||||
fn poll_read(
|
||||
self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>,
|
||||
mut buf: ReadBufCursor<'_>,
|
||||
) -> Poll<io::Result<()>> {
|
||||
// Fill the read buffer with initialized data
|
||||
let read_slice = unsafe {
|
||||
let buffer = buf.as_mut();
|
||||
buffer.as_mut_ptr().write_bytes(0, buffer.len());
|
||||
slice::from_raw_parts_mut(buffer.as_mut_ptr().cast::<u8>(), buffer.len())
|
||||
};
|
||||
|
||||
// Read bytes from the underlying source
|
||||
let n = match self.pin_mut().poll_read(cx, read_slice) {
|
||||
Poll::Ready(Ok(n)) => n,
|
||||
Poll::Ready(Err(e)) => return Poll::Ready(Err(e)),
|
||||
Poll::Pending => return Poll::Pending,
|
||||
};
|
||||
|
||||
unsafe {
|
||||
buf.advance(n);
|
||||
}
|
||||
|
||||
Poll::Ready(Ok(()))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: AsyncWrite> rt::Write for HyperIo<T> {
|
||||
fn poll_write(
|
||||
self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>,
|
||||
buf: &[u8],
|
||||
) -> Poll<io::Result<usize>> {
|
||||
self.pin_mut().poll_write(cx, buf)
|
||||
}
|
||||
|
||||
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
|
||||
self.pin_mut().poll_flush(cx)
|
||||
}
|
||||
|
||||
fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
|
||||
self.pin_mut().poll_close(cx)
|
||||
}
|
||||
|
||||
fn poll_write_vectored(
|
||||
self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>,
|
||||
bufs: &[io::IoSlice<'_>],
|
||||
) -> Poll<io::Result<usize>> {
|
||||
self.pin_mut().poll_write_vectored(cx, bufs)
|
||||
}
|
||||
}
|
|
@ -1 +1,2 @@
|
|||
mod hyper;
|
||||
mod stream;
|
||||
|
|
Loading…
Add table
Reference in a new issue