rustmax/
lib.rs

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