malachite_base/strings/mod.rs
1// Copyright © 2026 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 crate::named::Named;
10use alloc::string::String;
11use alloc::vec::Vec;
12use core::fmt::{Binary, Debug, LowerHex, Octal, UpperHex};
13use hashbrown::HashSet;
14use itertools::Itertools;
15
16/// Sorts the characters of a string slice and returns them in a new [`String`].
17///
18/// # Worst-case complexity
19/// $T(n) = O(n \log n)$
20///
21/// $M(n) = O(n)$
22///
23/// where $T$ is time, $M$ is additional memory, and $n$ is `s.len()`.
24///
25/// # Examples
26/// ```
27/// use malachite_base::strings::string_sort;
28///
29/// assert_eq!(string_sort("Hello, world!"), " !,Hdellloorw");
30/// assert_eq!(string_sort("Mississippi"), "Miiiippssss");
31/// ```
32pub fn string_sort(s: &str) -> String {
33 let mut chars = s.chars().collect_vec();
34 chars.sort_unstable();
35 chars.iter().collect()
36}
37
38/// Takes a string slice's unique characters and returns them in a new [`String`].
39///
40/// The unique characters are output in order of appearance.
41///
42/// # Worst-case complexity
43/// $T(n) = O(n)$
44///
45/// $M(n) = O(n)$
46///
47/// where $T$ is time, $M$ is additional memory, and $n$ is `s.len()`.
48///
49/// # Examples
50/// ```
51/// use malachite_base::strings::string_unique;
52///
53/// assert_eq!(string_unique("Hello, world!"), "Helo, wrd!");
54/// assert_eq!(string_unique("Mississippi"), "Misp");
55/// ```
56pub fn string_unique(s: &str) -> String {
57 let mut chars = HashSet::new();
58 let mut nub = String::new();
59 for c in s.chars() {
60 if chars.insert(c) {
61 nub.push(c);
62 }
63 }
64 nub
65}
66
67/// Returns whether all of the first string slice's characters are present in the second string
68/// slice.
69///
70/// Does not take multiplicities into account.
71///
72/// # Worst-case complexity
73/// $T(n, m) = O(n + m)$
74///
75/// $M(n, m) = O(m)$
76///
77/// where $T$ is time, $M$ is additional memory, $n$ is `s.len()`, and $m$ is `t.len()`: the second
78/// string's characters are collected into a hash set, and the first string's characters are checked
79/// against it.
80///
81/// # Examples
82/// ```
83/// use malachite_base::strings::string_is_subset;
84///
85/// assert_eq!(string_is_subset("oH, well", "Hello, world!"), true);
86/// assert_eq!(string_is_subset("MMM", "Mississippi"), true);
87/// assert_eq!(string_is_subset("Hello, World!", "Hello, world!"), false);
88/// assert_eq!(string_is_subset("j", "Mississippi"), false);
89/// ```
90pub fn string_is_subset(s: &str, t: &str) -> bool {
91 let t_chars: HashSet<char> = t.chars().collect();
92 s.chars().all(|c| t_chars.contains(&c))
93}
94
95impl_named!(String);
96
97/// A trait that provides an ergonomic way to create the string specified by a [`Debug`]
98/// implementation.
99pub trait ToDebugString: Debug {
100 fn to_debug_string(&self) -> String;
101}
102
103impl<T: Debug> ToDebugString for T {
104 /// Returns the [`String`] produced by `T`s [`Debug`] implementation.
105 ///
106 /// # Examples
107 /// ```
108 /// use malachite_base::strings::ToDebugString;
109 ///
110 /// assert_eq!([1, 2, 3].to_debug_string(), "[1, 2, 3]");
111 /// assert_eq!(
112 /// [vec![2, 3], vec![], vec![4]].to_debug_string(),
113 /// "[[2, 3], [], [4]]"
114 /// );
115 /// assert_eq!(Some(5).to_debug_string(), "Some(5)");
116 /// ```
117 #[inline]
118 fn to_debug_string(&self) -> String {
119 ::alloc::format!("{self:?}")
120 }
121}
122
123/// A trait that provides an ergonomic way to create the string specified by a [`Binary`]
124/// implementation.
125pub trait ToBinaryString: Binary {
126 fn to_binary_string(&self) -> String;
127}
128
129impl<T: Binary> ToBinaryString for T {
130 /// Returns the [`String`] produced by `T`s [`Binary`] implementation.
131 ///
132 /// # Examples
133 /// ```
134 /// use malachite_base::strings::ToBinaryString;
135 ///
136 /// assert_eq!(5u64.to_binary_string(), "101");
137 /// assert_eq!((-100i16).to_binary_string(), "1111111110011100");
138 /// ```
139 #[inline]
140 fn to_binary_string(&self) -> String {
141 ::alloc::format!("{self:b}")
142 }
143}
144
145/// A trait that provides an ergonomic way to create the string specified by an [`Octal`]
146/// implementation.
147pub trait ToOctalString: Octal {
148 fn to_octal_string(&self) -> String;
149}
150
151impl<T: Octal> ToOctalString for T {
152 /// Returns the [`String`] produced by `T`s [`Octal`] implementation.
153 ///
154 /// # Examples
155 /// ```
156 /// use malachite_base::strings::ToOctalString;
157 ///
158 /// assert_eq!(50u64.to_octal_string(), "62");
159 /// assert_eq!((-100i16).to_octal_string(), "177634");
160 /// ```
161 #[inline]
162 fn to_octal_string(&self) -> String {
163 ::alloc::format!("{self:o}")
164 }
165}
166
167/// A trait that provides an ergonomic way to create the string specified by a [`LowerHex`]
168/// implementation.
169pub trait ToLowerHexString: LowerHex {
170 fn to_lower_hex_string(&self) -> String;
171}
172
173impl<T: LowerHex> ToLowerHexString for T {
174 /// Returns the [`String`] produced by `T`s [`LowerHex`] implementation.
175 ///
176 /// # Examples
177 /// ```
178 /// use malachite_base::strings::ToLowerHexString;
179 ///
180 /// assert_eq!(50u64.to_lower_hex_string(), "32");
181 /// assert_eq!((-100i16).to_lower_hex_string(), "ff9c");
182 /// ```
183 #[inline]
184 fn to_lower_hex_string(&self) -> String {
185 ::alloc::format!("{self:x}")
186 }
187}
188
189/// A trait that provides an ergonomic way to create the string specified by an [`UpperHex`]
190/// implementation.
191pub trait ToUpperHexString: UpperHex {
192 fn to_upper_hex_string(&self) -> String;
193}
194
195impl<T: UpperHex> ToUpperHexString for T {
196 /// Returns the [`String`] produced by `T`s [`UpperHex`] implementation.
197 ///
198 /// # Examples
199 /// ```
200 /// use malachite_base::strings::ToUpperHexString;
201 ///
202 /// assert_eq!(50u64.to_upper_hex_string(), "32");
203 /// assert_eq!((-100i16).to_upper_hex_string(), "FF9C");
204 /// ```
205 #[inline]
206 fn to_upper_hex_string(&self) -> String {
207 ::alloc::format!("{self:X}")
208 }
209}
210
211/// Generates [`String`]s, given an iterator that generates `Vec<char>`s.
212///
213/// This `struct` is created by [`strings_from_char_vecs`]; see its documentation for more.
214#[derive(Clone, Debug)]
215pub struct StringsFromCharVecs<I: Iterator<Item = Vec<char>>> {
216 css: I,
217}
218
219impl<I: Iterator<Item = Vec<char>>> Iterator for StringsFromCharVecs<I> {
220 type Item = String;
221
222 #[inline]
223 fn next(&mut self) -> Option<String> {
224 self.css.next().map(|cs| cs.into_iter().collect())
225 }
226}
227
228/// Generates [`String`]s, given an iterator that generates `Vec<char>`s.
229///
230/// The elements appear in the same order as they do in the given iterator, but as [`String`]s.
231///
232/// The output length is `css.count()`.
233///
234/// # Worst-case complexity per iteration
235/// $T(i) = O(\ell + T^\prime(i))$
236///
237/// $M(i) = O(\ell + M^\prime(i))$
238///
239/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, $T^\prime$ and
240/// $M^\prime$ are the time and memory functions of `css`, and $\ell$ is the length of the $i$th
241/// output string.
242///
243/// # Examples
244/// ```
245/// use itertools::Itertools;
246/// use malachite_base::strings::strings_from_char_vecs;
247///
248/// let ss =
249/// &strings_from_char_vecs([vec!['a', 'b'], vec!['c', 'd']].iter().cloned()).collect_vec();
250/// assert_eq!(
251/// ss.iter().map(|cs| cs.as_str()).collect_vec().as_slice(),
252/// &["ab", "cd"]
253/// );
254/// ```
255#[inline]
256pub const fn strings_from_char_vecs<I: Iterator<Item = Vec<char>>>(
257 css: I,
258) -> StringsFromCharVecs<I> {
259 StringsFromCharVecs { css }
260}
261
262/// Iterators that generate [`String`]s without repetition.
263pub mod exhaustive;
264/// The [`GmpConversionSpec`](gmp_format::GmpConversionSpec) struct, the
265/// [`GmpFormatArg`](gmp_format::GmpFormatArg) trait, and the [`gmp_format`](gmp_format::gmp_format)
266/// function, for formatting values according to GMP-style `printf` format strings; the
267/// [`gmp_format!`](crate::gmp_format) macro wraps them.
268pub mod gmp_format;
269#[cfg(feature = "random")]
270/// Iterators that generate [`String`]s randomly.
271pub mod random;