Cleanup: replace cfg-if with our macros (#361)

* Cleanup: replace cfg-if with our macros

* Prefix macros with cfg_

* Remove #[macro_export] from internal macros
yoshuawuyts-patch-1
Stjepan Glavina 5 years ago committed by GitHub
parent 46f0fb1c64
commit ec23632f3e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -21,13 +21,12 @@ features = ["docs"]
rustdoc-args = ["--cfg", "feature=\"docs\""] rustdoc-args = ["--cfg", "feature=\"docs\""]
[features] [features]
docs = ["broadcaster"] docs = ["unstable"]
unstable = ["broadcaster"] unstable = ["broadcaster"]
[dependencies] [dependencies]
async-macros = "1.0.0" async-macros = "1.0.0"
async-task = "1.0.0" async-task = "1.0.0"
cfg-if = "0.1.9"
crossbeam-channel = "0.3.9" crossbeam-channel = "0.3.9"
crossbeam-deque = "0.7.1" crossbeam-deque = "0.7.1"
crossbeam-utils = "0.6.6" crossbeam-utils = "0.6.6"

@ -1,7 +1,5 @@
use std::future::Future; use std::future::Future;
use cfg_if::cfg_if;
use crate::io; use crate::io;
use crate::path::Path; use crate::path::Path;
use crate::task::blocking; use crate::task::blocking;
@ -113,22 +111,13 @@ impl DirBuilder {
} }
} }
cfg_if! { cfg_unix! {
if #[cfg(feature = "docs")] { use crate::os::unix::fs::DirBuilderExt;
use crate::os::unix::fs::DirBuilderExt;
} else if #[cfg(unix)] {
use std::os::unix::fs::DirBuilderExt;
}
}
#[cfg_attr(feature = "docs", doc(cfg(unix)))] impl DirBuilderExt for DirBuilder {
cfg_if! { fn mode(&mut self, mode: u32) -> &mut Self {
if #[cfg(any(unix, feature = "docs"))] { self.mode = Some(mode);
impl DirBuilderExt for DirBuilder { self
fn mode(&mut self, mode: u32) -> &mut Self {
self.mode = Some(mode);
self
}
} }
} }
} }

@ -2,8 +2,6 @@ use std::ffi::OsString;
use std::fmt; use std::fmt;
use std::sync::Arc; use std::sync::Arc;
use cfg_if::cfg_if;
use crate::fs::{FileType, Metadata}; use crate::fs::{FileType, Metadata};
use crate::io; use crate::io;
use crate::path::PathBuf; use crate::path::PathBuf;
@ -160,21 +158,12 @@ impl fmt::Debug for DirEntry {
} }
} }
cfg_if! { cfg_unix! {
if #[cfg(feature = "docs")] { use crate::os::unix::fs::DirEntryExt;
use crate::os::unix::fs::DirEntryExt;
} else if #[cfg(unix)] {
use std::os::unix::fs::DirEntryExt;
}
}
#[cfg_attr(feature = "docs", doc(cfg(unix)))] impl DirEntryExt for DirEntry {
cfg_if! { fn ino(&self) -> u64 {
if #[cfg(any(unix, feature = "docs"))] { self.0.ino()
impl DirEntryExt for DirEntry {
fn ino(&self) -> u64 {
self.0.ino()
}
} }
} }
} }

@ -7,8 +7,6 @@ use std::pin::Pin;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use cfg_if::cfg_if;
use crate::fs::{Metadata, Permissions}; use crate::fs::{Metadata, Permissions};
use crate::future; use crate::future;
use crate::io::{self, Read, Seek, SeekFrom, Write}; use crate::io::{self, Read, Seek, SeekFrom, Write};
@ -401,67 +399,54 @@ impl From<std::fs::File> for File {
} }
} }
cfg_if! { cfg_unix! {
if #[cfg(feature = "docs")] { use crate::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
use crate::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
use crate::os::windows::io::{AsRawHandle, FromRawHandle, IntoRawHandle, RawHandle};
} else if #[cfg(unix)] {
use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
} else if #[cfg(windows)] {
use std::os::windows::io::{AsRawHandle, FromRawHandle, IntoRawHandle, RawHandle};
}
}
#[cfg_attr(feature = "docs", doc(cfg(unix)))] impl AsRawFd for File {
cfg_if! { fn as_raw_fd(&self) -> RawFd {
if #[cfg(any(unix, feature = "docs"))] { self.file.as_raw_fd()
impl AsRawFd for File {
fn as_raw_fd(&self) -> RawFd {
self.file.as_raw_fd()
}
} }
}
impl FromRawFd for File { impl FromRawFd for File {
unsafe fn from_raw_fd(fd: RawFd) -> File { unsafe fn from_raw_fd(fd: RawFd) -> File {
std::fs::File::from_raw_fd(fd).into() std::fs::File::from_raw_fd(fd).into()
}
} }
}
impl IntoRawFd for File { impl IntoRawFd for File {
fn into_raw_fd(self) -> RawFd { fn into_raw_fd(self) -> RawFd {
let file = self.file.clone(); let file = self.file.clone();
drop(self); drop(self);
Arc::try_unwrap(file) Arc::try_unwrap(file)
.expect("cannot acquire ownership of the file handle after drop") .expect("cannot acquire ownership of the file handle after drop")
.into_raw_fd() .into_raw_fd()
}
} }
} }
} }
#[cfg_attr(feature = "docs", doc(cfg(windows)))] cfg_windows! {
cfg_if! { use crate::os::windows::io::{AsRawHandle, FromRawHandle, IntoRawHandle, RawHandle};
if #[cfg(any(windows, feature = "docs"))] {
impl AsRawHandle for File { impl AsRawHandle for File {
fn as_raw_handle(&self) -> RawHandle { fn as_raw_handle(&self) -> RawHandle {
self.file.as_raw_handle() self.file.as_raw_handle()
}
} }
}
impl FromRawHandle for File { impl FromRawHandle for File {
unsafe fn from_raw_handle(handle: RawHandle) -> File { unsafe fn from_raw_handle(handle: RawHandle) -> File {
std::fs::File::from_raw_handle(handle).into() std::fs::File::from_raw_handle(handle).into()
}
} }
}
impl IntoRawHandle for File { impl IntoRawHandle for File {
fn into_raw_handle(self) -> RawHandle { fn into_raw_handle(self) -> RawHandle {
let file = self.file.clone(); let file = self.file.clone();
drop(self); drop(self);
Arc::try_unwrap(file) Arc::try_unwrap(file)
.expect("cannot acquire ownership of the file handle after drop") .expect("cannot acquire ownership of the file handle after drop")
.into_raw_handle() .into_raw_handle()
}
} }
} }
} }

@ -1,86 +1,84 @@
use cfg_if::cfg_if; cfg_not_docs! {
pub use std::fs::FileType;
}
cfg_docs! {
/// The type of a file or directory.
///
/// A file type is returned by [`Metadata::file_type`].
///
/// Note that file types are mutually exclusive, i.e. at most one of methods [`is_dir`],
/// [`is_file`], and [`is_symlink`] can return `true`.
///
/// This type is a re-export of [`std::fs::FileType`].
///
/// [`Metadata::file_type`]: struct.Metadata.html#method.file_type
/// [`is_dir`]: #method.is_dir
/// [`is_file`]: #method.is_file
/// [`is_symlink`]: #method.is_symlink
/// [`std::fs::FileType`]: https://doc.rust-lang.org/std/fs/struct.FileType.html
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub struct FileType {
_private: (),
}
cfg_if! { impl FileType {
if #[cfg(feature = "docs")] { /// Returns `true` if this file type represents a regular directory.
/// The type of a file or directory.
/// ///
/// A file type is returned by [`Metadata::file_type`]. /// If this file type represents a symbolic link, this method returns `false`.
/// ///
/// Note that file types are mutually exclusive, i.e. at most one of methods [`is_dir`], /// # Examples
/// [`is_file`], and [`is_symlink`] can return `true`.
/// ///
/// This type is a re-export of [`std::fs::FileType`]. /// ```no_run
/// # fn main() -> std::io::Result<()> { async_std::task::block_on(async {
/// #
/// use async_std::fs;
/// ///
/// [`Metadata::file_type`]: struct.Metadata.html#method.file_type /// let file_type = fs::metadata(".").await?.file_type();
/// [`is_dir`]: #method.is_dir /// println!("{:?}", file_type.is_dir());
/// [`is_file`]: #method.is_file /// #
/// [`is_symlink`]: #method.is_symlink /// # Ok(()) }) }
/// [`std::fs::FileType`]: https://doc.rust-lang.org/std/fs/struct.FileType.html /// ```
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] pub fn is_dir(&self) -> bool {
pub struct FileType { unimplemented!()
_private: (),
} }
impl FileType { /// Returns `true` if this file type represents a regular file.
/// Returns `true` if this file type represents a regular directory. ///
/// /// If this file type represents a symbolic link, this method returns `false`.
/// If this file type represents a symbolic link, this method returns `false`. ///
/// /// # Examples
/// # Examples ///
/// /// ```no_run
/// ```no_run /// # fn main() -> std::io::Result<()> { async_std::task::block_on(async {
/// # fn main() -> std::io::Result<()> { async_std::task::block_on(async { /// #
/// # /// use async_std::fs;
/// use async_std::fs; ///
/// /// let file_type = fs::metadata("a.txt").await?.file_type();
/// let file_type = fs::metadata(".").await?.file_type(); /// println!("{:?}", file_type.is_file());
/// println!("{:?}", file_type.is_dir()); /// #
/// # /// # Ok(()) }) }
/// # Ok(()) }) } /// ```
/// ``` pub fn is_file(&self) -> bool {
pub fn is_dir(&self) -> bool { unimplemented!()
unimplemented!() }
}
/// Returns `true` if this file type represents a regular file.
///
/// If this file type represents a symbolic link, this method returns `false`.
///
/// # Examples
///
/// ```no_run
/// # fn main() -> std::io::Result<()> { async_std::task::block_on(async {
/// #
/// use async_std::fs;
///
/// let file_type = fs::metadata("a.txt").await?.file_type();
/// println!("{:?}", file_type.is_file());
/// #
/// # Ok(()) }) }
/// ```
pub fn is_file(&self) -> bool {
unimplemented!()
}
/// Returns `true` if this file type represents a symbolic link. /// Returns `true` if this file type represents a symbolic link.
/// ///
/// # Examples /// # Examples
/// ///
/// ```no_run /// ```no_run
/// # fn main() -> std::io::Result<()> { async_std::task::block_on(async { /// # fn main() -> std::io::Result<()> { async_std::task::block_on(async {
/// # /// #
/// use async_std::fs; /// use async_std::fs;
/// ///
/// let file_type = fs::metadata("a.txt").await?.file_type(); /// let file_type = fs::metadata("a.txt").await?.file_type();
/// println!("{:?}", file_type.is_symlink()); /// println!("{:?}", file_type.is_symlink());
/// # /// #
/// # Ok(()) }) } /// # Ok(()) }) }
/// ``` /// ```
pub fn is_symlink(&self) -> bool { pub fn is_symlink(&self) -> bool {
unimplemented!() unimplemented!()
}
} }
} else {
pub use std::fs::FileType;
} }
} }

