From bba376a7242105d3253b7a73620dd352bb7a2978 Mon Sep 17 00:00:00 2001 From: Yuya Nishihara Date: Thu, 29 Feb 2024 13:00:59 +0900 Subject: [PATCH] templater: extract fallible i64->isize conversion to helper function --- cli/src/template_builder.rs | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/cli/src/template_builder.rs b/cli/src/template_builder.rs index 844836bb63..75ad4766b6 100644 --- a/cli/src/template_builder.rs +++ b/cli/src/template_builder.rs @@ -557,8 +557,8 @@ fn builtin_string_methods<'a, L: TemplateLanguage<'a>>() -> TemplateBuildMethodF ); map.insert("substr", |language, build_ctx, self_property, function| { let [start_idx, end_idx] = template_parser::expect_exact_arguments(function)?; - let start_idx_property = expect_integer_expression(language, build_ctx, start_idx)?; - let end_idx_property = expect_integer_expression(language, build_ctx, end_idx)?; + let start_idx_property = expect_isize_expression(language, build_ctx, start_idx)?; + let end_idx_property = expect_isize_expression(language, build_ctx, end_idx)?; let out_property = TemplateFunction::new( (self_property, start_idx_property, end_idx_property), |(s, start_idx, end_idx)| Ok(string_substr(&s, start_idx, end_idx)), @@ -595,13 +595,13 @@ fn builtin_string_methods<'a, L: TemplateLanguage<'a>>() -> TemplateBuildMethodF map } -fn string_substr(s: &str, start_idx: i64, end_idx: i64) -> String { +fn string_substr(s: &str, start_idx: isize, end_idx: isize) -> String { // TODO: If we add .len() method, we'll expose bytes-based and char-based APIs. // Having different index units would be confusing, so we might want to change // .substr() to bytes-based and round up/down towards char or grapheme-cluster // boundary. - let to_idx = |i: i64| -> usize { - let magnitude = usize::try_from(i.unsigned_abs()).unwrap_or(usize::MAX); + let to_idx = |i: isize| -> usize { + let magnitude = i.unsigned_abs(); if i < 0 { s.chars().count().saturating_sub(magnitude) } else { @@ -1032,6 +1032,17 @@ pub fn expect_integer_expression<'a, L: TemplateLanguage<'a>>( .ok_or_else(|| TemplateParseError::expected_type("Integer", node.span)) } +/// If the given expression `node` is of `Integer` type, converts it to `isize`. +pub fn expect_isize_expression<'a, L: TemplateLanguage<'a>>( + language: &L, + build_ctx: &BuildContext, + node: &ExpressionNode, +) -> TemplateParseResult + 'a>> { + let i64_property = expect_integer_expression(language, build_ctx, node)?; + let isize_property = TemplateFunction::new(i64_property, |v| Ok(isize::try_from(v)?)); + Ok(Box::new(isize_property)) +} + /// If the given expression `node` is of `Integer` type, converts it to `usize`. pub fn expect_usize_expression<'a, L: TemplateLanguage<'a>>( language: &L,