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
322#![deny(missing_docs)]
323#![deny(unused_must_use)]
324#![cfg_attr(not(miri), no_std)]
325#![cfg_attr(feature = "docsrs", feature(doc_cfg))]
326
327#[cfg(feature="std")]
328#[macro_use]
329#[doc(hidden)]
330pub extern crate std as std_;
331
332#[cfg(not(feature="std"))]
333#[doc(hidden)]
334pub extern crate core as std_;
335
336#[cfg(feature="alloc")]
337#[doc(hidden)]
338#[macro_use]
339pub extern crate alloc;
340
341
342#[doc(hidden)]
343#[cfg(feature = "enable_proc_macro_crate")]
344pub extern crate core_extensions_proc_macros;
345
346#[cfg(feature = "derive")]
347extern crate self as core_extensions;
348
349#[cfg(all(feature = "derive", feature = "const_default"))]
350include!{"./derive/const_default_docs.rs"}
351
352#[cfg(all(feature = "derive", feature = "transparent_newtype"))]
353include!{"./derive/transparent_newtype_docs.rs"}
354
355
356#[doc(hidden)]
357#[macro_use]
358pub mod macros;
359
360#[cfg(feature = "serde_")]
361extern crate serde;
362
363#[cfg(test)]
364extern crate rand;
365
366
367#[cfg(feature = "bools")]
368#[cfg_attr(feature = "docsrs", doc(cfg(feature = "bools")))]
369mod bool_extensions;
370
371#[cfg(feature = "bools")]
372#[cfg_attr(feature = "docsrs", doc(cfg(feature = "bools")))]
373pub use self::bool_extensions::BoolExt;
374
375
376#[cfg(feature = "callable")]
377#[cfg_attr(feature = "docsrs", doc(cfg(feature = "callable")))]
378pub mod callable;
379
380#[cfg(feature = "callable")]
381#[cfg_attr(feature = "docsrs", doc(cfg(feature = "callable")))]
382pub use self::callable::{CallExt, CallInto, CallMut, CallRef};
383
384
385#[cfg(feature = "collections")]
386#[cfg_attr(feature = "docsrs", doc(cfg(feature = "collections")))]
387pub mod collections;
388
389
390#[cfg(feature = "const_default")]
391#[cfg_attr(feature = "docsrs", doc(cfg(feature = "const_default")))]
392mod const_default_trait;
393
394#[cfg(feature = "const_default")]
395#[cfg_attr(feature = "docsrs", doc(cfg(feature = "const_default")))]
396pub use self::const_default_trait::ConstDefault;
397
398#[cfg(feature = "const_val")]
399#[cfg_attr(feature = "docsrs", doc(cfg(feature = "const_val")))]
400mod const_val;
401
402
403#[cfg(feature = "const_val")]
404#[cfg_attr(feature = "docsrs", doc(cfg(feature = "const_val")))]
405pub use self::const_val::ConstVal;
406
407
408#[cfg(feature = "integers")]
409#[cfg_attr(feature = "docsrs", doc(cfg(feature = "integers")))]
410pub mod integers;
411
412#[cfg(feature = "integers")]
413#[cfg_attr(feature = "docsrs", doc(cfg(feature = "integers")))]
414pub use self::integers::{IntegerExt, ToTime};
415
416
417#[cfg(feature = "iterators")]
418#[cfg_attr(feature = "docsrs", doc(cfg(feature = "iterators")))]
419pub mod iterators;
420
421#[cfg(feature = "iterators")]
422#[cfg_attr(feature = "docsrs", doc(cfg(feature = "iterators")))]
423pub use self::iterators::{IterCloner, IterConstructor, IteratorExt, LazyOnce};
424
425
426#[cfg(feature = "macro_utils")]
427#[doc(inline)]
428pub use crate::macros::macro_utils::*;
429
430
431
432#[cfg(feature = "marker_type")]
433#[cfg_attr(feature = "docsrs", doc(cfg(feature = "marker_type")))]
434mod marker_type;
435
436#[cfg(feature = "marker_type")]
437#[cfg_attr(feature = "docsrs", doc(cfg(feature = "marker_type")))]
438pub use self::marker_type::MarkerType;
439
440
441#[cfg(feature = "std")]
442pub mod measure_time;
443
444
445#[cfg(feature = "on_drop")]
446#[cfg_attr(feature = "docsrs", doc(cfg(feature = "on_drop")))]
447mod on_drop;
448
449#[cfg(feature = "on_drop")]
450#[cfg_attr(feature = "docsrs", doc(cfg(feature = "on_drop")))]
451pub use self::on_drop::RunOnDrop;
452
453
454#[cfg(feature = "option_result")]
455#[cfg_attr(feature = "docsrs", doc(cfg(feature = "option_result")))]
456pub mod option_result_ext;
457
458#[doc(no_inline)]
459#[cfg(feature = "option_result")]
460#[cfg_attr(feature = "docsrs", doc(cfg(feature = "option_result")))]
461pub use self::option_result_ext::{OptionExt, ResultExt, ResultLike, ResultLikeExt, TransposeOption};
462
463#[cfg(feature = "phantom")]
464#[cfg_attr(feature = "docsrs", doc(cfg(feature = "phantom")))]
465pub mod phantom;
466
467#[cfg(feature = "phantom")]
468#[cfg_attr(feature = "docsrs", doc(cfg(feature = "phantom")))]
469pub use self::phantom::{
470    AsPhantomData,
471    AndPhantom, AndPhantomCov,
472    as_phantom, as_covariant_phantom,
473    ContraVariantPhantom,
474    InvariantPhantom, InvariantRefPhantom, VariantDropPhantom, CovariantPhantom,
475};
476
477
478#[cfg(feature = "self_ops")]
479#[cfg_attr(feature = "docsrs", doc(cfg(feature = "self_ops")))]
480mod self_ops;
481
482#[cfg(feature = "self_ops")]
483#[cfg_attr(feature = "docsrs", doc(cfg(feature = "self_ops")))]
484pub use self::self_ops::SelfOps;
485
486
487#[cfg(feature = "slices")]
488#[cfg_attr(feature = "docsrs", doc(cfg(feature = "slices")))]
489pub mod slices;
490
491#[cfg(feature = "slices")]
492#[cfg_attr(feature = "docsrs", doc(cfg(feature = "slices")))]
493pub mod strings;
494
495#[cfg(feature = "slices")]
496#[cfg_attr(feature = "docsrs", doc(cfg(feature = "slices")))]
497pub use self::strings::StringExt;
498
499#[cfg(feature = "slices")]
500#[cfg_attr(feature = "docsrs", doc(cfg(feature = "slices")))]
501#[doc(no_inline)]
502pub use self::slices::{ValSliceExt,SliceExt};
503
504
505#[cfg(feature = "transparent_newtype")]
506#[cfg_attr(feature = "docsrs", doc(cfg(feature = "transparent_newtype")))]
507pub mod transparent_newtype;
508
509#[cfg(feature = "transparent_newtype")]
510#[cfg_attr(feature = "docsrs", doc(cfg(feature = "transparent_newtype")))]
511pub use self::transparent_newtype::{TransparentNewtype, TransparentNewtypeExt};
512
513
514#[cfg(feature = "type_identity")]
515#[cfg_attr(feature = "docsrs", doc(cfg(feature = "type_identity")))]
516mod type_identity;
517
518#[cfg(feature = "type_identity")]
519#[cfg_attr(feature = "docsrs", doc(cfg(feature = "type_identity")))]
520pub use self::type_identity::{TIdentity, TypeIdentity};
521
522
523#[cfg(feature = "__test")]
524#[doc(hidden)]
525pub mod test_utils;
526
527
528#[cfg(feature = "type_asserts")]
529#[cfg_attr(feature = "docsrs", doc(cfg(feature = "type_asserts")))]
530pub mod type_asserts;
531
532
533#[cfg(feature = "type_level_bool")]
534#[cfg_attr(feature = "docsrs", doc(cfg(feature = "type_level_bool")))]
535pub mod type_level_bool;
536
537
538pub mod utils;
539
540mod rust_version_assert;
541
542
543#[cfg(feature = "void")]
544#[cfg_attr(feature = "docsrs", doc(cfg(feature = "void")))]
545mod void;
546
547#[cfg(feature = "void")]
548#[cfg_attr(feature = "docsrs", doc(cfg(feature = "void")))]
549pub use self::void::Void;
550
551
552#[cfg(all(test, not(feature = "__test")))]
553compile_error! { "tests must be run with the \"__test\" feature" }
554
555#[doc(hidden)]
556pub mod __ {
557    pub use std_::marker::PhantomData as PD;
558    pub use std_::{concat, compile_error, stringify};
559    pub use self::foo::Usize as usize;
560
561    mod foo {
562        pub type Usize = usize;
563    }
564
565    #[cfg(feature = "marker_type")]
566    pub use crate::marker_type::assert_markertype;
567
568    #[cfg(feature = "macro_utils")]
569    pub use core_extensions_proc_macros::{__priv_rewrap_macro_parameters, count_tts};
570
571    #[cfg(feature = "enable_proc_macro_crate")]
572    pub use core_extensions_proc_macros::{__priv_unwrap_bound, __priv_split_generics};
573
574    #[cfg(feature = "item_parsing")]
575    pub use core_extensions_proc_macros::__priv_split_impl;
576}
577
578