newer_type/
lib.rs

1#![doc = include_str!("./README.md")]
2
3// internal
4pub use newer_type_macro::__implement_internal;
5
6/// Implement a trait for given enum or struct. The trait should be defined with
7/// [`target`] attribute.
8///
9/// # Example
10///
11/// ```
12/// use newer_type::implement;
13/// use newer_type::traits::{Extend, PartialEq};
14///
15/// #[implement(Extend<usize>)]
16/// struct Example1(Vec<usize>);
17///
18/// #[implement(Extend<T>)]
19/// struct Example2<T>(Vec<T>);
20///
21/// #[implement(for<T> PartialEq<T>)]
22/// struct Example3(String);
23///
24/// #[implement(for<T: std::fmt::Debug> PartialEq<T>)]
25/// struct Example4<U>(U);
26/// ```
27pub use newer_type_macro::implement;
28
29/// Define a trait for use of [`implement`] macro.
30///
31/// # Arguments (all optional)
32///
33/// - `alternative` ... Trait. If specified, implement this trait instead of the
34///   target trait itself. The target trait is used only for an argument of
35///   [`implement`] macro. See implementation of [`traits`].
36/// - `newer_type` ... Set path to `newer_type` crate. Defaults to
37///   `::newer_type`. Example:
38/// `::your_crate::_export::newer_type`.
39/// - `implementor` ... a (uninhabited) struct with one generic argument, used
40///   as `type_leak`'s implementor type. It should be specified when you use
41///   types with relative path in the trait definition.
42///
43///   # Example
44///
45///   ```
46///   use newer_type::target;
47///
48///   #[target]
49///   trait MyTrait {
50///       fn my_fn(&self) -> ::core::primitive::usize;
51///   }
52///   ```
53///
54///   ```
55///   use newer_type::target;
56///
57///   pub struct Implementor<T>(
58///       core::marker::PhantomData<T>,
59///       core::convert::Infallible
60///   );
61///
62///   type TypeFromContext = usize;
63///
64///   // Implementor should be public to all `MyTrait` users, and thus it should
65///   // be specified with absolute path (like
66///   // `::your_crate::path::to::Implementor`).
67///   #[target(implementor = Implementor)]
68///   trait MyTrait {
69///       fn my_fn(&self, t: TypeFromContext) -> Box<usize>;
70///   }
71///   ```
72pub use newer_type_macro::target;
73
74#[doc(hidden)]
75pub struct Alternate(::core::convert::Infallible);
76
77#[doc(hidden)]
78pub trait Repeater<const TRAIT_NUM: u64, const N: usize> {
79    type Type;
80}
81
82pub mod traits {
83    use super::*;
84    #[cfg(doc)]
85    use crate as newer_type;
86
87    macro_rules! emit_traits {
88        () => {};
89        (
90            $([$($trait_params:ident),*$(,)?])?{
91                #[target(alternative = $alternative:path)]
92                pub trait $trait_name:ident $($trait_contents:tt)*
93            }
94            $($t:tt)*
95        ) => {
96            #[target(alternative = $alternative, newer_type = $crate)]
97            #[doc = concat!("This trait is empty declaration of [`", stringify!($alternative), "`] to be used")]
98            #[doc = "with [`newer_type::implement`]."]
99            ///
100            /// # Example
101            /// ```ignore
102            #[doc = concat!(
103                " #[implement(",
104                    $(
105                        "for<",
106                        $(stringify!($trait_params),)+
107                        "> newer_type::traits::",
108                    )?
109                        stringify!($trait_name),
110                    $(
111                        "<",
112                        $(stringify!($trait_params),)+
113                        ">",
114                    )?
115                ")]")]
116            /// struct MyStruct {
117            #[doc = concat!("     slot: TypeWhichAlreadyImplements", stringify!($trait_name), ",")]
118            /// }
119            /// ```
120            pub trait $trait_name $($trait_contents)*
121            emit_traits!{ $($t)* }
122        };
123    }
124
125    emit_traits! {
126        {
127            #[target(alternative = ::core::iter::IntoIterator)]
128            pub trait IntoIterator {
129                type Item;
130                type IntoIter: ::core::iter::Iterator<Item = Self::Item>;
131                fn into_iter(self) -> Self::IntoIter;
132            }
133        }
134
135        [A]{
136            #[target(alternative = ::core::iter::Extend)]
137            pub trait Extend<A> {
138                fn extend<T>(&mut self, iter: T)
139                where
140                    T: ::core::iter::IntoIterator<Item = A>;
141            }
142        }
143
144        {
145            #[target(alternative = ::core::iter::Iterator)]
146            pub trait Iterator {
147                type Item;
148                fn next(&mut self) -> ::core::option::Option<Self::Item>;
149                fn size_hint(
150                    &self,
151                ) -> (
152                ::core::primitive::usize,
153                ::core::option::Option<::core::primitive::usize>,
154                );
155                fn count(self) -> ::core::primitive::usize
156                where
157                    Self: ::core::marker::Sized;
158                fn last(self) -> ::core::option::Option<Self::Item>
159                where
160                    Self: ::core::marker::Sized;
161                fn nth(&mut self, n: ::core::primitive::usize) -> Option<Self::Item>;
162            }
163        }
164
165        {
166            #[target(alternative = ::core::iter::FusedIterator)]
167            pub trait FusedIterator: ::core::iter::Iterator {}
168        }
169
170        {
171            #[target(alternative = ::core::iter::ExactSizeIterator)]
172            pub trait ExactSizeIterator: ::core::iter::Iterator {
173                fn len(&self) -> ::core::primitive::usize;
174            }
175        }
176
177        {
178            #[target(alternative = ::core::iter::DoubleEndedIterator)]
179            pub trait DoubleEndedIterator: ::core::iter::Iterator {
180                fn next_back(&mut self) -> ::core::option::Option<Self::Item>;
181
182                fn nth_back(
183                    &mut self,
184                    n: ::core::primitive::usize,
185                ) -> ::core::option::Option<Self::Item>;
186                // fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
187                // where
188                //     Self: ::core::marker::Sized,
189                //     F: ::core::ops::FnMut(B, Self::Item) -> R,
190                //     R: ::core::ops::Try<Output = B>;
191                fn rfold<B, F>(self, init: B, f: F) -> B
192                where
193                    Self: ::core::marker::Sized,
194                    F: ::core::ops::FnMut(B, Self::Item) -> B;
195                fn rfind<P>(&mut self, predicate: P) -> ::core::option::Option<Self::Item>
196                where
197                    Self: ::core::marker::Sized,
198                    P: ::core::ops::FnMut(&Self::Item) -> bool;
199            }
200        }
201
202        [Borrowed]{
203            #[target(alternative = ::core::borrow::Borrow)]
204            pub trait Borrow<Borrowed>
205            where
206                Borrowed: ?::core::marker::Sized,
207            {
208                // Required method
209                fn borrow(&self) -> &Borrowed;
210            }
211        }
212
213        [Borrowed]{
214            #[target(alternative = ::core::borrow::BorrowMut)]
215            pub trait BorrowMut<Borrowed>: ::core::borrow::Borrow<Borrowed>
216            where
217                Borrowed: ?::core::marker::Sized,
218            {
219                fn borrow_mut(&mut self) -> &mut Borrowed;
220            }
221        }
222
223        {
224            #[target(alternative = ::std::borrow::ToOwned)]
225            pub trait ToOwned {
226                type Owned: ::core::borrow::Borrow<Self>;
227                fn to_owned(&self) -> Self::Owned;
228                fn clone_into(&self, target: &mut Self::Owned);
229            }
230        }
231
232        [Rhs]{
233            #[target(alternative = ::core::cmp::PartialEq)]
234            pub trait PartialEq<Rhs = Self>
235            where
236                Rhs: ?::core::marker::Sized,
237            {
238                fn eq(&self, other: &Rhs) -> ::core::primitive::bool;
239                fn ne(&self, other: &Rhs) -> ::core::primitive::bool;
240            }
241        }
242
243        {
244            #[target(alternative = ::core::cmp::Eq)]
245            pub trait Eq: ::core::cmp::PartialEq {}
246        }
247
248        [Rhs]{
249            #[target(alternative = ::core::cmp::PartialOrd)]
250            pub trait PartialOrd<Rhs = Self>: ::core::cmp::PartialEq<Rhs>
251            where
252                Rhs: ?::core::marker::Sized,
253            {
254                fn partial_cmp(&self, other: &Rhs)
255                    -> ::core::option::Option<::core::cmp::Ordering>;
256
257                fn lt(&self, other: &Rhs) -> ::core::primitive::bool;
258                fn le(&self, other: &Rhs) -> ::core::primitive::bool;
259                fn gt(&self, other: &Rhs) -> ::core::primitive::bool;
260                fn ge(&self, other: &Rhs) -> ::core::primitive::bool;
261            }
262        }
263
264        {
265            #[target(alternative = ::core::cmp::Ord)]
266            pub trait Ord: ::core::cmp::Eq + ::core::cmp::PartialOrd {
267                fn cmp(&self, other: &Self) -> ::core::cmp::Ordering;
268                // fn max(self, other: Self) -> Self
269                // where
270                //     Self: ::core::marker::Sized;
271                // fn min(self, other: Self) -> Self
272                // where
273                //     Self: ::core::marker::Sized;
274                // fn clamp(self, min: Self, max: Self) -> Self
275                // where
276                //     Self: ::core::marker::Sized;
277            }
278        }
279        {
280            #[target(alternative = ::core::hash::Hash)]
281            pub trait Hash {
282                fn hash<H>(&self, state: &mut H)
283                   where H: ::core::hash::Hasher;
284            }
285        }
286        {
287            #[target(alternative = ::core::fmt::Display)]
288            pub trait Display {
289                fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result;
290            }
291        }
292        {
293            #[target(alternative = ::core::fmt::Debug)]
294            pub trait Debug {
295                fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result;
296            }
297        }
298    }
299}