in starlark/src/values/types/string/interpolation.rs [425:478]
fn format_capture<'v, T: Iterator<Item = Value<'v>>>(
capture: &str,
args: &mut FormatArgs<'v, T>,
kwargs: &Dict,
result: &mut String,
) -> anyhow::Result<()> {
let (n, conv) = {
if let Some((n, conv)) = capture.split_once('!') {
(n, conv)
} else {
(capture, "s")
}
};
let conv_s = |x: Value, result: &mut String| x.collect_str(result);
let conv_r = |x: Value, result: &mut String| x.collect_repr(result);
let conv: &dyn Fn(Value, &mut String) = match conv {
"s" => &conv_s,
"r" => &conv_r,
c => {
return Err(anyhow!(
concat!(
"'{}' is not a valid format string specifier, only ",
"'s' and 'r' are valid specifiers",
),
c
));
}
};
if n.is_empty() {
conv(args.next_ordered()?, result);
Ok(())
} else if n.chars().all(|c| c.is_ascii_digit()) {
let i = usize::from_str(n).unwrap();
conv(args.by_index(i)?, result);
Ok(())
} else {
if let Some(x) = n.chars().find(|c| match c {
'.' | ',' | '[' | ']' => true,
_ => false,
}) {
return Err(anyhow!(
"Invalid character '{}' inside replacement field",
x
));
}
match kwargs.get_str(n) {
None => Err(ValueError::KeyNotFound(n.to_owned()).into()),
Some(v) => {
conv(v, result);
Ok(())
}
}
}
}