Merge branch 'master' into add_stream_flatten

This commit is contained in:
k-nasa 2019-10-18 12:43:52 +09:00
commit 1c1e2230f3
49 changed files with 933 additions and 1084 deletions

View file

@ -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"

View file

@ -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
}
} }
} }
} }

View file

@ -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()
}
} }
} }
} }

View file

@ -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}; impl AsRawFd for File {
} else if #[cfg(unix)] { fn as_raw_fd(&self) -> RawFd {
use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd}; self.file.as_raw_fd()
} else if #[cfg(windows)] { }
use std::os::windows::io::{AsRawHandle, FromRawHandle, IntoRawHandle, RawHandle};
} }
}
#[cfg_attr(feature = "docs", doc(cfg(unix)))] impl FromRawFd for File {
cfg_if! { unsafe fn from_raw_fd(fd: RawFd) -> File {
if #[cfg(any(unix, feature = "docs"))] { std::fs::File::from_raw_fd(fd).into()
impl AsRawFd for File {
fn as_raw_fd(&self) -> RawFd {
self.file.as_raw_fd()
}
} }
}
impl FromRawFd for File { impl IntoRawFd for File {
unsafe fn from_raw_fd(fd: RawFd) -> File { fn into_raw_fd(self) -> RawFd {
std::fs::File::from_raw_fd(fd).into() let file = self.file.clone();
} drop(self);
} Arc::try_unwrap(file)
.expect("cannot acquire ownership of the file handle after drop")
impl IntoRawFd for File { .into_raw_fd()
fn into_raw_fd(self) -> RawFd {
let file = self.file.clone();
drop(self);
Arc::try_unwrap(file)
.expect("cannot acquire ownership of the file handle after drop")
.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 {
fn as_raw_handle(&self) -> RawHandle {
self.file.as_raw_handle()
}
}
impl FromRawHandle for File { impl AsRawHandle for File {
unsafe fn from_raw_handle(handle: RawHandle) -> File { fn as_raw_handle(&self) -> RawHandle {
std::fs::File::from_raw_handle(handle).into() self.file.as_raw_handle()
}
} }
}
impl IntoRawHandle for File { impl FromRawHandle for File {
fn into_raw_handle(self) -> RawHandle { unsafe fn from_raw_handle(handle: RawHandle) -> File {
let file = self.file.clone(); std::fs::File::from_raw_handle(handle).into()
drop(self); }
Arc::try_unwrap(file) }
.expect("cannot acquire ownership of the file handle after drop")
.into_raw_handle() impl IntoRawHandle for File {
} fn into_raw_handle(self) -> RawHandle {
let file = self.file.clone();
drop(self);
Arc::try_unwrap(file)
.expect("cannot acquire ownership of the file handle after drop")
.into_raw_handle()
} }
} }
} }

View file

@ -1,86 +1,84 @@
use cfg_if::cfg_if; cfg_not_docs! {
pub use std::fs::FileType;
}
cfg_if! { cfg_docs! {
if #[cfg(feature = "docs")] { /// The type of a file or directory.
/// 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: (),
}
impl FileType {
/// Returns `true` if this file type represents a regular 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 symbolic link.
/// Returns `true` if this file type represents a regular file. ///
/// /// # Examples
/// If this file type represents a symbolic link, this method returns `false`. ///
/// /// ```no_run
/// # Examples /// # fn main() -> std::io::Result<()> { async_std::task::block_on(async {
/// /// #
/// ```no_run /// use async_std::fs;
/// # fn main() -> std::io::Result<()> { async_std::task::block_on(async { ///
/// # /// let file_type = fs::metadata("a.txt").await?.file_type();
/// use async_std::fs; /// println!("{:?}", file_type.is_symlink());
/// /// #
/// let file_type = fs::metadata("a.txt").await?.file_type(); /// # Ok(()) }) }
/// println!("{:?}", file_type.is_file()); /// ```
/// # pub fn is_symlink(&self) -> bool {
/// # Ok(()) }) } unimplemented!()
/// ```
pub fn is_file(&self) -> bool {
unimplemented!()
}
/// Returns `true` if this file type represents a symbolic link.
///
/// # 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_symlink());
/// #
/// # Ok(()) }) }
/// ```
pub fn is_symlink(&self) -> bool {
unimplemented!()
}
} }
} else {
pub use std::fs::FileType;
} }
} }

