mirror of
https://github.com/async-rs/async-std.git
synced 2025-05-16 03:51:32 +00:00
Simplify extension traits using a macro
This commit is contained in:
parent
f922e9c034
commit
79eab9eb9a
7 changed files with 1780 additions and 1940 deletions
|
@ -13,14 +13,15 @@ use cfg_if::cfg_if;
|
|||
|
||||
use crate::io;
|
||||
use crate::task::{Context, Poll};
|
||||
use crate::utils::extension_trait;
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "docs")] {
|
||||
use std::ops::{Deref, DerefMut};
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub struct ImplFuture<'a, T>(std::marker::PhantomData<&'a T>);
|
||||
|
||||
extension_trait! {
|
||||
/// Allows reading from a buffered byte stream.
|
||||
///
|
||||
/// This trait is a re-export of [`futures::io::AsyncBufRead`] and is an async version of
|
||||
|
@ -38,7 +39,7 @@ cfg_if! {
|
|||
/// [`futures::io::AsyncBufRead`]:
|
||||
/// https://docs.rs/futures-preview/0.3.0-alpha.17/futures/io/trait.AsyncBufRead.html
|
||||
/// [provided methods]: #provided-methods
|
||||
pub trait BufRead {
|
||||
pub trait BufRead [BufReadExt: futures_io::AsyncBufRead] {
|
||||
/// Returns the contents of the internal buffer, filling it with more data from the
|
||||
/// inner reader if it is empty.
|
||||
///
|
||||
|
@ -110,11 +111,16 @@ cfg_if! {
|
|||
&'a mut self,
|
||||
byte: u8,
|
||||
buf: &'a mut Vec<u8>,
|
||||
) -> ImplFuture<'a, io::Result<usize>>
|
||||
) -> impl Future<Output = usize> + 'a [ReadUntilFuture<'a, Self>]
|
||||
where
|
||||
Self: Unpin,
|
||||
{
|
||||
unreachable!()
|
||||
ReadUntilFuture {
|
||||
reader: self,
|
||||
byte,
|
||||
buf,
|
||||
read: 0,
|
||||
}
|
||||
}
|
||||
|
||||
/// Reads all bytes and appends them into `buf` until a newline (the 0xA byte) is
|
||||
|
@ -156,11 +162,16 @@ cfg_if! {
|
|||
fn read_line<'a>(
|
||||
&'a mut self,
|
||||
buf: &'a mut String,
|
||||
) -> ImplFuture<'a, io::Result<usize>>
|
||||
) -> impl Future<Output = io::Result<usize>> + 'a [ReadLineFuture<'a, Self>]
|
||||
where
|
||||
Self: Unpin,
|
||||
{
|
||||
unreachable!()
|
||||
ReadLineFuture {
|
||||
reader: self,
|
||||
bytes: unsafe { mem::replace(buf.as_mut_vec(), Vec::new()) },
|
||||
buf,
|
||||
read: 0,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a stream over the lines of this byte stream.
|
||||
|
@ -196,7 +207,12 @@ cfg_if! {
|
|||
where
|
||||
Self: Unpin + Sized,
|
||||
{
|
||||
unreachable!()
|
||||
Lines {
|
||||
reader: self,
|
||||
buf: String::new(),
|
||||
bytes: Vec::new(),
|
||||
read: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -255,51 +271,7 @@ cfg_if! {
|
|||
unreachable!()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pub use futures_io::AsyncBufRead as BufRead;
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub trait BufReadExt: futures_io::AsyncBufRead {
|
||||
fn read_until<'a>(&'a mut self, byte: u8, buf: &'a mut Vec<u8>) -> ReadUntilFuture<'a, Self>
|
||||
where
|
||||
Self: Unpin,
|
||||
{
|
||||
ReadUntilFuture {
|
||||
reader: self,
|
||||
byte,
|
||||
buf,
|
||||
read: 0,
|
||||
}
|
||||
}
|
||||
|
||||
fn read_line<'a>(&'a mut self, buf: &'a mut String) -> ReadLineFuture<'a, Self>
|
||||
where
|
||||
Self: Unpin,
|
||||
{
|
||||
ReadLineFuture {
|
||||
reader: self,
|
||||
bytes: unsafe { mem::replace(buf.as_mut_vec(), Vec::new()) },
|
||||
buf,
|
||||
read: 0,
|
||||
}
|
||||
}
|
||||
|
||||
fn lines(self) -> Lines<Self>
|
||||
where
|
||||
Self: Unpin + Sized,
|
||||
{
|
||||
Lines {
|
||||
reader: self,
|
||||
buf: String::new(),
|
||||
bytes: Vec::new(),
|
||||
read: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: futures_io::AsyncBufRead + ?Sized> BufReadExt for T {}
|
||||
|
||||
pub fn read_until_internal<R: BufReadExt + ?Sized>(
|
||||
mut reader: Pin<&mut R>,
|
||||
|
|
|
@ -11,10 +11,10 @@ use read_to_string::ReadToStringFuture;
|
|||
use read_vectored::ReadVectoredFuture;
|
||||
|
||||
use std::mem;
|
||||
|
||||
use cfg_if::cfg_if;
|
||||
|
||||
use crate::io::IoSliceMut;
|
||||
use crate::utils::extension_trait;
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "docs")] {
|
||||
|
@ -23,10 +23,10 @@ cfg_if! {
|
|||
|
||||
use crate::io;
|
||||
use crate::task::{Context, Poll};
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub struct ImplFuture<'a, T>(std::marker::PhantomData<&'a T>);
|
||||
|
||||
extension_trait! {
|
||||
/// Allows reading from a byte stream.
|
||||
///
|
||||
/// This trait is a re-export of [`futures::io::AsyncRead`] and is an async version of
|
||||
|
@ -45,7 +45,7 @@ cfg_if! {
|
|||
/// https://docs.rs/futures-preview/0.3.0-alpha.17/futures/io/trait.AsyncRead.html
|
||||
/// [`poll_read`]: #tymethod.poll_read
|
||||
/// [`poll_read_vectored`]: #method.poll_read_vectored
|
||||
pub trait Read {
|
||||
pub trait Read [ReadExt: futures_io::AsyncRead] {
|
||||
/// Attempt to read from the `AsyncRead` into `buf`.
|
||||
fn poll_read(
|
||||
self: Pin<&mut Self>,
|
||||
|
@ -91,11 +91,11 @@ cfg_if! {
|
|||
/// #
|
||||
/// # Ok(()) }) }
|
||||
/// ```
|
||||
fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> ImplFuture<'a, io::Result<usize>>
|
||||
fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> impl Future<Output = io::Result<usize>> + 'a [ReadFuture<'a, Self>]
|
||||
where
|
||||
Self: Unpin
|
||||
{
|
||||
unreachable!()
|
||||
ReadFuture { reader: self, buf }
|
||||
}
|
||||
|
||||
/// Like [`read`], except that it reads into a slice of buffers.
|
||||
|
@ -111,11 +111,11 @@ cfg_if! {
|
|||
fn read_vectored<'a>(
|
||||
&'a mut self,
|
||||
bufs: &'a mut [IoSliceMut<'a>],
|
||||
) -> ImplFuture<'a, io::Result<usize>>
|
||||
) -> impl Future<Output = io::Result<usize>> + 'a [ReadVectoredFuture<'a, Self>]
|
||||
where
|
||||
Self: Unpin,
|
||||
{
|
||||
unreachable!()
|
||||
ReadVectoredFuture { reader: self, bufs }
|
||||
}
|
||||
|
||||
/// Reads all bytes from the byte stream.
|
||||
|
@ -146,11 +146,16 @@ cfg_if! {
|
|||
fn read_to_end<'a>(
|
||||
&'a mut self,
|
||||
buf: &'a mut Vec<u8>,
|
||||
) -> ImplFuture<'a, io::Result<usize>>
|
||||
) -> impl Future<Output = io::Result<usize>> + 'a [ReadToEndFuture<'a, Self>]
|
||||
where
|
||||
Self: Unpin,
|
||||
{
|
||||
unreachable!()
|
||||
let start_len = buf.len();
|
||||
ReadToEndFuture {
|
||||
reader: self,
|
||||
buf,
|
||||
start_len,
|
||||
}
|
||||
}
|
||||
|
||||
/// Reads all bytes from the byte stream and appends them into a string.
|
||||
|
@ -178,11 +183,17 @@ cfg_if! {
|
|||
fn read_to_string<'a>(
|
||||
&'a mut self,
|
||||
buf: &'a mut String,
|
||||
) -> ImplFuture<'a, io::Result<usize>>
|
||||
) -> impl Future<Output = io::Result<usize>> + 'a [ReadToStringFuture<'a, Self>]
|
||||
where
|
||||
Self: Unpin,
|
||||
{
|
||||
unreachable!()
|
||||
let start_len = buf.len();
|
||||
ReadToStringFuture {
|
||||
reader: self,
|
||||
bytes: unsafe { mem::replace(buf.as_mut_vec(), Vec::new()) },
|
||||
buf,
|
||||
start_len,
|
||||
}
|
||||
}
|
||||
|
||||
/// Reads the exact number of bytes required to fill `buf`.
|
||||
|
@ -222,11 +233,11 @@ cfg_if! {
|
|||
/// #
|
||||
/// # Ok(()) }) }
|
||||
/// ```
|
||||
fn read_exact<'a>(&'a mut self, buf: &'a mut [u8]) -> ImplFuture<'a, io::Result<()>>
|
||||
fn read_exact<'a>(&'a mut self, buf: &'a mut [u8]) -> impl Future<Output = io::Result<()>> + 'a [ReadExactFuture<'a, Self>]
|
||||
where
|
||||
Self: Unpin,
|
||||
{
|
||||
unreachable!()
|
||||
ReadExactFuture { reader: self, buf }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -273,61 +284,4 @@ cfg_if! {
|
|||
unreachable!()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pub use futures_io::AsyncRead as Read;
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub trait ReadExt: futures_io::AsyncRead {
|
||||
fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> ReadFuture<'a, Self>
|
||||
where
|
||||
Self: Unpin,
|
||||
{
|
||||
ReadFuture { reader: self, buf }
|
||||
}
|
||||
|
||||
fn read_vectored<'a>(
|
||||
&'a mut self,
|
||||
bufs: &'a mut [IoSliceMut<'a>],
|
||||
) -> ReadVectoredFuture<'a, Self>
|
||||
where
|
||||
Self: Unpin,
|
||||
{
|
||||
ReadVectoredFuture { reader: self, bufs }
|
||||
}
|
||||
|
||||
fn read_to_end<'a>(&'a mut self, buf: &'a mut Vec<u8>) -> ReadToEndFuture<'a, Self>
|
||||
where
|
||||
Self: Unpin,
|
||||
{
|
||||
let start_len = buf.len();
|
||||
ReadToEndFuture {
|
||||
reader: self,
|
||||
buf,
|
||||
start_len,
|
||||
}
|
||||
}
|
||||
|
||||
fn read_to_string<'a>(&'a mut self, buf: &'a mut String) -> ReadToStringFuture<'a, Self>
|
||||
where
|
||||
Self: Unpin,
|
||||
{
|
||||
let start_len = buf.len();
|
||||
ReadToStringFuture {
|
||||
reader: self,
|
||||
bytes: unsafe { mem::replace(buf.as_mut_vec(), Vec::new()) },
|
||||
buf,
|
||||
start_len,
|
||||
}
|
||||
}
|
||||
|
||||
fn read_exact<'a>(&'a mut self, buf: &'a mut [u8]) -> ReadExactFuture<'a, Self>
|
||||
where
|
||||
Self: Unpin,
|
||||
{
|
||||
ReadExactFuture { reader: self, buf }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: futures_io::AsyncRead + ?Sized> ReadExt for T {}
|
||||
|
|
|
@ -5,14 +5,15 @@ use cfg_if::cfg_if;
|
|||
use crate::future::Future;
|
||||
use crate::io::{self, SeekFrom};
|
||||
use crate::task::{Context, Poll};
|
||||
use crate::utils::extension_trait;
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "docs")] {
|
||||
use std::ops::{Deref, DerefMut};
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub struct ImplFuture<T>(std::marker::PhantomData<T>);
|
||||
|
||||
extension_trait! {
|
||||
/// Allows seeking through a byte stream.
|
||||
///
|
||||
/// This trait is a re-export of [`futures::io::AsyncSeek`] and is an async version of
|
||||
|
@ -30,7 +31,7 @@ cfg_if! {
|
|||
/// [`futures::io::AsyncSeek`]:
|
||||
/// https://docs.rs/futures-preview/0.3.0-alpha.17/futures/io/trait.AsyncSeek.html
|
||||
/// [provided methods]: #provided-methods
|
||||
pub trait Seek {
|
||||
pub trait Seek [SeekExt: futures_io::AsyncSeek] {
|
||||
/// Attempt to seek to an offset, in bytes, in a stream.
|
||||
fn poll_seek(
|
||||
self: Pin<&mut Self>,
|
||||
|
@ -60,11 +61,14 @@ cfg_if! {
|
|||
/// #
|
||||
/// # Ok(()) }) }
|
||||
/// ```
|
||||
fn seek(&mut self, pos: SeekFrom) -> ImplFuture<io::Result<u64>>
|
||||
fn seek(
|
||||
&mut self,
|
||||
pos: SeekFrom,
|
||||
) -> impl Future<Output = io::Result<u64>> [SeekFuture<'_, Self>]
|
||||
where
|
||||
Self: Unpin
|
||||
Self: Unpin,
|
||||
{
|
||||
unreachable!()
|
||||
SeekFuture { seeker: self, pos }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,22 +105,7 @@ cfg_if! {
|
|||
unreachable!()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pub use futures_io::AsyncSeek as Seek;
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub trait SeekExt: futures_io::AsyncSeek {
|
||||
fn seek(&mut self, pos: SeekFrom) -> SeekFuture<'_, Self>
|
||||
where
|
||||
Self: Unpin,
|
||||
{
|
||||
SeekFuture { seeker: self, pos }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: futures_io::AsyncSeek + ?Sized> SeekExt for T {}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[allow(missing_debug_implementations)]
|
||||
|
|
|
@ -11,6 +11,7 @@ use write_vectored::WriteVectoredFuture;
|
|||
use cfg_if::cfg_if;
|
||||
|
||||
use crate::io::IoSlice;
|
||||
use crate::utils::extension_trait;
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "docs")] {
|
||||
|
@ -19,10 +20,10 @@ cfg_if! {
|
|||
|
||||
use crate::io;
|
||||
use crate::task::{Context, Poll};
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub struct ImplFuture<'a, T>(std::marker::PhantomData<&'a T>);
|
||||
|
||||
extension_trait! {
|
||||
/// Allows writing to a byte stream.
|
||||
///
|
||||
/// This trait is a re-export of [`futures::io::AsyncWrite`] and is an async version of
|
||||
|
@ -44,7 +45,7 @@ cfg_if! {
|
|||
/// [`poll_write_vectored`]: #method.poll_write_vectored
|
||||
/// [`poll_flush`]: #tymethod.poll_flush
|
||||
/// [`poll_close`]: #tymethod.poll_close
|
||||
pub trait Write {
|
||||
pub trait Write [WriteExt: futures_io::AsyncWrite] {
|
||||
/// Attempt to write bytes from `buf` into the object.
|
||||
fn poll_write(
|
||||
self: Pin<&mut Self>,
|
||||
|
@ -92,11 +93,11 @@ cfg_if! {
|
|||
/// #
|
||||
/// # Ok(()) }) }
|
||||
/// ```
|
||||
fn write<'a>(&'a mut self, buf: &'a [u8]) -> ImplFuture<'a, io::Result<usize>>
|
||||
fn write<'a>(&'a mut self, buf: &'a [u8]) -> impl Future<Output = io::Result<usize>> + 'a [WriteFuture<'a, Self>]
|
||||
where
|
||||
Self: Unpin,
|
||||
{
|
||||
unreachable!()
|
||||
WriteFuture { writer: self, buf }
|
||||
}
|
||||
|
||||
/// Flushes the stream to ensure that all buffered contents reach their destination.
|
||||
|
@ -116,11 +117,11 @@ cfg_if! {
|
|||
/// #
|
||||
/// # Ok(()) }) }
|
||||
/// ```
|
||||
fn flush(&mut self) -> ImplFuture<'_, io::Result<()>>
|
||||
fn flush(&mut self) -> impl Future<Output = io::Result<()>> + '_ [FlushFuture<'_, Self>]
|
||||
where
|
||||
Self: Unpin,
|
||||
{
|
||||
unreachable!()
|
||||
FlushFuture { writer: self }
|
||||
}
|
||||
|
||||
/// Like [`write`], except that it writes from a slice of buffers.
|
||||
|
@ -136,11 +137,11 @@ cfg_if! {
|
|||
fn write_vectored<'a>(
|
||||
&'a mut self,
|
||||
bufs: &'a [IoSlice<'a>],
|
||||
) -> ImplFuture<'a, io::Result<usize>>
|
||||
) -> impl Future<Output = io::Result<usize>> + 'a [WriteVectoredFuture<'a, Self>]
|
||||
where
|
||||
Self: Unpin,
|
||||
{
|
||||
unreachable!()
|
||||
WriteVectoredFuture { writer: self, bufs }
|
||||
}
|
||||
|
||||
/// Writes an entire buffer into the byte stream.
|
||||
|
@ -167,11 +168,11 @@ cfg_if! {
|
|||
/// ```
|
||||
///
|
||||
/// [`write`]: #tymethod.write
|
||||
fn write_all<'a>(&'a mut self, buf: &'a [u8]) -> ImplFuture<'a, io::Result<()>>
|
||||
fn write_all<'a>(&'a mut self, buf: &'a [u8]) -> impl Future<Output = io::Result<()>> + 'a [WriteAllFuture<'a, Self>]
|
||||
where
|
||||
Self: Unpin,
|
||||
{
|
||||
unreachable!()
|
||||
WriteAllFuture { writer: self, buf }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -250,40 +251,4 @@ cfg_if! {
|
|||
unreachable!()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pub use futures_io::AsyncWrite as Write;
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub trait WriteExt: Write {
|
||||
fn write<'a>(&'a mut self, buf: &'a [u8]) -> WriteFuture<'a, Self>
|
||||
where
|
||||
Self: Unpin,
|
||||
{
|
||||
WriteFuture { writer: self, buf }
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> FlushFuture<'_, Self>
|
||||
where
|
||||
Self: Unpin,
|
||||
{
|
||||
FlushFuture { writer: self }
|
||||
}
|
||||
|
||||
fn write_vectored<'a>(&'a mut self, bufs: &'a [IoSlice<'a>]) -> WriteVectoredFuture<'a, Self>
|
||||
where
|
||||
Self: Unpin,
|
||||
{
|
||||
WriteVectoredFuture { writer: self, bufs }
|
||||
}
|
||||
|
||||
fn write_all<'a>(&'a mut self, buf: &'a [u8]) -> WriteAllFuture<'a, Self>
|
||||
where
|
||||
Self: Unpin,
|
||||
{
|
||||
WriteAllFuture { writer: self, buf }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Write + ?Sized> WriteExt for T {}
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#![doc(test(attr(deny(rust_2018_idioms, warnings))))]
|
||||
#![doc(test(attr(allow(unused_extern_crates, unused_variables))))]
|
||||
#![doc(html_logo_url = "https://async.rs/images/logo--hero.svg")]
|
||||
#![recursion_limit = "1024"]
|
||||
|
||||
use cfg_if::cfg_if;
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
86
src/utils.rs
86
src/utils.rs
|
@ -19,3 +19,89 @@ pub fn abort_on_panic<T>(f: impl FnOnce() -> T) -> T {
|
|||
mem::forget(bomb);
|
||||
t
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[macro_export]
|
||||
macro_rules! extension_trait {
|
||||
(@gen ($($head:tt)*) pub trait $name:ident [$ext:ident: $orig:path] { $($body:tt)* } $($imp:item)*) => {
|
||||
#[allow(dead_code)]
|
||||
mod owned {
|
||||
#[doc(hidden)]
|
||||
pub struct ImplFuture<T>(std::marker::PhantomData<T>);
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
mod borrowed {
|
||||
#[doc(hidden)]
|
||||
pub struct ImplFuture<'a, T>(std::marker::PhantomData<&'a T>);
|
||||
}
|
||||
|
||||
#[cfg(feature = "docs")]
|
||||
$($head)* pub trait $name {
|
||||
extension_trait!(@doc () $($body)*);
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "docs"))]
|
||||
pub use $orig as $name;
|
||||
|
||||
$($head)* pub trait $ext: $orig {
|
||||
extension_trait!(@ext () $($body)*);
|
||||
}
|
||||
|
||||
impl<T: $orig + ?Sized> $ext for T {}
|
||||
|
||||
$(#[cfg(feature = "docs")] $imp)*
|
||||
};
|
||||
(@gen ($($head:tt)*) $token:tt $($tail:tt)*) => {
|
||||
extension_trait!(@gen ($($head)* $token) $($tail)*);
|
||||
};
|
||||
|
||||
(@doc ($($head:tt)*) fn $name:ident $args:tt $(-> $ret:ty)?; $($tail:tt)*) => {
|
||||
extension_trait!(@doc ($($head)* fn $name $args $(-> $ret)?;) $($tail)*);
|
||||
};
|
||||
(@ext ($($head:tt)*) fn $name:ident $args:tt $(-> $ret:ty)?; $($tail:tt)*) => {
|
||||
extension_trait!(@ext ($($head)*) $($tail)*);
|
||||
};
|
||||
|
||||
(@doc ($($head:tt)*) fn $name:ident $args:tt $(-> $ret:ty)? { $($body:tt)* } $($tail:tt)*) => {
|
||||
extension_trait!(@doc ($($head)* fn $name $args $(-> $ret)? { $($body)* }) $($tail)*);
|
||||
};
|
||||
(@ext ($($head:tt)*) fn $name:ident $args:tt $(-> $ret:ty)? { $($body:tt)* } $($tail:tt)*) => {
|
||||
extension_trait!(@ext ($($head)*) $($tail)*);
|
||||
};
|
||||
|
||||
(@doc ($($head:tt)*) type $name:ident; $($tail:tt)*) => {
|
||||
extension_trait!(@doc ($($head)* type $name;) $($tail)*);
|
||||
};
|
||||
(@ext ($($head:tt)*) type $ident:ty; $($tail:tt)*) => {
|
||||
extension_trait!(@ext ($($head)*) $($tail)*);
|
||||
};
|
||||
|
||||
(@doc ($($head:tt)*) -> impl Future<Output = $out:ty> [$f:ty] $($tail:tt)*) => {
|
||||
extension_trait!(@doc ($($head)* -> owned::ImplFuture<$out>) $($tail)*);
|
||||
};
|
||||
(@ext ($($head:tt)*) -> impl Future<Output = $out:ty> [$f:ty] $($tail:tt)*) => {
|
||||
extension_trait!(@ext ($($head)* -> $f) $($tail)*);
|
||||
};
|
||||
|
||||
(@doc ($($head:tt)*) -> impl Future<Output = $out:ty> + $lt:lifetime [$f:ty] $($tail:tt)*) => {
|
||||
extension_trait!(@doc ($($head)* -> borrowed::ImplFuture<$lt, $out>) $($tail)*);
|
||||
};
|
||||
(@ext ($($head:tt)*) -> impl Future<Output = $out:ty> + $lt:lifetime [$f:ty] $($tail:tt)*) => {
|
||||
extension_trait!(@ext ($($head)* -> $f) $($tail)*);
|
||||
};
|
||||
|
||||
(@doc ($($head:tt)*) $token:tt $($tail:tt)*) => {
|
||||
extension_trait!(@doc ($($head)* $token) $($tail)*);
|
||||
};
|
||||
(@ext ($($head:tt)*) $token:tt $($tail:tt)*) => {
|
||||
extension_trait!(@ext ($($head)* $token) $($tail)*);
|
||||
};
|
||||
|
||||
(@doc ($($head:tt)*)) => { $($head)* };
|
||||
(@ext ($($head:tt)*)) => { $($head)* };
|
||||
|
||||
($($head:tt)*) => { extension_trait!(@gen () $($head)*); };
|
||||
}
|
||||
|
||||
pub use crate::extension_trait;
|
||||
|
|
Loading…
Reference in a new issue