Skip to main content

nanvm_lib/vm/string/
cmp.rs

1use core::cmp::Ordering;
2
3use crate::{
4    common::sized_index::SizedIndex,
5    vm::{IVm, String},
6};
7
8/// Lexicographic order by UTF-16 code unit — `String::lessThan`, the rule
9/// `<` uses when both operands are strings. Not codepoint-aware: a
10/// surrogate pair is compared unit by unit, the same as any other pair of
11/// code units, never combined into one codepoint first.
12impl<A: IVm> PartialOrd for String<A> {
13    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
14        Some(self.cmp(other))
15    }
16}
17
18impl<A: IVm> Eq for String<A> {}
19
20impl<A: IVm> Ord for String<A> {
21    fn cmp(&self, other: &Self) -> Ordering {
22        self.clone().index_iter().cmp(other.clone())
23    }
24}
25
26#[cfg(test)]
27mod tests {
28    use crate::naive::Naive;
29
30    type T = super::String<Naive>;
31
32    fn s(v: &str) -> T {
33        v.into()
34    }
35
36    #[test]
37    fn equal_strings() {
38        assert_eq!(s("abc").cmp(&s("abc")), core::cmp::Ordering::Equal);
39    }
40
41    #[test]
42    fn shorter_prefix_is_less() {
43        assert!(s("ab") < s("abc"));
44        assert!(s("abc") > s("ab"));
45    }
46
47    #[test]
48    fn first_differing_unit_decides() {
49        assert!(s("10") < s("9"));
50        assert!(s("a") < s("b"));
51        assert!(s("B") < s("a"));
52    }
53
54    #[test]
55    fn empty_string_is_least() {
56        assert!(s("") < s("a"));
57    }
58}