View file

@ -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; }
use crate::fs::{FileType, Permissions}; cfg_docs! {
use std::time::SystemTime;
/// Metadata for a file or directory. use crate::fs::{FileType, Permissions};
/// 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.
/// /// 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 ///
/// # 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(".").await?; ///
/// println!("{:?}", metadata.is_dir()); /// let metadata = fs::metadata("a.txt").await?;
/// # /// println!("{:?}", metadata.is_file());
/// # Ok(()) }) } /// #
/// ``` /// # Ok(()) }) }
pub fn is_dir(&self) -> bool { /// ```
unimplemented!() pub fn is_file(&self) -> bool {
} unimplemented!()
}
/// Returns `true` if this metadata is for a regular file.
/// /// Returns the file size in bytes.
/// 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.len());
/// println!("{:?}", metadata.is_file()); /// #
/// # /// # Ok(()) }) }
/// # Ok(()) }) } /// ```
/// ``` pub fn len(&self) -> u64 {
pub fn is_file(&self) -> bool { unimplemented!()
unimplemented!() }
}
/// Returns the permissions from this metadata.
/// 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.permissions());
/// println!("{}", metadata.len()); /// #
/// # /// # Ok(()) }) }
/// # Ok(()) }) } /// ```
/// ``` pub fn permissions(&self) -> Permissions {
pub fn len(&self) -> u64 { unimplemented!()
unimplemented!() }
}
/// Returns the last modification time.
/// Returns the permissions from this metadata. ///
/// /// # Errors
/// # Examples ///
/// /// This data may not be available on all platforms, in which case an error will be
/// ```no_run /// returned.
/// # fn main() -> std::io::Result<()> { async_std::task::block_on(async { ///
/// # /// # Examples
/// use async_std::fs; ///
/// /// ```no_run
/// let metadata = fs::metadata("a.txt").await?; /// # fn main() -> std::io::Result<()> { async_std::task::block_on(async {
/// println!("{:?}", metadata.permissions()); /// #
/// # /// use async_std::fs;
/// # Ok(()) }) } ///
/// ``` /// let metadata = fs::metadata("a.txt").await?;
pub fn permissions(&self) -> Permissions { /// println!("{:?}", metadata.modified());
unimplemented!() /// #
} /// # Ok(()) }) }
/// ```
/// Returns the last modification time. pub fn modified(&self) -> io::Result<SystemTime> {
/// unimplemented!()
/// # Errors }
///
/// This data may not be available on all platforms, in which case an error will be /// Returns the last access time.
/// returned. ///
/// /// # Errors
/// # Examples ///
/// /// This data may not be available on all platforms, in which case an error will be
/// ```no_run /// returned.
/// # fn main() -> std::io::Result<()> { async_std::task::block_on(async { ///
/// # /// # Examples
/// use async_std::fs; ///
/// /// ```no_run
/// let metadata = fs::metadata("a.txt").await?; /// # fn main() -> std::io::Result<()> { async_std::task::block_on(async {
/// println!("{:?}", metadata.modified()); /// #
/// # /// use async_std::fs;
/// # Ok(()) }) } ///
/// ``` /// let metadata = fs::metadata("a.txt").await?;
pub fn modified(&self) -> io::Result<SystemTime> { /// println!("{:?}", metadata.accessed());
unimplemented!() /// #
} /// # Ok(()) }) }
/// ```
/// Returns the last access time. pub fn accessed(&self) -> io::Result<SystemTime> {
/// unimplemented!()
/// # Errors }
///
/// This data may not be available on all platforms, in which case an error will be /// Returns the creation time.
/// returned. ///
/// /// # Errors
/// # Examples ///
/// /// This data may not be available on all platforms, in which case an error will be
/// ```no_run /// returned.
/// # fn main() -> std::io::Result<()> { async_std::task::block_on(async { ///
/// # /// # Examples
/// use async_std::fs; ///
/// /// ```no_run
/// let metadata = fs::metadata("a.txt").await?; /// # fn main() -> std::io::Result<()> { async_std::task::block_on(async {
/// println!("{:?}", metadata.accessed()); /// #
/// # /// use async_std::fs;
/// # Ok(()) }) } ///
/// ``` /// let metadata = fs::metadata("a.txt").await?;
pub fn accessed(&self) -> io::Result<SystemTime> { /// println!("{:?}", metadata.created());
unimplemented!() /// #
} /// # Ok(()) }) }
/// ```
/// Returns the creation time. pub fn created(&self) -> io::Result<SystemTime> {
/// unimplemented!()
/// # Errors
///
/// This data may not be available on all platforms, in which case an error will be
/// returned.
///
/// # Examples
///
/// ```no_run
/// # fn main() -> std::io::Result<()> { async_std::task::block_on(async {
/// #
/// use async_std::fs;
///
/// let metadata = fs::metadata("a.txt").await?;
/// println!("{:?}", metadata.created());
/// #
/// # Ok(()) }) }
/// ```
pub fn created(&self) -> io::Result<SystemTime> {
unimplemented!()
}
} }
} else {
pub use std::fs::Metadata;
} }
} }

