rustmax/
lib.rs

1#![doc = include_str!("../doc-src/root-docs.md")]
2#![allow(clippy::needless_doctest_main)]
3
4/* ---------- */
5
6
7#![no_std]
8
9
10/* ---------- */
11
12
13pub mod prelude {
14    //! The `rmx` prelude.
15
16
17    /* standard library preludes */
18
19    #[cfg(all(feature = "rmx-rustlib-core", not(feature = "rmx-rustlib-std")))]
20    pub use ::core::prelude::rust_2021::*;
21
22    #[cfg(feature = "rmx-rustlib-std")]
23    pub use ::std::prelude::rust_2021::*;
24
25
26    /* standard library macros */
27
28    #[cfg(feature = "rmx-rustlib-alloc")]
29    pub use ::alloc::{format, vec};
30
31
32    /* standard library exports that aren't in its prelude */
33
34    // Ordering is recommended by
35    // `clippy::comparison_chain` and if it's
36    // important enough that the compiler suggests
37    // using it instead of comparison operator syntax,
38    // let's put it in the prelude.
39    #[cfg(feature = "rmx-rustlib-core")]
40    pub use ::core::cmp::Ordering;
41
42
43    /* other preludes */
44
45    #[cfg(feature = "futures")]
46    pub use ::futures::prelude::*;
47
48
49    /* common non-std imports */
50
51    #[cfg(feature = "anyhow")]
52    pub use ::anyhow::{
53        Context as _,
54        anyhow, bail,
55    };
56
57    #[cfg(feature = "anyhow")]
58    pub use crate::extras::{
59        AnyResult, AnyError, A,
60    };
61
62    #[cfg(feature = "cfg-if")]
63    pub use ::cfg_if::cfg_if;
64
65    #[cfg(feature = "extension-trait")]
66    pub use ::extension_trait::extension_trait;
67
68    #[cfg(feature = "log")]
69    pub use ::log::{error, warn, info, debug, trace};
70
71    #[cfg(all(feature = "futures", feature = "rmx-feature-default"))]
72    pub use ::futures::{
73        executor::block_on,
74        future::Either,
75    };
76
77    #[cfg(feature = "itertools")]
78    pub use ::itertools::Itertools as _;
79
80
81    /* extras */
82
83    pub use crate::extras::{
84        default,
85    };
86
87    #[cfg(feature = "rmx-rustlib-core")]
88    pub use crate::bug;
89
90    #[cfg(feature = "rmx-rustlib-alloc")]
91    pub use crate::extras::S;
92
93    #[cfg(feature = "rmx-rustlib-alloc")]
94    pub use crate::extras::O;
95
96    #[cfg(feature = "extension-trait")]
97    pub use crate::extras::QuickToString as _;
98    #[cfg(feature = "extension-trait")]
99    pub use crate::extras::QuickToOwned as _;
100    #[cfg(feature = "extension-trait")]
101    pub use crate::extras::QuickClone as _;
102    #[cfg(feature = "extension-trait")]
103    pub use crate::extras::OptionExpect as _;
104    #[cfg(feature = "extension-trait")]
105    pub use crate::extras::ResultExpect as _;
106    #[cfg(all(feature = "extension-trait", feature = "anyhow"))]
107    pub use crate::extras::AnyResultExpect as _;
108    #[cfg(feature = "extension-trait")]
109    pub use crate::extras::ResultIgnore as _;
110    #[cfg(feature = "extension-trait")]
111    pub use crate::extras::RangeExt as _;
112}
113
114pub mod extras {
115    //! Additional tidbits defined by `rmx`.
116
117    /// Like 'unimplemented' but shorter to type.
118    #[cfg(feature = "rmx-rustlib-core")]
119    #[macro_export]
120    macro_rules! bug {
121        () => {
122            core::panic!("unexpected case (bug!)")
123        };
124        ($($arg:tt)+) => {
125            core::panic!("unexpected case (bug!): {}", $crate::format_args!($($arg)+))
126        };
127    }
128
129    #[cfg(feature = "anyhow")]
130    pub use ::anyhow::{
131        Result as AnyResult,
132        Error as AnyError,
133        anyhow as A,
134    };
135
136    pub fn default<T: Default>() -> T {
137        Default::default()
138    }
139
140    pub fn init() {
141        #[cfg(feature = "env_logger")]
142        fn maybe_init_env_logger() {
143            crate::env_logger::Builder::new()
144                .filter_level(log::LevelFilter::Info)
145                .format_timestamp(None)
146                .parse_default_env()
147                .init();
148        }
149        #[cfg(not(feature = "env_logger"))]
150        fn maybe_init_env_logger() { }
151
152        maybe_init_env_logger();
153    }
154
155    pub fn init_crate_name(crate_name: &str) {
156        #[cfg(feature = "env_logger")]
157        fn maybe_init_env_logger(crate_name: &str) {
158            crate::env_logger::Builder::new()
159                .filter_module(crate_name, log::LevelFilter::Info)
160                .format_timestamp(None)
161                .parse_default_env()
162                .init();
163        }
164        #[cfg(not(feature = "env_logger"))]
165        fn maybe_init_env_logger(_crate_name: &str) { }
166
167        maybe_init_env_logger(crate_name);
168    }
169
170    pub fn recurse<F, R>(f: F) -> R
171    where F: FnOnce() -> R
172    {
173        // todo could grow stack here
174        f()
175    }
176
177    #[cfg(feature = "rmx-rustlib-alloc")]
178    #[allow(non_snake_case)]
179    pub fn S<T>(
180        s: &T,
181    ) -> crate::alloc::string::String
182    where T: crate::alloc::string::ToString + ?Sized,
183    {
184        crate::alloc::string::ToString::to_string(s)
185    }
186
187    #[cfg(feature = "rmx-rustlib-alloc")]
188    #[allow(non_snake_case)]
189    pub fn O<T>(
190        o: &T,
191    ) -> T::Owned
192    where T: crate::alloc::borrow::ToOwned + ?Sized,
193    {
194        crate::alloc::borrow::ToOwned::to_owned(o)
195    }
196
197    #[cfg(feature = "extension-trait")]
198    #[extension_trait::extension_trait]
199    pub impl<T> QuickToString for T
200    where T: crate::alloc::string::ToString + ?Sized,
201    {
202        #[allow(non_snake_case)]
203        fn S(&self) -> crate::alloc::string::String {
204            crate::alloc::string::ToString::to_string(self)
205        }
206    }
207
208    #[cfg(feature = "extension-trait")]
209    #[extension_trait::extension_trait]
210    pub impl<T> QuickToOwned for T
211        where T: crate::alloc::borrow::ToOwned,
212    {
213        type Owned = T::Owned;
214
215        #[allow(non_snake_case)]
216        fn O(&self) -> Self::Owned {
217            crate::alloc::borrow::ToOwned::to_owned(self)
218        }
219    }
220
221    #[cfg(feature = "extension-trait")]
222    #[extension_trait::extension_trait]
223    pub impl<T> QuickClone<T> for T
224    where T: Clone
225    {
226        #[allow(non_snake_case)]
227        fn C(&self) -> T {
228            self.clone()
229        }
230    }
231
232    #[cfg(feature = "extension-trait")]
233    #[extension_trait::extension_trait]
234    pub impl<T> OptionExpect<T> for Option<T> {
235        #[track_caller]
236        #[allow(non_snake_case)]
237        fn X(self) -> T {
238            match self {
239                Some(v) => v,
240                None => panic!("impossible `None` option"),
241            }
242        }
243    }
244
245    #[cfg(feature = "extension-trait")]
246    #[extension_trait::extension_trait]
247    pub impl<T, E> ResultExpect<T, E> for Result<T, E>
248    where E: core::error::Error
249    {
250        #[track_caller]
251        #[allow(non_snake_case)]
252        fn X(self) -> T {
253            match self {
254                Ok(v) => v,
255                Err(e) => panic!("impossible `Err` result: {e}"),
256            }
257        }
258    }
259
260    #[cfg(all(feature = "extension-trait", feature = "anyhow"))]
261    #[extension_trait::extension_trait]
262    pub impl<T> AnyResultExpect<T> for AnyResult<T>
263    {
264        #[track_caller]
265        #[allow(non_snake_case)]
266        fn X(self) -> T {
267            match self {
268                Ok(v) => v,
269                Err(e) => panic!("impossible `Err` result: {e}"),
270            }
271        }
272    }
273
274    /// Ignore a `Result`.
275    ///
276    /// This is nice because the common idiom of `let _ = ...` is untyped
277    /// and can accidentally be applied to non-`Result` types like `Future`s.
278    #[cfg(feature = "extension-trait")]
279    #[extension_trait::extension_trait]
280    pub impl<T, E> ResultIgnore<T, E> for Result<T, E>
281    {
282        #[track_caller]
283        #[allow(non_snake_case)]
284        fn I(self) {
285            let _ = self;
286        }
287    }
288
289    // todo: define this for generic Range<N>
290    // todo: put this in a crate and elaborate
291    #[cfg(feature = "extension-trait")]
292    #[extension_trait::extension_trait]
293    pub impl RangeExt for core::ops::Range<usize> {
294        fn from_start_len(start: usize, len: usize) -> Option<core::ops::Range<usize>> {
295            Some(start..start.checked_add(len)?)
296        }
297
298        fn subrange(&self, sub: core::ops::Range<usize>) -> Option<core::ops::Range<usize>> {
299            if sub.start >= self.len() || sub.end > self.len() {
300                return None;
301            }
302            let new_start = self.start.checked_add(sub.start);
303            let new_end = self.start.checked_add(sub.end);
304            match (new_start, new_end) {
305                (Some(new_start), Some(new_end)) => Some(new_start..new_end),
306                _ => None,
307            }
308        }
309
310        fn checked_sub(&self, other: usize) -> Option<core::ops::Range<usize>> {
311            let new_start = self.start.checked_sub(other);
312            let new_end = self.end.checked_sub(other);
313            match (new_start, new_end) {
314                (Some(new_start), Some(new_end)) => Some(new_start..new_end),
315                _ => None,
316            }
317        }
318    }
319}
320
321
322/* ---------- */
323
324
325#[cfg(feature = "rmx-rustlib-core")]
326#[doc(inline)]
327pub extern crate core;
328
329#[cfg(feature = "rmx-rustlib-alloc")]
330#[doc(inline)]
331pub extern crate alloc;
332
333#[cfg(feature = "rmx-rustlib-std")]
334#[doc(inline)]
335pub extern crate std;
336
337#[cfg(feature = "rmx-rustlib-proc_macro")]
338#[doc(inline)]
339pub extern crate proc_macro;
340
341
342/* ---------- */
343
344
345#[cfg(feature = "ahash")]
346pub mod ahash {
347    #![doc = include_str!("../doc-src/crate-ahash.md")]
348
349    pub use ::ahash::*;
350}
351
352
353#[cfg(feature = "anyhow")]
354pub mod anyhow {
355    //! Easy error handling.
356    //!
357    //! See crate [`::anyhow`].
358
359    pub use ::anyhow::*;
360}
361
362#[cfg(feature = "axum")]
363pub mod axum {
364    //! Web application framework based on [`tokio`](super::tokio).
365    //!
366    //! See crate [`::axum`].
367
368    pub use ::axum::*;
369}
370
371#[cfg(feature = "backtrace")]
372pub mod backtrace {
373    //! Callstack backtraces on demand.
374    //!
375    //! See crate [`::backtrace`].
376
377    pub use ::backtrace::*;
378}
379
380#[cfg(feature = "base64")]
381pub mod base64 {
382    //! Base-64 encoding and decoding.
383    //!
384    //! See crate [`::base64`].
385
386    pub use ::base64::*;
387}
388
389#[cfg(feature = "bindgen")]
390pub mod bindgen {
391    //! Generate Rust bindings to C and C++ libraries.
392    //!
393    //! See crate [`::bindgen`].
394
395    pub use ::bindgen::*;
396}
397
398#[cfg(feature = "bitflags")]
399pub mod bitflags {
400    #![doc = include_str!("../doc-src/crate-bitflags.md")]
401
402    pub use ::bitflags::*;
403}
404
405#[cfg(feature = "blake3")]
406pub mod blake3 {
407    //! The BLAKE3 cryptographic hash function.
408    //!
409    //! See crate [`::blake3`].
410
411    pub use ::blake3::*;
412}
413
414#[cfg(feature = "byteorder")]
415pub mod byteorder {
416    //! Big-endian and little-endian encoding.
417    //!
418    //! See crate [`::byteorder`].
419
420    pub use ::byteorder::*;
421}
422
423#[cfg(feature = "bytes")]
424pub mod bytes {
425    //! Abstractions for working with byte buffers: [`Bytes`], [`Buf`], and [`BufMut`].
426    //!
427    //! See crate [`::bytes`].
428
429    pub use ::bytes::*;
430}
431
432#[cfg(feature = "cc")]
433pub mod cc {
434    //! A basic cross-platform C compiler driver.
435    //!
436    //! See crate [`::cc`].
437
438    pub use ::cc::*;
439}
440
441#[cfg(feature = "cfg-if")]
442pub mod cfg_if {
443    //! A macro for writing conditional compilation as `if` / `else` blocks.
444    //!
445    //! See crate [`::cfg_if`].
446
447    pub use ::cfg_if::*;
448}
449
450#[cfg(feature = "chrono")]
451pub mod chrono {
452    //! Dates and time (legacy).
453    //!
454    //! See crate [`::chrono`].
455
456    pub use ::chrono::*;
457}
458
459#[cfg(feature = "clap")]
460pub mod clap {
461    //! Command line parsing.
462    //!
463    //! See crate [`::clap`].
464
465    pub use ::clap::*;
466}
467
468#[cfg(feature = "ctrlc")]
469pub mod ctrlc {
470    //! Simple handling of CTRL-C for CLI programs.
471    //!
472    //! See crate [`::ctrlc`].
473
474    pub use ::ctrlc::*;
475}
476
477#[cfg(feature = "crossbeam")]
478pub mod crossbeam {
479    //! Concurrency tools to supplement [`std::sync`], including fast channels.
480    //!
481    //! See crate [`::crossbeam`].
482
483    pub use ::crossbeam::*;
484}
485
486#[cfg(feature = "cxx")]
487pub mod cxx {
488    //! C++ bridge runtime support; paired with [`cxx_build`](super::cxx_build).
489    //!
490    //! See crate [`::cxx`].
491
492    pub use ::cxx::*;
493}
494
495#[cfg(feature = "cxx-build")]
496pub mod cxx_build {
497    //! C++ bridge generator; paired with [`cxx`](super::cxx).
498    //!
499    //! See crate [`::cxx`].
500
501    pub use ::cxx::*;
502}
503
504#[cfg(feature = "derive_more")]
505pub mod derive_more {
506    //! `derive` for more standard traits.
507    //!
508    //! See crate [`::derive_more`].
509
510    pub use ::derive_more::*;
511}
512
513#[cfg(feature = "env_logger")]
514pub mod env_logger {
515    //! A basic logger to use with the [`log`](super::log) crate.
516    //!
517    //! See crate [`::env_logger`].
518
519    pub use ::env_logger::*;
520}
521
522#[cfg(feature = "extension-trait")]
523pub mod extension_trait {
524    //! A macro for defining extension methods to external types.
525    //!
526    //! See crate [`::extension_trait`].
527
528    pub use ::extension_trait::*;
529}
530
531#[cfg(feature = "futures")]
532pub mod futures {
533    //! Abstractions for asynchronous programming.
534    //!
535    //! See crate [`::futures`].
536
537    pub use ::futures::*;
538}
539
540#[cfg(feature = "hex")]
541pub mod hex {
542    //! Encoding and decoding hexidecimal strings.
543    //!
544    //! See crate [`::hex`].
545
546    pub use ::hex::*;
547}
548
549#[cfg(feature = "http")]
550pub mod http {
551    //! Shared definitions related to the HTTP protocol.
552    //!
553    //! See crate [`::http`].
554
555    pub use ::http::*;
556}
557
558#[cfg(feature = "hyper")]
559pub mod hyper {
560    //! HTTP, versions 1 and 2.
561    //!
562    //! See crate [`::hyper`].
563
564    pub use ::hyper::*;
565}
566
567#[cfg(feature = "itertools")]
568pub mod itertools {
569    //! Additional methods for iterators.
570    //!
571    //! See crate [`::itertools`].
572
573    pub use ::itertools::*;
574}
575
576#[cfg(feature = "jiff")]
577pub mod jiff {
578    //! Dates and time.
579    //!
580    //! See crate [`::jiff`].
581
582    pub use ::jiff::*;
583}
584
585#[cfg(feature = "json5")]
586pub mod json5 {
587    //! JSON5, a superset of JSON with expanded syntax.
588    //!
589    //! See crate [`::json5`].
590
591    pub use ::json5::*;
592}
593
594#[cfg(feature = "libc")]
595pub mod libc {
596    //! Bindings to the C standard library.
597    //!
598    //! See crate [`::libc`].
599
600    pub use ::libc::*;
601}
602
603#[cfg(feature = "log")]
604pub mod log {
605    //! A simple logging framework.
606    //!
607    //! See crate [`::log`].
608
609    pub use ::log::*;
610}
611
612#[cfg(feature = "mime")]
613pub mod mime {
614    //! MIME media types.
615    //!
616    //! See crate [`::mime`].
617
618    pub use ::mime::*;
619}
620
621#[cfg(feature = "nom")]
622pub mod nom {
623    //! An efficient parser combinator.
624    //!
625    //! See crate [`::nom`].
626
627    pub use ::nom::*;
628}
629
630#[cfg(feature = "num-bigint")]
631pub mod num_bigint {
632    //! Arbitrary-sized integers.
633    //!
634    //! See crate [`::num_bigint`].
635
636    pub use ::num_bigint::*;
637}
638
639#[cfg(feature = "num_cpus")]
640pub mod num_cpus {
641    //! Get the number of CPUS on a machine.
642    //!
643    //! See crate [`::num_cpus`].
644
645    pub use ::num_cpus::*;
646}
647
648#[cfg(feature = "num_enum")]
649pub mod num_enum {
650    //! Conversions between numbers and enums.
651    //!
652    //! See crate [`::num_enum`].
653
654    pub use ::num_enum::*;
655}
656
657#[cfg(feature = "proc-macro2")]
658pub mod proc_macro2 {
659    //! A preferred wrapper around the standard [`proc_macro`] crate.
660    //!
661    //! See crate [`::proc_macro2`].
662
663    pub use ::proc_macro2::*;
664}
665
666#[cfg(feature = "proptest")]
667pub mod proptest {
668    //! Testing over generated inputs, ala QuickCheck.
669    //!
670    //! See crate [`::proptest`].
671
672    pub use ::proptest::*;
673}
674
675#[cfg(feature = "quote")]
676pub mod quote {
677    //! The `quote!` macro for turning code blocks into source tokens.
678    //!
679    //! See crate [`::quote`].
680
681    pub use ::quote::*;
682}
683
684#[cfg(feature = "rand")]
685pub mod rand {
686    //! Random number generators.
687    //!
688    //! See crate [`::rand`].
689
690    pub use ::rand::*;
691}
692
693#[cfg(feature = "rand_chacha")]
694pub mod rand_chacha {
695    //! The ChaCha cryptographically-secure random number generators.
696    //!
697    //! See crate [`::rand_chacha`].
698
699    pub use ::rand_chacha::*;
700}
701
702#[cfg(feature = "rand_pcg")]
703pub mod rand_pcg {
704    //! The PCG non-cryptographically-secure random number generators.
705    //!
706    //! See crate [`::rand_pcg`].
707
708    pub use ::rand_pcg::*;
709}
710
711#[cfg(feature = "rayon")]
712pub mod rayon {
713    //! Parallel iterators and other parallel processing tools.
714    //!
715    //! See crate [`::rayon`].
716
717    pub use ::rayon::*;
718}
719
720#[cfg(feature = "regex")]
721pub mod regex {
722    //! Regular expressions.
723    //!
724    //! See crate [`::regex`].
725
726    pub use ::regex::*;
727}
728
729#[cfg(feature = "reqwest")]
730pub mod reqwest {
731    //! Simple HTTP requests, synchronous and asynchronous.
732    //!
733    //! See crate [`::reqwest`].
734
735    pub use ::reqwest::*;
736}
737
738#[cfg(feature = "rustyline")]
739pub mod rustyline {
740    //! Command-line input reading with history.
741    //!
742    //! See crate [`::rustyline`].
743    
744    pub use ::rustyline::*;
745}
746
747#[cfg(feature = "semver")]
748pub mod semver {
749    //! The software versioning standard used by Rust
750    //!
751    //! See crate [`::semver`].
752
753    pub use ::semver::*;
754}
755
756#[cfg(feature = "serde")]
757pub mod serde {
758    //! The standard Rust serialization framework.
759    //!
760    //! See crate [`::serde`].
761
762    pub use ::serde::*;
763}
764
765#[cfg(feature = "serde_json")]
766pub mod serde_json {
767    //! JSON serialization / deserialization with [`serde`](super::serde).
768    //!
769    //! See crate [`::serde_json`].
770
771    pub use ::serde_json::*;
772}
773
774#[cfg(feature = "sha2")]
775pub mod sha2 {
776    //! The SHA2 cryptographic hash functions.
777    //!
778    //! See crate [`::sha2`].
779
780    pub use ::sha2::*;
781}
782
783#[cfg(feature = "socket2")]
784pub mod socket2 {
785    //! Low-level network socket programming beyond [`std::net`].
786    //!
787    //! See crate [`::socket2`].
788
789    pub use ::socket2::*;
790}
791
792#[cfg(feature = "static_assertions")]
793pub mod static_assertions {
794    //! Compile-time assertions about constants, types, etc.
795    //!
796    //! See crate [`::static_assertions`].
797
798    pub use ::static_assertions::*;
799}
800
801#[cfg(feature = "syn")]
802pub mod syn {
803    //! A Rust parser used by procedural macros.
804    //!
805    //! See crate [`::syn`].
806
807    pub use ::syn::*;
808}
809
810#[cfg(feature = "tempfile")]
811pub mod tempfile {
812    //! Temporary files and directories.
813    //!
814    //! See crate [`::tempfile`].
815
816    pub use ::tempfile::*;
817}
818
819#[cfg(feature = "tera")]
820pub mod tera {
821    //! A text template engine based on Jinja2.
822    //!
823    //! See crate [`::tera`].
824
825    pub use ::tera::*;
826}
827
828#[cfg(feature = "termcolor")]
829pub mod termcolor {
830    //! Cross-platform library for writing colored output to the terminal.
831    //!
832    //! See crate [`::termcolor`].
833
834    pub use ::termcolor::*;
835}
836
837#[cfg(feature = "thiserror")]
838pub mod thiserror {
839    //! Tools for defining custom error types.
840    //!
841    //! See crate [`::thiserror`].
842
843    pub use ::thiserror::*;
844}
845
846#[cfg(feature = "tokio")]
847pub mod tokio {
848    //! An async task runtime and I/O library.
849    //!
850    //! See crate [`::tokio`].
851
852    pub use ::tokio::*;
853}
854
855#[cfg(feature = "tower")]
856pub mod tower {
857    //! Service request/response abstraction (HTTP middleware)
858    //! for [`tokio`](super::tokio) and [`axum`](super::axum).
859    //!
860    //! See crate [`::tower`].
861
862    pub use ::tower::*;
863}
864
865#[cfg(feature = "toml")]
866pub mod toml {
867    //! TOML serialization / deserialization with `serde`.
868    //!
869    //! See crate [`::toml`].
870
871    pub use ::toml::*;
872}
873
874#[cfg(feature = "unicode-segmentation")]
875pub mod unicode_segmentation {
876    //! Splitting strings on grapheme cluster, word, and sentence boundaries.
877    //!
878    //! See crate [`::unicode_segmentation`].
879
880    pub use ::unicode_segmentation::*;
881}
882
883#[cfg(feature = "url")]
884pub mod url {
885    //! URL parsing and data structures.
886    //!
887    //! See crate [`::url`].
888
889    pub use ::url::*;
890}
891
892#[cfg(feature = "walkdir")]
893pub mod walkdir {
894    //! Efficient directory traversal.
895    //!
896    //! See crate [`::walkdir`].
897
898    pub use ::walkdir::*;
899}
900
901#[cfg(feature = "xshell")]
902pub mod xshell {
903    //! A Swiss-army knife for writing shell-style scripts in Rust.
904    //!
905    //! See crate [`::xshell`].
906
907    pub use ::xshell::*;
908}