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