View file

@ -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
}
} }
} }
} }

View file

@ -1,58 +1,56 @@
use cfg_if::cfg_if; cfg_not_docs! {
pub use std::fs::Permissions;
}
cfg_if! { cfg_docs! {
if #[cfg(feature = "docs")] { /// A set of permissions on a file or directory.
/// 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: (),
}
impl Permissions {
/// Returns the read-only flag.
/// ///
/// 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;
} }
} }

View file

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

View file

@ -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.

View file

@ -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;
} }

View file

@ -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.

View file

@ -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! {
if #[cfg(feature = "docs")] {
use std::pin::Pin;
use std::ops::{Deref, DerefMut};
use crate::io;
use crate::task::{Context, Poll};
}
}
extension_trait! { extension_trait! {
use std::pin::Pin;
use std::ops::{Deref, DerefMut};
use crate::io;
use crate::task::{Context, Poll};
#[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?;

View file

@ -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)
}
}

21
src/io/seek/seek.rs Normal file
View file

@ -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)
}
}

View file

@ -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()
}
} }
} }
} }

View file

@ -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()
}
} }
} }
} }

View file

@ -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()
}
} }
} }
} }

View file

@ -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;
use crate::utils::extension_trait;
use crate::io;
cfg_if! {
if #[cfg(feature = "docs")] {
use std::pin::Pin;
use std::ops::{Deref, DerefMut};
use crate::task::{Context, Poll};
}
}
extension_trait! { extension_trait! {
use std::pin::Pin;
use std::ops::{Deref, DerefMut};
use crate::task::{Context, Poll};
#[doc = r#" #[doc = r#"
Allows writing to a byte stream. Allows writing to a byte stream.

View file

@ -49,7 +49,8 @@
#![recursion_limit = "1024"] #![recursion_limit = "1024"]
#![feature(associated_type_bounds)] #![feature(associated_type_bounds)]
use cfg_if::cfg_if; #[macro_use]
mod utils;
pub mod fs; pub mod fs;
pub mod future; pub mod future;
@ -62,26 +63,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};

View file

@ -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 {

View file

@ -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>); }
}
macro_rules! ret { cfg_docs! {
(impl Future<Output = $out:ty>, $fut:ty) => (ImplFuture<$out>); #[doc(hidden)]
} pub struct ImplFuture<T>(std::marker::PhantomData<T>);
} else {
macro_rules! ret { macro_rules! ret {
(impl Future<Output = $out:ty>, $fut:ty) => ($fut); (impl Future<Output = $out:ty>, $fut:ty) => (ImplFuture<$out>);
}
} }
} }

View file

