summaryrefslogtreecommitdiff
path: root/src/eval/str.rs
blob: 3b4349a161213ee6c1472eb3c5940758bb76b167 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
use super::{Array, Value};
use crate::diag::StrResult;
use crate::util::EcoString;

/// Extra methods on strings.
pub trait StrExt {
    /// Repeat a string a number of times.
    fn repeat(&self, n: i64) -> StrResult<EcoString>;

    /// Split this string at whitespace or a specific pattern.
    fn split(&self, at: Option<EcoString>) -> Array;
}

impl StrExt for EcoString {
    fn repeat(&self, n: i64) -> StrResult<EcoString> {
        let n = usize::try_from(n)
            .ok()
            .and_then(|n| self.len().checked_mul(n).map(|_| n))
            .ok_or_else(|| format!("cannot repeat this string {} times", n))?;

        Ok(self.repeat(n))
    }

    fn split(&self, at: Option<EcoString>) -> Array {
        if let Some(pat) = at {
            self.as_str()
                .split(pat.as_str())
                .map(|s| Value::Str(s.into()))
                .collect()
        } else {
            self.as_str()
                .split_whitespace()
                .map(|s| Value::Str(s.into()))
                .collect()
        }
    }
}