@ -1,5 +1,3 @@
use cfg_if::cfg_if;
use crate::io; use crate::io;
use crate::path::Path; use crate::path::Path;
use crate::task::blocking; use crate::task::blocking;
@ -39,193 +37,193 @@ pub async fn metadata<P: AsRef<Path>>(path: P) -> io::Result<Metadata> {
blocking::spawn(move || std::fs::metadata(path)).await blocking::spawn(move || std::fs::metadata(path)).await
} }
cfg_if! { cfg_not_docs! {
if #[cfg(feature = "docs")] { pub use std::fs::Metadata;
use std::time::SystemTime; }
cfg_docs! {
use std::time::SystemTime;
use crate::fs::{FileType, Permissions}; use crate::fs::{FileType, Permissions};
/// Metadata for a file or directory. /// Metadata for a file or directory.
///
/// Metadata is returned by [`metadata`] and [`symlink_metadata`].
///
/// This type is a re-export of [`std::fs::Metadata`].
///
/// [`metadata`]: fn.metadata.html
/// [`symlink_metadata`]: fn.symlink_metadata.html
/// [`is_dir`]: #method.is_dir
/// [`is_file`]: #method.is_file
/// [`std::fs::Metadata`]: https://doc.rust-lang.org/std/fs/struct.Metadata.html
#[derive(Clone, Debug)]
pub struct Metadata {
_private: (),
}
impl Metadata {
/// Returns the file type from this metadata.
/// ///
/// Metadata is returned by [`metadata`] and [`symlink_metadata`]. /// # Examples
/// ///
/// This type is a re-export of [`std::fs::Metadata`]. /// ```no_run
/// # fn main() -> std::io::Result<()> { async_std::task::block_on(async {
/// #
/// use async_std::fs;
/// ///
/// [`metadata`]: fn.metadata.html /// let metadata = fs::metadata("a.txt").await?;
/// [`symlink_metadata`]: fn.symlink_metadata.html /// println!("{:?}", metadata.file_type());
/// [`is_dir`]: #method.is_dir /// #
/// [`is_file`]: #method.is_file /// # Ok(()) }) }
/// [`std::fs::Metadata`]: https://doc.rust-lang.org/std/fs/struct.Metadata.html /// ```
#[derive(Clone, Debug)] pub fn file_type(&self) -> FileType {
pub struct Metadata { unimplemented!()
_private: (),
} }
impl Metadata { /// Returns `true` if this metadata is for a regular directory.
/// Returns the file type from this metadata. ///
/// /// If this metadata is for a symbolic link, this method returns `false`.
/// # Examples ///
/// /// # Examples
/// ```no_run ///
/// # fn main() -> std::io::Result<()> { async_std::task::block_on(async { /// ```no_run
/// # /// # fn main() -> std::io::Result<()> { async_std::task::block_on(async {
/// use async_std::fs; /// #
/// /// use async_std::fs;
/// let metadata = fs::metadata("a.txt").await?; ///
/// println!("{:?}", metadata.file_type()); /// let metadata = fs::metadata(".").await?;
/// # /// println!("{:?}", metadata.is_dir());
/// # Ok(()) }) } /// #
/// ``` /// # Ok(()) }) }
pub fn file_type(&self) -> FileType { /// ```
unimplemented!() pub fn is_dir(&self) -> bool {
} unimplemented!()
}
/// Returns `true` if this metadata is for a regular directory.
///
/// If this metadata is for a symbolic link, this method returns `false`.
///
/// # Examples
///
/// ```no_run
/// # fn main() -> std::io::Result<()> { async_std::task::block_on(async {
/// #
/// use async_std::fs;
///
/// let metadata = fs::metadata(".").await?;
/// println!("{:?}", metadata.is_dir());
/// #
/// # Ok(()) }) }
/// ```
pub fn is_dir(&self) -> bool {
unimplemented!()
}
/// Returns `true` if this metadata is for a regular file. /// Returns `true` if this metadata is for a regular file.
/// ///
/// If this metadata is for a symbolic link, this method returns `false`. /// If this metadata is for a symbolic link, this method returns `false`.
/// ///
/// # Examples /// # Examples
/// ///
/// ```no_run /// ```no_run
/// # fn main() -> std::io::Result<()> { async_std::task::block_on(async { /// # fn main() -> std::io::Result<()> { async_std::task::block_on(async {
/// # /// #
/// use async_std::fs; /// use async_std::fs;
/// ///
/// let metadata = fs::metadata("a.txt").await?; /// let metadata = fs::metadata("a.txt").await?;
/// println!("{:?}", metadata.is_file()); /// println!("{:?}", metadata.is_file());
/// # /// #
/// # Ok(()) }) } /// # Ok(()) }) }
/// ``` /// ```
pub fn is_file(&self) -> bool { pub fn is_file(&self) -> bool {
unimplemented!() unimplemented!()
} }
/// Returns the file size in bytes. /// Returns the file size in bytes.
/// ///
/// # Examples /// # Examples
/// ///
/// ```no_run /// ```no_run
/// # fn main() -> std::io::Result<()> { async_std::task::block_on(async { /// # fn main() -> std::io::Result<()> { async_std::task::block_on(async {
/// # /// #
/// use async_std::fs; /// use async_std::fs;
/// ///
/// let metadata = fs::metadata("a.txt").await?; /// let metadata = fs::metadata("a.txt").await?;
/// println!("{}", metadata.len()); /// println!("{}", metadata.len());
/// # /// #
/// # Ok(()) }) } /// # Ok(()) }) }
/// ``` /// ```
pub fn len(&self) -> u64 { pub fn len(&self) -> u64 {
unimplemented!() unimplemented!()
} }
/// Returns the permissions from this metadata. /// Returns the permissions from this metadata.
/// ///
/// # Examples /// # Examples
/// ///
/// ```no_run /// ```no_run
/// # fn main() -> std::io::Result<()> { async_std::task::block_on(async { /// # fn main() -> std::io::Result<()> { async_std::task::block_on(async {
/// # /// #
/// use async_std::fs; /// use async_std::fs;
/// ///
/// let metadata = fs::metadata("a.txt").await?; /// let metadata = fs::metadata("a.txt").await?;
/// println!("{:?}", metadata.permissions()); /// println!("{:?}", metadata.permissions());
/// # /// #
/// # Ok(()) }) } /// # Ok(()) }) }
/// ``` /// ```
pub fn permissions(&self) -> Permissions { pub fn permissions(&self) -> Permissions {
unimplemented!() unimplemented!()
} }
/// Returns the last modification time. /// Returns the last modification time.
/// ///
/// # Errors /// # Errors
/// ///
/// This data may not be available on all platforms, in which case an error will be /// This data may not be available on all platforms, in which case an error will be
/// returned. /// returned.
/// ///
/// # Examples /// # Examples
/// ///
/// ```no_run /// ```no_run
/// # fn main() -> std::io::Result<()> { async_std::task::block_on(async { /// # fn main() -> std::io::Result<()> { async_std::task::block_on(async {
/// # /// #
/// use async_std::fs; /// use async_std::fs;
/// ///
/// let metadata = fs::metadata("a.txt").await?; /// let metadata = fs::metadata("a.txt").await?;
/// println!("{:?}", metadata.modified()); /// println!("{:?}", metadata.modified());
/// # /// #
/// # Ok(()) }) } /// # Ok(()) }) }
/// ``` /// ```
pub fn modified(&self) -> io::Result<SystemTime> { pub fn modified(&self) -> io::Result<SystemTime> {
unimplemented!() unimplemented!()
} }
/// Returns the last access time. /// Returns the last access time.
/// ///
/// # Errors /// # Errors
/// ///
/// This data may not be available on all platforms, in which case an error will be /// This data may not be available on all platforms, in which case an error will be
/// returned. /// returned.
/// ///
/// # Examples /// # Examples
/// ///
/// ```no_run /// ```no_run
/// # fn main() -> std::io::Result<()> { async_std::task::block_on(async { /// # fn main() -> std::io::Result<()> { async_std::task::block_on(async {
/// # /// #
/// use async_std::fs; /// use async_std::fs;
/// ///
/// let metadata = fs::metadata("a.txt").await?; /// let metadata = fs::metadata("a.txt").await?;
/// println!("{:?}", metadata.accessed()); /// println!("{:?}", metadata.accessed());
/// # /// #
/// # Ok(()) }) } /// # Ok(()) }) }
/// ``` /// ```
pub fn accessed(&self) -> io::Result<SystemTime> { pub fn accessed(&self) -> io::Result<SystemTime> {
unimplemented!() unimplemented!()
} }
/// Returns the creation time. /// Returns the creation time.
/// ///
/// # Errors /// # Errors
/// ///
/// This data may not be available on all platforms, in which case an error will be /// This data may not be available on all platforms, in which case an error will be
/// returned. /// returned.
/// ///
/// # Examples /// # Examples
/// ///
/// ```no_run /// ```no_run
/// # fn main() -> std::io::Result<()> { async_std::task::block_on(async { /// # fn main() -> std::io::Result<()> { async_std::task::block_on(async {
/// # /// #
/// use async_std::fs; /// use async_std::fs;
/// ///
/// let metadata = fs::metadata("a.txt").await?; /// let metadata = fs::metadata("a.txt").await?;
/// println!("{:?}", metadata.created()); /// println!("{:?}", metadata.created());
/// # /// #
/// # Ok(()) }) } /// # Ok(()) }) }
/// ``` /// ```
pub fn created(&self) -> io::Result<SystemTime> { pub fn created(&self) -> io::Result<SystemTime> {
unimplemented!() unimplemented!()
}
} }
} else {
pub use std::fs::Metadata;
} }
} }

@ -1,7 +1,5 @@
use std::future::Future; use std::future::Future;
use cfg_if::cfg_if;
use crate::fs::File; use crate::fs::File;
use crate::io; use crate::io;
use crate::path::Path; use crate::path::Path;
@ -296,27 +294,18 @@ impl Default for OpenOptions {
} }
} }
cfg_if! { cfg_unix! {
if #[cfg(feature = "docs")] { use crate::os::unix::fs::OpenOptionsExt;
use crate::os::unix::fs::OpenOptionsExt;
} else if #[cfg(unix)] {
use std::os::unix::fs::OpenOptionsExt;
}
}
#[cfg_attr(feature = "docs", doc(cfg(unix)))] impl OpenOptionsExt for OpenOptions {
cfg_if! { fn mode(&mut self, mode: u32) -> &mut Self {
if #[cfg(any(unix, feature = "docs"))] { self.0.mode(mode);
impl OpenOptionsExt for OpenOptions { self
fn mode(&mut self, mode: u32) -> &mut Self { }
self.0.mode(mode);
self
}
fn custom_flags(&mut self, flags: i32) -> &mut Self { fn custom_flags(&mut self, flags: i32) -> &mut Self {
self.0.custom_flags(flags); self.0.custom_flags(flags);
self self
}
} }
} }
} }