@ -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}; impl AsRawFd for TcpListener {
} else if #[cfg(unix)] { fn as_raw_fd(&self) -> RawFd {
use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd}; self.watcher.get_ref().as_raw_fd()
} else if #[cfg(windows)] { }
// use std::os::windows::io::{AsRawHandle, FromRawHandle, IntoRawHandle, RawHandle};
} }
}
#[cfg_attr(feature = "docs", doc(cfg(unix)))] impl FromRawFd for TcpListener {
cfg_if! { unsafe fn from_raw_fd(fd: RawFd) -> TcpListener {
if #[cfg(any(unix, feature = "docs"))] { std::net::TcpListener::from_raw_fd(fd).into()
impl AsRawFd for TcpListener {
fn as_raw_fd(&self) -> RawFd {
self.watcher.get_ref().as_raw_fd()
}
} }
}
impl FromRawFd for TcpListener { impl IntoRawFd for TcpListener {
unsafe fn from_raw_fd(fd: RawFd) -> TcpListener { fn into_raw_fd(self) -> RawFd {
std::net::TcpListener::from_raw_fd(fd).into() self.watcher.into_inner().into_raw_fd()
}
}
impl IntoRawFd for TcpListener {
fn into_raw_fd(self) -> RawFd {
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
// } // }
// } // }
}
} }

View file

@ -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}; impl AsRawFd for TcpStream {
} else if #[cfg(unix)] { fn as_raw_fd(&self) -> RawFd {
use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd}; self.watcher.get_ref().as_raw_fd()
} else if #[cfg(windows)] { }
// use std::os::windows::io::{AsRawHandle, FromRawHandle, IntoRawHandle, RawHandle};
} }
}
#[cfg_attr(feature = "docs", doc(cfg(unix)))] impl FromRawFd for TcpStream {
cfg_if! { unsafe fn from_raw_fd(fd: RawFd) -> TcpStream {
if #[cfg(any(unix, feature = "docs"))] { std::net::TcpStream::from_raw_fd(fd).into()
impl AsRawFd for TcpStream {
fn as_raw_fd(&self) -> RawFd {
self.watcher.get_ref().as_raw_fd()
}
} }
}
impl FromRawFd for TcpStream { impl IntoRawFd for TcpStream {
unsafe fn from_raw_fd(fd: RawFd) -> TcpStream { fn into_raw_fd(self) -> RawFd {
std::net::TcpStream::from_raw_fd(fd).into() self.watcher.into_inner().into_raw_fd()
}
}
impl IntoRawFd for TcpStream {
fn into_raw_fd(self) -> RawFd {
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
// } // }
// } // }
}
} }

View file

@ -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}; impl AsRawFd for UdpSocket {
} else if #[cfg(unix)] { fn as_raw_fd(&self) -> RawFd {
use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd}; self.watcher.get_ref().as_raw_fd()
} else if #[cfg(windows)] { }
// use std::os::windows::io::{AsRawHandle, FromRawHandle, IntoRawHandle, RawHandle};
} }
}
#[cfg_attr(feature = "docs", doc(cfg(unix)))] impl FromRawFd for UdpSocket {
cfg_if! { unsafe fn from_raw_fd(fd: RawFd) -> UdpSocket {
if #[cfg(any(unix, feature = "docs"))] { std::net::UdpSocket::from_raw_fd(fd).into()
impl AsRawFd for UdpSocket {
fn as_raw_fd(&self) -> RawFd {
self.watcher.get_ref().as_raw_fd()
}
} }
}
impl FromRawFd for UdpSocket { impl IntoRawFd for UdpSocket {
unsafe fn from_raw_fd(fd: RawFd) -> UdpSocket { fn into_raw_fd(self) -> RawFd {
std::net::UdpSocket::from_raw_fd(fd).into() self.watcher.into_inner().into_raw_fd()
}
}
impl IntoRawFd for UdpSocket {
fn into_raw_fd(self) -> RawFd {
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 // }
// }
// }
}
} }

View file

@ -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; }

View file

