1// SPDX-License-Identifier: Apache-2.0 OR MIT
2
3pub(crate) mod iterator {
4 use crate::derive::*;
5
6 pub(crate) const NAME: &[&str] = &["Iterator"];
7
8 pub(crate) fn derive(_cx: &Context, data: &Data) -> Result<TokenStream> {
9 // TODO: Add try_fold once try_trait_v2 is stabilized https://github.com/rust-lang/rust/issues/84277
10 Ok(derive_trait(data, &parse_quote!(::core::iter::Iterator), None, parse_quote! {
11 trait Iterator {
12 type Item;
13 #[inline]
14 fn next(&mut self) -> ::core::option::Option<Self::Item>;
15 #[inline]
16 fn size_hint(&self) -> (usize, ::core::option::Option<usize>);
17 #[inline]
18 fn count(self) -> usize;
19 #[inline]
20 fn last(self) -> ::core::option::Option<Self::Item>;
21 #[inline]
22 fn nth(&mut self, n: usize) -> ::core::option::Option<Self::Item>;
23 #[inline]
24 #[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"]
25 fn collect<__U: ::core::iter::FromIterator<Self::Item>>(self) -> __U;
26 #[inline]
27 fn partition<__U, __F>(self, f: __F) -> (__U, __U)
28 where
29 __U: ::core::default::Default + ::core::iter::Extend<Self::Item>,
30 __F: ::core::ops::FnMut(&Self::Item) -> bool;
31
32 // Once try_trait_v2 is stabilized, we can replace these by implementing try_rfold.
33 #[inline]
34 fn fold<__U, __F>(self, init: __U, f: __F) -> __U
35 where
36 __F: ::core::ops::FnMut(__U, Self::Item) -> __U;
37 #[inline]
38 fn all<__F>(&mut self, f: __F) -> bool
39 where
40 __F: ::core::ops::FnMut(Self::Item) -> bool;
41 #[inline]
42 fn any<__F>(&mut self, f: __F) -> bool
43 where
44 __F: ::core::ops::FnMut(Self::Item) -> bool;
45 #[inline]
46 fn find<__P>(&mut self, predicate: __P) -> ::core::option::Option<Self::Item>
47 where
48 __P: ::core::ops::FnMut(&Self::Item) -> bool;
49 #[inline]
50 fn find_map<__U, __F>(&mut self, f: __F) -> ::core::option::Option<__U>
51 where
52 __F: ::core::ops::FnMut(Self::Item) -> ::core::option::Option<__U>;
53 #[inline]
54 fn position<__P>(&mut self, predicate: __P) -> ::core::option::Option<usize>
55 where
56 __P: ::core::ops::FnMut(Self::Item) -> bool;
57 }
58 }))
59 }
60}
61
62pub(crate) mod double_ended_iterator {
63 use crate::derive::*;
64
65 pub(crate) const NAME: &[&str] = &["DoubleEndedIterator"];
66
67 pub(crate) fn derive(_cx: &Context, data: &Data) -> Result<TokenStream> {
68 // TODO: Add try_rfold once try_trait_v2 is stabilized https://github.com/rust-lang/rust/issues/84277
69 // TODO: Add advance_back_by once stabilized https://github.com/rust-lang/rust/issues/77404
70 Ok(derive_trait(
71 data,
72 &parse_quote!(::core::iter::DoubleEndedIterator),
73 Some(format_ident!("Item")),
74 parse_quote! {
75 trait DoubleEndedIterator: ::core::iter::Iterator {
76 #[inline]
77 fn next_back(&mut self) -> ::core::option::Option<Self::Item>;
78 #[inline]
79 fn nth_back(&mut self, n: usize) -> ::core::option::Option<Self::Item>;
80
81 // Once try_trait_v2 is stabilized, we can replace these by implementing try_rfold.
82 #[inline]
83 fn rfold<__U, __F>(self, init: __U, f: __F) -> __U
84 where
85 __F: ::core::ops::FnMut(__U, Self::Item) -> __U;
86 #[inline]
87 fn rfind<__P>(&mut self, predicate: __P) -> ::core::option::Option<Self::Item>
88 where
89 __P: ::core::ops::FnMut(&Self::Item) -> bool;
90 }
91 },
92 ))
93 }
94}
95
96pub(crate) mod exact_size_iterator {
97 use crate::derive::*;
98
99 pub(crate) const NAME: &[&str] = &["ExactSizeIterator"];
100
101 pub(crate) fn derive(_cx: &Context, data: &Data) -> Result<TokenStream> {
102 // TODO: Add is_empty once stabilized https://github.com/rust-lang/rust/issues/35428
103 Ok(derive_trait(
104 data,
105 &parse_quote!(::core::iter::ExactSizeIterator),
106 supertraits_types:Some(format_ident!("Item")),
107 trait_def:parse_quote! {
108 trait ExactSizeIterator: ::core::iter::Iterator {
109 #[inline]
110 fn len(&self) -> usize;
111 }
112 },
113 ))
114 }
115}
116
117pub(crate) mod fused_iterator {
118 use crate::derive::*;
119
120 pub(crate) const NAME: &[&str] = &["FusedIterator"];
121
122 pub(crate) fn derive(_cx: &Context, data: &Data) -> Result<TokenStream> {
123 Ok(derive_trait(
124 data,
125 &parse_quote!(::core::iter::FusedIterator),
126 supertraits_types:Some(format_ident!("Item")),
127 trait_def:parse_quote! {
128 trait FusedIterator: ::core::iter::Iterator {}
129 },
130 ))
131 }
132}
133
134#[cfg(feature = "trusted_len")]
135pub(crate) mod trusted_len {
136 use crate::derive::*;
137
138 pub(crate) const NAME: &[&str] = &["TrustedLen"];
139
140 pub(crate) fn derive(_cx: &Context, data: &Data) -> Result<TokenStream> {
141 Ok(derive_trait(
142 data,
143 &parse_quote!(::core::iter::TrustedLen),
144 Some(format_ident!("Item")),
145 parse_quote! {
146 unsafe trait TrustedLen: ::core::iter::Iterator {}
147 },
148 ))
149 }
150}
151
152pub(crate) mod extend {
153 use crate::derive::*;
154
155 pub(crate) const NAME: &[&str] = &["Extend"];
156
157 pub(crate) fn derive(_cx: &Context, data: &Data) -> Result<TokenStream> {
158 // TODO: Add extend_one,extend_reserve once stabilized https://github.com/rust-lang/rust/issues/72631
159 Ok(derive_trait(data, &parse_quote!(::core::iter::Extend), supertraits_types:None, trait_def:parse_quote! {
160 trait Extend<__A> {
161 #[inline]
162 fn extend<__T: ::core::iter::IntoIterator<Item = __A>>(&mut self, iter: __T);
163 }
164 }))
165 }
166}
167