Add len and split methods to the default methods
This commit is contained in:
parent
00e67d34d9
commit
f29573d9ad
@ -9,7 +9,12 @@ use super::TemplateAccessibleMethod;
|
|||||||
const DEFAULT_TEMPLATE_ACCESSIBLE_METHODS: &'static [(
|
const DEFAULT_TEMPLATE_ACCESSIBLE_METHODS: &'static [(
|
||||||
&'static str,
|
&'static str,
|
||||||
fn(Value, Vec<Value>) -> Result<Value, String>,
|
fn(Value, Vec<Value>) -> Result<Value, String>,
|
||||||
)] = &[("leftpad", leftpad), ("urlencode", urlencode)];
|
)] = &[
|
||||||
|
("leftpad", leftpad),
|
||||||
|
("urlencode", urlencode),
|
||||||
|
("len", len),
|
||||||
|
("split", split),
|
||||||
|
];
|
||||||
|
|
||||||
/// Return a map of the default suggested template-accessible methods.
|
/// Return a map of the default suggested template-accessible methods.
|
||||||
pub fn default_template_accessible_methods() -> BTreeMap<String, TemplateAccessibleMethod> {
|
pub fn default_template_accessible_methods() -> BTreeMap<String, TemplateAccessibleMethod> {
|
||||||
@ -24,6 +29,9 @@ pub fn default_template_accessible_methods() -> BTreeMap<String, TemplateAccessi
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Left-pads a string to a given length using a given padding character.
|
||||||
|
///
|
||||||
|
/// `<Str>.leftpad(<Int>, <Str>) -> Str`
|
||||||
pub fn leftpad(obj: Value, args: Vec<Value>) -> Result<Value, String> {
|
pub fn leftpad(obj: Value, args: Vec<Value>) -> Result<Value, String> {
|
||||||
let Value::Str(string_to_pad) = obj else {
|
let Value::Str(string_to_pad) = obj else {
|
||||||
return Err(format!("{obj:?} is not a string: can't leftpad!"));
|
return Err(format!("{obj:?} is not a string: can't leftpad!"));
|
||||||
@ -60,6 +68,9 @@ pub fn leftpad(obj: Value, args: Vec<Value>) -> Result<Value, String> {
|
|||||||
Ok(Value::Str(Arc::new(result)))
|
Ok(Value::Str(Arc::new(result)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// URL-encodes sensitive characters in a string.
|
||||||
|
///
|
||||||
|
/// `<Str>.urlencode() -> Str`
|
||||||
pub fn urlencode(obj: Value, args: Vec<Value>) -> Result<Value, String> {
|
pub fn urlencode(obj: Value, args: Vec<Value>) -> Result<Value, String> {
|
||||||
let Value::Str(string_to_encode) = obj else {
|
let Value::Str(string_to_encode) = obj else {
|
||||||
return Err(format!("{obj:?} is not a string: can't urlencode!"));
|
return Err(format!("{obj:?} is not a string: can't urlencode!"));
|
||||||
@ -72,3 +83,47 @@ pub fn urlencode(obj: Value, args: Vec<Value>) -> Result<Value, String> {
|
|||||||
percent_encoding::utf8_percent_encode(&string_to_encode, NON_ALPHANUMERIC).to_string(),
|
percent_encoding::utf8_percent_encode(&string_to_encode, NON_ALPHANUMERIC).to_string(),
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the length of a given string or list.
|
||||||
|
///
|
||||||
|
/// - `<Str>.len() -> Int`
|
||||||
|
/// - `<List>.len() -> Int`
|
||||||
|
pub fn len(obj: Value, args: Vec<Value>) -> Result<Value, String> {
|
||||||
|
if args.len() != 0 {
|
||||||
|
return Err(format!("len takes 0 args, not {}", args.len()));
|
||||||
|
}
|
||||||
|
|
||||||
|
match obj {
|
||||||
|
Value::Str(string) => Ok(Value::Int(string.len() as i64)),
|
||||||
|
Value::List(list) => Ok(Value::Int(list.len() as i64)),
|
||||||
|
_ => {
|
||||||
|
return Err(format!(
|
||||||
|
"{obj:?} is not a string or list: can't get length!"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Splits a string by given delimiters.
|
||||||
|
///
|
||||||
|
/// `<Str>.split(<Str>) -> List of Str`
|
||||||
|
pub fn split(obj: Value, args: Vec<Value>) -> Result<Value, String> {
|
||||||
|
if args.len() != 1 {
|
||||||
|
return Err(format!("split takes 1 arg, not {}", args.len()));
|
||||||
|
}
|
||||||
|
|
||||||
|
let Value::Str(string_to_split) = obj else {
|
||||||
|
return Err(format!("{obj:?} is not a string: can't split!"));
|
||||||
|
};
|
||||||
|
|
||||||
|
let Value::Str(delimiter) = &args[0] else {
|
||||||
|
return Err(format!("first arg is not a string: can't split!"));
|
||||||
|
};
|
||||||
|
|
||||||
|
let result = string_to_split
|
||||||
|
.split(delimiter.as_str())
|
||||||
|
.map(|segment| Value::Str(Arc::new(segment.to_owned())))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
Ok(Value::List(result))
|
||||||
|
}
|
||||||
|
@ -75,6 +75,13 @@ br
|
|||||||
"padded to 15: ${$sts.carrot.leftpad(15, 'M')}"
|
"padded to 15: ${$sts.carrot.leftpad(15, 'M')}"
|
||||||
br
|
br
|
||||||
"urlencoded: ${$sts.carrot.urlencode()}"
|
"urlencoded: ${$sts.carrot.urlencode()}"
|
||||||
|
br
|
||||||
|
"length: ${$sts.carrot.len()}"
|
||||||
|
br
|
||||||
|
"split on A: "
|
||||||
|
for $part in $sts.carrot.split("A")
|
||||||
|
"($part)"
|
||||||
|
br
|
||||||
"#
|
"#
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
source: hornbeam_interpreter/tests/snapshots.rs
|
source: hornbeam_interpreter/tests/snapshots.rs
|
||||||
expression: "simple_render(r#\"\n\"unpadded: ${$sts.carrot}\"\nbr\n\"padded to 15: ${$sts.carrot.leftpad(15, 'M')}\"\nbr\n\"urlencoded: ${$sts.carrot.urlencode()}\"\n \"#)"
|
expression: "simple_render(r#\"\n\"unpadded: ${$sts.carrot}\"\nbr\n\"padded to 15: ${$sts.carrot.leftpad(15, 'M')}\"\nbr\n\"urlencoded: ${$sts.carrot.urlencode()}\"\nbr\n\"length: ${$sts.carrot.len()}\"\nbr\n\"split on A: \"\nfor $part in $sts.carrot.split(\"A\")\n \"($part)\"\n br\n \"#)"
|
||||||
---
|
---
|
||||||
unpadded: mmm CARROT!<br>padded to 15: MMMMmmm CARROT!<br>urlencoded: mmm%20CARROT%21
|
unpadded: mmm CARROT!<br>padded to 15: MMMMmmm CARROT!<br>urlencoded: mmm%20CARROT%21<br>length: 11<br>split on A: (mmm C)<br>(RROT!)<br>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user