Skip to content

Commit b074022

Browse files
author
Zibi Braniecki
committed
Switch to Cow
1 parent 2984d98 commit b074022

File tree

4 files changed

+31
-30
lines changed

4 files changed

+31
-30
lines changed

fluent-bundle/src/resolve.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -177,11 +177,7 @@ impl<'source> ResolveValue for ast::InlineExpression<'source> {
177177
fn to_value(&self, env: &Env) -> Result<FluentValue, ResolverError> {
178178
match self {
179179
ast::InlineExpression::StringLiteral { raw } => {
180-
if let Some(unescaped_value) = unescape_unicode(raw) {
181-
Ok(FluentValue::from(unescaped_value))
182-
} else {
183-
Ok(FluentValue::from(*raw))
184-
}
180+
Ok(FluentValue::from(unescape_unicode(raw).into_owned()))
185181
}
186182
ast::InlineExpression::NumberLiteral { value } => {
187183
Ok(FluentValue::as_number(*value).unwrap())

fluent-syntax/src/unicode.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::borrow::Cow;
12
use std::char;
23

34
fn encode_unicode(s: &str) -> char {
@@ -7,22 +8,22 @@ fn encode_unicode(s: &str) -> char {
78
.unwrap_or('�')
89
}
910

10-
pub fn unescape_unicode(string: &str) -> Option<String> {
11-
let bytes = string.as_bytes();
11+
pub fn unescape_unicode<'u>(input: &'u str) -> Cow<'u, str> {
12+
let bytes = input.as_bytes();
1213
let mut result: Option<String> = None;
1314

1415
let mut ptr = 0;
1516

1617
while let Some(b) = bytes.get(ptr) {
1718
if b != &b'\\' {
18-
if let Some(ref mut result) = result {
19-
result.push(*b as char);
19+
if let Some(ref mut s) = result {
20+
s.push(*b as char);
2021
}
2122
ptr += 1;
2223
continue;
2324
}
2425

25-
let new_string = result.get_or_insert_with(|| String::from(&string[0..ptr]));
26+
let new_string = result.get_or_insert_with(|| String::from(&input[0..ptr]));
2627

2728
ptr += 1;
2829

@@ -33,7 +34,7 @@ pub fn unescape_unicode(string: &str) -> Option<String> {
3334
let start = ptr + 1;
3435
let len = if u == &b'u' { 4 } else { 6 };
3536
ptr += len;
36-
string
37+
input
3738
.get(start..(start + len))
3839
.map(|slice| encode_unicode(slice))
3940
.unwrap_or('�')
@@ -43,5 +44,5 @@ pub fn unescape_unicode(string: &str) -> Option<String> {
4344
new_string.push(new_char);
4445
ptr += 1;
4546
}
46-
return result;
47+
result.map_or_else(|| Cow::from(input), Cow::from)
4748
}

fluent-syntax/tests/ast/mod.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -359,11 +359,7 @@ where
359359
let mut map = serializer.serialize_map(Some(3))?;
360360
map.serialize_entry("type", "StringLiteral")?;
361361
map.serialize_entry("raw", raw)?;
362-
if let Some(unescaped_value) = unescape_unicode(&raw) {
363-
map.serialize_entry("value", &unescaped_value)?;
364-
} else {
365-
map.serialize_entry("value", &raw)?;
366-
}
362+
map.serialize_entry("value", &unescape_unicode(&raw))?;
367363
map.end()
368364
}
369365

fluent-syntax/tests/unicode.rs

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,32 @@
11
use fluent_syntax::unicode::unescape_unicode;
2+
use std::borrow::Cow;
3+
4+
fn is_cow_borrowed<'a>(input: Cow<'a, str>) -> bool {
5+
if let Cow::Borrowed(_) = input {
6+
true
7+
} else {
8+
false
9+
}
10+
}
211

312
#[test]
413
fn unescape_unicode_test() {
5-
assert_eq!(unescape_unicode("foo"), None);
6-
assert_eq!(unescape_unicode("foo \\\\"), Some("foo \\".to_owned()));
7-
assert_eq!(unescape_unicode("foo \\\""), Some("foo \"".to_owned()));
8-
assert_eq!(
9-
unescape_unicode("foo \\\\ faa"),
10-
Some("foo \\ faa".to_owned())
11-
);
14+
assert!(is_cow_borrowed(unescape_unicode("foo")));
15+
16+
assert_eq!(unescape_unicode("foo"), "foo");
17+
assert_eq!(unescape_unicode("foo \\\\"), "foo \\");
18+
assert_eq!(unescape_unicode("foo \\\""), "foo \"");
19+
assert_eq!(unescape_unicode("foo \\\\ faa"), "foo \\ faa");
1220
assert_eq!(
1321
unescape_unicode("foo \\\\ faa \\\\ fii"),
14-
Some("foo \\ faa \\ fii".to_owned())
22+
"foo \\ faa \\ fii"
1523
);
1624
assert_eq!(
1725
unescape_unicode("foo \\\\\\\" faa \\\"\\\\ fii"),
18-
Some("foo \\\" faa \"\\ fii".to_owned())
26+
"foo \\\" faa \"\\ fii"
1927
);
20-
assert_eq!(unescape_unicode("\\u0041\\u004F"), Some("AO".to_owned()));
21-
assert_eq!(unescape_unicode("\\uA"), Some("�".to_owned()));
22-
assert_eq!(unescape_unicode("\\uA0Pl"), Some("�".to_owned()));
23-
assert_eq!(unescape_unicode("\\d Foo"), Some("� Foo".to_owned()));
28+
assert_eq!(unescape_unicode("\\u0041\\u004F"), "AO");
29+
assert_eq!(unescape_unicode("\\uA"), "�");
30+
assert_eq!(unescape_unicode("\\uA0Pl"), "�");
31+
assert_eq!(unescape_unicode("\\d Foo"), "� Foo");
2432
}

0 commit comments

Comments
 (0)