@ -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 extensions to `OpenOptions`. /// Unix-specific extension methods for `DirEntry`.
pub trait OpenOptionsExt { pub trait DirEntryExt {
/// Sets the mode bits that a new file will be created with. /// Returns the underlying `d_ino` field in the contained `dirent`
/// /// structure.
/// If a new file is created as part of a `File::open_opts` call then this fn ino(&self) -> u64;
/// 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.
/// The operating system masks out bits with the systems `umask`, to produce
/// the final permissions.
fn mode(&mut self, mode: u32) -> &mut Self;
/// Pass custom flags to the `flags` argument of `open`. /// Unix-specific extensions to `OpenOptions`.
/// pub trait OpenOptionsExt {
/// The bits that define the access mode are masked out with `O_ACCMODE`, to /// Sets the mode bits that a new file will be created with.
/// ensure they do not interfere with the access mode set by Rusts options. ///
/// /// If a new file is created as part of a `File::open_opts` call then this
/// Custom flags can only set flags, not remove flags set by Rusts options. /// specified `mode` will be used as the permission bits for the new file.
/// This options overwrites any previously set custom flags. /// If no `mode` is set, the default of `0o666` will be used.
fn custom_flags(&mut self, flags: i32) -> &mut Self; /// The operating system masks out bits with the systems `umask`, to produce
} /// the final permissions.
} else { fn mode(&mut self, mode: u32) -> &mut Self;
pub use std::os::unix::fs::{DirBuilderExt, OpenOptionsExt};
/// Pass custom flags to the `flags` argument of `open`.
///
/// 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.
///
/// Custom flags can only set flags, not remove flags set by Rusts options.
/// This options overwrites any previously set custom flags.
fn custom_flags(&mut self, flags: i32) -> &mut Self;
} }
} }

View file

@ -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};
} }
} }

View file

@ -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; }
use crate::path::Path; cfg_docs! {
use std::fmt;
/// An address associated with a Unix socket. 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: (),
}
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;
} }
} }

View file

@ -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,
};
} }
} }

View file

@ -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;
}
} }

View file

@ -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.
/// ///

View file

@ -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.
/// ///

View file

@ -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.

View file

@ -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.
/// ///

View file

@ -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 {}

View file

@ -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,

View file

@ -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;

View file

@ -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 double_ended_stream::DoubleEndedStream;
pub use exact_size_stream::ExactSizeStream; pub use exact_size_stream::ExactSizeStream;
pub use extend::Extend; pub use extend::Extend;
pub use from_stream::FromStream; pub use from_stream::FromStream;
pub use fused_stream::FusedStream; pub use fused_stream::FusedStream;
pub use interval::{interval, Interval}; pub use interval::{interval, Interval};
pub use into_stream::IntoStream; pub use into_stream::IntoStream;
pub use product::Product; pub use product::Product;
pub use sum::Sum; pub use stream::Merge;
pub use sum::Sum;
pub use stream::Merge;
}
} }

View file

@ -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.

View file

@ -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> {

View file

@ -93,33 +93,24 @@ 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;
use crate::stream::IntoStream; use crate::stream::IntoStream;
use crate::utils::extension_trait;
cfg_if! { cfg_unstable! {
if #[cfg(feature = "docs")] { use std::pin::Pin;
use std::ops::{Deref, DerefMut};
use crate::task::{Context, Poll}; use crate::future::Future;
} use crate::stream::FromStream;
}
cfg_if! { pub use merge::Merge;
if #[cfg(any(feature = "unstable", feature = "docs"))] {
mod merge;
use std::pin::Pin; mod merge;
use crate::future::Future;
use crate::stream::FromStream;
pub use merge::Merge;
}
} }
extension_trait! { extension_trait! {
use std::ops::{Deref, DerefMut};
use crate::task::{Context, Poll};
#[doc = r#" #[doc = r#"
An asynchronous stream of values. An asynchronous stream of values.
@ -498,6 +489,7 @@ extension_trait! {
# #
# }) } # }) }
``` ```
"#] "#]
fn last( fn last(
self, self,
@ -1344,7 +1336,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>(
@ -1383,7 +1375,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
@ -1413,9 +1405,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));
# #
# }) } # }) }
``` ```
@ -1434,7 +1426,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
@ -1451,9 +1443,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);
# #
# }) } # }) }
``` ```

View file

@ -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.

View file

@ -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);

View file

@ -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;
}

View file

@ -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>

View file

@ -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() {

View file

@ -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)*);
};
}