@ -1,58 +1,56 @@
use cfg_if::cfg_if; cfg_not_docs! {
pub use std::fs::Permissions;
}
cfg_docs! {
/// A set of permissions on a file or directory.
///
/// This type is a re-export of [`std::fs::Permissions`].
///
/// [`std::fs::Permissions`]: https://doc.rust-lang.org/std/fs/struct.Permissions.html
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct Permissions {
_private: (),
}
cfg_if! { impl Permissions {
if #[cfg(feature = "docs")] { /// Returns the read-only flag.
/// A set of permissions on a file or directory.
/// ///
/// This type is a re-export of [`std::fs::Permissions`]. /// # Examples
/// ///
/// [`std::fs::Permissions`]: https://doc.rust-lang.org/std/fs/struct.Permissions.html /// ```no_run
#[derive(Clone, PartialEq, Eq, Debug)] /// # fn main() -> std::io::Result<()> { async_std::task::block_on(async {
pub struct Permissions { /// #
_private: (), /// use async_std::fs;
///
/// let perm = fs::metadata("a.txt").await?.permissions();
/// println!("{:?}", perm.readonly());
/// #
/// # Ok(()) }) }
/// ```
pub fn readonly(&self) -> bool {
unimplemented!()
} }
impl Permissions { /// Configures the read-only flag.
/// Returns the read-only flag. ///
/// /// [`fs::set_permissions`]: fn.set_permissions.html
/// # Examples ///
/// /// # Examples
/// ```no_run ///
/// # fn main() -> std::io::Result<()> { async_std::task::block_on(async { /// ```no_run
/// # /// # fn main() -> std::io::Result<()> { async_std::task::block_on(async {
/// use async_std::fs; /// #
/// /// use async_std::fs;
/// let perm = fs::metadata("a.txt").await?.permissions(); ///
/// println!("{:?}", perm.readonly()); /// let mut perm = fs::metadata("a.txt").await?.permissions();
/// # /// perm.set_readonly(true);
/// # Ok(()) }) } /// fs::set_permissions("a.txt", perm).await?;
/// ``` /// #
pub fn readonly(&self) -> bool { /// # Ok(()) }) }
unimplemented!() /// ```
} pub fn set_readonly(&mut self, readonly: bool) {
unimplemented!()
/// Configures the read-only flag.
///
/// [`fs::set_permissions`]: fn.set_permissions.html
///
/// # Examples
///
/// ```no_run
/// # fn main() -> std::io::Result<()> { async_std::task::block_on(async {
/// #
/// use async_std::fs;
///
/// let mut perm = fs::metadata("a.txt").await?.permissions();
/// perm.set_readonly(true);
/// fs::set_permissions("a.txt", perm).await?;
/// #
/// # Ok(()) }) }
/// ```
pub fn set_readonly(&mut self, readonly: bool) {
unimplemented!()
}
} }
} else {
pub use std::fs::Permissions;
} }
} }

@ -1,15 +1,9 @@
use crate::utils::extension_trait; extension_trait! {
use std::pin::Pin;
use std::ops::{Deref, DerefMut};
cfg_if::cfg_if! { use crate::task::{Context, Poll};
if #[cfg(feature = "docs")] {
use std::pin::Pin;
use std::ops::{Deref, DerefMut};
use crate::task::{Context, Poll};
}
}
extension_trait! {
#[doc = r#" #[doc = r#"
A future represents an asynchronous computation. A future represents an asynchronous computation.

@ -30,7 +30,7 @@ use crate::future::Future;
/// } /// }
/// } /// }
/// ``` /// ```
#[cfg(any(feature = "unstable", feature = "docs"))] #[cfg(feature = "unstable")]
#[cfg_attr(feature = "docs", doc(cfg(unstable)))] #[cfg_attr(feature = "docs", doc(cfg(unstable)))]
pub trait IntoFuture { pub trait IntoFuture {
/// The type of value produced on completion. /// The type of value produced on completion.

@ -44,12 +44,6 @@
#[doc(inline)] #[doc(inline)]
pub use async_macros::{join, try_join}; pub use async_macros::{join, try_join};
#[doc(inline)]
#[cfg_attr(feature = "docs", doc(cfg(unstable)))]
pub use async_macros::{select, try_select};
use cfg_if::cfg_if;
pub use future::Future; pub use future::Future;
pub use pending::pending; pub use pending::pending;
pub use poll_fn::poll_fn; pub use poll_fn::poll_fn;
@ -62,10 +56,10 @@ mod poll_fn;
mod ready; mod ready;
mod timeout; mod timeout;
cfg_if! { cfg_unstable! {
if #[cfg(any(feature = "unstable", feature = "docs"))] { #[doc(inline)]
mod into_future; pub use async_macros::{select, try_select};
pub use into_future::IntoFuture; pub use into_future::IntoFuture;
} mod into_future;
} }

@ -12,19 +12,12 @@ use read_until::ReadUntilFuture;
use std::mem; use std::mem;
use std::pin::Pin; use std::pin::Pin;
use cfg_if::cfg_if;
use crate::io; use crate::io;
use crate::task::{Context, Poll}; use crate::task::{Context, Poll};
use crate::utils::extension_trait;
cfg_if! {
if #[cfg(feature = "docs")] {
use std::ops::{Deref, DerefMut};
}
}
extension_trait! { extension_trait! {
use std::ops::{Deref, DerefMut};
#[doc = r#" #[doc = r#"
Allows reading from a buffered byte stream. Allows reading from a buffered byte stream.

@ -13,23 +13,17 @@ use read_to_end::{read_to_end_internal, ReadToEndFuture};
use read_to_string::ReadToStringFuture; use read_to_string::ReadToStringFuture;
use read_vectored::ReadVectoredFuture; use read_vectored::ReadVectoredFuture;
use cfg_if::cfg_if;
use std::mem; use std::mem;
use crate::io::IoSliceMut; use crate::io::IoSliceMut;
use crate::utils::extension_trait;
cfg_if! { extension_trait! {
if #[cfg(feature = "docs")] { use std::pin::Pin;
use std::pin::Pin; use std::ops::{Deref, DerefMut};
use std::ops::{Deref, DerefMut};
use crate::io; use crate::io;
use crate::task::{Context, Poll}; use crate::task::{Context, Poll};
}
}
extension_trait! {
#[doc = r#" #[doc = r#"
Allows reading from a byte stream. Allows reading from a byte stream.
@ -309,34 +303,34 @@ extension_trait! {
#[doc = r#" #[doc = r#"
Creates a "by reference" adaptor for this instance of `Read`. Creates a "by reference" adaptor for this instance of `Read`.
The returned adaptor also implements `Read` and will simply borrow this The returned adaptor also implements `Read` and will simply borrow this
current reader. current reader.
# Examples # Examples
[`File`][file]s implement `Read`: [`File`][file]s implement `Read`:
[file]: ../fs/struct.File.html [file]: ../fs/struct.File.html
```no_run ```no_run
# fn main() -> std::io::Result<()> { async_std::task::block_on(async { # fn main() -> std::io::Result<()> { async_std::task::block_on(async {
# #
use async_std::prelude::*; use async_std::prelude::*;
use async_std::fs::File; use async_std::fs::File;
let mut f = File::open("foo.txt").await?; let mut f = File::open("foo.txt").await?;
let mut buffer = Vec::new(); let mut buffer = Vec::new();
let mut other_buffer = Vec::new(); let mut other_buffer = Vec::new();
{ {
let reference = f.by_ref(); let reference = f.by_ref();
// read at most 5 bytes // read at most 5 bytes
reference.take(5).read_to_end(&mut buffer).await?; reference.take(5).read_to_end(&mut buffer).await?;
} // drop our &mut reference so we can use f again } // drop our &mut reference so we can use f again
// original file still usable, read the rest // original file still usable, read the rest
f.read_to_end(&mut other_buffer).await?; f.read_to_end(&mut other_buffer).await?;
# #
@ -348,27 +342,27 @@ extension_trait! {
#[doc = r#" #[doc = r#"
Transforms this `Read` instance to a `Stream` over its bytes. Transforms this `Read` instance to a `Stream` over its bytes.
The returned type implements `Stream` where the `Item` is The returned type implements `Stream` where the `Item` is
`Result<u8, io::Error>`. `Result<u8, io::Error>`.
The yielded item is `Ok` if a byte was successfully read and `Err` The yielded item is `Ok` if a byte was successfully read and `Err`
otherwise. EOF is mapped to returning `None` from this iterator. otherwise. EOF is mapped to returning `None` from this iterator.
# Examples # Examples
[`File`][file]s implement `Read`: [`File`][file]s implement `Read`:
[file]: ../fs/struct.File.html [file]: ../fs/struct.File.html
```no_run ```no_run
# fn main() -> std::io::Result<()> { async_std::task::block_on(async { # fn main() -> std::io::Result<()> { async_std::task::block_on(async {
# #
use async_std::prelude::*; use async_std::prelude::*;
use async_std::fs::File; use async_std::fs::File;
let f = File::open("foo.txt").await?; let f = File::open("foo.txt").await?;
let mut s = f.bytes(); let mut s = f.bytes();
while let Some(byte) = s.next().await { while let Some(byte) = s.next().await {
println!("{}", byte.unwrap()); println!("{}", byte.unwrap());
} }
@ -382,29 +376,29 @@ extension_trait! {
#[doc = r#" #[doc = r#"
Creates an adaptor which will chain this stream with another. Creates an adaptor which will chain this stream with another.
The returned `Read` instance will first read all bytes from this object The returned `Read` instance will first read all bytes from this object
until EOF is encountered. Afterwards the output is equivalent to the until EOF is encountered. Afterwards the output is equivalent to the
output of `next`. output of `next`.
# Examples # Examples
[`File`][file]s implement `Read`: [`File`][file]s implement `Read`:
[file]: ../fs/struct.File.html [file]: ../fs/struct.File.html
```no_run ```no_run
# fn main() -> std::io::Result<()> { async_std::task::block_on(async { # fn main() -> std::io::Result<()> { async_std::task::block_on(async {
# #
use async_std::prelude::*; use async_std::prelude::*;
use async_std::fs::File; use async_std::fs::File;
let f1 = File::open("foo.txt").await?; let f1 = File::open("foo.txt").await?;
let f2 = File::open("bar.txt").await?; let f2 = File::open("bar.txt").await?;
let mut handle = f1.chain(f2); let mut handle = f1.chain(f2);
let mut buffer = String::new(); let mut buffer = String::new();
// read the value into a String. We could use any Read method here, // read the value into a String. We could use any Read method here,
// this is just one example. // this is just one example.
handle.read_to_string(&mut buffer).await?; handle.read_to_string(&mut buffer).await?;

@ -1,19 +1,16 @@
use std::pin::Pin; mod seek;
use cfg_if::cfg_if; use seek::SeekFuture;
use crate::future::Future; use crate::io::SeekFrom;
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};
}
}
extension_trait! { extension_trait! {
use std::ops::{Deref, DerefMut};
use std::pin::Pin;
use crate::io;
use crate::task::{Context, Poll};
#[doc = r#" #[doc = r#"
Allows seeking through a byte stream. Allows seeking through a byte stream.
@ -114,19 +111,3 @@ extension_trait! {
} }
} }
} }
#[doc(hidden)]
#[allow(missing_debug_implementations)]
pub struct SeekFuture<'a, T: Unpin + ?Sized> {
seeker: &'a mut T,
pos: SeekFrom,
}
impl<T: SeekExt + Unpin + ?Sized> Future for SeekFuture<'_, T> {
type Output = io::Result<u64>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let pos = self.pos;
Pin::new(&mut *self.seeker).poll_seek(cx, pos)
}
}

@ -0,0 +1,21 @@
use std::pin::Pin;
use crate::future::Future;
use crate::io::{self, Seek, SeekFrom};
use crate::task::{Context, Poll};
#[doc(hidden)]
#[allow(missing_debug_implementations)]
pub struct SeekFuture<'a, T: Unpin + ?Sized> {
pub(crate) seeker: &'a mut T,
pub(crate) pos: SeekFrom,
}
impl<T: Seek + Unpin + ?Sized> Future for SeekFuture<'_, T> {
type Output = io::Result<u64>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let pos = self.pos;
Pin::new(&mut *self.seeker).poll_seek(cx, pos)
}
}

