malachite_base/options/mod.rs
1// Copyright © 2025 Mikhail Hogrefe
2//
3// This file is part of Malachite.
4//
5// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
6// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
7// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
8
9use core::str::FromStr;
10
11/// Converts a string to an `Option<T>`, where `T` implements [`FromStr`].
12///
13/// If the string does not represent a valid `Option<T>`, `None` is returned.
14///
15/// If `T` does not implement [`FromStr`], try using [`option_from_str_custom`] instead.
16///
17/// # Examples
18/// ```
19/// use malachite_base::options::option_from_str;
20///
21/// assert_eq!(option_from_str::<bool>("Some(false)"), Some(Some(false)));
22/// assert_eq!(option_from_str::<u32>("Some(5)"), Some(Some(5)));
23/// assert_eq!(option_from_str::<u32>("None"), Some(None));
24/// assert_eq!(option_from_str::<u32>("Some(hi)"), None);
25/// assert_eq!(option_from_str::<bool>("abc"), None);
26/// ```
27#[inline]
28pub fn option_from_str<T: FromStr>(src: &str) -> Option<Option<T>> {
29 option_from_str_custom(&(|t| t.parse().ok()), src)
30}
31
32/// Converts a string to an `Option<T>`, given a function to parse a string into a `T`.
33///
34/// If the string does not represent a valid `Option<T>`, `None` is returned.
35///
36/// If `f` just uses the [`FromStr`] implementation on `T`, you can use [`option_from_str`] instead.
37///
38/// # Examples
39/// ```
40/// use malachite_base::options::{option_from_str, option_from_str_custom};
41/// use malachite_base::orderings::ordering_from_str;
42/// use std::cmp::Ordering::{self, *};
43///
44/// assert_eq!(
45/// option_from_str_custom::<Ordering>(&ordering_from_str, "Some(Less)"),
46/// Some(Some(Less))
47/// );
48/// assert_eq!(
49/// option_from_str_custom::<Option<bool>>(&option_from_str, "Some(Some(false))"),
50/// Some(Some(Some(false)))
51/// );
52/// assert_eq!(
53/// option_from_str_custom::<Ordering>(&ordering_from_str, "Some(hi)"),
54/// None
55/// );
56/// assert_eq!(
57/// option_from_str_custom::<Ordering>(&ordering_from_str, "abc"),
58/// None
59/// );
60/// ```
61pub fn option_from_str_custom<T>(f: &dyn Fn(&str) -> Option<T>, src: &str) -> Option<Option<T>> {
62 if src == "None" {
63 Some(None)
64 } else if src.starts_with("Some(") && src.ends_with(')') {
65 f(&src[5..src.len() - 1]).map(Some)
66 } else {
67 None
68 }
69}
70
71/// Iterators that generate [`Option`]s without repetition.
72pub mod exhaustive;
73#[cfg(feature = "random")]
74/// Iterators that generate [`Option`]s randomly.
75pub mod random;