1#![doc(test(
74 no_crate_inject,
75 attr(allow(
76 dead_code,
77 unused_variables,
78 clippy::undocumented_unsafe_blocks,
79 clippy::unused_trait_names,
80 ))
81))]
82#![forbid(unsafe_code)]
83
84use derive_utils::{derive_trait, quick_derive};
85use proc_macro::TokenStream;
86use quote::{format_ident, quote};
87use syn::{Ident, parse_macro_input, parse_quote};
88
89fn default_crate_name() -> (Ident, Option<String>) {
90 (format_ident!("futures"), None)
91}
92
93#[cfg(feature = "renamed")]
94fn crate_name(crate_names: &[&str]) -> (Ident, Option<String>) {
95 use find_crate::Manifest;
96
97 let Some(manifest) = Manifest::new().ok() else { return default_crate_name() };
98
99 manifest
100 .find2(|name, version| {
101 if name == "futures" {
102 version == "*" || version == "0.3" || version.starts_with("0.3.")
103 } else {
104 crate_names.contains(&name)
105 }
106 })
107 .map_or_else(default_crate_name, |package| {
108 if package.is_original() {
109 (format_ident!("{}", package.name), None)
110 } else {
111 (format_ident!("{}", &package.name), Some(package.original_name().to_owned()))
112 }
113 })
114}
115
116#[cfg(not(feature = "renamed"))]
117fn crate_name(_: &[&str]) -> (Ident, Option<String>) {
118 default_crate_name()
119}
120
121#[proc_macro_derive(Future)]
122pub fn derive_future(input: TokenStream) -> TokenStream {
123 quick_derive! {
124 input,
125 ::core::future::Future,
126 trait Future {
127 type Output;
128 #[inline]
129 fn poll(
130 self: ::core::pin::Pin<&mut Self>,
131 cx: &mut ::core::task::Context<'_>,
132 ) -> ::core::task::Poll<Self::Output>;
133 }
134 }
135}
136
137#[proc_macro_derive(Stream)]
138pub fn derive_stream(input: TokenStream) -> TokenStream {
139 let (crate_, _) = crate_name(&["futures", "futures-util", "futures-core"]);
140
141 derive_trait(
142 &parse_macro_input!(input),
143 parse_quote!(::#crate_::stream::Stream),
144 None,
145 parse_quote! {
146 trait Stream {
147 type Item;
148 #[inline]
149 fn poll_next(
150 self: ::core::pin::Pin<&mut Self>,
151 cx: &mut ::core::task::Context<'_>,
152 ) -> ::core::task::Poll<::core::option::Option<Self::Item>>;
153 #[inline]
154 fn size_hint(&self) -> (usize, ::core::option::Option<usize>);
155 }
156 },
157 )
158 .into()
159}
160
161#[proc_macro_derive(Sink)]
162pub fn derive_sink(input: TokenStream) -> TokenStream {
163 let (crate_, original) = crate_name(&["futures", "futures-sink"]);
164 let path = if original.as_deref() == Some("futures-sink") {
165 quote!(::#crate_)
166 } else {
167 quote!(::#crate_::sink)
168 };
169
170 derive_trait(&parse_macro_input!(input), parse_quote!(#path::Sink), None, parse_quote! {
171 trait Sink<__Item> {
172 type Error;
173 #[inline]
174 fn poll_ready(
175 self: ::core::pin::Pin<&mut Self>,
176 cx: &mut ::core::task::Context<'_>,
177 ) -> ::core::task::Poll<::core::result::Result<(), Self::Error>>;
178 #[inline]
179 fn start_send(
180 self: ::core::pin::Pin<&mut Self>,
181 item: __Item,
182 ) -> ::core::result::Result<(), Self::Error>;
183 #[inline]
184 fn poll_flush(
185 self: ::core::pin::Pin<&mut Self>,
186 cx: &mut ::core::task::Context<'_>,
187 ) -> ::core::task::Poll<::core::result::Result<(), Self::Error>>;
188 #[inline]
189 fn poll_close(
190 self: ::core::pin::Pin<&mut Self>,
191 cx: &mut ::core::task::Context<'_>,
192 ) -> ::core::task::Poll<::core::result::Result<(), Self::Error>>;
193 }
194 })
195 .into()
196}
197
198#[proc_macro_derive(AsyncRead)]
199pub fn derive_async_read(input: TokenStream) -> TokenStream {
200 let (crate_, original) = crate_name(&["futures", "futures-io"]);
201
202 let path = if original.as_deref() == Some("futures-io") {
203 quote!(::#crate_)
204 } else {
205 quote!(::#crate_::io)
206 };
207
208 derive_trait(&parse_macro_input!(input), parse_quote!(#path::AsyncRead), None, parse_quote! {
209 trait AsyncRead {
210 #[inline]
211 fn poll_read(
212 self: ::core::pin::Pin<&mut Self>,
213 cx: &mut ::core::task::Context<'_>,
214 buf: &mut [u8],
215 ) -> ::core::task::Poll<::std::io::Result<usize>>;
216 #[inline]
217 fn poll_read_vectored(
218 self: ::core::pin::Pin<&mut Self>,
219 cx: &mut ::core::task::Context<'_>,
220 bufs: &mut [::std::io::IoSliceMut<'_>],
221 ) -> ::core::task::Poll<::std::io::Result<usize>>;
222 }
223 })
224 .into()
225}
226
227#[proc_macro_derive(AsyncWrite)]
228pub fn derive_async_write(input: TokenStream) -> TokenStream {
229 let (crate_, original) = crate_name(&["futures", "futures-io"]);
230
231 let path = if original.as_deref() == Some("futures-io") {
232 quote!(::#crate_)
233 } else {
234 quote!(::#crate_::io)
235 };
236
237 derive_trait(&parse_macro_input!(input), parse_quote!(#path::AsyncWrite), None, parse_quote! {
238 trait AsyncWrite {
239 #[inline]
240 fn poll_write(
241 self: ::core::pin::Pin<&mut Self>,
242 cx: &mut ::core::task::Context<'_>,
243 buf: &[u8],
244 ) -> ::core::task::Poll<::std::io::Result<usize>>;
245 #[inline]
246 fn poll_write_vectored(
247 self: ::core::pin::Pin<&mut Self>,
248 cx: &mut ::core::task::Context<'_>,
249 bufs: &[::std::io::IoSlice<'_>],
250 ) -> ::core::task::Poll<::std::io::Result<usize>>;
251 #[inline]
252 fn poll_flush(
253 self: ::core::pin::Pin<&mut Self>,
254 cx: &mut ::core::task::Context<'_>,
255 ) -> ::core::task::Poll<::std::io::Result<()>>;
256 #[inline]
257 fn poll_close(
258 self: ::core::pin::Pin<&mut Self>,
259 cx: &mut ::core::task::Context<'_>,
260 ) -> ::core::task::Poll<::std::io::Result<()>>;
261 }
262 })
263 .into()
264}
265
266#[proc_macro_derive(AsyncSeek)]
267pub fn derive_async_seek(input: TokenStream) -> TokenStream {
268 let (crate_, original) = crate_name(&["futures", "futures-io"]);
269
270 let path = if original.as_deref() == Some("futures-io") {
271 quote!(::#crate_)
272 } else {
273 quote!(::#crate_::io)
274 };
275
276 derive_trait(&parse_macro_input!(input), parse_quote!(#path::AsyncSeek), None, parse_quote! {
277 trait AsyncSeek {
278 #[inline]
279 fn poll_seek(
280 self: ::core::pin::Pin<&mut Self>,
281 cx: &mut ::core::task::Context<'_>,
282 pos: ::std::io::SeekFrom,
283 ) -> ::core::task::Poll<::std::io::Result<u64>>;
284 }
285 })
286 .into()
287}
288
289#[proc_macro_derive(AsyncBufRead)]
290pub fn derive_async_buf_read(input: TokenStream) -> TokenStream {
291 let (crate_, original) = crate_name(&["futures", "futures-io"]);
292
293 let path = if original.as_deref() == Some("futures-io") {
294 quote!(::#crate_)
295 } else {
296 quote!(::#crate_::io)
297 };
298
299 derive_trait(
300 &parse_macro_input!(input),
301 parse_quote!(#path::AsyncBufRead),
302 None,
303 parse_quote! {
304 trait AsyncBufRead {
305 #[inline]
306 fn poll_fill_buf<'__a>(
307 self: ::core::pin::Pin<&'__a mut Self>,
308 cx: &mut ::core::task::Context<'_>,
309 ) -> ::core::task::Poll<::std::io::Result<&'__a [u8]>>;
310 #[inline]
311 fn consume(self: ::core::pin::Pin<&mut Self>, amt: usize);
312 }
313 },
314 )
315 .into()
316}