@ -1,8 +1,6 @@
use std::pin::Pin; use std::pin::Pin;
use std::sync::Mutex; use std::sync::Mutex;
use cfg_if::cfg_if;
use crate::future::Future; use crate::future::Future;
use crate::io::{self, Write}; use crate::io::{self, Write};
use crate::task::{blocking, Context, JoinHandle, Poll}; use crate::task::{blocking, Context, JoinHandle, Poll};
@ -162,35 +160,22 @@ impl Write for Stderr {
} }
} }
cfg_if! { cfg_unix! {
if #[cfg(feature = "docs")] { use crate::os::unix::io::{AsRawFd, RawFd};
use crate::os::unix::io::{AsRawFd, RawFd};
use crate::os::windows::io::{AsRawHandle, RawHandle};
} else if #[cfg(unix)] {
use std::os::unix::io::{AsRawFd, RawFd};
} else if #[cfg(windows)] {
use std::os::windows::io::{AsRawHandle, RawHandle};
}
}
#[cfg_attr(feature = "docs", doc(cfg(unix)))] impl AsRawFd for Stderr {
cfg_if! { fn as_raw_fd(&self) -> RawFd {
if #[cfg(any(unix, feature = "docs"))] { std::io::stderr().as_raw_fd()
impl AsRawFd for Stderr {
fn as_raw_fd(&self) -> RawFd {
std::io::stderr().as_raw_fd()
}
} }
} }
} }
#[cfg_attr(feature = "docs", doc(cfg(unix)))] cfg_windows! {
cfg_if! { use crate::os::windows::io::{AsRawHandle, RawHandle};
if #[cfg(any(windows, feature = "docs"))] {
impl AsRawHandle for Stderr { impl AsRawHandle for Stderr {
fn as_raw_handle(&self) -> RawHandle { fn as_raw_handle(&self) -> RawHandle {
std::io::stderr().as_raw_handle() std::io::stderr().as_raw_handle()
}
} }
} }
} }

@ -1,8 +1,6 @@
use std::pin::Pin; use std::pin::Pin;
use std::sync::Mutex; use std::sync::Mutex;
use cfg_if::cfg_if;
use crate::future::{self, Future}; use crate::future::{self, Future};
use crate::io::{self, Read}; use crate::io::{self, Read};
use crate::task::{blocking, Context, JoinHandle, Poll}; use crate::task::{blocking, Context, JoinHandle, Poll};
@ -186,35 +184,22 @@ impl Read for Stdin {
} }
} }
cfg_if! { cfg_unix! {
if #[cfg(feature = "docs")] { use crate::os::unix::io::{AsRawFd, RawFd};
use crate::os::unix::io::{AsRawFd, RawFd};
use crate::os::windows::io::{AsRawHandle, RawHandle};
} else if #[cfg(unix)] {
use std::os::unix::io::{AsRawFd, RawFd};
} else if #[cfg(windows)] {
use std::os::windows::io::{AsRawHandle, RawHandle};
}
}
#[cfg_attr(feature = "docs", doc(cfg(unix)))] impl AsRawFd for Stdin {
cfg_if! { fn as_raw_fd(&self) -> RawFd {
if #[cfg(any(unix, feature = "docs"))] { std::io::stdin().as_raw_fd()
impl AsRawFd for Stdin {
fn as_raw_fd(&self) -> RawFd {
std::io::stdin().as_raw_fd()
}
} }
} }
} }
#[cfg_attr(feature = "docs", doc(cfg(unix)))] cfg_windows! {
cfg_if! { use crate::os::windows::io::{AsRawHandle, RawHandle};
if #[cfg(any(windows, feature = "docs"))] {
impl AsRawHandle for Stdin { impl AsRawHandle for Stdin {
fn as_raw_handle(&self) -> RawHandle { fn as_raw_handle(&self) -> RawHandle {
std::io::stdin().as_raw_handle() std::io::stdin().as_raw_handle()
}
} }
} }
} }

@ -1,8 +1,6 @@
use std::pin::Pin; use std::pin::Pin;
use std::sync::Mutex; use std::sync::Mutex;
use cfg_if::cfg_if;
use crate::future::Future; use crate::future::Future;
use crate::io::{self, Write}; use crate::io::{self, Write};
use crate::task::{blocking, Context, JoinHandle, Poll}; use crate::task::{blocking, Context, JoinHandle, Poll};
@ -162,35 +160,22 @@ impl Write for Stdout {
} }
} }
cfg_if! { cfg_unix! {
if #[cfg(feature = "docs")] { use crate::os::unix::io::{AsRawFd, RawFd};
use crate::os::unix::io::{AsRawFd, RawFd};
use crate::os::windows::io::{AsRawHandle, RawHandle};
} else if #[cfg(unix)] {
use std::os::unix::io::{AsRawFd, RawFd};
} else if #[cfg(windows)] {
use std::os::windows::io::{AsRawHandle, RawHandle};
}
}
#[cfg_attr(feature = "docs", doc(cfg(unix)))] impl AsRawFd for Stdout {
cfg_if! { fn as_raw_fd(&self) -> RawFd {
if #[cfg(any(unix, feature = "docs"))] { std::io::stdout().as_raw_fd()
impl AsRawFd for Stdout {
fn as_raw_fd(&self) -> RawFd {
std::io::stdout().as_raw_fd()
}
} }
} }
} }
#[cfg_attr(feature = "docs", doc(cfg(unix)))] cfg_windows! {
cfg_if! { use crate::os::windows::io::{AsRawHandle, RawHandle};
if #[cfg(any(windows, feature = "docs"))] {
impl AsRawHandle for Stdout { impl AsRawHandle for Stdout {
fn as_raw_handle(&self) -> RawHandle { fn as_raw_handle(&self) -> RawHandle {
std::io::stdout().as_raw_handle() std::io::stdout().as_raw_handle()
}
} }
} }
} }

@ -10,22 +10,14 @@ use write_all::WriteAllFuture;
use write_fmt::WriteFmtFuture; use write_fmt::WriteFmtFuture;
use write_vectored::WriteVectoredFuture; use write_vectored::WriteVectoredFuture;
use cfg_if::cfg_if; use crate::io::{self, IoSlice};
use crate::io::IoSlice; extension_trait! {
use crate::utils::extension_trait; use std::pin::Pin;
use std::ops::{Deref, DerefMut};
use crate::io; use crate::task::{Context, Poll};
cfg_if! {
if #[cfg(feature = "docs")] {
use std::pin::Pin;
use std::ops::{Deref, DerefMut};
use crate::task::{Context, Poll};
}
}
extension_trait! {
#[doc = r#" #[doc = r#"
Allows writing to a byte stream. Allows writing to a byte stream.

@ -48,7 +48,8 @@
#![doc(html_logo_url = "https://async.rs/images/logo--hero.svg")] #![doc(html_logo_url = "https://async.rs/images/logo--hero.svg")]
#![recursion_limit = "1024"] #![recursion_limit = "1024"]
use cfg_if::cfg_if; #[macro_use]
mod utils;
pub mod fs; pub mod fs;
pub mod future; pub mod future;
@ -61,26 +62,19 @@ pub mod stream;
pub mod sync; pub mod sync;
pub mod task; pub mod task;
cfg_if! { cfg_unstable! {
if #[cfg(any(feature = "unstable", feature = "docs"))] { pub mod pin;
#[cfg_attr(feature = "docs", doc(cfg(unstable)))] pub mod process;
pub mod pin;
#[cfg_attr(feature = "docs", doc(cfg(unstable)))]
pub mod process;
mod unit; mod unit;
mod vec; mod vec;
mod result; mod result;
mod option; mod option;
mod string; mod string;
mod collections; mod collections;
}
#[doc(inline)]
pub use std::{write, writeln};
} }
mod macros; mod macros;
pub(crate) mod utils;
#[cfg(any(feature = "unstable", feature = "docs"))]
#[cfg_attr(feature = "docs", doc(cfg(unstable)))]
#[doc(inline)]
pub use std::{write, writeln};

@ -43,7 +43,7 @@
/// # /// #
/// # }) /// # })
/// ``` /// ```
#[cfg(any(feature = "unstable", feature = "docs"))] #[cfg(feature = "unstable")]
#[cfg_attr(feature = "docs", doc(cfg(unstable)))] #[cfg_attr(feature = "docs", doc(cfg(unstable)))]
#[macro_export] #[macro_export]
macro_rules! print { macro_rules! print {
@ -81,7 +81,7 @@ macro_rules! print {
/// # /// #
/// # }) /// # })
/// ``` /// ```
#[cfg(any(feature = "unstable", feature = "docs"))] #[cfg(feature = "unstable")]
#[cfg_attr(feature = "docs", doc(cfg(unstable)))] #[cfg_attr(feature = "docs", doc(cfg(unstable)))]
#[macro_export] #[macro_export]
macro_rules! println { macro_rules! println {
@ -119,7 +119,7 @@ macro_rules! println {
/// # /// #
/// # }) /// # })
/// ``` /// ```
#[cfg(any(feature = "unstable", feature = "docs"))] #[cfg(feature = "unstable")]
#[cfg_attr(feature = "docs", doc(cfg(unstable)))] #[cfg_attr(feature = "docs", doc(cfg(unstable)))]
#[macro_export] #[macro_export]
macro_rules! eprint { macro_rules! eprint {
@ -153,7 +153,7 @@ macro_rules! eprint {
/// # /// #
/// # }) /// # })
/// ``` /// ```
#[cfg(any(feature = "unstable", feature = "docs"))] #[cfg(feature = "unstable")]
#[cfg_attr(feature = "docs", doc(cfg(unstable)))] #[cfg_attr(feature = "docs", doc(cfg(unstable)))]
#[macro_export] #[macro_export]
macro_rules! eprintln { macro_rules! eprintln {

@ -3,24 +3,22 @@ use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
use std::net::{SocketAddr, SocketAddrV4, SocketAddrV6}; use std::net::{SocketAddr, SocketAddrV4, SocketAddrV6};
use std::pin::Pin; use std::pin::Pin;
use cfg_if::cfg_if;
use crate::future::Future; use crate::future::Future;
use crate::io; use crate::io;
use crate::task::{blocking, Context, JoinHandle, Poll}; use crate::task::{blocking, Context, JoinHandle, Poll};
cfg_if! { cfg_not_docs! {
if #[cfg(feature = "docs")] { macro_rules! ret {
#[doc(hidden)] (impl Future<Output = $out:ty>, $fut:ty) => ($fut);
pub struct ImplFuture<T>(std::marker::PhantomData<T>); }
}
cfg_docs! {
#[doc(hidden)]
pub struct ImplFuture<T>(std::marker::PhantomData<T>);
macro_rules! ret { macro_rules! ret {
(impl Future<Output = $out:ty>, $fut:ty) => (ImplFuture<$out>); (impl Future<Output = $out:ty>, $fut:ty) => (ImplFuture<$out>);
}
} else {
macro_rules! ret {
(impl Future<Output = $out:ty>, $fut:ty) => ($fut);
}
} }
} }

@ -1,13 +1,10 @@
use std::net::SocketAddr; use std::net::SocketAddr;
use std::pin::Pin; use std::pin::Pin;
use cfg_if::cfg_if;
use super::TcpStream;
use crate::future::{self, Future}; use crate::future::{self, Future};
use crate::io; use crate::io;
use crate::net::driver::Watcher; use crate::net::driver::Watcher;
use crate::net::ToSocketAddrs; use crate::net::{TcpStream, ToSocketAddrs};
use crate::stream::Stream; use crate::stream::Stream;
use crate::task::{Context, Poll}; use crate::task::{Context, Poll};
@ -213,59 +210,46 @@ impl From<std::net::TcpListener> for TcpListener {
} }
} }
cfg_if! { cfg_unix! {
if #[cfg(feature = "docs")] { use crate::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
use crate::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
// use crate::os::windows::io::{AsRawHandle, FromRawHandle, IntoRawHandle, RawHandle};
} else if #[cfg(unix)] {
use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
} else if #[cfg(windows)] {
// use std::os::windows::io::{AsRawHandle, FromRawHandle, IntoRawHandle, RawHandle};
}
}
#[cfg_attr(feature = "docs", doc(cfg(unix)))] impl AsRawFd for TcpListener {
cfg_if! { fn as_raw_fd(&self) -> RawFd {
if #[cfg(any(unix, feature = "docs"))] { self.watcher.get_ref().as_raw_fd()
impl AsRawFd for TcpListener {
fn as_raw_fd(&self) -> RawFd {
self.watcher.get_ref().as_raw_fd()
}
} }
}
impl FromRawFd for TcpListener { impl FromRawFd for TcpListener {
unsafe fn from_raw_fd(fd: RawFd) -> TcpListener { unsafe fn from_raw_fd(fd: RawFd) -> TcpListener {
std::net::TcpListener::from_raw_fd(fd).into() std::net::TcpListener::from_raw_fd(fd).into()
}
} }
}
impl IntoRawFd for TcpListener { impl IntoRawFd for TcpListener {
fn into_raw_fd(self) -> RawFd { fn into_raw_fd(self) -> RawFd {
self.watcher.into_inner().into_raw_fd() self.watcher.into_inner().into_raw_fd()
}
} }
} }
} }
#[cfg_attr(feature = "docs", doc(cfg(windows)))] cfg_windows! {
cfg_if! { // use crate::os::windows::io::{AsRawHandle, FromRawHandle, IntoRawHandle, RawHandle};
if #[cfg(any(windows, feature = "docs"))] { //
// impl AsRawSocket for TcpListener { // impl AsRawSocket for TcpListener {
// fn as_raw_socket(&self) -> RawSocket { // fn as_raw_socket(&self) -> RawSocket {
// self.raw_socket // self.raw_socket
// } // }
// } // }
// //
// impl FromRawSocket for TcpListener { // impl FromRawSocket for TcpListener {
// unsafe fn from_raw_socket(handle: RawSocket) -> TcpListener { // unsafe fn from_raw_socket(handle: RawSocket) -> TcpListener {
// net::TcpListener::from_raw_socket(handle).try_into().unwrap() // net::TcpListener::from_raw_socket(handle).try_into().unwrap()
// } // }
// } // }
// //
// impl IntoRawSocket for TcpListener { // impl IntoRawSocket for TcpListener {
// fn into_raw_socket(self) -> RawSocket { // fn into_raw_socket(self) -> RawSocket {
// self.raw_socket // self.raw_socket
// } // }
// } // }
}
} }

