1#![cfg_attr(not(feature = "std"), no_std)]
69#![cfg_attr(docsrs, feature(doc_cfg))]
70
71#[cfg(feature = "alloc")]
76extern crate alloc;
77
78#[cfg(feature = "alloc")]
79use alloc::string::String;
80
81#[cfg(feature = "alloc")]
82#[doc(hidden)]
83pub mod __macro_private {
84 pub use alloc::borrow::Cow;
85}
86
87#[cfg(feature = "alloc")]
106#[macro_export]
107macro_rules! cow_into_owned {
108 ($owned:expr, $cow:expr $(,)?) => {{
109 match $cow {
110 $crate::__macro_private::Cow::Owned(s) => s,
111 $crate::__macro_private::Cow::Borrowed(_) => $owned,
112 }
113 }};
114}
115
116mod ends_with_ignore_ascii_case;
117mod ends_with_ignore_ascii_case_multiple;
118#[cfg(feature = "alloc")]
119mod ends_with_ignore_case;
120mod ends_with_multiple;
121mod eq_ignore_ascii_case;
122mod eq_ignore_ascii_case_multiple;
123#[cfg(feature = "unicase")]
124mod eq_ignore_case;
125mod eq_multiple;
126#[cfg(feature = "alloc")]
127mod escape_characters;
128#[cfg(feature = "alloc")]
129mod expand_tabs;
130mod is_ascii_lowercased;
131mod is_ascii_uppercased;
132mod is_lowercased;
133mod is_uppercased;
134#[cfg(feature = "alloc")]
135mod newlines;
136#[cfg(feature = "alloc")]
137mod normalize_newlines;
138#[cfg(feature = "alloc")]
139mod pattern;
140#[cfg(feature = "alloc")]
141mod remove_all_invisible_characters;
142#[cfg(feature = "alloc")]
143mod replace;
144#[cfg(feature = "alloc")]
145mod replace_newlines_with_space;
146mod starts_with_ignore_ascii_case;
147mod starts_with_ignore_ascii_case_multiple;
148#[cfg(feature = "alloc")]
149mod starts_with_ignore_case;
150mod starts_with_multiple;
151#[cfg(feature = "alloc")]
152mod to_lowercase;
153#[cfg(feature = "alloc")]
154mod to_uppercase;
155#[cfg(feature = "alloc")]
156mod trim;
157
158pub use ends_with_ignore_ascii_case::*;
159pub use ends_with_ignore_ascii_case_multiple::*;
160#[cfg(feature = "alloc")]
161pub use ends_with_ignore_case::*;
162pub use ends_with_multiple::*;
163pub use eq_ignore_ascii_case::*;
164pub use eq_ignore_ascii_case_multiple::*;
165#[cfg(feature = "unicase")]
166pub use eq_ignore_case::*;
167pub use eq_multiple::*;
168#[cfg(feature = "alloc")]
169pub use escape_characters::*;
170#[cfg(feature = "alloc")]
171pub use expand_tabs::*;
172pub use is_ascii_lowercased::*;
173pub use is_ascii_uppercased::*;
174pub use is_lowercased::*;
175pub use is_uppercased::*;
176#[cfg(feature = "alloc")]
177pub use normalize_newlines::*;
178#[cfg(feature = "alloc")]
179pub use pattern::*;
180#[cfg(feature = "alloc")]
181pub use remove_all_invisible_characters::*;
182#[cfg(feature = "alloc")]
183pub use replace::*;
184#[cfg(feature = "alloc")]
185pub use replace_newlines_with_space::*;
186pub use starts_with_ignore_ascii_case::*;
187pub use starts_with_ignore_ascii_case_multiple::*;
188#[cfg(feature = "alloc")]
189pub use starts_with_ignore_case::*;
190pub use starts_with_multiple::*;
191#[cfg(feature = "alloc")]
192pub use to_lowercase::*;
193#[cfg(feature = "alloc")]
194pub use to_uppercase::*;
195#[cfg(feature = "alloc")]
196pub use trim::*;
197
198#[cfg(feature = "alloc")]
199pub(crate) unsafe fn find_substring_position(parent: &str, sub: &str) -> (usize, usize) {
200 let parent_start_address = parent.as_ptr() as usize;
201
202 let sub_start_address = sub.as_ptr() as usize;
203 let position_len = sub.len();
204
205 let position_start = sub_start_address - parent_start_address;
206
207 (position_start, position_len)
208}
209
210#[cfg(feature = "alloc")]
211pub(crate) unsafe fn into_substring_in_place(
212 mut s: String,
213 (start, len): (usize, usize),
214) -> String {
215 let bytes = s.as_mut_vec();
216
217 bytes.drain(..start);
218 bytes.truncate(len);
219
220 s
221}
222
223#[cfg(feature = "alloc")]
224macro_rules! to_substring_in_place {
225 ($parent:ident, $sub:ident) => {{
226 let position = $crate::find_substring_position($parent.as_str(), $sub);
227
228 $crate::into_substring_in_place($parent, position)
229 }};
230}
231
232#[cfg(feature = "alloc")]
233pub(crate) use to_substring_in_place;