Skip to main content

rune/modules/
string.rs

1//! Strings.
2
3use core::char;
4use core::cmp::Ordering;
5use core::num::{ParseFloatError, ParseIntError};
6
7use crate as rune;
8use crate::alloc;
9use crate::alloc::fmt::TryWrite;
10use crate::alloc::prelude::*;
11use crate::alloc::string::FromUtf8Error;
12use crate::compile::Named;
13use crate::runtime::{
14    Bytes, Dismantle, Formatter, FromValue, Function, Handover, Hasher, Inline, MaybeTypeOf, Range,
15    RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive, Ref, Repr, ToValue, TypeOf,
16    Value, VmError, VmErrorKind,
17};
18use crate::{Any, ContextError, Module, TypeHash};
19
20/// Strings.
21///
22/// Strings in Rune are declared with the literal `"string"` syntax, but can also be
23/// interacted with through the fundamental [`String`] type.
24///
25/// ```rune
26/// let string1 = "Hello";
27/// let string2 = String::new();
28/// string2.push_str("Hello");
29///
30/// assert_eq!(string1, string2);
31/// ```
32#[rune::module(::std::string)]
33pub fn module() -> Result<Module, ContextError> {
34    let mut m = Module::from_meta(self::module__meta)?;
35
36    m.ty::<String>()?;
37
38    m.function_meta(string_from)?;
39    m.function_meta(string_from_str)?;
40    m.function_meta(string_new)?;
41    m.function_meta(string_with_capacity)?;
42    m.function_meta(len)?;
43    m.function_meta(starts_with)?;
44    m.function_meta(ends_with)?;
45    m.function_meta(capacity)?;
46    m.function_meta(clear)?;
47    m.function_meta(contains)?;
48    m.function_meta(push)?;
49    m.function_meta(push_str)?;
50    m.function_meta(reserve)?;
51    m.function_meta(reserve_exact)?;
52    m.function_meta(from_utf8)?;
53    m.function_meta(as_bytes)?;
54    m.function_meta(into_bytes)?;
55    m.function_meta(shrink_to_fit)?;
56    m.function_meta(char_at)?;
57    m.function_meta(split)?;
58    m.function_meta(split_once)?;
59    m.associated_function("split_str", __rune_fn__split)?;
60    m.function_meta(trim)?;
61    m.function_meta(trim_end)?;
62    m.function_meta(replace)?;
63    m.function_meta(is_empty)?;
64    m.function_meta(chars)?;
65    m.function_meta(get__meta)?;
66    m.function_meta(parse_int)?;
67    m.function_meta(parse_float)?;
68    m.function_meta(parse_char)?;
69    m.function_meta(to_lowercase)?;
70    m.function_meta(to_uppercase)?;
71
72    m.function_meta(add)?;
73    m.function_meta(add_assign)?;
74    m.function_meta(index_get)?;
75
76    m.function_meta(clone__meta)?;
77    m.implement_trait::<String>(rune::item!(::std::clone::Clone))?;
78
79    m.function_meta(partial_eq__meta)?;
80    m.implement_trait::<String>(rune::item!(::std::cmp::PartialEq))?;
81
82    m.function_meta(eq__meta)?;
83    m.implement_trait::<String>(rune::item!(::std::cmp::Eq))?;
84
85    m.function_meta(partial_cmp__meta)?;
86    m.implement_trait::<String>(rune::item!(::std::cmp::PartialOrd))?;
87
88    m.function_meta(cmp__meta)?;
89    m.implement_trait::<String>(rune::item!(::std::cmp::Ord))?;
90
91    m.function_meta(hash__meta)?;
92
93    m.function_meta(display_fmt__meta)?;
94    m.function_meta(debug_fmt__meta)?;
95
96    m.ty::<Chars>()?;
97    m.function_meta(Chars::next__meta)?;
98    m.function_meta(Chars::next_back__meta)?;
99    m.implement_trait::<Chars>(rune::item!(::std::iter::Iterator))?;
100    m.implement_trait::<Chars>(rune::item!(::std::iter::DoubleEndedIterator))?;
101
102    macro_rules! split {
103        ($ty:ty) => {
104            m.ty::<Split<$ty>>()?;
105            m.function_meta(Split::<$ty>::next__meta)?;
106            m.implement_trait::<Split<$ty>>(rune::item!(::std::iter::Iterator))?;
107        };
108    }
109
110    split!(Function);
111    split!(String);
112    split!(char);
113    Ok(m)
114}
115
116/// Converts a vector of bytes to a `String`.
117///
118/// A string ([`String`]) is made of bytes ([`u8`]), and a vector of bytes
119/// ([`Vec<u8>`]) is made of bytes, so this function converts between the two.
120/// Not all byte slices are valid `String`s, however: `String` requires that it
121/// is valid UTF-8. `from_utf8()` checks to ensure that the bytes are valid
122/// UTF-8, and then does the conversion.
123///
124/// If you are sure that the byte slice is valid UTF-8, and you don't want to
125/// incur the overhead of the validity check, there is an unsafe version of this
126/// function, [`from_utf8_unchecked`], which has the same behavior but skips the
127/// check.
128///
129/// The inverse of this method is [`into_bytes`].
130///
131/// # Errors
132///
133/// Returns [`Err`] if the slice is not UTF-8 with a description as to why the
134/// provided bytes are not UTF-8. The vector you moved in is also included.
135///
136/// # Examples
137///
138/// Basic usage:
139///
140/// ```rune
141/// // some bytes, in a vector
142/// let sparkle_heart = Bytes::from_vec([240u8, 159u8, 146u8, 150u8]);
143///
144/// // We know these bytes are valid, so we'll use `unwrap()`.
145/// let sparkle_heart = String::from_utf8(sparkle_heart).unwrap();
146///
147/// assert_eq!("💖", sparkle_heart);
148/// ```
149///
150/// Incorrect bytes:
151///
152/// ```rune
153/// // some invalid bytes, in a vector
154/// let sparkle_heart = Bytes::from_vec([0u8, 159u8, 146u8, 150u8]);
155///
156/// assert!(String::from_utf8(sparkle_heart).is_err());
157/// ```
158///
159/// See the docs for [`FromUtf8Error`] for more details on what you can do with
160/// this error.
161///
162/// [`from_utf8_unchecked`]: String::from_utf8_unchecked
163/// [`Vec<u8>`]: crate::vec::Vec "Vec"
164/// [`&str`]: prim@str "&str"
165/// [`into_bytes`]: String::into_bytes
166#[rune::function(free, path = String::from_utf8)]
167fn from_utf8(bytes: &[u8]) -> Result<Result<String, FromUtf8Error>, VmError> {
168    let vec = Vec::try_from(bytes)?;
169    Ok(String::from_utf8(vec))
170}
171
172/// Returns a byte slice of this `String`'s contents.
173///
174/// The inverse of this method is [`from_utf8`].
175///
176/// [`from_utf8`]: String::from_utf8
177///
178/// # Examples
179///
180/// Basic usage:
181///
182/// ```rune
183/// let s = "hello";
184/// assert_eq!(b"hello", s.as_bytes());
185/// assert!(is_readable(s));
186/// ```
187#[rune::function(instance)]
188fn as_bytes(s: &str) -> Result<Bytes, VmError> {
189    Ok(Bytes::from_vec(Vec::try_from(s.as_bytes())?))
190}
191
192/// Constructs a string from another string.
193///
194/// # Examples
195///
196/// Basic usage:
197///
198/// ```rune
199/// let s = String::from("hello");
200/// assert_eq!(s, "hello");
201/// ```
202#[rune::function(free, path = String::from)]
203fn string_from(value: &str) -> Result<String, VmError> {
204    Ok(String::try_from(value)?)
205}
206
207#[rune::function(free, path = String::from_str, deprecated = "Use String::from instead")]
208fn string_from_str(value: &str) -> Result<String, VmError> {
209    Ok(String::try_from(value)?)
210}
211
212/// Creates a new empty `String`.
213///
214/// Given that the `String` is empty, this will not allocate any initial buffer.
215/// While that means that this initial operation is very inexpensive, it may
216/// cause excessive allocation later when you add data. If you have an idea of
217/// how much data the `String` will hold, consider the [`with_capacity`] method
218/// to prevent excessive re-allocation.
219///
220/// [`with_capacity`]: String::with_capacity
221///
222/// # Examples
223///
224/// Basic usage:
225///
226/// ```rune
227/// let s = String::new();
228/// ```
229#[rune::function(free, path = String::new)]
230fn string_new() -> String {
231    String::new()
232}
233
234/// Creates a new empty `String` with at least the specified capacity.
235///
236/// `String`s have an internal buffer to hold their data. The capacity is the
237/// length of that buffer, and can be queried with the [`capacity`] method. This
238/// method creates an empty `String`, but one with an initial buffer that can
239/// hold at least `capacity` bytes. This is useful when you may be appending a
240/// bunch of data to the `String`, reducing the number of reallocations it needs
241/// to do.
242///
243/// [`capacity`]: String::capacity
244///
245/// If the given capacity is `0`, no allocation will occur, and this method is
246/// identical to the [`new`] method.
247///
248/// [`new`]: String::new
249///
250/// # Examples
251///
252/// Basic usage:
253///
254/// ```rune
255/// let s = String::with_capacity(10);
256///
257/// // The String contains no chars, even though it has capacity for more
258/// assert_eq!(s.len(), 0);
259///
260/// // These are all done without reallocating...
261/// let cap = s.capacity();
262///
263/// for _ in 0..10 {
264///     s.push('a');
265/// }
266///
267/// assert_eq!(s.capacity(), cap);
268///
269/// // ...but this may make the string reallocate
270/// s.push('a');
271/// ```
272#[rune::function(free, path = String::with_capacity)]
273fn string_with_capacity(capacity: usize) -> Result<String, VmError> {
274    Ok(String::try_with_capacity(capacity)?)
275}
276
277/// Returns the length of `self`.
278///
279/// This length is in bytes, not [`char`]s or graphemes. In other words, it
280/// might not be what a human considers the length of the string.
281///
282/// [`char`]: prim@char
283///
284/// # Examples
285///
286/// Basic usage:
287///
288/// ```rune
289/// let len = "foo".len();
290/// assert_eq!(3, len);
291///
292/// assert_eq!("ƒoo".len(), 4); // fancy f!
293/// assert_eq!("ƒoo".chars().count(), 3);
294/// ```
295#[rune::function(instance)]
296fn len(this: &str) -> usize {
297    this.len()
298}
299
300/// Returns `true` if the given pattern matches a prefix of this string slice.
301///
302/// Returns `false` if it does not.
303///
304/// The [pattern] can be a `&str`, [`char`], a slice of [`char`]s, or a function
305/// or closure that determines if a character matches.
306///
307/// [`char`]: prim@char
308/// [pattern]: self::pattern
309///
310/// # Examples
311///
312/// Basic usage:
313///
314/// ```rune
315/// let bananas = "bananas";
316///
317/// assert!(bananas.starts_with("bana"));
318/// assert!(!bananas.starts_with("nana"));
319/// ```
320#[rune::function(instance)]
321fn starts_with(this: &str, other: &str) -> bool {
322    this.starts_with(other)
323}
324
325/// Returns `true` if the given pattern matches a suffix of this string slice.
326///
327/// Returns `false` if it does not.
328///
329/// The [pattern] can be a `&str`, [`char`], a slice of [`char`]s, or a function
330/// or closure that determines if a character matches.
331///
332/// [`char`]: prim@char
333/// [pattern]: self::pattern
334///
335/// # Examples
336///
337/// Basic usage:
338///
339/// ```rune
340/// let bananas = "bananas";
341///
342/// assert!(bananas.ends_with("anas"));
343/// assert!(!bananas.ends_with("nana"));
344/// ```
345#[rune::function(instance)]
346fn ends_with(this: &str, other: &str) -> bool {
347    this.ends_with(other)
348}
349
350/// Returns this `String`'s capacity, in bytes.
351///
352/// # Examples
353///
354/// Basic usage:
355///
356/// ```rune
357/// let s = String::with_capacity(10);
358///
359/// assert!(s.capacity() >= 10);
360/// ```
361#[rune::function(instance)]
362fn capacity(this: &String) -> usize {
363    this.capacity()
364}
365
366/// Truncates this `String`, removing all contents.
367///
368/// While this means the `String` will have a length of zero, it does not touch
369/// its capacity.
370///
371/// # Examples
372///
373/// Basic usage:
374///
375/// ```rune
376/// let s = "foo";
377///
378/// s.clear();
379///
380/// assert!(s.is_empty());
381/// assert_eq!(0, s.len());
382/// assert_eq!(3, s.capacity());
383/// ```
384#[rune::function(instance)]
385fn clear(this: &mut String) {
386    this.clear();
387}
388
389/// Returns `true` if the given pattern matches a sub-slice of this string
390/// slice.
391///
392/// Returns `false` if it does not.
393///
394/// The [pattern] can be a `String`, [`char`], or a function or closure that
395/// determines if a character matches.
396///
397/// [`char`]: prim@char
398/// [pattern]: self::pattern
399///
400/// # Examples
401///
402/// Basic usage:
403///
404/// ```rune
405/// let bananas = "bananas";
406///
407/// assert!(bananas.contains("nana"));
408/// assert!(!bananas.contains("apples"));
409/// ```
410#[rune::function(instance)]
411fn contains(this: &str, other: &str) -> bool {
412    this.contains(other)
413}
414
415/// Appends the given [`char`] to the end of this `String`.
416///
417/// # Examples
418///
419/// Basic usage:
420///
421/// ```rune
422/// let s = "abc";
423///
424/// s.push('1');
425/// s.push('2');
426/// s.push('3');
427///
428/// assert_eq!("abc123", s);
429/// ```
430#[rune::function(instance)]
431fn push(this: &mut String, c: char) -> Result<(), VmError> {
432    this.try_push(c)?;
433    Ok(())
434}
435
436/// Appends a given string slice onto the end of this `String`.
437///
438/// # Examples
439///
440/// Basic usage:
441///
442/// ```rune
443/// let s = "foo";
444///
445/// s.push_str("bar");
446///
447/// assert_eq!("foobar", s);
448/// ```
449#[rune::function(instance)]
450fn push_str(this: &mut String, other: &str) -> Result<(), VmError> {
451    this.try_push_str(other)?;
452    Ok(())
453}
454
455/// Reserves capacity for at least `additional` bytes more than the current
456/// length. The allocator may reserve more space to speculatively avoid frequent
457/// allocations. After calling `reserve`, capacity will be greater than or equal
458/// to `self.len() + additional`. Does nothing if capacity is already
459/// sufficient.
460///
461/// # Panics
462///
463/// Panics if the new capacity overflows [`usize`].
464///
465/// # Examples
466///
467/// Basic usage:
468///
469/// ```rune
470/// let s = String::new();
471///
472/// s.reserve(10);
473///
474/// assert!(s.capacity() >= 10);
475/// ```
476///
477/// This might not actually increase the capacity:
478///
479/// ```rune
480/// let s = String::with_capacity(10);
481/// s.push('a');
482/// s.push('b');
483///
484/// // s now has a length of 2 and a capacity of at least 10
485/// let capacity = s.capacity();
486/// assert_eq!(2, s.len());
487/// assert!(capacity >= 10);
488///
489/// // Since we already have at least an extra 8 capacity, calling this...
490/// s.reserve(8);
491///
492/// // ... doesn't actually increase.
493/// assert_eq!(capacity, s.capacity());
494/// ```
495#[rune::function(instance)]
496fn reserve(this: &mut String, additional: usize) -> Result<(), VmError> {
497    this.try_reserve(additional)?;
498    Ok(())
499}
500
501/// Reserves the minimum capacity for at least `additional` bytes more than the
502/// current length. Unlike [`reserve`], this will not deliberately over-allocate
503/// to speculatively avoid frequent allocations. After calling `reserve_exact`,
504/// capacity will be greater than or equal to `self.len() + additional`. Does
505/// nothing if the capacity is already sufficient.
506///
507/// [`reserve`]: String::reserve
508///
509/// # Panics
510///
511/// Panics if the new capacity overflows [`usize`].
512///
513/// # Examples
514///
515/// Basic usage:
516///
517/// ```rune
518/// let s = String::new();
519///
520/// s.reserve_exact(10);
521///
522/// assert!(s.capacity() >= 10);
523/// ```
524///
525/// This might not actually increase the capacity:
526///
527/// ```rune
528/// let s = String::with_capacity(10);
529/// s.push('a');
530/// s.push('b');
531///
532/// // s now has a length of 2 and a capacity of at least 10
533/// let capacity = s.capacity();
534/// assert_eq!(2, s.len());
535/// assert!(capacity >= 10);
536///
537/// // Since we already have at least an extra 8 capacity, calling this...
538/// s.reserve_exact(8);
539///
540/// // ... doesn't actually increase.
541/// assert_eq!(capacity, s.capacity());
542/// ```
543#[rune::function(instance)]
544fn reserve_exact(this: &mut String, additional: usize) -> alloc::Result<()> {
545    this.try_reserve_exact(additional)
546}
547
548/// Returns a byte slice of this `String`'s contents while moving the string.
549///
550/// The inverse of this method is [`from_utf8`].
551///
552/// [`from_utf8`]: String::from_utf8
553///
554/// # Examples
555///
556/// Basic usage:
557///
558/// ```rune
559/// let s = "hello";
560/// assert_eq!(b"hello", s.into_bytes());
561/// assert!(!is_readable(s));
562/// ```
563#[rune::function(instance)]
564fn into_bytes(s: String) -> Bytes {
565    Bytes::from_vec(s.into_bytes())
566}
567
568/// Checks that `index`-th byte is the first byte in a UTF-8 code point sequence
569/// or the end of the string.
570///
571/// The start and end of the string (when `index == self.len()`) are considered
572/// to be boundaries.
573///
574/// Returns `false` if `index` is greater than `self.len()`.
575///
576/// # Examples
577///
578/// ```rune
579/// let s = "Löwe 老虎 Léopard";
580/// assert!(s.is_char_boundary(0));
581/// // start of `老`
582/// assert!(s.is_char_boundary(6));
583/// assert!(s.is_char_boundary(s.len()));
584///
585/// // second byte of `ö`
586/// assert!(!s.is_char_boundary(2));
587///
588/// // third byte of `老`
589/// assert!(!s.is_char_boundary(8));
590/// ```
591#[rune::function(instance)]
592fn is_char_boundary(s: &str, index: usize) -> bool {
593    s.is_char_boundary(index)
594}
595
596/// Access the character at the given byte index.
597///
598/// Returns `None` if the index is out of bounds or not a character boundary.
599///
600/// # Examples
601///
602/// ```rune
603/// let s = "おはよう";
604/// assert_eq!(s.char_at(0), Some('お'));
605/// assert_eq!(s.char_at(1), None);
606/// assert_eq!(s.char_at(2), None);
607/// assert_eq!(s.char_at(3), Some('は'));
608/// ```
609#[rune::function(instance)]
610fn char_at(s: &str, index: usize) -> Option<char> {
611    if !s.is_char_boundary(index) {
612        return None;
613    }
614
615    s[index..].chars().next()
616}
617
618/// Clones the string and its underlying storage.
619///
620/// # Examples
621///
622/// Basic usage:
623///
624/// ```rune
625/// let a = "h";
626/// let b = a;
627/// b.push('i');
628///
629/// // `a` and `b` refer to the same underlying string.
630/// assert_eq!(a, b);
631///
632/// let c = b.clone();
633/// c.push('!');
634/// assert_ne!(a, c);
635/// ```
636#[rune::function(keep, instance, protocol = CLONE)]
637fn clone(this: &String) -> alloc::Result<String> {
638    this.try_clone()
639}
640
641/// Test two strings for partial equality.
642///
643/// # Examples
644///
645/// ```rune
646/// use std::ops::partial_eq;
647///
648/// assert_eq!(partial_eq("a", "a"), true);
649/// assert_eq!(partial_eq("a", "ab"), false);
650/// assert_eq!(partial_eq("ab", "a"), false);
651/// ```
652#[rune::function(keep, instance, protocol = PARTIAL_EQ)]
653#[inline]
654fn partial_eq(this: &str, rhs: &str) -> bool {
655    this.eq(rhs)
656}
657
658/// Test two strings for total equality.
659///
660/// # Examples
661///
662/// ```rune
663/// use std::ops::eq;
664///
665/// assert_eq!(eq("a", "a"), true);
666/// assert_eq!(eq("a", "ab"), false);
667/// assert_eq!(eq("ab", "a"), false);
668/// ```
669#[rune::function(keep, instance, protocol = EQ)]
670#[inline]
671fn eq(this: &str, rhs: &str) -> bool {
672    this.eq(rhs)
673}
674
675/// Perform a partial ordered comparison between two strings.
676///
677/// # Examples
678///
679/// ```rune
680/// assert!("a" < "ab");
681/// assert!("ab" > "a");
682/// assert!("a" == "a");
683/// ```
684///
685/// Using explicit functions:
686///
687/// ```rune
688/// use std::cmp::Ordering;
689/// use std::ops::partial_cmp;
690///
691/// assert_eq!(partial_cmp("a", "ab"), Some(Ordering::Less));
692/// assert_eq!(partial_cmp("ab", "a"), Some(Ordering::Greater));
693/// assert_eq!(partial_cmp("a", "a"), Some(Ordering::Equal));
694/// ```
695#[rune::function(keep, instance, protocol = PARTIAL_CMP)]
696#[inline]
697fn partial_cmp(this: &str, rhs: &str) -> Option<Ordering> {
698    this.partial_cmp(rhs)
699}
700
701/// Perform a totally ordered comparison between two strings.
702///
703/// # Examples
704///
705/// ```rune
706/// use std::cmp::Ordering;
707/// use std::ops::cmp;
708///
709/// assert_eq!(cmp("a", "ab"), Ordering::Less);
710/// assert_eq!(cmp("ab", "a"), Ordering::Greater);
711/// assert_eq!(cmp("a", "a"), Ordering::Equal);
712/// ```
713#[rune::function(keep, instance, protocol = CMP)]
714#[inline]
715fn cmp(this: &str, rhs: &str) -> Ordering {
716    this.cmp(rhs)
717}
718
719/// Hash the string.
720///
721/// # Examples
722///
723/// ```rune
724/// use std::ops::hash;
725///
726/// let a = "hello";
727/// let b = "hello";
728///
729/// assert_eq!(hash(a), hash(b));
730/// ```
731#[rune::function(keep, instance, protocol = HASH)]
732fn hash(this: &str, hasher: &mut Hasher) {
733    hasher.write_str(this);
734}
735
736/// Write a display representation of a string.
737///
738/// # Examples
739///
740/// ```rune
741/// println!("{}", "Hello");
742/// ```
743#[rune::function(keep, instance, protocol = DISPLAY_FMT)]
744#[inline]
745fn display_fmt(this: &str, f: &mut Formatter) -> alloc::Result<()> {
746    write!(f, "{this}")
747}
748
749/// Write a debug representation of a string.
750///
751/// # Examples
752///
753/// ```rune
754/// println!("{:?}", "Hello");
755/// ```
756#[rune::function(keep, instance, protocol = DEBUG_FMT)]
757#[inline]
758fn debug_fmt(this: &str, f: &mut Formatter) -> alloc::Result<()> {
759    write!(f, "{this:?}")
760}
761
762/// Shrinks the capacity of this `String` to match its length.
763///
764/// # Examples
765///
766/// Basic usage:
767///
768/// ```rune
769/// let s = "foo";
770///
771/// s.reserve(100);
772/// assert!(s.capacity() >= 100);
773///
774/// s.shrink_to_fit();
775/// assert_eq!(3, s.capacity());
776/// ```
777#[rune::function(instance)]
778fn shrink_to_fit(s: &mut String) -> alloc::Result<()> {
779    s.try_shrink_to_fit()
780}
781
782/// An iterator over substrings of this string slice, separated by
783/// characters matched by a pattern.
784///
785/// The [pattern] can be a `&str`, [`char`], a slice of [`char`]s, or a
786/// function or closure that determines if a character matches.
787///
788/// [`char`]: prim@char
789/// [pattern]: self::pattern
790///
791/// # Iterator behavior
792///
793/// The returned iterator will be a [`DoubleEndedIterator`] if the pattern
794/// allows a reverse search and forward/reverse search yields the same
795/// elements. This is true for, e.g., [`char`], but not for `&str`.
796///
797/// If the pattern allows a reverse search but its results might differ
798/// from a forward search, the [`rsplit`] method can be used.
799///
800/// [`rsplit`]: str::rsplit
801///
802/// # Examples
803///
804/// Simple patterns:
805///
806/// ```rune
807/// let v = "Mary had a little lamb".split(' ').collect::<Vec>();
808/// assert_eq!(v, ["Mary", "had", "a", "little", "lamb"]);
809///
810/// let v = "".split('X').collect::<Vec>();
811/// assert_eq!(v, [""]);
812///
813/// let v = "lionXXtigerXleopard".split('X').collect::<Vec>();
814/// assert_eq!(v, ["lion", "", "tiger", "leopard"]);
815///
816/// let v = "lion::tiger::leopard".split("::").collect::<Vec>();
817/// assert_eq!(v, ["lion", "tiger", "leopard"]);
818///
819/// let v = "abc1def2ghi".split(char::is_numeric).collect::<Vec>();
820/// assert_eq!(v, ["abc", "def", "ghi"]);
821///
822/// let v = "lionXtigerXleopard".split(char::is_uppercase).collect::<Vec>();
823/// assert_eq!(v, ["lion", "tiger", "leopard"]);
824/// ```
825///
826/// A more complex pattern, using a closure:
827///
828/// ```rune
829/// let v = "abc1defXghi".split(|c| c == '1' || c == 'X').collect::<Vec>();
830/// assert_eq!(v, ["abc", "def", "ghi"]);
831/// ```
832///
833/// If a string contains multiple contiguous separators, you will end up
834/// with empty strings in the output:
835///
836/// ```rune
837/// let x = "||||a||b|c";
838/// let d = x.split('|').collect::<Vec>();
839///
840/// assert_eq!(d, ["", "", "", "", "a", "", "b", "c"]);
841/// ```
842///
843/// Contiguous separators are separated by the empty string.
844///
845/// ```rune
846/// let x = "(///)";
847/// let d = x.split('/').collect::<Vec>();
848///
849/// assert_eq!(d, ["(", "", "", ")"]);
850/// ```
851///
852/// Separators at the start or end of a string are neighbored
853/// by empty strings.
854///
855/// ```rune
856/// let d = "010".split("0").collect::<Vec>();
857/// assert_eq!(d, ["", "1", ""]);
858/// ```
859///
860/// When the empty string is used as a separator, it separates
861/// every character in the string, along with the beginning
862/// and end of the string.
863///
864/// ```rune
865/// let f = "rust".split("").collect::<Vec>();
866/// assert_eq!(f, ["", "r", "u", "s", "t", ""]);
867/// ```
868///
869/// Contiguous separators can lead to possibly surprising behavior
870/// when whitespace is used as the separator. This code is correct:
871///
872/// ```rune
873/// let x = "    a  b c";
874/// let d = x.split(' ').collect::<Vec>();
875///
876/// assert_eq!(d, ["", "", "", "", "a", "", "b", "c"]);
877/// ```
878///
879/// It does _not_ give you:
880///
881/// ```rune,ignore
882/// assert_eq!(d, ["a", "b", "c"]);
883/// ```
884///
885/// Use [`split_whitespace`] for this behavior.
886///
887/// [`split_whitespace`]: str::split_whitespace
888#[rune::function(instance, deprecated = "Use String::split instead")]
889fn split(this: Ref<str>, value: Value) -> Result<Value, VmError> {
890    match value.as_ref() {
891        Repr::Inline(Inline::Char(c)) => Ok(rune::to_value(Split::new(this, *c))?),
892        Repr::Inline(value) => Err(VmError::from([
893            VmErrorKind::expected::<String>(value.type_info()),
894            VmErrorKind::bad_argument(0),
895        ])),
896        Repr::Dynamic(value) => Err(VmError::from([
897            VmErrorKind::expected::<String>(value.type_info()),
898            VmErrorKind::bad_argument(0),
899        ])),
900        Repr::Any(value) => match value.type_hash() {
901            String::HASH => {
902                let s = value.borrow_ref::<String>()?;
903
904                let split = rune::to_value(Split::new(this, String::try_from(s.as_str())?))?;
905
906                Ok(split)
907            }
908            Function::HASH => {
909                let f = value.borrow_ref::<Function>()?;
910                let split = rune::to_value(Split::new(this, f.try_clone()?))?;
911                Ok(split)
912            }
913            _ => Err(VmError::from([
914                VmErrorKind::expected::<String>(value.type_info()),
915                VmErrorKind::bad_argument(0),
916            ])),
917        },
918    }
919}
920
921/// Splits the string on the first occurrence of the specified delimiter and
922/// returns prefix before delimiter and suffix after delimiter.
923///
924/// # Examples
925///
926/// ```rune
927/// assert_eq!("cfg".split_once('='), None);
928/// assert_eq!("cfg=".split_once('='), Some(("cfg", "")));
929/// assert_eq!("cfg=foo".split_once('='), Some(("cfg", "foo")));
930/// assert_eq!("cfg=foo=bar".split_once('='), Some(("cfg", "foo=bar")));
931/// ```
932#[rune::function(instance)]
933fn split_once(this: &str, value: Value) -> Result<Option<(String, String)>, VmError> {
934    let outcome = match value.as_ref() {
935        Repr::Inline(Inline::Char(pat)) => this.split_once(*pat),
936        Repr::Inline(value) => {
937            return Err(VmError::from([
938                VmErrorKind::expected::<String>(value.type_info()),
939                VmErrorKind::bad_argument(0),
940            ]));
941        }
942        Repr::Dynamic(value) => {
943            return Err(VmError::from([
944                VmErrorKind::expected::<String>(value.type_info()),
945                VmErrorKind::bad_argument(0),
946            ]));
947        }
948        Repr::Any(value) => match value.type_hash() {
949            String::HASH => {
950                let s = value.borrow_ref::<String>()?;
951                this.split_once(s.as_str())
952            }
953            Function::HASH => {
954                let f = value.borrow_ref::<Function>()?;
955                let mut err = None;
956
957                let outcome = this.split_once(|c: char| match f.call::<bool>((c,)) {
958                    Ok(b) => b,
959                    Err(e) => {
960                        if err.is_none() {
961                            err = Some(e);
962                        }
963
964                        false
965                    }
966                });
967
968                if let Some(e) = err.take() {
969                    return Err(e);
970                }
971
972                outcome
973            }
974            _ => {
975                return Err(VmError::from([
976                    VmErrorKind::expected::<String>(value.type_info()),
977                    VmErrorKind::bad_argument(0),
978                ]));
979            }
980        },
981    };
982
983    let Some((a, b)) = outcome else {
984        return Ok(None);
985    };
986
987    Ok(Some((a.try_to_owned()?, b.try_to_owned()?)))
988}
989
990/// Returns a string slice with leading and trailing whitespace removed.
991///
992/// 'Whitespace' is defined according to the terms of the Unicode Derived Core
993/// Property `White_Space`, which includes newlines.
994///
995/// # Examples
996///
997/// Basic usage:
998///
999/// ```rune
1000/// let s = "\n Hello\tworld\t\n";
1001///
1002/// assert_eq!("Hello\tworld", s.trim());
1003/// ```
1004#[rune::function(instance)]
1005fn trim(this: &str) -> alloc::Result<String> {
1006    this.trim().try_to_owned()
1007}
1008
1009/// Returns a string slice with trailing whitespace removed.
1010///
1011/// 'Whitespace' is defined according to the terms of the Unicode Derived Core
1012/// Property `White_Space`, which includes newlines.
1013///
1014/// # Text directionality
1015///
1016/// A string is a sequence of bytes. `end` in this context means the last
1017/// position of that byte string; for a left-to-right language like English or
1018/// Russian, this will be right side, and for right-to-left languages like
1019/// Arabic or Hebrew, this will be the left side.
1020///
1021/// # Examples
1022///
1023/// Basic usage:
1024///
1025/// ```rune
1026/// let s = "\n Hello\tworld\t\n";
1027/// assert_eq!("\n Hello\tworld", s.trim_end());
1028/// ```
1029///
1030/// Directionality:
1031///
1032/// ```rune
1033/// let s = "  English  ";
1034/// assert!(Some('h') == s.trim_end().chars().rev().next());
1035///
1036/// let s = "  עברית  ";
1037/// assert!(Some('ת') == s.trim_end().chars().rev().next());
1038/// ```
1039#[rune::function(instance)]
1040fn trim_end(this: &str) -> alloc::Result<String> {
1041    this.trim_end().try_to_owned()
1042}
1043
1044/// Returns `true` if `self` has a length of zero bytes.
1045///
1046/// # Examples
1047///
1048/// Basic usage:
1049///
1050/// ```rune
1051/// let s = "";
1052/// assert!(s.is_empty());
1053///
1054/// let s = "not empty";
1055/// assert!(!s.is_empty());
1056/// ```
1057#[rune::function(instance)]
1058fn is_empty(this: &str) -> bool {
1059    this.is_empty()
1060}
1061
1062/// Replaces all matches of a pattern with another string.
1063///
1064/// `replace` creates a new [`String`], and copies the data from this string
1065/// slice into it. While doing so, it attempts to find matches of a pattern. If
1066/// it finds any, it replaces them with the replacement string slice.
1067///
1068/// # Examples
1069///
1070/// Basic usage:
1071///
1072/// ```rune
1073/// let s = "this is old";
1074///
1075/// assert_eq!("this is new", s.replace("old", "new"));
1076/// assert_eq!("than an old", s.replace("is", "an"));
1077/// ```
1078///
1079/// When the pattern doesn't match, it returns this string slice as [`String`]:
1080///
1081/// ```rune
1082/// let s = "this is old";
1083/// assert_eq!(s, s.replace("cookie monster", "little lamb"));
1084/// ```
1085#[rune::function(instance)]
1086fn replace(this: &str, from: &str, to: &str) -> alloc::Result<String> {
1087    alloc::str::replace(this, from, to)
1088}
1089
1090/// Returns an iterator over the [`char`]s of a string slice.
1091///
1092/// As a string slice consists of valid UTF-8, we can iterate through a string
1093/// slice by [`char`]. This method returns such an iterator.
1094///
1095/// It's important to remember that [`char`] represents a Unicode Scalar Value,
1096/// and might not match your idea of what a 'character' is. Iteration over
1097/// grapheme clusters may be what you actually want. This functionality is not
1098/// provided by Rust's standard library, check crates.io instead.
1099///
1100/// # Examples
1101///
1102/// Basic usage:
1103///
1104/// ```rune
1105/// let word = "goodbye";
1106///
1107/// let count = word.chars().count();
1108/// assert_eq!(7, count);
1109///
1110/// let chars = word.chars();
1111///
1112/// assert_eq!(Some('g'), chars.next());
1113/// assert_eq!(Some('o'), chars.next());
1114/// assert_eq!(Some('o'), chars.next());
1115/// assert_eq!(Some('d'), chars.next());
1116/// assert_eq!(Some('b'), chars.next());
1117/// assert_eq!(Some('y'), chars.next());
1118/// assert_eq!(Some('e'), chars.next());
1119///
1120/// assert_eq!(None, chars.next());
1121/// ```
1122///
1123/// Remember, [`char`]s might not match your intuition about characters:
1124///
1125/// [`char`]: prim@char
1126///
1127/// ```rune
1128/// let y = "y̆";
1129///
1130/// let chars = y.chars();
1131///
1132/// assert_eq!(Some('y'), chars.next()); // not 'y̆'
1133/// assert_eq!(Some('\u{0306}'), chars.next());
1134///
1135/// assert_eq!(None, chars.next());
1136/// ```
1137#[rune::function(instance)]
1138fn chars(s: Ref<str>) -> Chars {
1139    Chars::new(s)
1140}
1141
1142/// Returns a subslice of `str`.
1143///
1144/// This is the non-panicking alternative to indexing the `str`. Returns
1145/// [`None`] whenever equivalent indexing operation would panic.
1146///
1147/// # Examples
1148///
1149/// ```rune
1150/// let v = "🗻∈🌏";
1151///
1152/// assert_eq!(Some("🗻"), v.get(0..4));
1153///
1154/// // indices not on UTF-8 sequence boundaries
1155/// assert!(v.get(1..).is_none());
1156/// assert!(v.get(..8).is_none());
1157///
1158/// // out of bounds
1159/// assert!(v.get(..42).is_none());
1160/// ```
1161#[rune::function(keep, instance)]
1162fn get(this: &str, key: Value) -> Result<Option<String>, VmError> {
1163    use crate::runtime::TypeOf;
1164
1165    let slice = match key.as_any() {
1166        Some(value) => match value.type_hash() {
1167            RangeFrom::HASH => {
1168                let range = value.borrow_ref::<RangeFrom>()?;
1169                let start = range.start.as_usize()?;
1170                this.get(start..)
1171            }
1172            RangeFull::HASH => {
1173                _ = value.borrow_ref::<RangeFull>()?;
1174                this.get(..)
1175            }
1176            RangeInclusive::HASH => {
1177                let range = value.borrow_ref::<RangeInclusive>()?;
1178                let start = range.start.as_usize()?;
1179                let end = range.end.as_usize()?;
1180                this.get(start..=end)
1181            }
1182            RangeToInclusive::HASH => {
1183                let range = value.borrow_ref::<RangeToInclusive>()?;
1184                let end = range.end.as_usize()?;
1185                this.get(..=end)
1186            }
1187            RangeTo::HASH => {
1188                let range = value.borrow_ref::<RangeTo>()?;
1189                let end = range.end.as_usize()?;
1190                this.get(..end)
1191            }
1192            Range::HASH => {
1193                let range = value.borrow_ref::<Range>()?;
1194                let start = range.start.as_usize()?;
1195                let end = range.end.as_usize()?;
1196                this.get(start..end)
1197            }
1198            _ => {
1199                return Err(VmError::from(VmErrorKind::UnsupportedIndexGet {
1200                    target: String::type_info(),
1201                    index: value.type_info(),
1202                }))
1203            }
1204        },
1205        _ => {
1206            return Err(VmError::from(VmErrorKind::UnsupportedIndexGet {
1207                target: String::type_info(),
1208                index: key.type_info(),
1209            }))
1210        }
1211    };
1212
1213    let Some(slice) = slice else {
1214        return Ok(None);
1215    };
1216
1217    Ok(Some(slice.try_to_owned()?))
1218}
1219
1220/// The add operation for strings.
1221#[rune::function(instance, protocol = ADD)]
1222fn add(a: &str, b: &str) -> Result<String, VmError> {
1223    let mut string = String::try_with_capacity(a.len() + b.len())?;
1224    string.try_push_str(a)?;
1225    string.try_push_str(b)?;
1226    Ok(string)
1227}
1228
1229/// The add assign operation for strings.
1230#[rune::function(instance, protocol = ADD_ASSIGN)]
1231fn add_assign(this: &mut String, other: &str) -> Result<(), VmError> {
1232    this.try_push_str(other)?;
1233    Ok(())
1234}
1235
1236/// Get a specific string index.
1237#[rune::function(instance, protocol = INDEX_GET)]
1238fn index_get(s: &str, key: Value) -> Result<String, VmError> {
1239    match get(s, key)? {
1240        Some(slice) => Ok(slice),
1241        None => Err(VmError::panic("missing string slice")),
1242    }
1243}
1244
1245/// Parses this string into an integer.
1246///
1247/// # Errors
1248///
1249/// Will return [`Err`] if it's not possible to parse this string slice into an
1250/// integer.
1251///
1252/// # Examples
1253///
1254/// Basic usage
1255///
1256/// ```rune
1257/// let four = "4".parse::<i64>()?;
1258/// assert_eq!(4, four);
1259/// ```
1260#[rune::function(instance, path = parse::<i64>)]
1261fn parse_int(s: &str) -> Result<i64, ParseIntError> {
1262    str::parse::<i64>(s)
1263}
1264
1265/// Parses this string into a float.
1266///
1267/// # Errors
1268///
1269/// Will return [`Err`] if it's not possible to parse this string slice into an
1270/// float.
1271///
1272/// # Examples
1273///
1274/// Basic usage
1275///
1276/// ```rune
1277/// let pi = "3.1415".parse::<f64>()?;
1278/// assert_eq!(3.1415, pi);
1279/// ```
1280#[rune::function(instance, path = parse::<f64>)]
1281fn parse_float(s: &str) -> Result<f64, ParseFloatError> {
1282    str::parse::<f64>(s)
1283}
1284
1285/// Parses this string into a character.
1286///
1287/// # Errors
1288///
1289/// Will return [`Err`] if it's not possible to parse this string slice into an
1290/// integer.
1291///
1292/// # Examples
1293///
1294/// Basic usage
1295///
1296/// ```rune
1297/// let a = "a".parse::<char>()?;
1298/// assert_eq!('a', a);
1299/// ```
1300#[rune::function(instance, path = parse::<char>)]
1301fn parse_char(s: &str) -> Result<char, char::ParseCharError> {
1302    str::parse::<char>(s)
1303}
1304
1305/// Returns the lowercase equivalent of this string slice, as a new [`String`].
1306///
1307/// 'Lowercase' is defined according to the terms of the Unicode Derived Core Property
1308/// `Lowercase`.
1309///
1310/// Since some characters can expand into multiple characters when changing
1311/// the case, this function returns a [`String`] instead of modifying the
1312/// parameter in-place.
1313///
1314/// # Examples
1315///
1316/// Basic usage:
1317///
1318/// ```rune
1319/// let s = "HELLO";
1320///
1321/// assert_eq!("hello", s.to_lowercase());
1322/// ```
1323///
1324/// A tricky example, with sigma:
1325///
1326/// ```rune
1327/// let sigma = "Σ";
1328///
1329/// assert_eq!("σ", sigma.to_lowercase());
1330///
1331/// // but at the end of a word, it's ς, not σ:
1332/// let odysseus = "ὈΔΥΣΣΕΎΣ";
1333///
1334/// assert_eq!("ὀδυσσεύς", odysseus.to_lowercase());
1335/// ```
1336///
1337/// Languages without case are not changed:
1338///
1339/// ```rune
1340/// let new_year = "农历新年";
1341///
1342/// assert_eq!(new_year, new_year.to_lowercase());
1343/// ```
1344#[rune::function(instance)]
1345fn to_lowercase(s: &str) -> Result<String, VmError> {
1346    let mut lowercase = String::try_with_capacity(s.len())?;
1347
1348    for (i, c) in s.char_indices() {
1349        // Inlined code to from std::str to handle upper-case sigma,
1350        // since it is the only Unicode character that is context-dependent
1351        // See https://github.com/rust-lang/rust/issues/26035 for more context
1352        if c == 'Σ' {
1353            lowercase.try_push_str(map_uppercase_sigma(s, i))?;
1354        } else {
1355            lowercase.try_extend(c.to_lowercase())?;
1356        }
1357    }
1358
1359    return Ok(lowercase);
1360
1361    fn map_uppercase_sigma(from: &str, i: usize) -> &'static str {
1362        // See https://www.unicode.org/versions/Unicode7.0.0/ch03.pdf#G33992
1363        // for the definition of `Final_Sigma`.
1364        debug_assert!('Σ'.len_utf8() == 2);
1365        let is_word_final = case_ignorable_then_cased(from[..i].chars().rev())
1366            && !case_ignorable_then_cased(from[i + 2..].chars());
1367        if is_word_final {
1368            "ς"
1369        } else {
1370            "σ"
1371        }
1372    }
1373
1374    fn case_ignorable_then_cased<I: core::iter::Iterator<Item = char>>(mut iter: I) -> bool {
1375        match iter.find(|&c| !unicode::case_ignorable::lookup(c)) {
1376            Some(c) => unicode::cased::lookup(c),
1377            None => false,
1378        }
1379    }
1380}
1381
1382/// Returns the uppercase equivalent of this string slice, as a new [`String`].
1383///
1384/// 'Uppercase' is defined according to the terms of the Unicode Derived Core Property
1385/// `Uppercase`.
1386///
1387/// Since some characters can expand into multiple characters when changing
1388/// the case, this function returns a [`String`] instead of modifying the
1389/// parameter in-place.
1390///
1391/// # Examples
1392///
1393/// Basic usage:
1394///
1395/// ```rune
1396/// let s = "hello";
1397///
1398/// assert_eq!("HELLO", s.to_uppercase());
1399/// ```
1400///
1401/// Scripts without case are not changed:
1402///
1403/// ```rune
1404/// let new_year = "农历新年";
1405///
1406/// assert_eq!(new_year, new_year.to_uppercase());
1407/// ```
1408///
1409/// One character can become multiple:
1410/// ```rune
1411/// let s = "tschüß";
1412///
1413/// assert_eq!("TSCHÜSS", s.to_uppercase());
1414/// ```
1415#[rune::function(instance)]
1416fn to_uppercase(s: &str) -> Result<String, VmError> {
1417    let mut uppercase = String::try_with_capacity(s.len())?;
1418    uppercase.try_extend(s.chars().flat_map(|c| c.to_uppercase()))?;
1419    Ok(uppercase)
1420}
1421
1422#[derive(Any)]
1423#[rune(item = ::std::string)]
1424struct Chars {
1425    string: Ref<str>,
1426    start: usize,
1427    end: usize,
1428}
1429
1430impl Chars {
1431    fn new(string: Ref<str>) -> Self {
1432        let end = string.len();
1433        Self {
1434            string,
1435            start: 0,
1436            end,
1437        }
1438    }
1439
1440    #[rune::function(keep, protocol = NEXT)]
1441    fn next(&mut self) -> Option<char> {
1442        let string = self.string.get(self.start..self.end)?;
1443        let c = string.chars().next()?;
1444        self.start += c.len_utf8();
1445        Some(c)
1446    }
1447
1448    #[rune::function(keep, protocol = NEXT_BACK)]
1449    fn next_back(&mut self) -> Option<char> {
1450        let string = self.string.get(self.start..self.end)?;
1451        let c = string.chars().next_back()?;
1452        self.end -= c.len_utf8();
1453        Some(c)
1454    }
1455}
1456
1457pub(crate) trait Pattern:
1458    'static + TryClone + Named + FromValue + ToValue + MaybeTypeOf + TypeOf
1459{
1460    fn test(&self, tail: &str) -> Result<(bool, usize), VmError>;
1461
1462    fn is_empty(&self) -> bool;
1463
1464    /// Hand over the values the pattern is made of, if it is made of any.
1465    ///
1466    /// A pattern which is a function carries what the closure captured, and a
1467    /// script can nest one split inside the next by capturing it, so what a
1468    /// pattern holds has to be handed over rather than dropped in place.
1469    fn dismantle(&mut self, _: &mut Handover<'_>) {}
1470}
1471
1472impl Pattern for String {
1473    fn test(&self, tail: &str) -> Result<(bool, usize), VmError> {
1474        if tail.starts_with(self.as_str()) {
1475            Ok((true, self.len()))
1476        } else {
1477            let Some(c) = tail.chars().next() else {
1478                return Ok((false, 0));
1479            };
1480
1481            Ok((false, c.len_utf8()))
1482        }
1483    }
1484
1485    #[inline]
1486    fn is_empty(&self) -> bool {
1487        String::is_empty(self)
1488    }
1489}
1490
1491impl Pattern for char {
1492    fn test(&self, tail: &str) -> Result<(bool, usize), VmError> {
1493        let Some(c) = tail.chars().next() else {
1494            return Ok((false, 0));
1495        };
1496
1497        Ok((c == *self, c.len_utf8()))
1498    }
1499
1500    #[inline]
1501    fn is_empty(&self) -> bool {
1502        false
1503    }
1504}
1505
1506impl Pattern for Function {
1507    fn dismantle(&mut self, out: &mut Handover<'_>) {
1508        Dismantle::dismantle(self, out)
1509    }
1510
1511    fn test(&self, tail: &str) -> Result<(bool, usize), VmError> {
1512        let Some(c) = tail.chars().next() else {
1513            return Ok((false, 0));
1514        };
1515
1516        Ok((self.call((c,))?, c.len_utf8()))
1517    }
1518
1519    #[inline]
1520    fn is_empty(&self) -> bool {
1521        false
1522    }
1523}
1524
1525#[derive(Any)]
1526#[rune(item = ::std::string, dismantle)]
1527pub(crate) struct Split<T>
1528where
1529    T: Pattern,
1530{
1531    string: Option<Ref<str>>,
1532    pattern: T,
1533    from: usize,
1534    to: usize,
1535}
1536
1537impl<T> Split<T>
1538where
1539    T: Pattern,
1540{
1541    fn new(string: Ref<str>, pattern: T) -> Self {
1542        Self {
1543            string: Some(string),
1544            pattern,
1545            from: 0,
1546            to: 0,
1547        }
1548    }
1549
1550    #[rune::function(keep, protocol = NEXT)]
1551    fn next(&mut self) -> Result<Option<String>, VmError> {
1552        let Some(string) = &self.string else {
1553            return Ok(None);
1554        };
1555
1556        if self.from == string.len() && self.from == self.to {
1557            self.string = None;
1558            let out = "".try_to_owned()?;
1559            return Ok(Some(out));
1560        }
1561
1562        while self.to < string.len() {
1563            let Some(tail) = string.get(self.to..) else {
1564                return Ok(None);
1565            };
1566
1567            let (m, len) = self.pattern.test(tail)?;
1568
1569            if m {
1570                let head = string.get(self.from..self.to).unwrap_or_default();
1571                let out = head.try_to_owned()?;
1572
1573                if len == 0 {
1574                    self.from = self.to;
1575                    self.to += tail.chars().next().map_or(0, |c| c.len_utf8());
1576                } else {
1577                    self.to += len;
1578                    self.from = self.to;
1579                }
1580
1581                return Ok(Some(out));
1582            } else {
1583                self.to += len;
1584            }
1585        }
1586
1587        let tail = string.get(self.from..self.to).unwrap_or_default();
1588        self.from = self.to;
1589        let out = tail.try_to_owned()?;
1590
1591        if !self.pattern.is_empty() {
1592            self.string = None;
1593        }
1594
1595        Ok(Some(out))
1596    }
1597
1598    #[rune::function(keep, protocol = INTO_ITER)]
1599    fn into_iter(self) -> Self {
1600        self
1601    }
1602}
1603
1604// Inlined code from core::unicode, since using it directly is marked as using an
1605// unstable library feature
1606mod unicode {
1607    fn decode_prefix_sum(short_offset_run_header: u32) -> u32 {
1608        short_offset_run_header & ((1 << 21) - 1)
1609    }
1610
1611    fn decode_length(short_offset_run_header: u32) -> usize {
1612        (short_offset_run_header >> 21) as usize
1613    }
1614
1615    #[inline(always)]
1616    fn skip_search<const SOR: usize, const OFFSETS: usize>(
1617        needle: u32,
1618        short_offset_runs: &[u32; SOR],
1619        offsets: &[u8; OFFSETS],
1620    ) -> bool {
1621        // Note that this *cannot* be past the end of the array, as the last
1622        // element is greater than std::char::MAX (the largest possible needle).
1623        //
1624        // So, we cannot have found it (i.e. Ok(idx) + 1 != length) and the correct
1625        // location cannot be past it, so Err(idx) != length either.
1626        //
1627        // This means that we can avoid bounds checking for the accesses below, too.
1628        let last_idx =
1629            match short_offset_runs.binary_search_by_key(&(needle << 11), |header| header << 11) {
1630                Ok(idx) => idx + 1,
1631                Err(idx) => idx,
1632            };
1633
1634        let mut offset_idx = decode_length(short_offset_runs[last_idx]);
1635        let length = if let Some(next) = short_offset_runs.get(last_idx + 1) {
1636            decode_length(*next) - offset_idx
1637        } else {
1638            offsets.len() - offset_idx
1639        };
1640        let prev = last_idx
1641            .checked_sub(1)
1642            .map(|prev| decode_prefix_sum(short_offset_runs[prev]))
1643            .unwrap_or(0);
1644
1645        let total = needle - prev;
1646        let mut prefix_sum = 0;
1647        for _ in 0..(length - 1) {
1648            let offset = offsets[offset_idx];
1649            prefix_sum += offset as u32;
1650            if prefix_sum > total {
1651                break;
1652            }
1653            offset_idx += 1;
1654        }
1655        offset_idx % 2 == 1
1656    }
1657
1658    #[rustfmt::skip]
1659    pub mod case_ignorable {
1660        static SHORT_OFFSET_RUNS: [u32; 35] = [
1661            688, 44045149, 572528402, 576724925, 807414908, 878718981, 903913493, 929080568, 933275148,
1662            937491230, 1138818560, 1147208189, 1210124160, 1222707713, 1235291428, 1260457643,
1663            1264654383, 1499535675, 1507925040, 1566646003, 1629566000, 1650551536, 1658941263,
1664            1671540720, 1688321181, 1700908800, 1709298023, 1717688832, 1738661888, 1763828398,
1665            1797383403, 1805773008, 1809970171, 1819148289, 1824457200,
1666        ];
1667        static OFFSETS: [u8; 875] = [
1668            39, 1, 6, 1, 11, 1, 35, 1, 1, 1, 71, 1, 4, 1, 1, 1, 4, 1, 2, 2, 0, 192, 4, 2, 4, 1, 9, 2,
1669            1, 1, 251, 7, 207, 1, 5, 1, 49, 45, 1, 1, 1, 2, 1, 2, 1, 1, 44, 1, 11, 6, 10, 11, 1, 1, 35,
1670            1, 10, 21, 16, 1, 101, 8, 1, 10, 1, 4, 33, 1, 1, 1, 30, 27, 91, 11, 58, 11, 4, 1, 2, 1, 24,
1671            24, 43, 3, 44, 1, 7, 2, 6, 8, 41, 58, 55, 1, 1, 1, 4, 8, 4, 1, 3, 7, 10, 2, 13, 1, 15, 1,
1672            58, 1, 4, 4, 8, 1, 20, 2, 26, 1, 2, 2, 57, 1, 4, 2, 4, 2, 2, 3, 3, 1, 30, 2, 3, 1, 11, 2,
1673            57, 1, 4, 5, 1, 2, 4, 1, 20, 2, 22, 6, 1, 1, 58, 1, 2, 1, 1, 4, 8, 1, 7, 2, 11, 2, 30, 1,
1674            61, 1, 12, 1, 50, 1, 3, 1, 55, 1, 1, 3, 5, 3, 1, 4, 7, 2, 11, 2, 29, 1, 58, 1, 2, 1, 6, 1,
1675            5, 2, 20, 2, 28, 2, 57, 2, 4, 4, 8, 1, 20, 2, 29, 1, 72, 1, 7, 3, 1, 1, 90, 1, 2, 7, 11, 9,
1676            98, 1, 2, 9, 9, 1, 1, 7, 73, 2, 27, 1, 1, 1, 1, 1, 55, 14, 1, 5, 1, 2, 5, 11, 1, 36, 9, 1,
1677            102, 4, 1, 6, 1, 2, 2, 2, 25, 2, 4, 3, 16, 4, 13, 1, 2, 2, 6, 1, 15, 1, 94, 1, 0, 3, 0, 3,
1678            29, 2, 30, 2, 30, 2, 64, 2, 1, 7, 8, 1, 2, 11, 3, 1, 5, 1, 45, 5, 51, 1, 65, 2, 34, 1, 118,
1679            3, 4, 2, 9, 1, 6, 3, 219, 2, 2, 1, 58, 1, 1, 7, 1, 1, 1, 1, 2, 8, 6, 10, 2, 1, 39, 1, 8, 31,
1680            49, 4, 48, 1, 1, 5, 1, 1, 5, 1, 40, 9, 12, 2, 32, 4, 2, 2, 1, 3, 56, 1, 1, 2, 3, 1, 1, 3,
1681            58, 8, 2, 2, 64, 6, 82, 3, 1, 13, 1, 7, 4, 1, 6, 1, 3, 2, 50, 63, 13, 1, 34, 101, 0, 1, 1,
1682            3, 11, 3, 13, 3, 13, 3, 13, 2, 12, 5, 8, 2, 10, 1, 2, 1, 2, 5, 49, 5, 1, 10, 1, 1, 13, 1,
1683            16, 13, 51, 33, 0, 2, 113, 3, 125, 1, 15, 1, 96, 32, 47, 1, 0, 1, 36, 4, 3, 5, 5, 1, 93, 6,
1684            93, 3, 0, 1, 0, 6, 0, 1, 98, 4, 1, 10, 1, 1, 28, 4, 80, 2, 14, 34, 78, 1, 23, 3, 103, 3, 3,
1685            2, 8, 1, 3, 1, 4, 1, 25, 2, 5, 1, 151, 2, 26, 18, 13, 1, 38, 8, 25, 11, 46, 3, 48, 1, 2, 4,
1686            2, 2, 17, 1, 21, 2, 66, 6, 2, 2, 2, 2, 12, 1, 8, 1, 35, 1, 11, 1, 51, 1, 1, 3, 2, 2, 5, 2,
1687            1, 1, 27, 1, 14, 2, 5, 2, 1, 1, 100, 5, 9, 3, 121, 1, 2, 1, 4, 1, 0, 1, 147, 17, 0, 16, 3,
1688            1, 12, 16, 34, 1, 2, 1, 169, 1, 7, 1, 6, 1, 11, 1, 35, 1, 1, 1, 47, 1, 45, 2, 67, 1, 21, 3,
1689            0, 1, 226, 1, 149, 5, 0, 6, 1, 42, 1, 9, 0, 3, 1, 2, 5, 4, 40, 3, 4, 1, 165, 2, 0, 4, 0, 2,
1690            80, 3, 70, 11, 49, 4, 123, 1, 54, 15, 41, 1, 2, 2, 10, 3, 49, 4, 2, 2, 2, 1, 4, 1, 10, 1,
1691            50, 3, 36, 5, 1, 8, 62, 1, 12, 2, 52, 9, 10, 4, 2, 1, 95, 3, 2, 1, 1, 2, 6, 1, 2, 1, 157, 1,
1692            3, 8, 21, 2, 57, 2, 3, 1, 37, 7, 3, 5, 195, 8, 2, 3, 1, 1, 23, 1, 84, 6, 1, 1, 4, 2, 1, 2,
1693            238, 4, 6, 2, 1, 2, 27, 2, 85, 8, 2, 1, 1, 2, 106, 1, 1, 1, 2, 6, 1, 1, 101, 3, 2, 4, 1, 5,
1694            0, 9, 1, 2, 0, 2, 1, 1, 4, 1, 144, 4, 2, 2, 4, 1, 32, 10, 40, 6, 2, 4, 8, 1, 9, 6, 2, 3, 46,
1695            13, 1, 2, 0, 7, 1, 6, 1, 1, 82, 22, 2, 7, 1, 2, 1, 2, 122, 6, 3, 1, 1, 2, 1, 7, 1, 1, 72, 2,
1696            3, 1, 1, 1, 0, 2, 11, 2, 52, 5, 5, 1, 1, 1, 0, 17, 6, 15, 0, 5, 59, 7, 9, 4, 0, 1, 63, 17,
1697            64, 2, 1, 2, 0, 4, 1, 7, 1, 2, 0, 2, 1, 4, 0, 46, 2, 23, 0, 3, 9, 16, 2, 7, 30, 4, 148, 3,
1698            0, 55, 4, 50, 8, 1, 14, 1, 22, 5, 1, 15, 0, 7, 1, 17, 2, 7, 1, 2, 1, 5, 5, 62, 33, 1, 160,
1699            14, 0, 1, 61, 4, 0, 5, 0, 7, 109, 8, 0, 5, 0, 1, 30, 96, 128, 240, 0,
1700        ];
1701        pub fn lookup(c: char) -> bool {
1702            super::skip_search(
1703                c as u32,
1704                &SHORT_OFFSET_RUNS,
1705                &OFFSETS,
1706            )
1707        }
1708    }
1709
1710    #[rustfmt::skip]
1711    pub mod cased {
1712        static SHORT_OFFSET_RUNS: [u32; 22] = [
1713            4256, 115348384, 136322176, 144711446, 163587254, 320875520, 325101120, 350268208,
1714            392231680, 404815649, 413205504, 421595008, 467733632, 484513952, 492924480, 497144832,
1715            501339814, 578936576, 627171376, 639756544, 643952944, 649261450,
1716        ];
1717        static OFFSETS: [u8; 315] = [
1718            65, 26, 6, 26, 47, 1, 10, 1, 4, 1, 5, 23, 1, 31, 1, 195, 1, 4, 4, 208, 1, 36, 7, 2, 30, 5,
1719            96, 1, 42, 4, 2, 2, 2, 4, 1, 1, 6, 1, 1, 3, 1, 1, 1, 20, 1, 83, 1, 139, 8, 166, 1, 38, 9,
1720            41, 0, 38, 1, 1, 5, 1, 2, 43, 1, 4, 0, 86, 2, 6, 0, 9, 7, 43, 2, 3, 64, 192, 64, 0, 2, 6, 2,
1721            38, 2, 6, 2, 8, 1, 1, 1, 1, 1, 1, 1, 31, 2, 53, 1, 7, 1, 1, 3, 3, 1, 7, 3, 4, 2, 6, 4, 13,
1722            5, 3, 1, 7, 116, 1, 13, 1, 16, 13, 101, 1, 4, 1, 2, 10, 1, 1, 3, 5, 6, 1, 1, 1, 1, 1, 1, 4,
1723            1, 6, 4, 1, 2, 4, 5, 5, 4, 1, 17, 32, 3, 2, 0, 52, 0, 229, 6, 4, 3, 2, 12, 38, 1, 1, 5, 1,
1724            0, 46, 18, 30, 132, 102, 3, 4, 1, 59, 5, 2, 1, 1, 1, 5, 24, 5, 1, 3, 0, 43, 1, 14, 6, 80, 0,
1725            7, 12, 5, 0, 26, 6, 26, 0, 80, 96, 36, 4, 36, 116, 11, 1, 15, 1, 7, 1, 2, 1, 11, 1, 15, 1,
1726            7, 1, 2, 0, 1, 2, 3, 1, 42, 1, 9, 0, 51, 13, 51, 0, 64, 0, 64, 0, 85, 1, 71, 1, 2, 2, 1, 2,
1727            2, 2, 4, 1, 12, 1, 1, 1, 7, 1, 65, 1, 4, 2, 8, 1, 7, 1, 28, 1, 4, 1, 5, 1, 1, 3, 7, 1, 0, 2,
1728            25, 1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, 8, 0, 10, 1, 20, 6, 6,
1729            0, 62, 0, 68, 0, 26, 6, 26, 6, 26, 0,
1730        ];
1731        pub fn lookup(c: char) -> bool {
1732            super::skip_search(
1733                c as u32,
1734                &SHORT_OFFSET_RUNS,
1735                &OFFSETS,
1736            )
1737        }
1738    }
1739}
1740
1741/// A split carries the pattern it was handed, which is a value made of values
1742/// when it is a function, so it hands it over rather than being dropped in
1743/// place.
1744impl<T> Dismantle for Split<T>
1745where
1746    T: Pattern,
1747{
1748    fn dismantle(&mut self, out: &mut Handover<'_>) {
1749        Pattern::dismantle(&mut self.pattern, out)
1750    }
1751}