gat_std/
lib.rs

1//! GAT implementations of `std` traits
2//!
3//! Traits are in the same respective paths as their `std` variants. The `gatify`
4//! macro changes operators to desugar to the traits in this crate instead of their `std`
5//! equivalents.
6
7#![warn(
8    missing_docs,
9    elided_lifetimes_in_paths,
10    explicit_outlives_requirements,
11    missing_abi,
12    noop_method_call,
13    pointer_structural_match,
14    semicolon_in_expressions_from_macros,
15    unused_import_braces,
16    unused_lifetimes,
17    unsafe_op_in_unsafe_fn,
18    clippy::cargo,
19    clippy::missing_panics_doc,
20    clippy::doc_markdown,
21    clippy::ptr_as_ptr,
22    clippy::cloned_instead_of_copied,
23    clippy::unreadable_literal,
24    clippy::undocumented_unsafe_blocks,
25    clippy::cast_sign_loss,
26    clippy::cast_precision_loss,
27    clippy::cast_possible_truncation,
28    clippy::cast_possible_wrap
29)]
30#![no_std]
31
32#[cfg(feature = "alloc")]
33extern crate alloc;
34
35/// Rewrites `std` operators to use their GAT equivalents. Can be applied to any item or statement.
36///
37/// ## Index
38///
39/// The `[]` operator is converted to use the [`ops::Index`] or [`ops::IndexMut`] trait.
40/// This may not always be a perfect drop-in replacement, despite the blanket impl for
41/// [`core::ops::Index`] - if the macro can't tell which impl is expected from context, it will
42/// error out, pointing to the operator that caused the error.
43///
44/// ## For Loops
45///
46/// For loops are converted to use either [`core::iter::Iterator`] or [`iter::Iterator`], depending
47/// on which is implemented. If both are implemented, priority is given to the lending iterator.
48///
49pub use gat_std_proc::gatify;
50
51pub mod iter;
52pub mod ops;
53
54#[doc(hidden)]
55pub mod __impl {
56    pub struct IntoIter<T>(pub T);
57
58    pub trait ViaLending {
59        type Selector;
60
61        fn select(&self) -> Self::Selector;
62    }
63
64    impl<T: crate::iter::IntoIterator> ViaLending for &IntoIter<T> {
65        type Selector = Lending;
66
67        fn select(&self) -> Self::Selector {
68            Lending
69        }
70    }
71
72    pub trait ViaCore {
73        type Selector;
74
75        fn select(&self) -> Self::Selector;
76    }
77
78    impl<T: core::iter::IntoIterator> ViaCore for IntoIter<T> {
79        type Selector = Core;
80
81        fn select(&self) -> Self::Selector {
82            Core
83        }
84    }
85
86    pub struct Lending;
87
88    impl Lending {
89        pub fn into_iter<T: crate::iter::IntoIterator>(self, iter: IntoIter<T>) -> T::IntoIter {
90            iter.0.into_iter()
91        }
92    }
93
94    pub struct Core;
95
96    impl Core {
97        pub fn into_iter<T: core::iter::IntoIterator>(self, iter: IntoIter<T>) -> T::IntoIter {
98            iter.0.into_iter()
99        }
100    }
101}