1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
#![deny(unsafe_code)] #![warn( clippy::cargo, clippy::nursery, clippy::pedantic, clippy::restriction, future_incompatible, rust_2018_idioms )] #![warn( box_pointers, macro_use_extern_crate, meta_variable_misuse, missing_copy_implementations, missing_crate_level_docs, missing_debug_implementations, missing_docs, non_ascii_idents, single_use_lifetimes, trivial_casts, trivial_numeric_casts, unaligned_references, unreachable_pub, unused_import_braces, unused_lifetimes, unused_qualifications, unused_results, variant_size_differences )] #![allow( clippy::blanket_clippy_restriction_lints, clippy::else_if_without_else, clippy::exhaustive_enums, clippy::future_not_send, clippy::implicit_return, clippy::missing_inline_in_public_items, clippy::non_ascii_literal, clippy::pattern_type_mismatch, clippy::redundant_pub_crate, clippy::shadow_reuse, clippy::tabs_in_doc_comments, clippy::unreachable, clippy::wildcard_enum_match_arm, variant_size_differences )] #![allow(clippy::cargo_common_metadata)] #![cfg_attr( doc, warn(rustdoc::all), allow(rustdoc::missing_doc_code_examples, rustdoc::private_doc_tests) )] //! Proc-Macros for the `allochronic-util` crate. use proc_macro::TokenStream; use proc_macro2::Span; use syn::Error; mod select; /// Easy generation of errors in proc macros. fn error(span: Span, message: &str) -> TokenStream { Error::new(span, message).into_compile_error().into() } /// Polls all passed [`Future`](std::future::Future)s or /// [`Stream`](std::stream::Stream)s until one is ready and returns /// it. Prioritizes by order. /// /// # Raw-mode /// If the `complete` item is unspecified, [`Future`](std::future::Future)s and /// [`Stream`](std::stream::Stream)s will be pulled beyond exhaustion. If a high /// priority item is exhausted and [`select!`](crate::select!) is being used in /// a loop, it will continuously return the same result, which might be /// unintended. /// /// # Fused-mode /// If the `complete` item is specified, all polled items have to implement /// `FusedFuture` or `FusedStream`, for [`Stream`](std::stream::Stream)s this /// will unwrap the [`Option`]. The `complete` item will be executed once all /// items have been exhausted. Items will not be pulled beyond exhaustion. /// /// # Examples /// Raw-mode: /// ``` /// # futures_executor::block_on(async { /// use futures_util::stream; /// use allochronic_util::select; /// /// let mut stream1 = stream::iter(1..=3); /// let mut stream2 = stream::iter(4..=6); /// let mut stream3 = stream::iter(7..=9); /// /// let mut counter = 0; /// /// while let Some(result) = select![ /// result: &mut stream1 => result, /// result: &mut stream2 => result, /// result: &mut stream3 => result, /// ] { /// counter += 1; /// assert_eq!(counter, result); /// } /// /// // this loop will only reach the number of three, because it will abort after the first stream /// // is exhausted /// assert_eq!(counter, 3); /// # }); /// ``` /// Fused-mode: /// ``` /// # futures_executor::block_on(async { /// use futures_util::stream::{self, StreamExt}; /// use allochronic_util::select; /// /// let mut stream1 = stream::iter(1..=3).fuse(); /// let mut stream2 = stream::iter(4..=6).fuse(); /// let mut stream3 = stream::iter(7..=9).fuse(); /// /// let mut counter = 0; /// /// while let Some(result) = select![ /// result: &mut stream1 => Some(result), /// result: &mut stream2 => Some(result), /// result: &mut stream3 => Some(result), /// complete => None, /// ] { /// counter += 1; /// assert_eq!(counter, result); /// } /// /// assert_eq!(counter, 9); /// # }); /// ``` #[proc_macro] pub fn select(item: TokenStream) -> TokenStream { select::select(item) }