@ -2,8 +2,6 @@ use std::io::{IoSlice, IoSliceMut, Read as _, Write as _};
use std::net::SocketAddr; use std::net::SocketAddr;
use std::pin::Pin; use std::pin::Pin;
use cfg_if::cfg_if;
use crate::future; use crate::future;
use crate::io::{self, Read, Write}; use crate::io::{self, Read, Write};
use crate::net::driver::Watcher; use crate::net::driver::Watcher;
@ -367,59 +365,46 @@ impl From<std::net::TcpStream> for TcpStream {
} }
} }
cfg_if! { cfg_unix! {
if #[cfg(feature = "docs")] { use crate::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
use crate::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
// use crate::os::windows::io::{AsRawHandle, FromRawHandle, IntoRawHandle, RawHandle};
} else if #[cfg(unix)] {
use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
} else if #[cfg(windows)] {
// use std::os::windows::io::{AsRawHandle, FromRawHandle, IntoRawHandle, RawHandle};
}
}
#[cfg_attr(feature = "docs", doc(cfg(unix)))] impl AsRawFd for TcpStream {
cfg_if! { fn as_raw_fd(&self) -> RawFd {
if #[cfg(any(unix, feature = "docs"))] { self.watcher.get_ref().as_raw_fd()
impl AsRawFd for TcpStream {
fn as_raw_fd(&self) -> RawFd {
self.watcher.get_ref().as_raw_fd()
}
} }
}
impl FromRawFd for TcpStream { impl FromRawFd for TcpStream {
unsafe fn from_raw_fd(fd: RawFd) -> TcpStream { unsafe fn from_raw_fd(fd: RawFd) -> TcpStream {
std::net::TcpStream::from_raw_fd(fd).into() std::net::TcpStream::from_raw_fd(fd).into()
}
} }
}
impl IntoRawFd for TcpStream { impl IntoRawFd for TcpStream {
fn into_raw_fd(self) -> RawFd { fn into_raw_fd(self) -> RawFd {
self.watcher.into_inner().into_raw_fd() self.watcher.into_inner().into_raw_fd()
}
} }
} }
} }
#[cfg_attr(feature = "docs", doc(cfg(windows)))] cfg_windows! {
cfg_if! { // use crate::os::windows::io::{AsRawHandle, FromRawHandle, IntoRawHandle, RawHandle};
if #[cfg(any(windows, feature = "docs"))] { //
// impl AsRawSocket for TcpStream { // impl AsRawSocket for TcpStream {
// fn as_raw_socket(&self) -> RawSocket { // fn as_raw_socket(&self) -> RawSocket {
// self.raw_socket // self.raw_socket
// } // }
// } // }
// //
// impl FromRawSocket for TcpStream { // impl FromRawSocket for TcpStream {
// unsafe fn from_raw_socket(handle: RawSocket) -> TcpStream { // unsafe fn from_raw_socket(handle: RawSocket) -> TcpStream {
// net::TcpStream::from_raw_socket(handle).try_into().unwrap() // net::TcpStream::from_raw_socket(handle).try_into().unwrap()
// } // }
// } // }
// //
// impl IntoRawSocket for TcpListener { // impl IntoRawSocket for TcpListener {
// fn into_raw_socket(self) -> RawSocket { // fn into_raw_socket(self) -> RawSocket {
// self.raw_socket // self.raw_socket
// } // }
// } // }
}
} }

@ -1,7 +1,5 @@
use std::io; use std::io;
use std::net::SocketAddr; use std::net::SocketAddr;
use cfg_if::cfg_if;
use std::net::{Ipv4Addr, Ipv6Addr}; use std::net::{Ipv4Addr, Ipv6Addr};
use crate::future; use crate::future;
@ -463,61 +461,46 @@ impl From<std::net::UdpSocket> for UdpSocket {
} }
} }
cfg_if! { cfg_unix! {
if #[cfg(feature = "docs")] { use crate::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
use crate::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
// use crate::os::windows::io::{AsRawHandle, FromRawHandle, IntoRawHandle, RawHandle};
} else if #[cfg(unix)] {
use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
} else if #[cfg(windows)] {
// use std::os::windows::io::{AsRawHandle, FromRawHandle, IntoRawHandle, RawHandle};
}
}
#[cfg_attr(feature = "docs", doc(cfg(unix)))] impl AsRawFd for UdpSocket {
cfg_if! { fn as_raw_fd(&self) -> RawFd {
if #[cfg(any(unix, feature = "docs"))] { self.watcher.get_ref().as_raw_fd()
impl AsRawFd for UdpSocket {
fn as_raw_fd(&self) -> RawFd {
self.watcher.get_ref().as_raw_fd()
}
} }
}
impl FromRawFd for UdpSocket { impl FromRawFd for UdpSocket {
unsafe fn from_raw_fd(fd: RawFd) -> UdpSocket { unsafe fn from_raw_fd(fd: RawFd) -> UdpSocket {
std::net::UdpSocket::from_raw_fd(fd).into() std::net::UdpSocket::from_raw_fd(fd).into()
}
} }
}
impl IntoRawFd for UdpSocket { impl IntoRawFd for UdpSocket {
fn into_raw_fd(self) -> RawFd { fn into_raw_fd(self) -> RawFd {
self.watcher.into_inner().into_raw_fd() self.watcher.into_inner().into_raw_fd()
}
} }
} }
} }
#[cfg_attr(feature = "docs", doc(cfg(windows)))] cfg_windows! {
cfg_if! { // use crate::os::windows::io::{AsRawHandle, FromRawHandle, IntoRawHandle, RawHandle};
if #[cfg(any(windows, feature = "docs"))] { //
// use std::os::windows::io::{AsRawSocket, FromRawSocket, IntoRawSocket, RawSocket}; // impl AsRawSocket for UdpSocket {
// // fn as_raw_socket(&self) -> RawSocket {
// impl AsRawSocket for UdpSocket { // self.raw_socket
// fn as_raw_socket(&self) -> RawSocket { // }
// self.raw_socket // }
// } //
// } // impl FromRawSocket for UdpSocket {
// // unsafe fn from_raw_socket(handle: RawSocket) -> UdpSocket {
// impl FromRawSocket for UdpSocket { // net::UdpSocket::from_raw_socket(handle).into()
// unsafe fn from_raw_socket(handle: RawSocket) -> UdpSocket { // }
// net::UdpSocket::from_raw_socket(handle).into() // }
// } //
// } // impl IntoRawSocket for UdpSocket {
// // fn into_raw_socket(self) -> RawSocket {
// impl IntoRawSocket for UdpSocket { // self.raw_socket
// fn into_raw_socket(self) -> RawSocket { // }
// self.raw_socket // }
// }
// }
}
} }

@ -1,9 +1,9 @@
//! OS-specific extensions. //! OS-specific extensions.
#[cfg(any(unix, feature = "docs"))] cfg_unix! {
#[cfg_attr(feature = "docs", doc(cfg(unix)))] pub mod unix;
pub mod unix; }
#[cfg(any(windows, feature = "docs"))] cfg_windows! {
#[cfg_attr(feature = "docs", doc(cfg(windows)))] pub mod windows;
pub mod windows; }

