async_transmit/lib.rs
1//! # Async trait for transmitting data to peers
2//!
3//! `async-transmit` crate provides `Transmit` trait which allows value to be transmit asynchronously.
4//!
5//! This crate relies on [async-trait][], the original definition of the `Transmit` trait is:
6//!
7//! [async-trait]: https://github.com/dtolnay/async-trait
8//!
9//! ```
10//! use async_trait::async_trait;
11//!
12//! #[async_trait]
13//! pub trait Transmit {
14//! type Item;
15//! type Error;
16//!
17//! async fn transmit(&mut self, item: Self::Item) -> Result<(), Self::Error>
18//! where
19//! Self::Item: 'async_trait;
20//! }
21//! ```
22//!
23//! So use `#[async_trait]` to when implement `Transmit` like:
24//!
25//! ```
26//! use async_transmit::*;
27//! use async_trait::async_trait;
28//!
29//! struct VoidTransmitter<I, E> {
30//! phantom: std::marker::PhantomData<(I, E)>,
31//! }
32//!
33//! #[async_trait]
34//! impl<I, E> Transmit for VoidTransmitter<I, E>
35//! where
36//! I: Send,
37//! E: Send,
38//! {
39//! type Item = I;
40//! type Error = E;
41//!
42//! async fn transmit(&mut self, item: Self::Item) -> Result<(), Self::Error>
43//! where
44//! I: 'async_trait,
45//! {
46//! // Do Nothing
47//! Ok(())
48//! }
49//! }
50//! ```
51//!
52//! ## With async-std/async-channel
53//!
54//! If you'd like to play with [`async_std::channel::Sender`][] or [`async_channel::Sender`][],
55//! use `with-async-channel` feature like:
56//!
57//! [`async_std::channel::Sender`]: https://docs.rs/async-std/1.9.0/async_std/channel/struct.Sender.html
58//! [`async_channel::Sender`]: https://docs.rs/async-channel/1.6.1/async_channel/struct.Sender.html
59//!
60//! ```toml
61//! [dependencies.async-transmit]
62//! version = "0.1.0"
63//! features = ["with-async-channel"]
64//! ```
65//!
66//! Then you can use `transmit()` method through `Transmit` trait on the sender like:
67//!
68//! ```
69//! # use anyhow::Result;
70//! # use futures::executor;
71//! # fn main() -> Result<()> {
72//! # #[cfg(feature = "with-async-channel")]
73//! # executor::block_on(async {
74//! use async_transmit::*;
75//!
76//! let (mut s, r) = async_channel::unbounded::<&'static str>();
77//!
78//! s.transmit("Hello").await?;
79//! s.transmit("World").await?;
80//! drop(s);
81//! assert_eq!(Some("Hello"), r.recv().await.ok());
82//! assert_eq!(Some("World"), r.recv().await.ok());
83//! assert_eq!(None, r.recv().await.ok());
84//! # Ok(()) as Result<()>
85//! # })?;
86//! # Ok(())
87//! # }
88//! ```
89//!
90//! ## With tokio
91//!
92//! If you'd like to play with [`tokio::sync::mpsc::Sender`][] or [`tokio::sync::mpsc::UnboundedSender`],
93//! use `with-tokio` feature like:
94//!
95//! [`tokio::sync::mpsc::Sender`]: https://docs.rs/tokio/1.3.0/tokio/sync/mpsc/struct.Sender.html
96//! [`tokio::sync::mpsc::UnboundedSender`]: https://docs.rs/tokio/1.3.0/tokio/sync/mpsc/struct.UnboundedSender.html
97//!
98//! ```toml
99//! [dependencies.async-transmit]
100//! version = "0.1.0"
101//! features = ["with-tokio"]
102//! ```
103//!
104//! Then you can use `transmit()` method through `Transmit` trait on the sender like:
105//!
106//! ```
107//! # use anyhow::Result;
108//! # use futures::executor;
109//! # fn main() -> Result<()> {
110//! # #[cfg(feature = "with-tokio")]
111//! # executor::block_on(async {
112//! use async_transmit::*;
113//!
114//! let (mut s, mut r) = tokio::sync::mpsc::unbounded_channel::<&'static str>();
115//!
116//! s.transmit("Hello").await?;
117//! s.transmit("World").await?;
118//! drop(s);
119//! assert_eq!(Some("Hello"), r.recv().await);
120//! assert_eq!(Some("World"), r.recv().await);
121//! assert_eq!(None, r.recv().await);
122//! # Ok(()) as Result<()>
123//! # })?;
124//! # Ok(())
125//! # }
126//! ```
127//!
128//! ## With futures-rs
129//!
130//! If you'd like to play with [`futures::sink::Sink`], use `with-sink` feature like:
131//!
132//! [`futures::sink::Sink`]: https://docs.rs/futures/0.3.13/futures/sink/trait.Sink.html
133//!
134//! ```toml
135//! [dependencies.async-transmit]
136//! version = "0.1.0"
137//! features = ["with-sink"]
138//! ```
139//!
140//! Then you can use `async_transmit::from_sink()` to create a wrapper object which implements `Transmit`
141//! trait like:
142//!
143//! ```
144//! # use anyhow::Result;
145//! # use futures::executor;
146//! # fn main() -> Result<()> {
147//! # #[cfg(feature = "with-sink")]
148//! # executor::block_on(async {
149//! use async_transmit::*;
150//! use futures::prelude::*;
151//!
152//! let (s, mut r) = futures::channel::mpsc::unbounded::<&'static str>();
153//! let mut s = from_sink(s);
154//!
155//! s.transmit("Hello").await?;
156//! s.transmit("World").await?;
157//! drop(s);
158//! assert_eq!(Some("Hello"), r.next().await);
159//! assert_eq!(Some("World"), r.next().await);
160//! assert_eq!(None, r.next().await);
161//! # Ok(()) as Result<()>
162//! # })?;
163//! # Ok(())
164//! # }
165//! ```
166//!
167#![doc(test(attr(deny(rust_2018_idioms, warnings))))]
168#![doc(test(attr(allow(unused_extern_crates, unused_variables, unused_imports))))]
169#![recursion_limit = "2048"]
170
171mod transmit;
172pub use transmit::*;