Skip to content

Commit b4bce3e

Browse files
Add FluentValue.into_string to prevent String clone (#301)
1 parent 2d7b1fa commit b4bce3e

File tree

3 files changed

+27
-2
lines changed

3 files changed

+27
-2
lines changed

fluent-bundle/src/bundle.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -494,7 +494,7 @@ impl<R, M> FluentBundle<R, M> {
494494
{
495495
let mut scope = Scope::new(self, args, Some(errors));
496496
let value = pattern.resolve(&mut scope);
497-
value.as_string(&scope)
497+
value.into_string(&scope)
498498
}
499499

500500
/// Makes the provided rust function available to messages with the name `id`. See

fluent-bundle/src/resolver/inline_expression.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ impl<'bundle> WriteValue<'bundle> for ast::InlineExpression<&'bundle str> {
9393
if let FluentValue::Error = result {
9494
self.write_error(w)
9595
} else {
96-
w.write_str(&result.as_string(scope))
96+
w.write_str(&result.into_string(scope))
9797
}
9898
} else {
9999
scope.write_ref_error(w, self)

fluent-bundle/src/types/mod.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,9 @@ impl<'source> FluentValue<'source> {
235235
}
236236

237237
/// Converts the [`FluentValue`] to a string.
238+
///
239+
/// Clones inner values when owned, borrowed data is not cloned.
240+
/// Prefer using [`FluentValue::into_string()`] when possible.
238241
pub fn as_string<R: Borrow<FluentResource>, M>(&self, scope: &Scope<R, M>) -> Cow<'source, str>
239242
where
240243
M: MemoizerKind,
@@ -253,6 +256,28 @@ impl<'source> FluentValue<'source> {
253256
}
254257
}
255258

259+
/// Converts the [`FluentValue`] to a string.
260+
///
261+
/// Takes self by-value to be able to skip expensive clones.
262+
/// Prefer this method over [`FluentValue::as_string()`] when possible.
263+
pub fn into_string<R: Borrow<FluentResource>, M>(self, scope: &Scope<R, M>) -> Cow<'source, str>
264+
where
265+
M: MemoizerKind,
266+
{
267+
if let Some(formatter) = &scope.bundle.formatter {
268+
if let Some(val) = formatter(&self, &scope.bundle.intls) {
269+
return val.into();
270+
}
271+
}
272+
match self {
273+
FluentValue::String(s) => s,
274+
FluentValue::Number(n) => n.as_string(),
275+
FluentValue::Custom(s) => scope.bundle.intls.stringify_value(s.as_ref()),
276+
FluentValue::Error => "".into(),
277+
FluentValue::None => "".into(),
278+
}
279+
}
280+
256281
pub fn into_owned<'a>(&self) -> FluentValue<'a> {
257282
match self {
258283
FluentValue::String(str) => FluentValue::String(Cow::from(str.to_string())),

0 commit comments

Comments
 (0)