diff options
Diffstat (limited to 'src/eval/str.rs')
| -rw-r--r-- | src/eval/str.rs | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/src/eval/str.rs b/src/eval/str.rs new file mode 100644 index 00000000..3b4349a1 --- /dev/null +++ b/src/eval/str.rs @@ -0,0 +1,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() + } + } +} |
