1use jrsonnet_evaluator::{2 error::{Error::*, Result},3 function::builtin,4 typed::{Either2, VecVal, M1},5 val::ArrValue,6 Either, IStr, Val,7};8use jrsonnet_gcmodule::Cc;910#[builtin]11pub const fn builtin_codepoint(str: char) -> Result<u32> {12 Ok(str as u32)13}1415#[builtin]16pub fn builtin_substr(str: IStr, from: usize, len: usize) -> Result<String> {17 Ok(str.chars().skip(from).take(len).collect())18}1920#[builtin]21pub fn builtin_char(n: u32) -> Result<char> {22 Ok(std::char::from_u32(n).ok_or_else(|| InvalidUnicodeCodepointGot(n))?)23}2425#[builtin]26pub fn builtin_str_replace(str: String, from: IStr, to: IStr) -> Result<String> {27 Ok(str.replace(&from as &str, &to as &str))28}2930#[builtin]31pub fn builtin_splitlimit(str: IStr, c: IStr, maxsplits: Either![usize, M1]) -> Result<VecVal> {32 use Either2::*;33 Ok(VecVal(Cc::new(match maxsplits {34 A(n) => str35 .splitn(n + 1, &c as &str)36 .map(|s| Val::Str(s.into()))37 .collect(),38 B(_) => str.split(&c as &str).map(|s| Val::Str(s.into())).collect(),39 })))40}4142#[builtin]43pub fn builtin_ascii_upper(str: IStr) -> Result<String> {44 Ok(str.to_ascii_uppercase())45}4647#[builtin]48pub fn builtin_ascii_lower(str: IStr) -> Result<String> {49 Ok(str.to_ascii_lowercase())50}5152#[builtin]53pub fn builtin_find_substr(pat: IStr, str: IStr) -> Result<ArrValue> {54 if pat.is_empty() || str.is_empty() || pat.len() > str.len() {55 return Ok(ArrValue::empty());56 }5758 let str = str.as_str();59 let pat = pat.as_bytes();60 let strb = str.as_bytes();6162 let max_pos = str.len() - pat.len();6364 let mut out: Vec<Val> = Vec::new();65 for (ch_idx, (i, _)) in str66 .char_indices()67 .take_while(|(i, _)| i <= &max_pos)68 .enumerate()69 {70 if &strb[i..i + pat.len()] == pat {71 out.push(Val::Num(ch_idx as f64))72 }73 }74 Ok(out.into())75}