@ -1,7 +1,5 @@
//! Unix-specific filesystem extensions. //! Unix-specific filesystem extensions.
use cfg_if::cfg_if;
use crate::io; use crate::io;
use crate::path::Path; use crate::path::Path;
use crate::task::blocking; use crate::task::blocking;
@ -31,43 +29,43 @@ pub async fn symlink<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Resu
blocking::spawn(move || std::os::unix::fs::symlink(&src, &dst)).await blocking::spawn(move || std::os::unix::fs::symlink(&src, &dst)).await
} }
cfg_if! { cfg_not_docs! {
if #[cfg(feature = "docs")] { pub use std::os::unix::fs::{DirBuilderExt, DirEntryExt, OpenOptionsExt};
/// Unix-specific extensions to `DirBuilder`. }
pub trait DirBuilderExt {
/// Sets the mode to create new directories with. This option defaults to
/// `0o777`.
fn mode(&mut self, mode: u32) -> &mut Self;
}
/// Unix-specific extension methods for `DirEntry`. cfg_docs! {
pub trait DirEntryExt { /// Unix-specific extensions to `DirBuilder`.
/// Returns the underlying `d_ino` field in the contained `dirent` pub trait DirBuilderExt {
/// structure. /// Sets the mode to create new directories with. This option defaults to
fn ino(&self) -> u64; /// `0o777`.
} fn mode(&mut self, mode: u32) -> &mut Self;
}
/// Unix-specific extension methods for `DirEntry`.
pub trait DirEntryExt {
/// Returns the underlying `d_ino` field in the contained `dirent`
/// structure.
fn ino(&self) -> u64;
}
/// Unix-specific extensions to `OpenOptions`. /// Unix-specific extensions to `OpenOptions`.
pub trait OpenOptionsExt { pub trait OpenOptionsExt {
/// Sets the mode bits that a new file will be created with. /// Sets the mode bits that a new file will be created with.
/// ///
/// If a new file is created as part of a `File::open_opts` call then this /// If a new file is created as part of a `File::open_opts` call then this
/// specified `mode` will be used as the permission bits for the new file. /// specified `mode` will be used as the permission bits for the new file.
/// If no `mode` is set, the default of `0o666` will be used. /// If no `mode` is set, the default of `0o666` will be used.
/// The operating system masks out bits with the systems `umask`, to produce /// The operating system masks out bits with the systems `umask`, to produce
/// the final permissions. /// the final permissions.
fn mode(&mut self, mode: u32) -> &mut Self; fn mode(&mut self, mode: u32) -> &mut Self;
/// Pass custom flags to the `flags` argument of `open`. /// Pass custom flags to the `flags` argument of `open`.
/// ///
/// The bits that define the access mode are masked out with `O_ACCMODE`, to /// The bits that define the access mode are masked out with `O_ACCMODE`, to
/// ensure they do not interfere with the access mode set by Rusts options. /// ensure they do not interfere with the access mode set by Rusts options.
/// ///
/// Custom flags can only set flags, not remove flags set by Rusts options. /// Custom flags can only set flags, not remove flags set by Rusts options.
/// This options overwrites any previously set custom flags. /// This options overwrites any previously set custom flags.
fn custom_flags(&mut self, flags: i32) -> &mut Self; fn custom_flags(&mut self, flags: i32) -> &mut Self;
}
} else {
pub use std::os::unix::fs::{DirBuilderExt, OpenOptionsExt};
} }
} }

@ -1,56 +1,54 @@
//! Unix-specific I/O extensions. //! Unix-specific I/O extensions.
use cfg_if::cfg_if; cfg_not_docs! {
pub use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
}
cfg_if! { cfg_docs! {
if #[cfg(feature = "docs")] { /// Raw file descriptors.
/// Raw file descriptors. pub type RawFd = std::os::raw::c_int;
pub type RawFd = std::os::raw::c_int;
/// A trait to extract the raw unix file descriptor from an underlying /// A trait to extract the raw unix file descriptor from an underlying
/// object. /// object.
///
/// This is only available on unix platforms and must be imported in order
/// to call the method. Windows platforms have a corresponding `AsRawHandle`
/// and `AsRawSocket` set of traits.
pub trait AsRawFd {
/// Extracts the raw file descriptor.
/// ///
/// This is only available on unix platforms and must be imported in order /// This method does **not** pass ownership of the raw file descriptor
/// to call the method. Windows platforms have a corresponding `AsRawHandle` /// to the caller. The descriptor is only guaranteed to be valid while
/// and `AsRawSocket` set of traits. /// the original object has not yet been destroyed.
pub trait AsRawFd { fn as_raw_fd(&self) -> RawFd;
/// Extracts the raw file descriptor. }
///
/// This method does **not** pass ownership of the raw file descriptor
/// to the caller. The descriptor is only guaranteed to be valid while
/// the original object has not yet been destroyed.
fn as_raw_fd(&self) -> RawFd;
}
/// A trait to express the ability to construct an object from a raw file /// A trait to express the ability to construct an object from a raw file
/// descriptor.
pub trait FromRawFd {
/// Constructs a new instance of `Self` from the given raw file
/// descriptor. /// descriptor.
pub trait FromRawFd { ///
/// Constructs a new instance of `Self` from the given raw file /// This function **consumes ownership** of the specified file
/// descriptor. /// descriptor. The returned object will take responsibility for closing
/// /// it when the object goes out of scope.
/// This function **consumes ownership** of the specified file ///
/// descriptor. The returned object will take responsibility for closing /// This function is also unsafe as the primitives currently returned
/// it when the object goes out of scope. /// have the contract that they are the sole owner of the file
/// /// descriptor they are wrapping. Usage of this function could
/// This function is also unsafe as the primitives currently returned /// accidentally allow violating this contract which can cause memory
/// have the contract that they are the sole owner of the file /// unsafety in code that relies on it being true.
/// descriptor they are wrapping. Usage of this function could unsafe fn from_raw_fd(fd: RawFd) -> Self;
/// accidentally allow violating this contract which can cause memory }
/// unsafety in code that relies on it being true.
unsafe fn from_raw_fd(fd: RawFd) -> Self;
}
/// A trait to express the ability to consume an object and acquire ownership of /// A trait to express the ability to consume an object and acquire ownership of
/// its raw file descriptor. /// its raw file descriptor.
pub trait IntoRawFd { pub trait IntoRawFd {
/// Consumes this object, returning the raw underlying file descriptor. /// Consumes this object, returning the raw underlying file descriptor.
/// ///
/// This function **transfers ownership** of the underlying file descriptor /// This function **transfers ownership** of the underlying file descriptor
/// to the caller. Callers are then the unique owners of the file descriptor /// to the caller. Callers are then the unique owners of the file descriptor
/// and must close the descriptor once it's no longer needed. /// and must close the descriptor once it's no longer needed.
fn into_raw_fd(self) -> RawFd; fn into_raw_fd(self) -> RawFd;
}
} else {
pub use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
} }
} }

@ -1,7 +1,5 @@
//! Unix-specific networking extensions. //! Unix-specific networking extensions.
use cfg_if::cfg_if;
pub use datagram::UnixDatagram; pub use datagram::UnixDatagram;
pub use listener::{Incoming, UnixListener}; pub use listener::{Incoming, UnixListener};
pub use stream::UnixStream; pub use stream::UnixStream;
@ -10,90 +8,90 @@ mod datagram;
mod listener; mod listener;
mod stream; mod stream;
cfg_if! { cfg_not_docs! {
if #[cfg(feature = "docs")] { pub use std::os::unix::net::SocketAddr;
use std::fmt; }
cfg_docs! {
use std::fmt;
use crate::path::Path;
use crate::path::Path; /// An address associated with a Unix socket.
///
/// # Examples
///
/// ```
/// use async_std::os::unix::net::UnixListener;
///
/// let socket = UnixListener::bind("/tmp/socket").await?;
/// let addr = socket.local_addr()?;
/// ```
#[derive(Clone)]
pub struct SocketAddr {
_private: (),
}
/// An address associated with a Unix socket. impl SocketAddr {
/// Returns `true` if the address is unnamed.
/// ///
/// # Examples /// # Examples
/// ///
/// ``` /// A named address:
///
/// ```no_run
/// use async_std::os::unix::net::UnixListener; /// use async_std::os::unix::net::UnixListener;
/// ///
/// let socket = UnixListener::bind("/tmp/socket").await?; /// let socket = UnixListener::bind("/tmp/socket").await?;
/// let addr = socket.local_addr()?; /// let addr = socket.local_addr()?;
/// assert_eq!(addr.is_unnamed(), false);
/// ``` /// ```
#[derive(Clone)] ///
pub struct SocketAddr { /// An unnamed address:
_private: (), ///
/// ```no_run
/// use async_std::os::unix::net::UnixDatagram;
///
/// let socket = UnixDatagram::unbound().await?;
/// let addr = socket.local_addr()?;
/// assert_eq!(addr.is_unnamed(), true);
/// ```
pub fn is_unnamed(&self) -> bool {
unreachable!("this impl only appears in the rendered docs")
} }
impl SocketAddr { /// Returns the contents of this address if it is a `pathname` address.
/// Returns `true` if the address is unnamed. ///
/// /// # Examples
/// # Examples ///
/// /// With a pathname:
/// A named address: ///
/// /// ```no_run
/// ```no_run /// use async_std::os::unix::net::UnixListener;
/// use async_std::os::unix::net::UnixListener; /// use async_std::path::Path;
/// ///
/// let socket = UnixListener::bind("/tmp/socket").await?; /// let socket = UnixListener::bind("/tmp/socket").await?;
/// let addr = socket.local_addr()?; /// let addr = socket.local_addr()?;
/// assert_eq!(addr.is_unnamed(), false); /// assert_eq!(addr.as_pathname(), Some(Path::new("/tmp/socket")));
/// ``` /// ```
/// ///
/// An unnamed address: /// Without a pathname:
/// ///
/// ```no_run /// ```
/// use async_std::os::unix::net::UnixDatagram; /// use async_std::os::unix::net::UnixDatagram;
/// ///
/// let socket = UnixDatagram::unbound().await?; /// let socket = UnixDatagram::unbound()?;
/// let addr = socket.local_addr()?; /// let addr = socket.local_addr()?;
/// assert_eq!(addr.is_unnamed(), true); /// assert_eq!(addr.as_pathname(), None);
/// ``` /// ```
pub fn is_unnamed(&self) -> bool { pub fn as_pathname(&self) -> Option<&Path> {
unreachable!("this impl only appears in the rendered docs") unreachable!("this impl only appears in the rendered docs")
}
/// Returns the contents of this address if it is a `pathname` address.
///
/// # Examples
///
/// With a pathname:
///
/// ```no_run
/// use async_std::os::unix::net::UnixListener;
/// use async_std::path::Path;
///
/// let socket = UnixListener::bind("/tmp/socket").await?;
/// let addr = socket.local_addr()?;
/// assert_eq!(addr.as_pathname(), Some(Path::new("/tmp/socket")));
/// ```
///
/// Without a pathname:
///
/// ```
/// use async_std::os::unix::net::UnixDatagram;
///
/// let socket = UnixDatagram::unbound()?;
/// let addr = socket.local_addr()?;
/// assert_eq!(addr.as_pathname(), None);
/// ```
pub fn as_pathname(&self) -> Option<&Path> {
unreachable!("this impl only appears in the rendered docs")
}
} }
}
impl fmt::Debug for SocketAddr { impl fmt::Debug for SocketAddr {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
unreachable!("this impl only appears in the rendered docs") unreachable!("this impl only appears in the rendered docs")
}
} }
} else {
pub use std::os::unix::net::SocketAddr;
} }
} }

