Skip to main content

nanvm_lib/vm/string/
partial_eq.rs

1use crate::{
2    common::sized_index::SizedIndex,
3    vm::{IContainer, IVm, String},
4};
5
6impl<A: IVm> PartialEq for String<A> {
7    fn eq(&self, other: &Self) -> bool {
8        self.0.items_eq(&other.0)
9    }
10}
11
12impl<A: IVm> String<A> {
13    /// Whether `self` is `s`, code unit by code unit against its UTF-16
14    /// encoding, without building a VM string from the literal โ€” the
15    /// question every built-in name lookup asks.
16    ///
17    /// An inherent method, not `PartialEq<str>`: a second `PartialEq`
18    /// impl would leave every `s == "x".into()` in the crate without a
19    /// target type for `into`.
20    pub(crate) fn is_str(&self, s: &str) -> bool {
21        (0..self.length()).map(|i| self[i]).eq(s.encode_utf16())
22    }
23}
24
25#[cfg(test)]
26mod tests {
27    use crate::{
28        naive::Naive,
29        vm::{String, ToString},
30    };
31
32    type A = Naive;
33
34    #[test]
35    fn is_str() {
36        let s: String<A> = "length".into();
37        assert!(s.is_str("length"));
38        assert!(!s.is_str("lengt"));
39        assert!(!s.is_str("lengths"));
40        assert!(!s.is_str(""));
41        let empty: String<A> = "".into();
42        assert!(empty.is_str(""));
43        assert!(!empty.is_str("a"));
44    }
45
46    /// The literal is compared as UTF-16, as the VM string holds it: a
47    /// character outside the BMP is its surrogate pair, and a lone
48    /// surrogate, which no `&str` spells, equals nothing.
49    #[test]
50    fn is_str_utf16() {
51        let pair: String<A> = "๐Ÿ˜€".into();
52        assert!(pair.is_str("๐Ÿ˜€"));
53        let lone: String<A> = [0xD83D].to_string();
54        assert!(!lone.is_str("๐Ÿ˜€"));
55        assert!(!lone.is_str("\u{FFFD}"));
56    }
57}