1
//! Thin veneer over `futures::channel::oneshot` to fix use with [`select!`](futures::select)
2
//!
3
//! A bare [`futures::channel::oneshot::Receiver`] doesn't work properly with
4
//! `futures::select!`, because it has a broken
5
//! [`FusedFuture`](futures::future::FusedFuture)
6
//! implementation.
7
//! (See [`futures-rs` ticket #2455](https://github.com/rust-lang/futures-rs/issues/2455).)
8
//!
9
//! Wrapping it up in a [`future::Fuse`](futures::future::Fuse) works around this,
10
//! with a minor performance penalty.
11
//!
12
//! ### Limitations
13
//!
14
//! The API of this [`Receiver`] is rather more limited.
15
//! For example, it lacks `.try_recv()`.
16
//
17
// The veneer is rather thin and the types from `futures-rs` show through.
18
// If we change this in the future, it will be a breaking change.
19
#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))]
20
#![doc = include_str!("../README.md")]
21
// @@ begin lint list maintained by maint/add_warning @@
22
#![allow(renamed_and_removed_lints)] // @@REMOVE_WHEN(ci_arti_stable)
23
#![allow(unknown_lints)] // @@REMOVE_WHEN(ci_arti_nightly)
24
#![warn(missing_docs)]
25
#![warn(noop_method_call)]
26
#![warn(unreachable_pub)]
27
#![warn(clippy::all)]
28
#![deny(clippy::await_holding_lock)]
29
#![deny(clippy::cargo_common_metadata)]
30
#![deny(clippy::cast_lossless)]
31
#![deny(clippy::checked_conversions)]
32
#![warn(clippy::cognitive_complexity)]
33
#![deny(clippy::debug_assert_with_mut_call)]
34
#![deny(clippy::exhaustive_enums)]
35
#![deny(clippy::exhaustive_structs)]
36
#![deny(clippy::expl_impl_clone_on_copy)]
37
#![deny(clippy::fallible_impl_from)]
38
#![deny(clippy::implicit_clone)]
39
#![deny(clippy::large_stack_arrays)]
40
#![warn(clippy::manual_ok_or)]
41
#![deny(clippy::missing_docs_in_private_items)]
42
#![warn(clippy::needless_borrow)]
43
#![warn(clippy::needless_pass_by_value)]
44
#![warn(clippy::option_option)]
45
#![deny(clippy::print_stderr)]
46
#![deny(clippy::print_stdout)]
47
#![warn(clippy::rc_buffer)]
48
#![deny(clippy::ref_option_ref)]
49
#![warn(clippy::semicolon_if_nothing_returned)]
50
#![warn(clippy::trait_duplication_in_bounds)]
51
#![deny(clippy::unchecked_duration_subtraction)]
52
#![deny(clippy::unnecessary_wraps)]
53
#![warn(clippy::unseparated_literal_suffix)]
54
#![deny(clippy::unwrap_used)]
55
#![deny(clippy::mod_module_files)]
56
#![allow(clippy::let_unit_value)] // This can reasonably be done for explicitness
57
#![allow(clippy::uninlined_format_args)]
58
#![allow(clippy::significant_drop_in_scrutinee)] // arti/-/merge_requests/588/#note_2812945
59
#![allow(clippy::result_large_err)] // temporary workaround for arti#587
60
#![allow(clippy::needless_raw_string_hashes)] // complained-about code is fine, often best
61
#![allow(clippy::needless_lifetimes)] // See arti#1765
62
//! <!-- @@ end lint list maintained by maint/add_warning @@ -->
63

            
64
use futures::channel::oneshot as fut_oneshot;
65
use futures::FutureExt as _;
66

            
67
pub use fut_oneshot::Canceled;
68

            
69
/// `oneshot::Sender` type alias
70
//
71
// This has to be `pub type` rather than `pub use` so that
72
// (i) call sites don't trip the "disallowed types" lint
73
// (ii) we can apply a fine-grained allow, here.
74
#[allow(clippy::disallowed_types)]
75
pub type Sender<T> = fut_oneshot::Sender<T>;
76

            
77
/// `oneshot::Receiver` that works properly with [`futures::select!`]
78
#[allow(clippy::disallowed_types)]
79
pub type Receiver<T> = futures::future::Fuse<fut_oneshot::Receiver<T>>;
80

            
81
/// Return a fresh oneshot channel
82
2321
pub fn channel<T>() -> (Sender<T>, Receiver<T>) {
83
2321
    #[allow(clippy::disallowed_methods)]
84
2321
    let (tx, rx) = fut_oneshot::channel();
85
2321
    (tx, rx.fuse())
86
2321
}