@ -1,50 +1,48 @@
//! Windows-specific I/O extensions. //! Windows-specific I/O extensions.
use cfg_if::cfg_if; cfg_not_docs! {
pub use std::os::windows::io::{
AsRawHandle, FromRawHandle, IntoRawHandle, RawHandle, RawSocket,
};
}
cfg_if! { cfg_docs! {
if #[cfg(feature = "docs")] { /// Raw HANDLEs.
/// Raw HANDLEs. pub type RawHandle = *mut std::os::raw::c_void;
pub type RawHandle = *mut std::os::raw::c_void;
/// Raw SOCKETs. /// Raw SOCKETs.
pub type RawSocket = u64; pub type RawSocket = u64;
/// Extracts raw handles. /// Extracts raw handles.
pub trait AsRawHandle { pub trait AsRawHandle {
/// Extracts the raw handle, without taking any ownership. /// Extracts the raw handle, without taking any ownership.
fn as_raw_handle(&self) -> RawHandle; fn as_raw_handle(&self) -> RawHandle;
} }
/// Construct I/O objects from raw handles. /// Construct I/O objects from raw handles.
pub trait FromRawHandle { pub trait FromRawHandle {
/// Constructs a new I/O object from the specified raw handle. /// Constructs a new I/O object from the specified raw handle.
/// ///
/// This function will **consume ownership** of the handle given, /// This function will **consume ownership** of the handle given,
/// passing responsibility for closing the handle to the returned /// passing responsibility for closing the handle to the returned
/// object. /// object.
/// ///
/// This function is also unsafe as the primitives currently returned /// This function is also unsafe as the primitives currently returned
/// have the contract that they are the sole owner of the file /// have the contract that they are the sole owner of the file
/// descriptor they are wrapping. Usage of this function could /// descriptor they are wrapping. Usage of this function could
/// accidentally allow violating this contract which can cause memory /// accidentally allow violating this contract which can cause memory
/// unsafety in code that relies on it being true. /// unsafety in code that relies on it being true.
unsafe fn from_raw_handle(handle: RawHandle) -> Self; unsafe fn from_raw_handle(handle: RawHandle) -> Self;
} }
/// A trait to express the ability to consume an object and acquire ownership of /// A trait to express the ability to consume an object and acquire ownership of
/// its raw `HANDLE`. /// its raw `HANDLE`.
pub trait IntoRawHandle { pub trait IntoRawHandle {
/// Consumes this object, returning the raw underlying handle. /// Consumes this object, returning the raw underlying handle.
/// ///
/// This function **transfers ownership** of the underlying handle to the /// This function **transfers ownership** of the underlying handle to the
/// caller. Callers are then the unique owners of the handle and must close /// caller. Callers are then the unique owners of the handle and must close
/// it once it's no longer needed. /// it once it's no longer needed.
fn into_raw_handle(self) -> RawHandle; fn into_raw_handle(self) -> RawHandle;
}
} else {
pub use std::os::windows::io::{
AsRawHandle, FromRawHandle, IntoRawHandle, RawHandle, RawSocket,
};
} }
} }

@ -11,8 +11,6 @@
//! use async_std::prelude::*; //! use async_std::prelude::*;
//! ``` //! ```
use cfg_if::cfg_if;
#[doc(no_inline)] #[doc(no_inline)]
pub use crate::future::Future; pub use crate::future::Future;
#[doc(no_inline)] #[doc(no_inline)]
@ -41,12 +39,9 @@ pub use crate::io::write::WriteExt as _;
#[doc(hidden)] #[doc(hidden)]
pub use crate::stream::stream::StreamExt as _; pub use crate::stream::stream::StreamExt as _;
cfg_if! { cfg_unstable! {
if #[cfg(any(feature = "unstable", feature = "docs"))] { #[doc(no_inline)]
#[doc(no_inline)] pub use crate::stream::DoubleEndedStream;
pub use crate::stream::DoubleEndedStream; #[doc(no_inline)]
pub use crate::stream::ExactSizeStream;
#[doc(no_inline)]
pub use crate::stream::ExactSizeStream;
}
} }

