core_extensions/
lib.rs

1//! Extension traits for many standard/core library types/traits.
2//! and other miscelaneuous types / traits / functions / macros.
3//!
4//! # Adding as dependency
5//! 
6//! This crate requires cargo features for enabling items, to get all of them you can use:
7//! 
8//! ```toml
9//! [dependencies.core_extensions]
10//! version = "1.5"
11//! features = [
12//!     ## enables items that use anything from the standard `std` or `alloc` crates.
13//!     "std",
14//!     ## Requires the latest stable release, enables all the rust-version-dependent features
15//!     "rust_latest_stable",
16//!     ## enables all the item features 
17//!     "all_items",
18//! ]
19//! ```
20//! The `"std"` feature is required to enable impls and items that use [`std`] types,
21//! otherwise only the [`core`] library is supported.
22//! 
23//! `"rust_latest_stable"` enables all the `"rust_1_*"` crate features
24//! to use the newest stable language features,
25//! [here's a list of all the `"rust_1_*"` features](#cargo-features-lang-section),
26//! 
27//! `"all_items"` enables all of the features for enabling items from this crate
28//! ([documented here](#cargo-features-section)):
29//! 
30//! Here is the expanded version of the above configuration:
31//! ```toml
32//! [dependencies.core_extensions]
33//! version = "1.5"
34//! features = [
35//!     "std",
36//!     "rust_latest_stable"
37//!     ## all of the features below are what "all_items" enables
38//!     "derive"
39//!     "bools",
40//!     "callable",
41//!     "collections",
42//!     "const_default",
43//!     "const_val",
44//!     "generics_parsing",
45//!     "integers",
46//!     "item_parsing",
47//!     "iterators",
48//!     "macro_utils",
49//!     "marker_type",
50//!     "on_drop",
51//!     "option_result",
52//!     "phantom",
53//!     "self_ops",
54//!     "slices",
55//!     "strings",
56//!     "transparent_newtype",
57//!     "type_asserts",
58//!     "type_identity",
59//!     "type_level_bool",
60//!     "void",
61//! ]
62//! ```
63//!
64//! # Examples
65//!
66//! Showcasing some features from this crate.
67//!
68//! ### `quasiconst`, generic constants.
69//!
70//! The [`quasiconst`] macro allows emulating generic constants by generating a 
71//! zero-sized generic type that implements the [`ConstVal`] trait,
72//! the preferred way to get its value is the [`getconst`] macro.
73//!
74//! This example demonstrates how you can use them to declare a generic VTABLE constant.
75//!
76#![cfg_attr(not(feature = "const_val"), doc = " ```ignore")]
77#![cfg_attr(feature = "const_val", doc = " ```rust")]
78//! use core_extensions::{getconst, quasiconst};
79//! 
80//! use std::fmt::{self, Debug};
81//! 
82//! 
83//! quasiconst!{
84//!     pub const VTABLE<T: Debug>: &'static Vtable = &Vtable {
85//!         size: std::mem::size_of::<T>(),
86//!         align: std::mem::align_of::<T>(),
87//!         drop: drop_erased::<T>,
88//!         fmt: debug_fmt_erased::<T>,
89//!     };
90//! }
91//! 
92//! # fn main() {
93//! const VTABLE_U8: &'static Vtable = getconst!(VTABLE<u8>);
94//! assert_eq!(VTABLE_U8.size, 1);
95//! assert_eq!(VTABLE_U8.align, 1);
96//! 
97//! const VTABLE_USIZE: &'static Vtable = getconst!(VTABLE<usize>);
98//! assert_eq!(VTABLE_USIZE.size, std::mem::size_of::<usize>());
99//! assert_eq!(VTABLE_USIZE.align, std::mem::align_of::<usize>());
100//! 
101//! const VTABLE_STRING: &'static Vtable = getconst!(VTABLE<&str>);
102//! assert_eq!(VTABLE_STRING.size, std::mem::size_of::<usize>() * 2);
103//! assert_eq!(VTABLE_STRING.align, std::mem::align_of::<usize>());
104//! # }
105//! 
106//! 
107//! 
108//! pub struct Vtable {
109//!     pub size: usize,
110//!     pub align: usize,
111//!     pub drop: unsafe fn(*mut ()),
112//!     pub fmt: unsafe fn(*const (), &mut fmt::Formatter<'_>) -> fmt::Result,
113//! }
114//! 
115//! unsafe fn drop_erased<T>(ptr: *mut ()) {
116//!     std::ptr::drop_in_place(ptr as *mut T)
117//! }
118//! 
119//! unsafe fn debug_fmt_erased<T>(ptr: *const (), f: &mut fmt::Formatter<'_>) -> fmt::Result 
120//! where
121//!     T: Debug,
122//! {
123//!     let this = unsafe{ &*(ptr as *const T) };
124//!     
125//!     Debug::fmt(this, f)
126//! }
127//! ```
128//! <span id = "cargo-features-section"></span>
129//! # Cargo Features
130//!
131//! ### Item features
132//!
133//! Item features enables items from this crate.
134//!
135//! The `"all_items"` feature enables all of these features,
136//! you can use it instead of the ones below if you don't mind longer compile-times.
137//!
138//! The `"all_items_no_derive"` feature eanbles all the features below
139//! except for the `"derive"` feature, 
140//! to reduce compile-times due to enabling the `syn` indirect dependency.
141//!
142//! - `"derive"`: Enables derive macros for traits declared in core_extensions.
143//! If a trait has a derive macro it'll mention and link to it.
144//!
145//! - `"bools"`: Enables the [`BoolExt`] trait, extension trait for `bool`.
146//!
147//! - `"callable"`: Enables the [`callable`] module, 
148//! with stably implementable equivalents of the `Fn*` traits.
149//!
150//! - `"collections"`: Enables the [`collections`] module, with traits for collection types.
151//!
152//! - `"const_default"`:
153//! Enables the [`ConstDefault`] trait, and [`const_default`] macro,
154//! for a `const` equivalent of the `Default` trait.
155//!
156//! - `"const_val"`:
157//! Enables the [`ConstVal`] trait (for types that represent constants), 
158//! [`getconst`] macro (for getting the [`ConstVal::VAL`] associated constant),
159//! and [`quasiconst`] macro (for declaring types that emulate generic constants).
160//! Enables the `"generics_parsing"` feature.
161//!
162//! - `"macro_utils`:
163//! Enables the [`rewrap_macro_parameters`], [`count_tts`], [`gen_ident_range`],
164//! [`tokens_method`], [`compile_error_stringify`], and [`parenthesize_args`] macro.
165//! Also enables the [`macro_attr`] attribute.
166//!
167//! - `"generics_parsing"`: 
168//! Enables the [`parse_generics`], [`parse_generics_and_where`],
169//! [`split_generics_and_where`], 
170//! [`parse_split_generics`], and [`parse_split_generics_and_where`] macros.
171//! These allow macros to parse items with generic parameters.
172//!
173//! - `"item_parsing"`: 
174//! Enables the `"macro_utils` and `"generics_parsing"` features.
175//! Enables the [`impl_parse_generics`] and [`impl_split`] macros.
176//!
177//! - `"integers"`: Enables the [`integers`] module, with extension traits for integer types.
178//!
179//! - `"iterators"`: Enables the [`iterators`] module, 
180//! with the [`IteratorExt`] extension trait for iterators, and a few iterator types.
181//!
182//! - `"marker_type"`: Enables the [`MarkerType`] trait,
183//! for trivially constructible, zero-sized, and aligned-to-1 types.
184//!
185//! - `"on_drop"`: Enables the [`RunOnDrop`] type,
186//! a wrapper type that runs a closure at the end of the scope.
187//!
188//! - `"option_result"`: Enables the [`option_result_ext`] module,
189//! with traits for `Option` and `Result`-like types.
190//!
191//! - `"phantom"`: Enables the [`phantom`] module(with `PhantomData`-related items),
192//! [`expr_as_phantom`] macro,[`map_phantomdata`] macro, and [`return_type_phantom`] macro.
193//!
194//! - `"self_ops"`: Enables the [`SelfOps`] trait, an extension trait for all types.
195//! It primarily has methods for calling free functions as methods.
196//!
197//! - `"slices"`:
198//! Enables the [`slices`] module, with extension traits for `[T]` and `str` slices.
199//!
200//! - `"strings"`:
201//! Enables the [`strings`] module, with the [`StringExt`] extension trait for strings.
202//!
203//! - `"transparent_newtype"`: Enables the [`transparent_newtype`] module,
204//! with extension traits and functions for `#[repr(transparent)]` newtypes with public fields.
205//! <br>
206//! Enables the `"marker_type"` feature.
207//!
208//! - `"type_asserts"`: Enables the [`type_asserts`] module, with type-level assertiosn,
209//! most useful in tests.
210//!
211//! - `"type_identity"`: Enables the [`TypeIdentity`] trait,
212//! for proving that two types are equal, and converting between them in a generic context.
213//!
214//! - `"type_level_bool"`: Enables the [`type_level_bool`] module,
215//! which encodes `bool`s on the type-level.
216//!
217//! - `"void"`: Enables the [`Void`] type, a type that can't be constructed, 
218//! for encodign impossible situations.
219//!
220//! <span id = "cargo-features-lang-section"></span>
221//! ### Rust Version numbers
222//!
223//! These features enable code that require some Rust version past the minimum supported one:
224//!
225//! - "rust_1_46": Makes [`TransparentNewtype`] and [`TypeIdentity`]
226//! associated functions that take `Rc<Self>` or `Arc<Self>` callable as methods.
227//!
228//! - "rust_1_51": Enables the "rust_1_46" feature, and impls of traits for all array lengths.
229//! Enables the `"on_drop"` feature because [`RunOnDrop`] is used by the impls for 
230//! arrays of all lengths.
231//!
232//! - "rust_latest_stable":
233//! Enables all the "rust_1_*" features.
234//! This requires the last stable release of Rust,
235//! since more `"rust_1_*"` features can be added at any time.
236//!
237//! ### Support for other crates
238//!
239//! All of these are disabled by default:
240//!
241//! - `"std"`: Enables `std` library support. Implies the `"alloc"` feature.
242//!
243//! - `"alloc"`: Enables `alloc` library support.
244//!
245//! - `"serde_"`: Enables serde support.
246//!
247//! ### Miscelaneous features
248//!
249//! `"track_caller"`:
250//! Enables the "rust_1_46" feature.
251//! Changes `ResultLike` to allow getting the caller location in `ResultLike::into_result_`,
252//! and makes `IsNoneError` store where it was constructed.
253//!
254//! `"docsrs"`: Used to document the required features in docs.rs, requires Rust nightly.
255//! Doesn't enable any items itself.
256//!
257//!
258//! # no-std support
259//!
260//! This crate works in `#![no_std]` contexts by default.
261//!
262//! # Supported Rust versions
263//!
264//! This crate support Rust back to 1.41.0,
265//! requiring cargo features to use language features from newer versions.
266//!
267//!
268//! [`collections`]: ./collections/index.html
269//! [`callable`]: ./callable/index.html
270//! [`integers`]: ./integers/index.html
271//! [`iterators`]: ./iterators/index.html
272//! [`option_result_ext`]: ./option_result_ext/index.html
273//! [`phantom`]: ./phantom/index.html
274//! [`slices`]: ./slices/index.html
275//! [`strings`]: ./strings/index.html
276//! [`transparent_newtype`]: ./transparent_newtype/index.html
277//! [`type_asserts`]: ./type_asserts/index.html
278//! [`type_level_bool`]: ./type_level_bool/index.html
279//!
280//! [`count_tts`]: ./macro.count_tts.html
281//! [`gen_ident_range`]: ./macro.gen_ident_range.html
282//! [`rewrap_macro_parameters`]: ./macro.rewrap_macro_parameters.html
283//! [`tokens_method`]: ./macro.tokens_method.html
284//! [`compile_error_stringify`]: ./macro.compile_error_stringify.html
285//! [`parenthesize_args`]: ./macro.parenthesize_args.html
286//! [`macro_attr`]: ./attr.macro_attr.html
287//! [`parse_generics`]: ./macro.parse_generics.html
288//! [`parse_generics_and_where`]: ./macro.parse_generics_and_where.html
289//! [`split_generics_and_where`]: ./macro.split_generics_and_where.html
290//! [`parse_split_generics`]: ./macro.parse_split_generics.html
291//! [`parse_split_generics_and_where`]: ./macro.parse_split_generics_and_where.html
292//!
293//! [`impl_parse_generics`]: ./macro.impl_parse_generics.html
294//! [`impl_split`]: ./macro.impl_split.html
295//!
296//! [`BoolExt`]: ./trait.BoolExt.html
297//! [`ConstDefault`]: ./trait.ConstDefault.html
298//! [`ConstVal`]: ./trait.ConstVal.html
299//! [`ConstVal::VAL`]: ./trait.ConstDefault.html#associatedconstant.VAL
300//! [`MarkerType`]: ./trait.MarkerType.html
301//! [`SelfOps`]: ./trait.SelfOps.html
302//! [`TypeIdentity`]: ./trait.TypeIdentity.html
303//! [`TransparentNewtype`]: ./transparent_newtype/trait.TransparentNewtype.html
304//!
305//! [`RunOnDrop`]: ./struct.RunOnDrop.html
306//! [`Void`]: ./enum.Void.html
307//! 
308//! [`const_default`]: ./macro.const_default.html
309//! [`getconst`]: ./macro.getconst.html
310//! [`quasiconst`]: ./macro.quasiconst.html
311//! [`expr_as_phantom`]: ./macro.expr_as_phantom.html
312//! [`map_phantomdata`]: ./macro.map_phantomdata.html
313//! [`return_type_phantom`]: ./macro.return_type_phantom.html
314//! 
315//! [`IteratorExt`]: ./iterators/trait.IteratorExt.html
316//! [`StringExt`]: ./strings/trait.StringExt.html
317//! 
318//! [`core`]: https://doc.rust-lang.org/core/
319//! [`std`]: https://doc.rust-lang.org/std/
320//! 
321#![allow(clippy::bool_assert_comparison)]
322#![allow(clippy::explicit_auto_deref)]
323#![allow(clippy::manual_map)]
324#![allow(clippy::needless_arbitrary_self_type)]
325#![allow(clippy::needless_doctest_main)]
326#![deny(missing_docs)]
327#![deny(unused_must_use)]
328#![cfg_attr(not(miri), no_std)]
329#![cfg_attr(feature = "docsrs", feature(doc_cfg))]
330
331#[cfg(feature="std")]
332#[macro_use]
333#[doc(hidden)]
334pub extern crate std as std_;
335
336#[cfg(not(feature="std"))]
337#[doc(hidden)]
338pub extern crate core as std_;
339
340#[cfg(feature="alloc")]
341#[doc(hidden)]
342#[macro_use]
343pub extern crate alloc;
344
345
346#[doc(hidden)]
347#[cfg(feature = "enable_proc_macro_crate")]
348pub extern crate core_extensions_proc_macros;
349
350#[cfg(feature = "derive")]
351extern crate self as core_extensions;
352
353#[cfg(all(feature = "derive", feature = "const_default"))]
354include!{"./derive/const_default_docs.rs"}
355
356#[cfg(all(feature = "derive", feature = "transparent_newtype"))]
357include!{"./derive/transparent_newtype_docs.rs"}
358
359
360#[doc(hidden)]
361#[macro_use]
362pub mod macros;
363
364#[cfg(feature = "serde_")]
365extern crate serde;
366
367#[cfg(all(test, feature = "rand"))]
368extern crate rand;
369
370
371#[cfg(feature = "bools")]
372#[cfg_attr(feature = "docsrs", doc(cfg(feature = "bools")))]
373mod bool_extensions;
374
375#[cfg(feature = "bools")]
376#[cfg_attr(feature = "docsrs", doc(cfg(feature = "bools")))]
377pub use self::bool_extensions::BoolExt;
378
379
380#[cfg(feature = "callable")]
381#[cfg_attr(feature = "docsrs", doc(cfg(feature = "callable")))]
382pub mod callable;
383
384#[cfg(feature = "callable")]
385#[cfg_attr(feature = "docsrs", doc(cfg(feature = "callable")))]
386pub use self::callable::{CallExt, CallInto, CallMut, CallRef};
387
388
389#[cfg(feature = "collections")]
390#[cfg_attr(feature = "docsrs", doc(cfg(feature = "collections")))]
391pub mod collections;
392
393
394#[cfg(feature = "const_default")]
395#[cfg_attr(feature = "docsrs", doc(cfg(feature = "const_default")))]
396mod const_default_trait;
397
398#[cfg(feature = "const_default")]
399#[cfg_attr(feature = "docsrs", doc(cfg(feature = "const_default")))]
400pub use self::const_default_trait::ConstDefault;
401
402#[cfg(feature = "const_val")]
403#[cfg_attr(feature = "docsrs", doc(cfg(feature = "const_val")))]
404mod const_val;
405
406
407#[cfg(feature = "const_val")]
408#[cfg_attr(feature = "docsrs", doc(cfg(feature = "const_val")))]
409pub use self::const_val::ConstVal;
410
411
412#[cfg(feature = "integers")]
413#[cfg_attr(feature = "docsrs", doc(cfg(feature = "integers")))]
414pub mod integers;
415
416#[cfg(feature = "integers")]
417#[cfg_attr(feature = "docsrs", doc(cfg(feature = "integers")))]
418pub use self::integers::{IntegerExt, ToTime};
419
420
421#[cfg(feature = "iterators")]
422#[cfg_attr(feature = "docsrs", doc(cfg(feature = "iterators")))]
423pub mod iterators;
424
425#[cfg(feature = "iterators")]
426#[cfg_attr(feature = "docsrs", doc(cfg(feature = "iterators")))]
427pub use self::iterators::{IterCloner, IterConstructor, IteratorExt, LazyOnce};
428
429
430#[cfg(feature = "macro_utils")]
431#[doc(inline)]
432pub use crate::macros::macro_utils::*;
433
434
435
436#[cfg(feature = "marker_type")]
437#[cfg_attr(feature = "docsrs", doc(cfg(feature = "marker_type")))]
438mod marker_type;
439
440#[cfg(feature = "marker_type")]
441#[cfg_attr(feature = "docsrs", doc(cfg(feature = "marker_type")))]
442pub use self::marker_type::MarkerType;
443
444
445#[cfg(feature = "std")]
446pub mod measure_time;
447
448
449#[cfg(feature = "on_drop")]
450#[cfg_attr(feature = "docsrs", doc(cfg(feature = "on_drop")))]
451mod on_drop;
452
453#[cfg(feature = "on_drop")]
454#[cfg_attr(feature = "docsrs", doc(cfg(feature = "on_drop")))]
455pub use self::on_drop::RunOnDrop;
456
457
458#[cfg(feature = "option_result")]
459#[cfg_attr(feature = "docsrs", doc(cfg(feature = "option_result")))]
460pub mod option_result_ext;
461
462#[doc(no_inline)]
463#[cfg(feature = "option_result")]
464#[cfg_attr(feature = "docsrs", doc(cfg(feature = "option_result")))]
465pub use self::option_result_ext::{OptionExt, ResultExt, ResultLike, ResultLikeExt, TransposeOption};
466
467#[cfg(feature = "phantom")]
468#[cfg_attr(feature = "docsrs", doc(cfg(feature = "phantom")))]
469pub mod phantom;
470
471#[cfg(feature = "phantom")]
472#[cfg_attr(feature = "docsrs", doc(cfg(feature = "phantom")))]
473pub use self::phantom::{
474    AsPhantomData,
475    AndPhantom, AndPhantomCov,
476    as_phantom, as_covariant_phantom,
477    ContraVariantPhantom,
478    InvariantPhantom, InvariantRefPhantom, VariantDropPhantom, CovariantPhantom,
479};
480
481
482#[cfg(feature = "self_ops")]
483#[cfg_attr(feature = "docsrs", doc(cfg(feature = "self_ops")))]
484mod self_ops;
485
486#[cfg(feature = "self_ops")]
487#[cfg_attr(feature = "docsrs", doc(cfg(feature = "self_ops")))]
488pub use self::self_ops::SelfOps;
489
490
491#[cfg(feature = "slices")]
492#[cfg_attr(feature = "docsrs", doc(cfg(feature = "slices")))]
493pub mod slices;
494
495#[cfg(feature = "slices")]
496#[cfg_attr(feature = "docsrs", doc(cfg(feature = "slices")))]
497pub mod strings;
498
499#[cfg(feature = "slices")]
500#[cfg_attr(feature = "docsrs", doc(cfg(feature = "slices")))]
501pub use self::strings::StringExt;
502
503#[cfg(feature = "slices")]
504#[cfg_attr(feature = "docsrs", doc(cfg(feature = "slices")))]
505#[doc(no_inline)]
506pub use self::slices::{ValSliceExt,SliceExt};
507
508
509#[cfg(feature = "transparent_newtype")]
510#[cfg_attr(feature = "docsrs", doc(cfg(feature = "transparent_newtype")))]
511pub mod transparent_newtype;
512
513#[cfg(feature = "transparent_newtype")]
514#[cfg_attr(feature = "docsrs", doc(cfg(feature = "transparent_newtype")))]
515pub use self::transparent_newtype::{TransparentNewtype, TransparentNewtypeExt};
516
517
518#[cfg(feature = "type_identity")]
519#[cfg_attr(feature = "docsrs", doc(cfg(feature = "type_identity")))]
520mod type_identity;
521
522#[cfg(feature = "type_identity")]
523#[cfg_attr(feature = "docsrs", doc(cfg(feature = "type_identity")))]
524pub use self::type_identity::{TIdentity, TypeIdentity};
525
526
527#[cfg(feature = "__test_older")]
528#[doc(hidden)]
529pub mod test_utils;
530
531
532#[cfg(feature = "type_asserts")]
533#[cfg_attr(feature = "docsrs", doc(cfg(feature = "type_asserts")))]
534pub mod type_asserts;
535
536
537#[cfg(feature = "type_level_bool")]
538#[cfg_attr(feature = "docsrs", doc(cfg(feature = "type_level_bool")))]
539pub mod type_level_bool;
540
541
542pub mod utils;
543
544mod rust_version_assert;
545
546
547#[cfg(feature = "void")]
548#[cfg_attr(feature = "docsrs", doc(cfg(feature = "void")))]
549pub mod void;
550
551#[cfg(feature = "void")]
552#[cfg_attr(feature = "docsrs", doc(cfg(feature = "void")))]
553pub use self::void::Void;
554
555
556#[cfg(all(test, not(feature = "__test_older")))]
557compile_error! { "tests must be run with the \"__test_older\" feature" }
558
559#[doc(hidden)]
560pub mod __ {
561    pub use std_::marker::PhantomData as PD;
562    pub use std_::{concat, compile_error, stringify};
563    pub use self::foo::Usize as usize;
564
565    mod foo {
566        pub type Usize = usize;
567    }
568
569    #[cfg(feature = "marker_type")]
570    pub use crate::marker_type::assert_markertype;
571
572    #[cfg(feature = "macro_utils")]
573    pub use core_extensions_proc_macros::{__priv_rewrap_macro_parameters, count_tts};
574
575    #[cfg(feature = "enable_proc_macro_crate")]
576    pub use core_extensions_proc_macros::{__priv_unwrap_bound, __priv_split_generics};
577
578    #[cfg(feature = "item_parsing")]
579    pub use core_extensions_proc_macros::__priv_split_impl;
580}
581
582