From dd3ab706ed87728e25a60e3ae098d0d3e26dab2c Mon Sep 17 00:00:00 2001 From: Andrew Gazelka Date: Mon, 7 Feb 2022 20:32:24 -0600 Subject: [PATCH 1/5] add future support --- Cargo.toml | 3 +++ src/lib.rs | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 9805cce..c8dca20 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,3 +11,6 @@ documentation = "https://docs.rs/nb" readme = "README.md" version = "1.0.0" # remember to update html_root_url edition = "2018" + +[dependencies] +pin-project-lite = "0.2.8" \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index fc2b516..9f00551 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -187,6 +187,10 @@ #![doc(html_root_url = "https://docs.rs/nb/1.0.0")] use core::fmt; +use core::future::Future; +use core::pin::Pin; +use core::task::{Context, Poll}; +use pin_project_lite::pin_project; /// A non-blocking result pub type Result = ::core::result::Result>; @@ -265,3 +269,47 @@ macro_rules! block { } }; } +pin_project! { + pub struct NbFuture Result> { + gen: Gen, + } +} + +impl Result> From for NbFuture { + fn from(gen: Gen) -> Self { + Self { gen } + } +} + +impl Result> Future for NbFuture { + type Output = core::result::Result; + + fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll { + let this = self.project(); + let res = (this.gen)(); + + match res { + Ok(res) => Poll::Ready(Ok(res)), + Err(Error::WouldBlock) => Poll::Pending, + Err(Error::Other(err)) => Poll::Ready(Err(err)), + } + } +} + +/// The equivalent of [block], expect instead of blocking this creates a +/// [Future] which can `.await`ed. +/// +/// # Input +/// +/// An expression `$e` that evaluates to `nb::Result` +/// +/// # Output +/// +/// - `Ok(t)` if `$e` evaluates to `Ok(t)` +/// - `Err(e)` if `$e` evaluates to `Err(nb::Error::Other(e))` +#[macro_export] +macro_rules! fut { + ($call:expr) => {{ + nb::NbFuture::from(|| $call) + }}; +} From 015c293a78572069d14b375ade87f75e8a68d74b Mon Sep 17 00:00:00 2001 From: Andrew Gazelka Date: Mon, 7 Feb 2022 20:35:07 -0600 Subject: [PATCH 2/5] update MSRV --- .github/bors.toml | 2 +- .github/workflows/ci.yml | 2 +- README.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/bors.toml b/.github/bors.toml index 6d27f5a..50ea957 100644 --- a/.github/bors.toml +++ b/.github/bors.toml @@ -3,5 +3,5 @@ delete_merged_branches = true required_approvals = 1 status = [ "ci-linux (stable, x86_64-unknown-linux-gnu)", - "ci-linux (1.35.0, x86_64-unknown-linux-gnu)", + "ci-linux (1.36.0, x86_64-unknown-linux-gnu)", ] diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5a8e9de..a3d4ea4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,7 @@ jobs: include: # Test MSRV - - rust: 1.35.0 + - rust: 1.36.0 TARGET: x86_64-unknown-linux-gnu # Test nightly but don't fail diff --git a/README.md b/README.md index 0fe23df..c0c0a82 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ This project is developed and maintained by the [HAL team][team]. ## Minimum Supported Rust Version (MSRV) -This crate is guaranteed to compile on stable Rust 1.35 and up. It *might* +This crate is guaranteed to compile on stable Rust 1.36 and up. It *might* compile with older versions but that may change in any new patch release. ## License From 7e24c5e0335fbc1a24753a16d101f9ea20b1338e Mon Sep 17 00:00:00 2001 From: Andrew Gazelka Date: Tue, 8 Feb 2022 10:16:52 -0600 Subject: [PATCH 3/5] remove pin_project for lower MSRV --- Cargo.toml | 5 +---- src/lib.rs | 12 +++++------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c8dca20..23f7e10 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,4 @@ homepage = "https://github.com/rust-embedded/nb" documentation = "https://docs.rs/nb" readme = "README.md" version = "1.0.0" # remember to update html_root_url -edition = "2018" - -[dependencies] -pin-project-lite = "0.2.8" \ No newline at end of file +edition = "2018" \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 9f00551..94ffd35 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -190,7 +190,6 @@ use core::fmt; use core::future::Future; use core::pin::Pin; use core::task::{Context, Poll}; -use pin_project_lite::pin_project; /// A non-blocking result pub type Result = ::core::result::Result>; @@ -269,10 +268,9 @@ macro_rules! block { } }; } -pin_project! { - pub struct NbFuture Result> { - gen: Gen, - } + +pub struct NbFuture Result> { + gen: Gen, } impl Result> From for NbFuture { @@ -285,8 +283,8 @@ impl Result> Future for NbFuture type Output = core::result::Result; fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll { - let this = self.project(); - let res = (this.gen)(); + let gen = unsafe { &mut self.get_unchecked_mut().gen }; + let res = gen(); match res { Ok(res) => Poll::Ready(Ok(res)), From 397560d3fb2c017a20891d5aaea3cce6a5bc425f Mon Sep 17 00:00:00 2001 From: Andrew Gazelka Date: Tue, 22 Feb 2022 15:06:31 -0800 Subject: [PATCH 4/5] add fut example --- src/lib.rs | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 94ffd35..2f39352 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -71,9 +71,11 @@ //! ``` //! //! Once your API uses [`nb::Result`] you can leverage the [`block!`], macro -//! to adapt it for blocking operation, or handle scheduling yourself. +//! to adapt it for blocking operation, or handle scheduling yourself. You can +//! also use the [`fut!`] macro to use it in an async/await context //! //! [`block!`]: macro.block.html +//! [`fut!`]: macro.fut.html //! [`nb::Result`]: type.Result.html //! //! # Examples @@ -182,6 +184,44 @@ //! # } //! # } //! ``` +//! ## Future mode +//! +//! Turn on an LED for one second and *then* loops back serial data. +//! +//! ``` +//! use core::convert::Infallible; +//! use nb::fut; +//! +//! use hal::{Led, Serial, Timer}; +//! +//! # async fn run() -> Result<(), Infallible>{ +//! Led.on(); +//! fut!(Timer.wait()).await; +//! Led.off(); +//! loop { +//! let byte = fut!(Serial.read()).await?; +//! fut!(Serial.write(byte)).await?; +//! } +//! # } +//! +//! # mod hal { +//! # use nb; +//! # use core::convert::Infallible; +//! # pub struct Led; +//! # impl Led { +//! # pub fn off(&self) {} +//! # pub fn on(&self) {} +//! # } +//! # pub struct Serial; +//! # impl Serial { +//! # pub fn read(&self) -> nb::Result { Ok(0) } +//! # pub fn write(&self, _: u8) -> nb::Result<(), Infallible> { Ok(()) } +//! # } +//! # pub struct Timer; +//! # impl Timer { +//! # pub fn wait(&self) -> nb::Result<(), Infallible> { Ok(()) } +//! # } +//! # } #![no_std] #![doc(html_root_url = "https://docs.rs/nb/1.0.0")] From 83ecc05865707c187dd2600a2d845478140d5af8 Mon Sep 17 00:00:00 2001 From: Andrew Gazelka Date: Tue, 22 Feb 2022 15:06:37 -0800 Subject: [PATCH 5/5] update MSRV to 1.39.0 to allow doctest .await --- .github/bors.toml | 2 +- .github/workflows/ci.yml | 2 +- README.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/bors.toml b/.github/bors.toml index 50ea957..cfbf59e 100644 --- a/.github/bors.toml +++ b/.github/bors.toml @@ -3,5 +3,5 @@ delete_merged_branches = true required_approvals = 1 status = [ "ci-linux (stable, x86_64-unknown-linux-gnu)", - "ci-linux (1.36.0, x86_64-unknown-linux-gnu)", + "ci-linux (1.39.0, x86_64-unknown-linux-gnu)", ] diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a3d4ea4..d054b7f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,7 @@ jobs: include: # Test MSRV - - rust: 1.36.0 + - rust: 1.39.0 TARGET: x86_64-unknown-linux-gnu # Test nightly but don't fail diff --git a/README.md b/README.md index c0c0a82..0c03c02 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ This project is developed and maintained by the [HAL team][team]. ## Minimum Supported Rust Version (MSRV) -This crate is guaranteed to compile on stable Rust 1.36 and up. It *might* +This crate is guaranteed to compile on stable Rust 1.39 and up. It *might* compile with older versions but that may change in any new patch release. ## License