scalar_value_string/
sv_string.rs

1use std::{
2    cmp::Ordering,
3    collections::{HashMap},
4    sync::{Arc, Weak, Mutex},
5    ops::{
6        Range,
7        RangeFull,
8        RangeInclusive,
9        RangeFrom,
10        RangeTo,
11        RangeToInclusive, Add,
12    }, fmt::{Debug, Display},
13};
14use once_cell::sync::Lazy;
15use super::character_validation::is_whitespace;
16
17pub type SvStringMap<V> = std::collections::BTreeMap<SvString, V>;
18pub type SvStringSet = std::collections::BTreeSet<SvString>;
19
20static INTERN_LIMIT: i32 = 512;
21
22static INTERNED: Lazy<Mutex<HashMap<i32, Vec<Weak<StringRepr0>>>>> = Lazy::new(|| {
23    Mutex::new(HashMap::new())
24});
25
26fn intern(s: Arc<StringRepr0>) -> Arc<StringRepr0> {
27    if s.m_len > INTERN_LIMIT {
28        return s.clone();
29    }
30    let p1 = &mut *INTERNED.lock().unwrap();
31    let mut p2 = p1.get_mut(&s.m_len);
32    let v = vec![];
33    if p2.is_none() {
34        p1.insert(s.m_len, v);
35        p2 = p1.get_mut(&s.m_len);
36    }
37    let p2 = p2.unwrap();
38    for s2 in p2.iter() {
39        let s2 = s2.upgrade().unwrap();
40        if s == s2 {
41            return s2.clone();
42        }
43    }
44    p2.push(Arc::downgrade(&s));
45    s.clone()
46}
47
48/// SvString data type. This string type consists of Unicode Scalar Value.
49/// The `len()` method returns the number of characters in
50/// Unicode Scalar Value.
51#[derive(Clone, Ord)]
52pub struct SvString {
53    m_repr: Arc<StringRepr0>,
54}
55
56impl Eq for SvString {
57}
58
59#[derive(Clone)]
60struct StringRepr0 {
61    m_len: i32,
62    m_repr: StringRepr1,
63}
64
65impl Ord for StringRepr0 {
66    fn cmp(&self, other: &Self) -> Ordering {
67        self.partial_cmp(other).unwrap_or(Ordering::Equal)
68    }
69}
70
71impl Eq for StringRepr0 {
72}
73
74impl Drop for StringRepr0 {
75    fn drop(&mut self) {
76        if self.m_len > INTERN_LIMIT {
77            return;
78        }
79        let p1 = &mut *INTERNED.lock().unwrap();
80        let p2 = p1.get_mut(&self.m_len);
81        if p2.is_none() {
82            return;
83        }
84        let p2 = p2.unwrap();
85        let mut i: usize = 0;
86        let mut f: Vec<usize> = vec![];
87        for s2 in p2.iter() {
88            if s2.upgrade().is_none() {
89                f.push(i);
90            }
91            i += 1;
92        }
93        for &i in f.iter().rev() {
94            p2.remove(i);
95        }
96        if p2.len() == 0 {
97            p1.remove(&self.m_len);
98        }
99    }
100}
101
102#[derive(Clone)]
103enum StringRepr1 {
104    Reference(Arc<StringRepr2>),
105    Slice(Slice),
106}
107
108impl StringRepr1 {
109    fn char_at(&self, index: usize) -> char {
110        match self {
111            StringRepr1::Reference(r) => r.char_at(index),
112            StringRepr1::Slice(s) => s.container.char_at(s.start + index),
113        }
114    }
115}
116
117#[derive(Clone)]
118struct Slice {
119    container: Arc<StringRepr2>,
120    start: usize,
121    end: usize,
122}
123
124impl PartialEq for Slice {
125    fn eq(&self, other: &Self) -> bool {
126        if (self.end - self.start) != (other.end - other.start) {
127            return false;
128        }
129        let mut l_i = self.start;
130        let mut r_i = other.start;
131        match self.container.as_ref() {
132            StringRepr2::Latin1(l) => {
133                match other.container.as_ref() {
134                    StringRepr2::Latin1(r) => {
135                        while l_i < self.end {
136                            if l[l_i] != r[r_i] {
137                                return false;
138                            }
139                            l_i += 1;
140                            r_i += 1;
141                        }
142                        true
143                    },
144                    StringRepr2::Ucs2(r) => {
145                        while l_i < self.end {
146                            if (l[l_i] as u16) != r[r_i] {
147                                return false;
148                            }
149                            l_i += 1;
150                            r_i += 1;
151                        }
152                        true
153                    },
154                    StringRepr2::Ucs4(r) => {
155                        while l_i < self.end {
156                            if (l[l_i] as u32) != r[r_i] {
157                                return false;
158                            }
159                            l_i += 1;
160                            r_i += 1;
161                        }
162                        true
163                    },
164                }
165            },
166            StringRepr2::Ucs2(l) => {
167                match other.container.as_ref() {
168                    StringRepr2::Latin1(r) => {
169                        while l_i < self.end {
170                            if l[l_i] != (r[r_i] as u16) {
171                                return false;
172                            }
173                            l_i += 1;
174                            r_i += 1;
175                        }
176                        true
177                    },
178                    StringRepr2::Ucs2(r) => {
179                        while l_i < self.end {
180                            if l[l_i] != r[r_i] {
181                                return false;
182                            }
183                            l_i += 1;
184                            r_i += 1;
185                        }
186                        true
187                    },
188                    StringRepr2::Ucs4(r) => {
189                        while l_i < self.end {
190                            if (l[l_i] as u32) != r[r_i] {
191                                return false;
192                            }
193                            l_i += 1;
194                            r_i += 1;
195                        }
196                        true
197                    },
198                }
199            },
200            StringRepr2::Ucs4(l) => {
201                match other.container.as_ref() {
202                    StringRepr2::Latin1(r) => {
203                        while l_i < self.end {
204                            if l[l_i] != (r[r_i] as u32) {
205                                return false;
206                            }
207                            l_i += 1;
208                            r_i += 1;
209                        }
210                        true
211                    },
212                    StringRepr2::Ucs2(r) => {
213                        while l_i < self.end {
214                            if l[l_i] != (r[r_i] as u32) {
215                                return false;
216                            }
217                            l_i += 1;
218                            r_i += 1;
219                        }
220                        true
221                    },
222                    StringRepr2::Ucs4(r) => {
223                        while l_i < self.end {
224                            if l[l_i] != r[r_i] {
225                                return false;
226                            }
227                            l_i += 1;
228                            r_i += 1;
229                        }
230                        true
231                    },
232                }
233            },
234        }
235    }
236}
237
238#[derive(Clone)]
239enum StringRepr2 {
240    Latin1(Vec<u8>),
241    Ucs2(Vec<u16>),
242    Ucs4(Vec<u32>),
243}
244
245impl StringRepr2 {
246    fn len(&self) -> usize {
247        match self {
248            StringRepr2::Latin1(v) => v.len(),
249            StringRepr2::Ucs2(v) => v.len(),
250            StringRepr2::Ucs4(v) => v.len(),
251        }
252    }
253
254    fn char_at(&self, index: usize) -> char {
255        match self {
256            StringRepr2::Latin1(v) => v[index] as char,
257            StringRepr2::Ucs2(v) => char::from_u32(v[index] as u32).unwrap_or('\x00'),
258            StringRepr2::Ucs4(v) => char::from_u32(v[index]).unwrap_or('\x00'),
259        }
260    }
261}
262
263impl PartialEq for StringRepr2 {
264    fn eq(&self, other: &Self) -> bool {
265        match self {
266            StringRepr2::Latin1(l) => {
267                match other {
268                    StringRepr2::Latin1(r) => {
269                        l.eq(r)
270                    },
271                    StringRepr2::Ucs2(r) => {
272                        l.iter().map(|&e| e as u16).collect::<Vec<u16>>().eq(r)
273                    },
274                    StringRepr2::Ucs4(r) => {
275                        l.iter().map(|&e| e as u32).collect::<Vec<u32>>().eq(r)
276                    },
277                }
278            },
279            StringRepr2::Ucs2(l) => {
280                match other {
281                    StringRepr2::Latin1(r) => {
282                        r.iter().map(|&e| e as u16).collect::<Vec<u16>>().eq(l)
283                    },
284                    StringRepr2::Ucs2(r) => {
285                        l.eq(r)
286                    },
287                    StringRepr2::Ucs4(r) => {
288                        l.iter().map(|&e| e as u32).collect::<Vec<u32>>().eq(r)
289                    },
290                }
291            },
292            StringRepr2::Ucs4(l) => {
293                match other {
294                    StringRepr2::Latin1(r) => {
295                        r.iter().map(|&e| e as u32).collect::<Vec<u32>>().eq(l)
296                    },
297                    StringRepr2::Ucs2(r) => {
298                        r.iter().map(|&e| e as u32).collect::<Vec<u32>>().eq(l)
299                    },
300                    StringRepr2::Ucs4(r) => {
301                        l.eq(r)
302                    },
303                }
304            },
305        }
306    }
307}
308
309impl PartialEq for SvString {
310    fn eq(&self, other: &Self) -> bool {
311        self.m_repr == other.m_repr
312    }
313}
314
315impl PartialEq for StringRepr0 {
316    fn eq(&self, other: &Self) -> bool {
317        match &self.m_repr {
318            StringRepr1::Reference(l) => {
319                match &other.m_repr {
320                    StringRepr1::Reference(r) => {
321                        Arc::ptr_eq(l, r) || l == r
322                    },
323                    StringRepr1::Slice(r) => {
324                        are_reference_and_slice_eq(l, r)
325                    },
326                }
327            },
328            StringRepr1::Slice(l) => {
329                match &other.m_repr {
330                    StringRepr1::Reference(r) => {
331                        are_reference_and_slice_eq(r, l)
332                    },
333                    StringRepr1::Slice(r) => {
334                        l == r
335                    },
336                }
337            },
338        }
339    }
340}
341
342fn are_reference_and_slice_eq(l: &Arc<StringRepr2>, r: &Slice) -> bool {
343    let l_l = l.len();
344    if l_l != (r.end - r.start) {
345        return false;
346    }
347    let mut l_i = 0;
348    let mut r_i = r.start;
349    match l.as_ref() {
350        StringRepr2::Latin1(l) => {
351            match r.container.as_ref() {
352                StringRepr2::Latin1(r) => {
353                    while l_i < l_l {
354                        if l[l_i] != r[r_i] {
355                            return false;
356                        }
357                        l_i += 1;
358                        r_i += 1;
359                    }
360                    true
361                },
362                StringRepr2::Ucs2(r) => {
363                    while l_i < l_l {
364                        if (l[l_i] as u16) != r[r_i] {
365                            return false;
366                        }
367                        l_i += 1;
368                        r_i += 1;
369                    }
370                    true
371                },
372                StringRepr2::Ucs4(r) => {
373                    while l_i < l_l {
374                        if (l[l_i] as u32) != r[r_i] {
375                            return false;
376                        }
377                        l_i += 1;
378                        r_i += 1;
379                    }
380                    true
381                },
382            }
383        },
384        StringRepr2::Ucs2(l) => {
385            match r.container.as_ref() {
386                StringRepr2::Latin1(r) => {
387                    while l_i < l_l {
388                        if l[l_i] != (r[r_i] as u16) {
389                            return false;
390                        }
391                        l_i += 1;
392                        r_i += 1;
393                    }
394                    true
395                },
396                StringRepr2::Ucs2(r) => {
397                    while l_i < l_l {
398                        if l[l_i] != r[r_i] {
399                            return false;
400                        }
401                        l_i += 1;
402                        r_i += 1;
403                    }
404                    true
405                },
406                StringRepr2::Ucs4(r) => {
407                    while l_i < l_l {
408                        if (l[l_i] as u32) != r[r_i] {
409                            return false;
410                        }
411                        l_i += 1;
412                        r_i += 1;
413                    }
414                    true
415                },
416            }
417        },
418        StringRepr2::Ucs4(l) => {
419            match r.container.as_ref() {
420                StringRepr2::Latin1(r) => {
421                    while l_i < l_l {
422                        if l[l_i] != (r[r_i] as u32) {
423                            return false;
424                        }
425                        l_i += 1;
426                        r_i += 1;
427                    }
428                    true
429                },
430                StringRepr2::Ucs2(r) => {
431                    while l_i < l_l {
432                        if l[l_i] != (r[r_i] as u32) {
433                            return false;
434                        }
435                        l_i += 1;
436                        r_i += 1;
437                    }
438                    true
439                },
440                StringRepr2::Ucs4(r) => {
441                    while l_i < l_l {
442                        if l[l_i] != r[r_i] {
443                            return false;
444                        }
445                        l_i += 1;
446                        r_i += 1;
447                    }
448                    true
449                },
450            }
451        },
452    }
453}
454
455impl PartialOrd for SvString {
456    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
457        self.m_repr.partial_cmp(&other.m_repr)
458    }
459}
460
461impl PartialOrd for StringRepr0 {
462    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
463        let mut l: Option<&StringRepr2> = None;
464        let mut l_i: usize = 0;
465        let mut l_l: usize = 0;
466        let mut r: Option<&StringRepr2> = None;
467        let mut r_i: usize = 0;
468        let mut r_l: usize = 0;
469        match &self.m_repr {
470            StringRepr1::Reference(v) => {
471                l_l = v.len();
472                l = Some(v.as_ref());
473            },
474            StringRepr1::Slice(s) => {
475                l = Some(s.container.as_ref());
476                l_i = s.start;
477                l_l = s.end;
478            },
479        }
480        match &other.m_repr {
481            StringRepr1::Reference(v) => {
482                r_l = v.len();
483                r = Some(v.as_ref());
484            },
485            StringRepr1::Slice(s) => {
486                r = Some(s.container.as_ref());
487                r_i = s.start;
488                r_l = s.end;
489            },
490        }
491        let l = l.unwrap();
492        let r = r.unwrap();
493        loop {
494            if l_i >= l_l {
495                return Some(Ordering::Less);
496            }
497            if r_i >= r_l {
498                return Some(Ordering::Greater);
499            }
500            let l_char = l.char_at(l_i);
501            let r_char = r.char_at(r_i);
502            if l_char < r_char {
503                return Some(Ordering::Less);
504            }
505            if l_char > r_char {
506                return Some(Ordering::Greater);
507            }
508            l_i += 1;
509            r_i += 1;
510        }
511        #[allow(unreachable_code)]
512        Some(Ordering::Equal)
513    }
514}
515
516impl From<char> for SvString {
517    fn from(value: char) -> Self {
518        SvString::from(value.to_string())
519    }
520}
521
522impl From<String> for SvString {
523    fn from(value: String) -> Self {
524        SvString::from(value.as_ref())
525    }
526}
527
528impl From<&str> for SvString {
529    fn from(value: &str) -> Self {
530        let mut r: Vec<char> = vec![];
531        // largest Unicode ordinal
532        let mut max_ordinal: char = '\x00';
533        for c in value.chars() {
534            r.push(c);
535            max_ordinal = char::max(c, max_ordinal);
536        }
537        SvString {
538            m_repr: intern(Arc::new(if max_ordinal < '\u{100}' {
539                StringRepr0 {
540                    m_len: r.len() as i32,
541                    m_repr: StringRepr1::Reference(
542                        Arc::new(StringRepr2::Latin1(r.iter().map(|&c| c as u8).collect()))
543                    ),
544                }
545            } else if max_ordinal < '\u{10000}' {
546                StringRepr0 {
547                    m_len: r.len() as i32,
548                    m_repr: StringRepr1::Reference(
549                        Arc::new(StringRepr2::Ucs2(r.iter().map(|&c| c as u16).collect()))
550                    ),
551                }
552            } else {
553                StringRepr0 {
554                    m_len: r.len() as i32,
555                    m_repr: StringRepr1::Reference(
556                        Arc::new(StringRepr2::Ucs4(r.iter().map(|&c| c as u32).collect()))
557                    ),
558                }
559            })),
560        }
561    }
562}
563
564impl From<Vec<char>> for SvString {
565    fn from(r: Vec<char>) -> Self {
566        // largest Unicode ordinal
567        let mut max_ordinal: char = '\x00';
568        for &c in r.iter() {
569            max_ordinal = char::max(c, max_ordinal);
570        }
571        SvString {
572            m_repr: intern(Arc::new(if max_ordinal < '\u{100}' {
573                StringRepr0 {
574                    m_len: r.len() as i32,
575                    m_repr: StringRepr1::Reference(
576                        Arc::new(StringRepr2::Latin1(r.iter().map(|&c| c as u8).collect()))
577                    ),
578                }
579            } else if max_ordinal < '\u{10000}' {
580                StringRepr0 {
581                    m_len: r.len() as i32,
582                    m_repr: StringRepr1::Reference(
583                        Arc::new(StringRepr2::Ucs2(r.iter().map(|&c| c as u16).collect()))
584                    ),
585                }
586            } else {
587                StringRepr0 {
588                    m_len: r.len() as i32,
589                    m_repr: StringRepr1::Reference(
590                        Arc::new(StringRepr2::Ucs4(r.iter().map(|&c| c as u32).collect()))
591                    ),
592                }
593            })),
594        }
595    }
596}
597
598impl SvString {
599    /// Empty string.
600    pub fn empty() -> Self {
601        Self {
602            m_repr: intern(Arc::new(StringRepr0 {
603                m_len: 0,
604                m_repr: StringRepr1::Reference(Arc::new(StringRepr2::Latin1(vec![]))),
605            })),
606        }
607    }
608
609    /// Length in Unicode Scalar Value.
610    pub fn len(&self) -> i32 {
611        self.m_repr.m_len
612    }
613
614    /// Converts this string into `String` type.
615    pub fn to_standard_string(&self) -> String {
616        self.chars().collect()
617    }
618
619    /// Obtains character at given position. If the index is out of bounds,
620    /// this method returns `'\x00'`.
621    pub fn char_at(&self, index: i32) -> char {
622        if index >= 0 && index < self.m_repr.m_len { self.m_repr.m_repr.char_at(index as usize) } else { '\x00' }
623    }
624
625    /// Iterates over each character.
626    pub fn chars(&self) -> impl Iterator<Item = char> + '_ {
627        match &&self.m_repr.m_repr {
628            StringRepr1::Reference(r) => {
629                CharIterator {
630                    container: r.as_ref(),
631                    index: 0,
632                    lim: r.len(),
633                }
634            },
635            StringRepr1::Slice(s) => {
636                CharIterator {
637                    container: s.container.as_ref(),
638                    index: s.start,
639                    lim: s.end,
640                }
641            },
642        }
643    }
644
645    /// Concatenates two strings.
646    pub fn concat(&self, other: impl AnySvStringType) -> SvString {
647        let other = other.convert();
648        let mut r: Vec<char> = vec![];
649        // largest Unicode ordinal
650        let mut max_ordinal: char = '\x00';
651        for ch in self.chars() {
652            r.push(ch);
653            max_ordinal = char::max(ch, max_ordinal);
654        }
655        for ch in other.chars() {
656            r.push(ch);
657            max_ordinal = char::max(ch, max_ordinal);
658        }
659        SvString {
660            m_repr: intern(Arc::new(if max_ordinal < '\u{100}' {
661                StringRepr0 {
662                    m_len: r.len() as i32,
663                    m_repr: StringRepr1::Reference(
664                        Arc::new(StringRepr2::Latin1(r.iter().map(|&c| c as u8).collect()))
665                    ),
666                }
667            } else if max_ordinal < '\u{10000}' {
668                StringRepr0 {
669                    m_len: r.len() as i32,
670                    m_repr: StringRepr1::Reference(
671                        Arc::new(StringRepr2::Ucs2(r.iter().map(|&c| c as u16).collect()))
672                    ),
673                }
674            } else {
675                StringRepr0 {
676                    m_len: r.len() as i32,
677                    m_repr: StringRepr1::Reference(
678                        Arc::new(StringRepr2::Ucs4(r.iter().map(|&c| c as u32).collect()))
679                    ),
680                }
681            })),
682        }
683    }
684
685    /// Determines whether the string contains another string.
686    pub fn contains(&self, other: impl AnySvStringType) -> bool {
687        self.index_of(other) != -1
688    }
689
690    /// Determines whether the string starts with another string.
691    pub fn starts_with(&self, other: impl AnySvStringType) -> bool {
692        let other = other.convert();
693        for i in 0..other.len() {
694            if i >= self.len() || self.char_at(i) != other.char_at(i) {
695                return false;
696            }
697        }
698        true
699    }
700
701    /// Determines whether the string ends with another string.
702    pub fn ends_with(&self, other: impl AnySvStringType) -> bool {
703        let other = other.convert();
704        let mut i = other.len() - 1;
705        let mut j = self.len() - 1;
706        while i >= 0 {
707            if j < 0 || self.char_at(j) != other.char_at(i) {
708                return false;
709            }
710            i -= 1;
711            j -= 1;
712        }
713        true
714    }
715
716    /// Finds the index of the given string. If the argument is not found,
717    /// this method returns `-1`.
718    pub fn index_of(&self, other: impl AnySvStringType) -> i32 {
719        let other = other.convert();
720        let mut remaining = other.chars();
721        let mut i: i32 = 0;
722        let mut j: i32 = -1;
723        for ch in self.chars() {
724            if j == -1 {
725                j = i;
726            }
727            let remaining_ch = remaining.next();
728            if remaining_ch.is_none() {
729                break;
730            }
731            if ch != remaining_ch.unwrap() {
732                remaining = other.chars();
733                j = -1;
734            }
735            i += 1;
736        }
737        if remaining.next().is_none() { j } else { -1 }
738    }
739
740    /// Finds the last index of the given string. If the argument is not found,
741    /// this method returns `-1`.
742    pub fn last_index_of(&self, other: impl AnySvStringType) -> i32 {
743        let other = other.convert();
744        if other.m_repr.m_len == 0 {
745            return self.m_repr.m_len;
746        }
747        let mut remaining = other.chars();
748        let mut i: i32 = 0;
749        let mut j: i32 = -1;
750        let mut r: Vec<i32> = vec![];
751        for ch in self.chars() {
752            if j == -1 {
753                j = i;
754            }
755            let remaining_ch = remaining.next();
756            if remaining_ch.is_none() {
757                r.push(j);
758                remaining = other.chars();
759                j = -1;
760            }
761            if ch != remaining_ch.unwrap() {
762                remaining = other.chars();
763                j = -1;
764            }
765            i += 1;
766        }
767        if r.len() > 0 { r[r.len() - 1] } else { -1 }
768    }
769
770    /// Determines whether the string is empty.
771    pub fn is_empty(&self) -> bool {
772        self.m_repr.m_len == 0
773    }
774
775    /// Repeats the string _n_ times.
776    pub fn repeat(&self, n: i32) -> SvString {
777        if n < 1 {
778            return SvString::empty();
779        }
780        let v = self.chars().collect::<Vec<char>>();
781        let mut r: Vec<char> = vec![];
782        // largest Unicode ordinal
783        let mut max_ordinal: char = '\x00';
784        for _ in 0..n {
785            for &ch in v.iter() {
786                r.push(ch);
787                max_ordinal = char::max(ch, max_ordinal);
788            }
789        }
790        SvString {
791            m_repr: intern(Arc::new(if max_ordinal < '\u{100}' {
792                StringRepr0 {
793                    m_len: r.len() as i32,
794                    m_repr: StringRepr1::Reference(
795                        Arc::new(StringRepr2::Latin1(r.iter().map(|&c| c as u8).collect()))
796                    ),
797                }
798            } else if max_ordinal < '\u{10000}' {
799                StringRepr0 {
800                    m_len: r.len() as i32,
801                    m_repr: StringRepr1::Reference(
802                        Arc::new(StringRepr2::Ucs2(r.iter().map(|&c| c as u16).collect()))
803                    ),
804                }
805            } else {
806                StringRepr0 {
807                    m_len: r.len() as i32,
808                    m_repr: StringRepr1::Reference(
809                        Arc::new(StringRepr2::Ucs4(r.iter().map(|&c| c as u32).collect()))
810                    ),
811                }
812            })),
813        }
814    }
815
816    /// Converts string to lowercase.
817    pub fn to_lowercase(&self) -> SvString {
818        SvString::from(self.to_standard_string().to_lowercase())
819    }
820
821    /// Converts string to uppercase.
822    pub fn to_uppercase(&self) -> SvString {
823        SvString::from(self.to_standard_string().to_uppercase())
824    }
825
826    /// Extracts a substring.
827    pub fn substr(&self, index: impl SvSubstringIndex) -> SvString {
828        self.covered_substring(index.from_index(), index.to_index())
829    }
830
831    /// Extracts a substring.
832    pub fn substr_with_length(&self, mut from: i32, mut len: i32) -> SvString {
833        from = i32::max(0, from);
834        from = i32::min(from, self.m_repr.m_len);
835        len = i32::max(0, len);
836        if from + len >= self.m_repr.m_len {
837            self.substr(from..)
838        } else {
839            self.substr(from..(from + len))
840        }
841    }
842
843    fn covered_substring(&self, mut from: i32, mut to: i32) -> SvString {
844        from = i32::max(0, from);
845        from = i32::min(from, self.m_repr.m_len);
846        to = i32::max(0, to);
847        to = i32::min(to, self.m_repr.m_len);
848        if to < from {
849            let k = from;
850            from = to;
851            to = k;
852        }
853        match &self.m_repr.m_repr {
854            StringRepr1::Reference(r) => {
855                SvString {
856                    m_repr: intern(Arc::new(StringRepr0 {
857                        m_len: to - from,
858                        m_repr: StringRepr1::Slice(Slice {
859                            container: r.clone(),
860                            start: from as usize,
861                            end: to as usize,
862                        }),
863                    }))
864                }
865            },
866            StringRepr1::Slice(slice) => {
867                SvString {
868                    m_repr: intern(Arc::new(StringRepr0 {
869                        m_len: to - from,
870                        m_repr: StringRepr1::Slice(Slice {
871                            container: slice.container.clone(),
872                            start: slice.start + (from as usize),
873                            end: slice.start + (to as usize),
874                        }),
875                    }))
876                }
877            },
878        }
879    }
880
881    /// Removes leading and trailing whitespace.
882    pub fn trim(&self) -> SvString {
883        let mut i: i32 = 0;
884        while is_whitespace(self.char_at(i)) {
885            i += 1;
886        }
887        let mut j: i32 = self.len();
888        while is_whitespace(self.char_at(j - 1)) {
889            j -= 1;
890        }
891        self.substr(i..j)
892    }
893
894    /// Removes leading whitespace.
895    pub fn trim_left(&self) -> SvString {
896        let mut i: i32 = 0;
897        while is_whitespace(self.char_at(i)) {
898            i += 1;
899        }
900        self.substr(i..)
901    }
902
903    /// Removes trailing whitespace.
904    pub fn trim_right(&self) -> SvString {
905        let mut i: i32 = self.len();
906        while is_whitespace(self.char_at(i - 1)) {
907            i -= 1;
908        }
909        self.substr(..i)
910    }
911
912    /// Concatenates a list of strings with given separator.
913    pub fn join(vector: Vec<SvString>, sep: impl AnySvStringType) -> SvString {
914        let sep = sep.convert();
915        let mut r: Vec<char> = vec![];
916        let mut max_ordinal: char = '\x00';
917        let mut add_sep = false;
918        for s in vector {
919            if add_sep {
920                for ch in sep.chars() {
921                    r.push(ch);
922                    max_ordinal = char::max(ch, max_ordinal);
923                }
924            }
925            for ch in s.chars() {
926                r.push(ch);
927                max_ordinal = char::max(ch, max_ordinal);
928            }
929            add_sep = true;
930        }
931        SvString {
932            m_repr: intern(Arc::new(if max_ordinal < '\u{100}' {
933                StringRepr0 {
934                    m_len: r.len() as i32,
935                    m_repr: StringRepr1::Reference(
936                        Arc::new(StringRepr2::Latin1(r.iter().map(|&c| c as u8).collect()))
937                    ),
938                }
939            } else if max_ordinal < '\u{10000}' {
940                StringRepr0 {
941                    m_len: r.len() as i32,
942                    m_repr: StringRepr1::Reference(
943                        Arc::new(StringRepr2::Ucs2(r.iter().map(|&c| c as u16).collect()))
944                    ),
945                }
946            } else {
947                StringRepr0 {
948                    m_len: r.len() as i32,
949                    m_repr: StringRepr1::Reference(
950                        Arc::new(StringRepr2::Ucs4(r.iter().map(|&c| c as u32).collect()))
951                    ),
952                }
953            })),
954        }
955    }
956}
957
958struct CharIterator<'a> {
959    container: &'a StringRepr2,
960    index: usize,
961    lim: usize,
962}
963
964impl<'a> Iterator for CharIterator<'a> {
965    type Item = char;
966    fn next(&mut self) -> Option<Self::Item> {
967        if self.index >= self.lim {
968            return None;
969        }
970        let r = self.container.char_at(self.index);
971        self.index += 1;
972        Some(r)
973    }
974}
975
976/// Allows taking any string type in certain
977/// methods.
978pub trait AnySvStringType {
979    fn convert(&self) -> SvString;
980}
981
982impl AnySvStringType for SvString {
983    fn convert(&self) -> SvString {
984        self.clone()
985    }
986}
987
988impl<'a> AnySvStringType for &'a str {
989    fn convert(&self) -> SvString {
990        SvString::from(*self)
991    }
992}
993
994impl<'a> AnySvStringType for char {
995    fn convert(&self) -> SvString {
996        SvString::from(*self)
997    }
998}
999
1000/// Allows taking range expressions in certain methods.
1001pub trait SvSubstringIndex {
1002    fn from_index(&self) -> i32;
1003    fn to_index(&self) -> i32;
1004}
1005
1006impl SvSubstringIndex for Range<i32> {
1007    fn from_index(&self) -> i32 {
1008        self.start
1009    }
1010    fn to_index(&self) -> i32 {
1011        self.end
1012    }
1013}
1014
1015impl SvSubstringIndex for RangeFrom<i32> {
1016    fn from_index(&self) -> i32 {
1017        self.start
1018    }
1019    fn to_index(&self) -> i32 {
1020        i32::MAX
1021    }
1022}
1023
1024impl SvSubstringIndex for RangeFull {
1025    fn from_index(&self) -> i32 {
1026        0
1027    }
1028    fn to_index(&self) -> i32 {
1029        i32::MAX
1030    }
1031}
1032
1033impl SvSubstringIndex for RangeInclusive<i32> {
1034    fn from_index(&self) -> i32 {
1035        *self.start()
1036    }
1037    fn to_index(&self) -> i32 {
1038        self.end() + 1
1039    }
1040}
1041
1042impl SvSubstringIndex for RangeTo<i32> {
1043    fn from_index(&self) -> i32 {
1044        0
1045    }
1046    fn to_index(&self) -> i32 {
1047        self.end
1048    }
1049}
1050
1051impl SvSubstringIndex for RangeToInclusive<i32> {
1052    fn from_index(&self) -> i32 {
1053        0
1054    }
1055    fn to_index(&self) -> i32 {
1056        self.end + 1
1057    }
1058}
1059
1060impl Debug for SvString {
1061    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1062        write!(f, "{}", self.to_standard_string())
1063    }
1064}
1065
1066impl Display for SvString {
1067    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1068        write!(f, "{}", self.to_standard_string())
1069    }
1070}
1071
1072impl Add for SvString {
1073    type Output = SvString;
1074    fn add(self, rhs: Self) -> Self::Output {
1075        self.concat(rhs)
1076    }
1077}