1#![doc = include_str!("../README.md")]
2#![forbid(unsafe_code)]
3#![no_std]
4
5#[cfg(any(test, feature = "alloc"))]
6extern crate alloc;
7
8#[cfg(test)]
9use alloc::format;
10
11use core::cmp::{PartialOrd, Ord, PartialEq, Eq, Ordering};
12use core::iter::FusedIterator;
13
14#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
15enum Sign {
16 Negative, Positive,
17}
18
19#[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq)]
23pub struct Text<'a> {
24 content: &'a str,
25}
26impl<'a> Text<'a> {
27 pub fn read(src: &'a str) -> Option<Self> {
30 if src.chars().next().unwrap_or('\0').is_digit(10) { return None; }
31
32 let mut pos = src.char_indices();
33 loop {
34 match pos.next() {
35 None => return if !src.is_empty() { Some(Self { content: src }) } else { None },
36 Some((i, ch)) => {
37 if (ch.is_ascii_whitespace() || ch.is_ascii_punctuation()) && Number::read(&src[i + 1..]).is_some() {
38 return Some(Self { content: &src[..i + 1] });
39 }
40 if ch.is_digit(10) {
41 return if i != 0 { Some(Self { content: &src[..i] }) } else { None };
42 }
43 }
44 }
45 }
46 }
47 pub fn as_str(&self) -> &'a str { self.content }
49}
50
51#[test]
52fn test_text() {
53 assert_eq!(Text::read("hello world ").map(|v| v.content), Some("hello world "));
54 assert_eq!(Text::read("hello world 7").map(|v| v.content), Some("hello world "));
55 assert_eq!(Text::read("hello world 7").map(|v| v.content), Some("hello world "));
56 assert_eq!(Text::read("hello world -7").map(|v| v.content), Some("hello world "));
57 assert_eq!(Text::read("hello world -7").map(|v| v.content), Some("hello world "));
58 assert_eq!(Text::read("hello world-").map(|v| v.content), Some("hello world-"));
59 assert_eq!(Text::read("hello world-4").map(|v| v.content), Some("hello world-"));
60 assert_eq!(Text::read("hello world--4").map(|v| v.content), Some("hello world-"));
61 assert_eq!(Text::read("hello world---4").map(|v| v.content), Some("hello world--"));
62 assert_eq!(Text::read("hello world----4").map(|v| v.content), Some("hello world---"));
63 assert_eq!(Text::read("hello world").map(|v| v.content), Some("hello world"));
64 assert_eq!(Text::read("hello wor4ld").map(|v| v.content), Some("hello wor"));
65 assert_eq!(Text::read("안영하세요 wor4ld").map(|v| v.content), Some("안영하세요 wor"));
66 assert_eq!(Text::read("h2ell wor4ld").map(|v| v.content), Some("h"));
67 assert_eq!(Text::read("34hello wor4ld").map(|v| v.content), None);
68 assert_eq!(Text::read("-34hello wor4ld").map(|v| v.content), Some("-"));
69 assert_eq!(Text::read("--34hello wor4ld").map(|v| v.content), Some("-"));
70 assert_eq!(Text::read("+-34hello wor4ld").map(|v| v.content), Some("+"));
71 assert_eq!(Text::read("+34hello wor4ld").map(|v| v.content), Some("+"));
72 assert_eq!(Text::read("-+34hello wor4ld").map(|v| v.content), Some("-"));
73 assert_eq!(Text::read("++34hello wor4ld").map(|v| v.content), Some("+"));
74 assert_eq!(Text::read("").map(|v| v.content), None);
75
76 for p in "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~".chars() {
77 assert_eq!(Text::read(&format!("hello world{p}-4")).map(|v| v.content), Some(format!("hello world{p}").as_str()));
78 }
79
80 fn get(v: &str) -> &str { Text::read(v).unwrap().as_str() }
81 assert_eq!(get("hello world"), "hello world");
82 assert_eq!(get("hello wor4ld"), "hello wor");
83 assert_eq!(get("h2ell wor4ld"), "h");
84 assert_eq!(get(" h2ell wor4ld"), " h");
85 assert_eq!(get(" h 2ell wor4ld"), " h ");
86}
87
88#[derive(Debug, Clone, Copy)]
93pub struct Number<'a> {
94 sign: Option<Sign>,
95 leading_zeros: usize,
96 content: &'a str,
97}
98impl<'a> Number<'a> {
99 pub fn read(src: &'a str) -> Option<Self> {
102 let (sign, tail) = match src.chars().next() {
103 Some('+') => (Some(Sign::Positive), &src[1..]),
104 Some('-') => (Some(Sign::Negative), &src[1..]),
105 _ => (None, src),
106 };
107
108 match tail.chars().position(|ch| !ch.is_digit(10)).unwrap_or(tail.len()) {
109 0 => None,
110 stop => {
111 let leading_zeros = tail.chars().position(|ch| ch != '0').unwrap_or(tail.len());
112 Some(Self { sign, leading_zeros, content: &src[..stop + (src.len() - tail.len())] }) }
114 }
115 }
116 pub fn as_str(&self) -> &'a str { self.content }
118}
119impl Ord for Number<'_> {
120 fn cmp(&self, other: &Self) -> Ordering {
121 let t = |x: &Self| (x.content.len() - if x.sign.is_some() { 1 } else { 0 } - x.leading_zeros, &x.content[if x.sign.is_some() { 1 } else { 0 } + x.leading_zeros..]);
122
123 match (self.sign.unwrap_or(Sign::Positive), other.sign.unwrap_or(Sign::Positive)) {
124 (Sign::Positive, Sign::Positive) => t(self).cmp(&t(other)),
125 (Sign::Positive, Sign::Negative) => if t(self).0 == 0 && t(other).0 == 0 { Ordering::Equal } else { Ordering::Greater },
126 (Sign::Negative, Sign::Positive) => if t(self).0 == 0 && t(other).0 == 0 { Ordering::Equal } else { Ordering::Less },
127 (Sign::Negative, Sign::Negative) => t(other).cmp(&t(self)),
128 }
129 }
130}
131impl PartialOrd for Number<'_> { fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.cmp(other)) } }
132impl PartialEq for Number<'_> { fn eq(&self, other: &Self) -> bool { self.cmp(other) == Ordering::Equal } }
133impl Eq for Number<'_> {}
134
135#[test]
136fn test_number() {
137 assert_eq!(Number::read("0").map(|v| (v.content, v.leading_zeros)), Some(("0", 1)));
138 assert_eq!(Number::read("+0").map(|v| (v.content, v.leading_zeros)), Some(("+0", 1)));
139 assert_eq!(Number::read("-0").map(|v| (v.content, v.leading_zeros)), Some(("-0", 1)));
140 assert_eq!(Number::read("00").map(|v| (v.content, v.leading_zeros)), Some(("00", 2)));
141 assert_eq!(Number::read("+00").map(|v| (v.content, v.leading_zeros)), Some(("+00", 2)));
142 assert_eq!(Number::read("-00").map(|v| (v.content, v.leading_zeros)), Some(("-00", 2)));
143 assert_eq!(Number::read("53426").map(|v| (v.content, v.leading_zeros)), Some(("53426", 0)));
144 assert_eq!(Number::read("-53426").map(|v| (v.content, v.leading_zeros)), Some(("-53426", 0)));
145 assert_eq!(Number::read("-53426g").map(|v| (v.content, v.leading_zeros)), Some(("-53426", 0)));
146 assert_eq!(Number::read("-053426").map(|v| (v.content, v.leading_zeros)), Some(("-053426", 1)));
147 assert_eq!(Number::read("-053426f").map(|v| (v.content, v.leading_zeros)), Some(("-053426", 1)));
148 assert_eq!(Number::read("+53426").map(|v| (v.content, v.leading_zeros)), Some(("+53426", 0)));
149 assert_eq!(Number::read("+53426g").map(|v| (v.content, v.leading_zeros)), Some(("+53426", 0)));
150 assert_eq!(Number::read("+053426").map(|v| (v.content, v.leading_zeros)), Some(("+053426", 1)));
151 assert_eq!(Number::read("+053426f").map(|v| (v.content, v.leading_zeros)), Some(("+053426", 1)));
152 assert_eq!(Number::read("053426").map(|v| (v.content, v.leading_zeros)), Some(("053426", 1)));
153 assert_eq!(Number::read("00053426").map(|v| (v.content, v.leading_zeros)), Some(("00053426", 3)));
154 assert_eq!(Number::read("00053d426").map(|v| (v.content, v.leading_zeros)), Some(("00053", 3)));
155 assert_eq!(Number::read("000g53d426").map(|v| (v.content, v.leading_zeros)), Some(("000", 3)));
156 assert_eq!(Number::read("00g53d426").map(|v| (v.content, v.leading_zeros)), Some(("00", 2)));
157 assert_eq!(Number::read("g53d426").map(|v| (v.content, v.leading_zeros)), None);
158
159 assert_eq!(Number::read("2345").unwrap().cmp(&Number::read("2346").unwrap()), Ordering::Less);
160 assert_eq!(Number::read("-2345").unwrap().cmp(&Number::read("-2346").unwrap()), Ordering::Greater);
161 assert_eq!(Number::read("-2345").unwrap().cmp(&Number::read("-2345").unwrap()), Ordering::Equal);
162 assert_eq!(Number::read("-2345").unwrap().cmp(&Number::read("+2345").unwrap()), Ordering::Less);
163 assert_eq!(Number::read("-2345").unwrap().cmp(&Number::read("2345").unwrap()), Ordering::Less);
164 assert_eq!(Number::read("+2345").unwrap().cmp(&Number::read("-2345").unwrap()), Ordering::Greater);
165 assert_eq!(Number::read("2345").unwrap().cmp(&Number::read("-2345").unwrap()), Ordering::Greater);
166 assert_eq!(Number::read("+2345").unwrap().cmp(&Number::read("+2345").unwrap()), Ordering::Equal);
167 assert_eq!(Number::read("+2345").unwrap().cmp(&Number::read("2345").unwrap()), Ordering::Equal);
168 assert_eq!(Number::read("2345").unwrap().cmp(&Number::read("+2345").unwrap()), Ordering::Equal);
169 assert_eq!(Number::read("2345").unwrap().cmp(&Number::read("2345").unwrap()), Ordering::Equal);
170 assert_eq!(Number::read("2345").unwrap().cmp(&Number::read("0002345").unwrap()), Ordering::Equal);
171 assert_eq!(Number::read("234").unwrap().cmp(&Number::read("2345").unwrap()), Ordering::Less);
172 assert_eq!(Number::read("0").unwrap().cmp(&Number::read("0").unwrap()), Ordering::Equal);
173 assert_eq!(Number::read("0").unwrap().cmp(&Number::read("+0").unwrap()), Ordering::Equal);
174 assert_eq!(Number::read("0").unwrap().cmp(&Number::read("-0").unwrap()), Ordering::Equal);
175 assert_eq!(Number::read("+0").unwrap().cmp(&Number::read("0").unwrap()), Ordering::Equal);
176 assert_eq!(Number::read("+0").unwrap().cmp(&Number::read("+0").unwrap()), Ordering::Equal);
177 assert_eq!(Number::read("+0").unwrap().cmp(&Number::read("-0").unwrap()), Ordering::Equal);
178 assert_eq!(Number::read("-0").unwrap().cmp(&Number::read("0").unwrap()), Ordering::Equal);
179 assert_eq!(Number::read("-0").unwrap().cmp(&Number::read("+0").unwrap()), Ordering::Equal);
180 assert_eq!(Number::read("-0").unwrap().cmp(&Number::read("-0").unwrap()), Ordering::Equal);
181 assert_eq!(Number::read("000000234").unwrap().cmp(&Number::read("2345").unwrap()), Ordering::Less);
182 assert_eq!(Number::read("000000234").unwrap().cmp(&Number::read("236521548").unwrap()), Ordering::Less);
183 assert_eq!(Number::read("000000234").unwrap().cmp(&Number::read("000000236521548").unwrap()), Ordering::Less);
184 assert_eq!(Number::read("01000000").unwrap().cmp(&Number::read("000000236521548").unwrap()), Ordering::Less);
185 assert_eq!(Number::read("123").unwrap().cmp(&Number::read("101").unwrap()), Ordering::Greater);
186
187 assert_eq!(Number::read("2345").unwrap(), Number::read("2345").unwrap());
188 assert_eq!(Number::read("2345").unwrap(), Number::read("02345").unwrap());
189 assert_eq!(Number::read("002345").unwrap(), Number::read("2345").unwrap());
190
191 assert_eq!(Number::read(""), None);
192 assert_eq!(Number::read("help"), None);
193 assert_eq!(Number::read("-"), None);
194 assert_eq!(Number::read("+"), None);
195
196 fn get(v: &str) -> &str { Number::read(v).unwrap().as_str() }
197 assert_eq!(get("2345"), "2345");
198 assert_eq!(get("002345"), "002345");
199 assert_eq!(get("00000"), "00000");
200 assert_eq!(get("0"), "0");
201
202 for a in -128..=128 {
203 for b in -128..=128 {
204 assert_eq!(Number::read(&format!("{a}")).unwrap().cmp(&Number::read(&format!("{b}")).unwrap()), a.cmp(&b));
205 assert_eq!(Number::read(&format!("{a}")).unwrap().cmp(&Number::read(&format!("{b:+}")).unwrap()), a.cmp(&b));
206 assert_eq!(Number::read(&format!("{a:+}")).unwrap().cmp(&Number::read(&format!("{b}")).unwrap()), a.cmp(&b));
207 assert_eq!(Number::read(&format!("{a:+}")).unwrap().cmp(&Number::read(&format!("{b:+}")).unwrap()), a.cmp(&b));
208 }
209
210 assert_eq!(Number::read("0").unwrap().cmp(&Number::read(&format!("{a:+}")).unwrap()), 0.cmp(&a));
211 assert_eq!(Number::read("+0").unwrap().cmp(&Number::read(&format!("{a:+}")).unwrap()), 0.cmp(&a));
212 assert_eq!(Number::read("-0").unwrap().cmp(&Number::read(&format!("{a:+}")).unwrap()), 0.cmp(&a));
213
214 assert_eq!(Number::read(&format!("{a:+}")).unwrap().cmp(&Number::read("0").unwrap()), a.cmp(&0));
215 assert_eq!(Number::read(&format!("{a:+}")).unwrap().cmp(&Number::read("+0").unwrap()), a.cmp(&0));
216 assert_eq!(Number::read(&format!("{a:+}")).unwrap().cmp(&Number::read("-0").unwrap()), a.cmp(&0));
217 }
218}
219
220#[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq)]
225pub enum Segment<'a> {
226 Number(Number<'a>),
227 Text(Text<'a>),
228}
229impl<'a> Segment<'a> {
230 pub fn read(src: &'a str, force_text: bool) -> Option<Self> {
234 if !force_text { if let Some(x) = Number::read(src) { return Some(Segment::Number(x)) } }
235 if let Some(x) = Text::read(src) { return Some(Segment::Text(x)) }
236 None
237 }
238 pub fn as_str(&self) -> &'a str {
240 match self {
241 Segment::Text(x) => x.as_str(),
242 Segment::Number(x) => x.as_str(),
243 }
244 }
245 pub fn as_number(&self) -> Option<Number<'a>> {
247 if let Segment::Number(x) = self { Some(*x) } else { None }
248 }
249 pub fn as_text(&self) -> Option<Text<'a>> {
251 if let Segment::Text(x) = self { Some(*x) } else { None }
252 }
253}
254
255#[test]
256fn test_segment() {
257 assert_eq!(Segment::read("00453hello", false).unwrap().as_number().unwrap().as_str(), "00453");
258 assert_eq!(Segment::read("453hello", false).unwrap().as_number().unwrap().as_str(), "453");
259 assert_eq!(Segment::read("000hello", false).unwrap().as_number().unwrap().as_str(), "000");
260 assert_eq!(Segment::read("hello 453", false).unwrap().as_text().unwrap().as_str(), "hello ");
261 assert_eq!(Segment::read(" ", false).unwrap().as_text().unwrap().as_str(), " ");
262 assert_eq!(Segment::read("", false), None);
263
264 fn get(v: &str) -> &str { Segment::read(v, false).unwrap().as_str() }
265 assert_eq!(get("hello 69"), "hello ");
266 assert_eq!(get("453 hello 69"), "453");
267 assert_eq!(get("00453 hello 69"), "00453");
268 assert_eq!(get("000"), "000");
269 assert_eq!(get("abc"), "abc");
270
271 assert_eq!(Segment::read("00000", false).unwrap().cmp(&Segment::read("aaaaa", false).unwrap()), Ordering::Less);
272 assert_eq!(Segment::read("aaaaa", false).unwrap().cmp(&Segment::read("00000", false).unwrap()), Ordering::Greater);
273 assert_eq!(Segment::read("0000", false).unwrap().cmp(&Segment::read("aaaaa", false).unwrap()), Ordering::Less);
274 assert_eq!(Segment::read("aaaa", false).unwrap().cmp(&Segment::read("00000", false).unwrap()), Ordering::Greater);
275 assert_eq!(Segment::read("00000", false).unwrap().cmp(&Segment::read("aaaa", false).unwrap()), Ordering::Less);
276 assert_eq!(Segment::read("aaaaa", false).unwrap().cmp(&Segment::read("0000", false).unwrap()), Ordering::Greater);
277
278 assert_eq!(Segment::read("24", false).unwrap().as_number().unwrap().as_str(), "24");
279 assert_eq!(Segment::read("24", true).is_none(), true);
280
281 assert_eq!(Segment::read("-24", false).unwrap().as_number().unwrap().as_str(), "-24");
282 assert_eq!(Segment::read("-24", true).unwrap().as_text().unwrap().as_str(), "-");
283
284 assert_eq!(Segment::read("+24", false).unwrap().as_number().unwrap().as_str(), "+24");
285 assert_eq!(Segment::read("+24", true).unwrap().as_text().unwrap().as_str(), "+");
286}
287
288#[derive(Clone, Copy)]
292pub struct SegmentIter<'a> {
293 src: &'a str,
294 force_text: bool,
295}
296impl<'a> SegmentIter<'a> {
297 pub fn new(src: &'a str) -> Self {
300 Self { src, force_text: false }
301 }
302 pub fn as_str(&self) -> &'a str {
305 self.src
306 }
307}
308impl<'a> Iterator for SegmentIter<'a> {
309 type Item = Segment<'a>;
310 fn next(&mut self) -> Option<Self::Item> {
311 let res = Segment::read(self.src, self.force_text)?;
312 self.force_text = res.as_number().is_some();
313 self.src = &self.src[res.as_str().len()..];
314 Some(res)
315 }
316}
317impl FusedIterator for SegmentIter<'_> {}
318
319#[test]
320fn test_segment_iter() {
321 let mut seq = SegmentIter::new("34543hello this is 00343 2 a test");
322 assert_eq!(seq.as_str(), "34543hello this is 00343 2 a test");
323 assert_eq!(seq.next().unwrap().as_number().unwrap().as_str(), "34543");
324 assert_eq!(seq.as_str(), "hello this is 00343 2 a test");
325 assert_eq!(seq.next().unwrap().as_text().unwrap().as_str(), "hello this is ");
326 assert_eq!(seq.as_str(), "00343 2 a test");
327 assert_eq!(seq.next().unwrap().as_number().unwrap().as_str(), "00343");
328 assert_eq!(seq.as_str(), " 2 a test");
329 assert_eq!(seq.next().unwrap().as_text().unwrap().as_str(), " ");
330 assert_eq!(seq.as_str(), "2 a test");
331 assert_eq!(seq.next().unwrap().as_number().unwrap().as_str(), "2");
332 assert_eq!(seq.as_str(), " a test");
333 assert_eq!(seq.next().unwrap().as_text().unwrap().as_str(), " a test");
334 assert_eq!(seq.as_str(), "");
335 for _ in 0..16 {
336 assert!(seq.next().is_none());
337 assert_eq!(seq.as_str(), "");
338 }
339
340 fn get(v: &str) -> &str { SegmentIter::new(v).as_str() }
341 assert_eq!(get("hello world"), "hello world");
342}
343
344pub fn cmp(a: &str, b: &str) -> Ordering {
358 SegmentIter::new(a).cmp(SegmentIter::new(b))
359}
360
361#[test]
362fn test_cmp() {
363 assert_eq!(cmp("hello-456", "hello-0999"), Ordering::Less);
364 assert_eq!(cmp("hellos-456", "hello-0999"), Ordering::Greater);
365 assert_eq!(cmp("hello--456", "hello-0999"), Ordering::Less);
366 assert_eq!(cmp("v1.4.12.3", "v1.4.4.3"), Ordering::Greater);
367 assert_eq!(cmp("val[-1]", "val[0]"), Ordering::Less);
368 assert_eq!(cmp("val[-1]", "val[2]"), Ordering::Less);
369 assert_eq!(cmp("val -1", "val 0"), Ordering::Less);
370 assert_eq!(cmp("val -1", "val 2"), Ordering::Less);
371
372 assert_eq!(cmp("2024-10-22", "2024-9-22"), Ordering::Greater);
373 assert_eq!(cmp("2024-6-22", "2024-10-22"), Ordering::Less);
374 assert_eq!(cmp("2024-10-22", "2024-10-22"), Ordering::Equal);
375 assert_eq!(cmp("2024-10-22", "2024-11-22"), Ordering::Less);
376 assert_eq!(cmp("2024-10-22", "2024-10-6"), Ordering::Greater);
377 assert_eq!(cmp("2024-10-22", "2024-10-06"), Ordering::Greater);
378 assert_eq!(cmp("2024-10-22", "300-10-22"), Ordering::Greater);
379 assert_eq!(cmp("2024-10-22", "03000-10-22"), Ordering::Less);
380
381 assert_eq!(cmp("2024+10+22", "2024+9+22"), Ordering::Greater);
382 assert_eq!(cmp("2024+6+22", "2024+10+22"), Ordering::Less);
383 assert_eq!(cmp("2024+10+22", "2024+10+22"), Ordering::Equal);
384 assert_eq!(cmp("2024+10+22", "2024+11+22"), Ordering::Less);
385 assert_eq!(cmp("2024+10+22", "2024+10+6"), Ordering::Greater);
386 assert_eq!(cmp("2024+10+22", "2024+10+06"), Ordering::Greater);
387 assert_eq!(cmp("2024+10+22", "300+10+22"), Ordering::Greater);
388 assert_eq!(cmp("2024+10+22", "03000+10+22"), Ordering::Less);
389
390 assert_eq!(cmp("2024/10/22", "2024/9/22"), Ordering::Greater);
391 assert_eq!(cmp("2024/6/22", "2024/10/22"), Ordering::Less);
392 assert_eq!(cmp("2024/10/22", "2024/10/22"), Ordering::Equal);
393 assert_eq!(cmp("2024/10/22", "2024/11/22"), Ordering::Less);
394 assert_eq!(cmp("2024/10/22", "2024/10/6"), Ordering::Greater);
395 assert_eq!(cmp("2024/10/22", "2024/10/06"), Ordering::Greater);
396 assert_eq!(cmp("2024/10/22", "300/10/22"), Ordering::Greater);
397 assert_eq!(cmp("2024/10/22", "03000/10/22"), Ordering::Less);
398}
399
400#[cfg(feature = "alloc")]
412pub fn sort<T: AsRef<str>>(arr: &mut [T]) {
413 arr.sort_by(|a, b| cmp(a.as_ref(), b.as_ref())) }
415
416pub fn sort_unstable<T: AsRef<str>>(arr: &mut [T]) {
420 arr.sort_unstable_by(|a, b| cmp(a.as_ref(), b.as_ref()))
421}
422
423#[test]
424#[cfg(feature = "alloc")]
425fn test_sort() {
426 use alloc::borrow::ToOwned;
427
428 macro_rules! sorted { ($in:expr) => {{ let mut v = $in; sort(&mut v); v }} }
429 assert_eq!(&sorted!(["file-1", "file-10", "file-2"]), &["file-1", "file-2", "file-10"]);
430 assert_eq!(&sorted!(["file-1".to_owned(), "file-10".to_owned(), "file-2".to_owned()]), &["file-1", "file-2", "file-10"]);
431
432 macro_rules! sorted_unstable { ($in:expr) => {{ let mut v = $in; sort_unstable(&mut v); v }} }
433 assert_eq!(&sorted_unstable!(["file-1", "file-10", "file-2"]), &["file-1", "file-2", "file-10"]);
434 assert_eq!(&sorted_unstable!(["file-1".to_owned(), "file-10".to_owned(), "file-2".to_owned()]), &["file-1", "file-2", "file-10"]);
435}
436
437#[test]
438fn test_sort_unstable() {
439 macro_rules! sorted_unstable { ($in:expr) => {{ let mut v = $in; sort_unstable(&mut v); v }} }
440 assert_eq!(&sorted_unstable!(["file-1", "file-10", "file-2"]), &["file-1", "file-2", "file-10"]);
441}