@ -10,8 +10,8 @@ use std::task::{Context, Poll};
/// `Item`s from the back, as well as the front. /// `Item`s from the back, as well as the front.
/// ///
/// [`Stream`]: trait.Stream.html /// [`Stream`]: trait.Stream.html
#[cfg(feature = "unstable")]
#[cfg_attr(feature = "docs", doc(cfg(unstable)))] #[cfg_attr(feature = "docs", doc(cfg(unstable)))]
#[cfg(any(feature = "unstable", feature = "docs"))]
pub trait DoubleEndedStream: Stream { pub trait DoubleEndedStream: Stream {
/// Removes and returns an element from the end of the stream. /// Removes and returns an element from the end of the stream.
/// ///

@ -76,8 +76,8 @@ pub use crate::stream::Stream;
/// # }); /// # });
/// # } /// # }
/// ``` /// ```
#[cfg(feature = "unstable")]
#[cfg_attr(feature = "docs", doc(cfg(unstable)))] #[cfg_attr(feature = "docs", doc(cfg(unstable)))]
#[cfg(any(feature = "unstable", feature = "docs"))]
pub trait ExactSizeStream: Stream { pub trait ExactSizeStream: Stream {
/// Returns the exact number of times the stream will iterate. /// Returns the exact number of times the stream will iterate.
/// ///

@ -27,6 +27,7 @@ use crate::stream::IntoStream;
/// # /// #
/// # }) } /// # }) }
/// ``` /// ```
#[cfg(feature = "unstable")]
#[cfg_attr(feature = "docs", doc(cfg(unstable)))] #[cfg_attr(feature = "docs", doc(cfg(unstable)))]
pub trait Extend<A> { pub trait Extend<A> {
/// Extends a collection with the contents of a stream. /// Extends a collection with the contents of a stream.

@ -106,8 +106,8 @@ use std::pin::Pin;
///``` ///```
/// ///
/// [`IntoStream`]: trait.IntoStream.html /// [`IntoStream`]: trait.IntoStream.html
#[cfg(feature = "unstable")]
#[cfg_attr(feature = "docs", doc(cfg(unstable)))] #[cfg_attr(feature = "docs", doc(cfg(unstable)))]
#[cfg(any(feature = "unstable", feature = "docs"))]
pub trait FromStream<T> { pub trait FromStream<T> {
/// Creates a value from a stream. /// Creates a value from a stream.
/// ///

@ -14,7 +14,7 @@ use crate::stream::Stream;
/// [`None`]: https://doc.rust-lang.org/std/option/enum.Option.html#variant.None /// [`None`]: https://doc.rust-lang.org/std/option/enum.Option.html#variant.None
/// [`Stream::fuse`]: trait.Stream.html#method.fuse /// [`Stream::fuse`]: trait.Stream.html#method.fuse
/// [`Fuse`]: struct.Fuse.html /// [`Fuse`]: struct.Fuse.html
#[cfg(any(feature = "unstable", feature = "docs"))] #[cfg(feature = "unstable")]
#[cfg_attr(feature = "docs", doc(cfg(unstable)))] #[cfg_attr(feature = "docs", doc(cfg(unstable)))]
pub trait FusedStream: Stream {} pub trait FusedStream: Stream {}

@ -43,9 +43,8 @@ use futures_timer::Delay;
/// # /// #
/// # Ok(()) }) } /// # Ok(()) }) }
/// ``` /// ```
#[cfg(any(feature = "unstable", feature = "docs"))] #[cfg(feature = "unstable")]
#[cfg_attr(feature = "docs", doc(cfg(unstable)))] #[cfg_attr(feature = "docs", doc(cfg(unstable)))]
#[doc(inline)]
pub fn interval(dur: Duration) -> Interval { pub fn interval(dur: Duration) -> Interval {
Interval { Interval {
delay: Delay::new(dur), delay: Delay::new(dur),
@ -55,9 +54,9 @@ pub fn interval(dur: Duration) -> Interval {
/// A stream representing notifications at fixed interval /// A stream representing notifications at fixed interval
/// ///
#[derive(Debug)] #[cfg(feature = "unstable")]
#[cfg_attr(feature = "docs", doc(cfg(unstable)))] #[cfg_attr(feature = "docs", doc(cfg(unstable)))]
#[doc(inline)] #[derive(Debug)]
pub struct Interval { pub struct Interval {
delay: Delay, delay: Delay,
interval: Duration, interval: Duration,

@ -13,8 +13,8 @@ use crate::stream::Stream;
/// See also: [`FromStream`]. /// See also: [`FromStream`].
/// ///
/// [`FromStream`]: trait.FromStream.html /// [`FromStream`]: trait.FromStream.html
#[cfg(feature = "unstable")]
#[cfg_attr(feature = "docs", doc(cfg(unstable)))] #[cfg_attr(feature = "docs", doc(cfg(unstable)))]
#[cfg(any(feature = "unstable", feature = "docs"))]
pub trait IntoStream { pub trait IntoStream {
/// The type of the elements being iterated over. /// The type of the elements being iterated over.
type Item; type Item;

@ -21,8 +21,6 @@
//! # }) //! # })
//! ``` //! ```
use cfg_if::cfg_if;
pub use empty::{empty, Empty}; pub use empty::{empty, Empty};
pub use from_fn::{from_fn, FromFn}; pub use from_fn::{from_fn, FromFn};
pub use once::{once, Once}; pub use once::{once, Once};
@ -40,28 +38,25 @@ mod once;
mod repeat; mod repeat;
mod repeat_with; mod repeat_with;
cfg_if! { cfg_unstable! {
if #[cfg(any(feature = "unstable", feature = "docs"))] { mod double_ended_stream;
mod double_ended_stream; mod exact_size_stream;
mod exact_size_stream; mod extend;
mod extend; mod from_stream;
mod from_stream; mod fused_stream;
mod fused_stream; mod interval;
mod interval; mod into_stream;
mod into_stream; mod product;
mod product; mod sum;
mod sum;
pub use double_ended_stream::DoubleEndedStream;
pub use exact_size_stream::ExactSizeStream;
pub use extend::Extend;
pub use from_stream::FromStream;
pub use fused_stream::FusedStream;
pub use interval::{interval, Interval};
pub use into_stream::IntoStream;
pub use product::Product;
pub use sum::Sum;
pub use stream::Merge; pub use double_ended_stream::DoubleEndedStream;
} pub use exact_size_stream::ExactSizeStream;
pub use extend::Extend;
pub use from_stream::FromStream;
pub use fused_stream::FusedStream;
pub use interval::{interval, Interval};
pub use into_stream::IntoStream;
pub use product::Product;
pub use stream::Merge;
pub use sum::Sum;
} }

@ -11,8 +11,8 @@ use crate::stream::Stream;
/// [`product`]: trait.Product.html#tymethod.product /// [`product`]: trait.Product.html#tymethod.product
/// [`FromStream`]: trait.FromStream.html /// [`FromStream`]: trait.FromStream.html
/// [`Stream::product`]: trait.Stream.html#method.product /// [`Stream::product`]: trait.Stream.html#method.product
#[cfg(feature = "unstable")]
#[cfg_attr(feature = "docs", doc(cfg(unstable)))] #[cfg_attr(feature = "docs", doc(cfg(unstable)))]
#[cfg(any(feature = "unstable", feature = "docs"))]
pub trait Product<A = Self>: Sized { pub trait Product<A = Self>: Sized {
/// Method which takes a stream and generates `Self` from the elements by /// Method which takes a stream and generates `Self` from the elements by
/// multiplying the items. /// multiplying the items.

@ -8,7 +8,7 @@ use futures_core::Stream;
/// This stream is returned by [`Stream::merge`]. /// This stream is returned by [`Stream::merge`].
/// ///
/// [`Stream::merge`]: trait.Stream.html#method.merge /// [`Stream::merge`]: trait.Stream.html#method.merge
#[cfg(any(feature = "unstable", feature = "docs"))] #[cfg(feature = "unstable")]
#[cfg_attr(feature = "docs", doc(cfg(unstable)))] #[cfg_attr(feature = "docs", doc(cfg(unstable)))]
#[derive(Debug)] #[derive(Debug)]
pub struct Merge<L, R> { pub struct Merge<L, R> {

@ -91,32 +91,22 @@ pub use zip::Zip;
use std::cmp::Ordering; use std::cmp::Ordering;
use std::marker::PhantomData; use std::marker::PhantomData;
use cfg_if::cfg_if; cfg_unstable! {
use std::pin::Pin;
use crate::utils::extension_trait; use crate::future::Future;
use crate::stream::FromStream;
cfg_if! { pub use merge::Merge;
if #[cfg(feature = "docs")] {
use std::ops::{Deref, DerefMut};
use crate::task::{Context, Poll}; mod merge;
}
} }
cfg_if! { extension_trait! {
if #[cfg(any(feature = "unstable", feature = "docs"))] { use std::ops::{Deref, DerefMut};
mod merge;
use std::pin::Pin;
use crate::future::Future;
use crate::stream::FromStream;
pub use merge::Merge; use crate::task::{Context, Poll};
}
}
extension_trait! {
#[doc = r#" #[doc = r#"
An asynchronous stream of values. An asynchronous stream of values.
@ -495,7 +485,7 @@ extension_trait! {
# #
# }) } # }) }
``` ```
"#] "#]
fn last( fn last(
self, self,
@ -1276,7 +1266,7 @@ extension_trait! {
[`stream`]: trait.Stream.html#tymethod.next [`stream`]: trait.Stream.html#tymethod.next
"#] "#]
#[cfg(any(feature = "unstable", feature = "docs"))] #[cfg(feature = "unstable")]
#[cfg_attr(feature = "docs", doc(cfg(unstable)))] #[cfg_attr(feature = "docs", doc(cfg(unstable)))]
#[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead (TODO)"] #[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead (TODO)"]
fn collect<'a, B>( fn collect<'a, B>(
@ -1315,7 +1305,7 @@ extension_trait! {
# }); # });
``` ```
"#] "#]
#[cfg(any(feature = "unstable", feature = "docs"))] #[cfg(feature = "unstable")]
#[cfg_attr(feature = "docs", doc(cfg(unstable)))] #[cfg_attr(feature = "docs", doc(cfg(unstable)))]
fn merge<U>(self, other: U) -> Merge<Self, U> fn merge<U>(self, other: U) -> Merge<Self, U>
where where
@ -1345,9 +1335,9 @@ extension_trait! {
let s4 = VecDeque::from(vec![1, 2, 4]); let s4 = VecDeque::from(vec![1, 2, 4]);
assert_eq!(s1.clone().partial_cmp(s1.clone()).await, Some(Ordering::Equal)); assert_eq!(s1.clone().partial_cmp(s1.clone()).await, Some(Ordering::Equal));
assert_eq!(s1.clone().partial_cmp(s2.clone()).await, Some(Ordering::Less)); assert_eq!(s1.clone().partial_cmp(s2.clone()).await, Some(Ordering::Less));
assert_eq!(s2.clone().partial_cmp(s1.clone()).await, Some(Ordering::Greater)); assert_eq!(s2.clone().partial_cmp(s1.clone()).await, Some(Ordering::Greater));
assert_eq!(s3.clone().partial_cmp(s4.clone()).await, Some(Ordering::Less)); assert_eq!(s3.clone().partial_cmp(s4.clone()).await, Some(Ordering::Less));
assert_eq!(s4.clone().partial_cmp(s3.clone()).await, Some(Ordering::Greater)); assert_eq!(s4.clone().partial_cmp(s3.clone()).await, Some(Ordering::Greater));
# #
# }) } # }) }
``` ```
@ -1366,7 +1356,7 @@ extension_trait! {
#[doc = r#" #[doc = r#"
Lexicographically compares the elements of this `Stream` with those Lexicographically compares the elements of this `Stream` with those
of another using 'Ord'. of another using 'Ord'.
# Examples # Examples
@ -1383,9 +1373,9 @@ extension_trait! {
let s4 = VecDeque::from(vec![1, 2, 4]); let s4 = VecDeque::from(vec![1, 2, 4]);
assert_eq!(s1.clone().cmp(s1.clone()).await, Ordering::Equal); assert_eq!(s1.clone().cmp(s1.clone()).await, Ordering::Equal);
assert_eq!(s1.clone().cmp(s2.clone()).await, Ordering::Less); assert_eq!(s1.clone().cmp(s2.clone()).await, Ordering::Less);
assert_eq!(s2.clone().cmp(s1.clone()).await, Ordering::Greater); assert_eq!(s2.clone().cmp(s1.clone()).await, Ordering::Greater);
assert_eq!(s3.clone().cmp(s4.clone()).await, Ordering::Less); assert_eq!(s3.clone().cmp(s4.clone()).await, Ordering::Less);
assert_eq!(s4.clone().cmp(s3.clone()).await, Ordering::Greater); assert_eq!(s4.clone().cmp(s3.clone()).await, Ordering::Greater);
# #
# }) } # }) }
``` ```

@ -11,8 +11,8 @@ use crate::stream::Stream;
/// [`sum`]: trait.Sum.html#tymethod.sum /// [`sum`]: trait.Sum.html#tymethod.sum
/// [`FromStream`]: trait.FromStream.html /// [`FromStream`]: trait.FromStream.html
/// [`Stream::sum`]: trait.Stream.html#method.sum /// [`Stream::sum`]: trait.Stream.html#method.sum
#[cfg(feature = "unstable")]
#[cfg_attr(feature = "docs", doc(cfg(unstable)))] #[cfg_attr(feature = "docs", doc(cfg(unstable)))]
#[cfg(any(feature = "unstable", feature = "docs"))]
pub trait Sum<A = Self>: Sized { pub trait Sum<A = Self>: Sized {
/// Method which takes a stream and generates `Self` from the elements by /// Method which takes a stream and generates `Self` from the elements by
/// "summing up" the items. /// "summing up" the items.

@ -32,6 +32,7 @@ use crate::sync::Mutex;
/// # }); /// # });
/// # } /// # }
/// ``` /// ```
#[cfg(feature = "unstable")]
#[cfg_attr(feature = "docs", doc(cfg(unstable)))] #[cfg_attr(feature = "docs", doc(cfg(unstable)))]
#[derive(Debug)] #[derive(Debug)]
pub struct Barrier { pub struct Barrier {
@ -61,6 +62,7 @@ struct BarrierState {
/// let barrier = Barrier::new(1); /// let barrier = Barrier::new(1);
/// let barrier_wait_result = barrier.wait(); /// let barrier_wait_result = barrier.wait();
/// ``` /// ```
#[cfg(feature = "unstable")]
#[cfg_attr(feature = "docs", doc(cfg(unstable)))] #[cfg_attr(feature = "docs", doc(cfg(unstable)))]
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct BarrierWaitResult(bool); pub struct BarrierWaitResult(bool);

@ -32,14 +32,13 @@
#[doc(inline)] #[doc(inline)]
pub use std::sync::{Arc, Weak}; pub use std::sync::{Arc, Weak};
#[cfg(any(feature = "unstable", feature = "docs"))]
pub use barrier::{Barrier, BarrierWaitResult};
pub use mutex::{Mutex, MutexGuard}; pub use mutex::{Mutex, MutexGuard};
pub use rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard}; pub use rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard};
#[cfg(any(feature = "unstable", feature = "docs"))]
#[cfg_attr(feature = "docs", doc(cfg(unstable)))]
mod barrier;
mod mutex; mod mutex;
mod rwlock; mod rwlock;
cfg_unstable! {
pub use barrier::{Barrier, BarrierWaitResult};
mod barrier;
}

@ -143,11 +143,9 @@ mod worker;
pub(crate) mod blocking; pub(crate) mod blocking;
cfg_if::cfg_if! { cfg_unstable! {
if #[cfg(any(feature = "unstable", feature = "docs"))] { mod yield_now;
mod yield_now; pub use yield_now::yield_now;
pub use yield_now::yield_now;
}
} }
/// Spawns a blocking task. /// Spawns a blocking task.
@ -178,7 +176,7 @@ cfg_if::cfg_if! {
/// ``` /// ```
// Once this function stabilizes we should merge `blocking::spawn` into this so // Once this function stabilizes we should merge `blocking::spawn` into this so
// all code in our crate uses `task::blocking` too. // all code in our crate uses `task::blocking` too.
#[cfg(any(feature = "unstable", feature = "docs"))] #[cfg(feature = "unstable")]
#[cfg_attr(feature = "docs", doc(cfg(unstable)))] #[cfg_attr(feature = "docs", doc(cfg(unstable)))]
#[inline] #[inline]
pub fn spawn_blocking<F, R>(f: F) -> task::JoinHandle<R> pub fn spawn_blocking<F, R>(f: F) -> task::JoinHandle<R>

@ -26,7 +26,7 @@ use std::pin::Pin;
/// # /// #
/// # }) } /// # }) }
/// ``` /// ```
#[cfg(any(feature = "unstable", feature = "docs"))] #[cfg(feature = "unstable")]
#[cfg_attr(feature = "docs", doc(cfg(unstable)))] #[cfg_attr(feature = "docs", doc(cfg(unstable)))]
#[inline] #[inline]
pub async fn yield_now() { pub async fn yield_now() {

@ -20,6 +20,64 @@ pub fn abort_on_panic<T>(f: impl FnOnce() -> T) -> T {
t t
} }
/// Declares unstable items.
#[doc(hidden)]
macro_rules! cfg_unstable {
($($item:item)*) => {
$(
#[cfg(feature = "unstable")]
#[cfg_attr(feature = "docs", doc(cfg(unstable)))]
$item
)*
}
}
/// Declares Unix-specific items.
#[doc(hidden)]
macro_rules! cfg_unix {
($($item:item)*) => {
$(
#[cfg(any(unix, feature = "docs"))]
#[cfg_attr(feature = "docs", doc(cfg(unix)))]
$item
)*
}
}
/// Declares Windows-specific items.
#[doc(hidden)]
macro_rules! cfg_windows {
($($item:item)*) => {
$(
#[cfg(any(windows, feature = "docs"))]
#[cfg_attr(feature = "docs", doc(cfg(windows)))]
$item
)*
}
}
/// Declares items when the "docs" feature is enabled.
#[doc(hidden)]
macro_rules! cfg_docs {
($($item:item)*) => {
$(
#[cfg(feature = "docs")]
$item
)*
}
}
/// Declares items when the "docs" feature is disabled.
#[doc(hidden)]
macro_rules! cfg_not_docs {
($($item:item)*) => {
$(
#[cfg(not(feature = "docs"))]
$item
)*
}
}
/// Defines an extension trait for a base trait. /// Defines an extension trait for a base trait.
/// ///
/// In generated docs, the base trait will contain methods from the extension trait. In actual /// In generated docs, the base trait will contain methods from the extension trait. In actual
@ -29,7 +87,6 @@ pub fn abort_on_panic<T>(f: impl FnOnce() -> T) -> T {
/// Inside invocations of this macro, we write a definitions that looks similar to the final /// Inside invocations of this macro, we write a definitions that looks similar to the final
/// rendered docs, and the macro then generates all the boilerplate for us. /// rendered docs, and the macro then generates all the boilerplate for us.
#[doc(hidden)] #[doc(hidden)]
#[macro_export]
macro_rules! extension_trait { macro_rules! extension_trait {
( (
// Interesting patterns: // Interesting patterns:
@ -113,6 +170,12 @@ macro_rules! extension_trait {
// Handle the end of the token list. // Handle the end of the token list.
(@doc ($($head:tt)*)) => { $($head)* }; (@doc ($($head:tt)*)) => { $($head)* };
(@ext ($($head:tt)*)) => { $($head)* }; (@ext ($($head:tt)*)) => { $($head)* };
}
pub use crate::extension_trait; // Parse imports at the beginning of the macro.
($import:item $($tail:tt)*) => {
#[cfg(feature = "docs")]
$import
extension_trait!($($tail)*);
};
}

Loading…
Cancel
Save