1
1
use super :: scope:: Scope ;
2
- use super :: { ResolveValue , ResolverError , WriteValue } ;
3
-
4
- use std:: borrow:: Borrow ;
5
- use std:: fmt;
6
-
7
- use fluent_syntax:: ast;
8
- use fluent_syntax:: unicode:: { unescape_unicode, unescape_unicode_to_string} ;
2
+ use super :: { ResolverError , WriteOrResolve , WriteOrResolveContext } ;
9
3
10
4
use crate :: entry:: GetEntry ;
11
5
use crate :: memoizer:: MemoizerKind ;
12
6
use crate :: resource:: FluentResource ;
13
7
use crate :: types:: FluentValue ;
8
+ use fluent_syntax:: ast;
9
+ use std:: borrow:: { Borrow , Cow } ;
10
+ use std:: fmt;
14
11
15
- impl < ' bundle > WriteValue < ' bundle > for ast:: InlineExpression < & ' bundle str > {
16
- fn write < ' ast , ' args , ' errors , W , R , M > (
12
+ impl < ' bundle > WriteOrResolve < ' bundle > for ast:: InlineExpression < & ' bundle str > {
13
+ fn write_or_resolve < ' ast , ' args , ' errors , R , M , T > (
17
14
& ' ast self ,
18
- w : & mut W ,
19
15
scope : & mut Scope < ' bundle , ' ast , ' args , ' errors , R , M > ,
20
- ) -> fmt:: Result
16
+ context : & mut T ,
17
+ ) -> T :: Result
21
18
where
22
- W : fmt:: Write ,
23
19
R : Borrow < FluentResource > ,
24
20
M : MemoizerKind ,
21
+ T : WriteOrResolveContext < ' bundle > ,
25
22
{
26
23
match self {
27
- Self :: StringLiteral { value } => unescape_unicode ( w , value) ,
24
+ Self :: StringLiteral { value } => context . unescape ( value) ,
28
25
Self :: MessageReference { id, attribute } => {
29
26
if let Some ( msg) = scope. bundle . get_entry_message ( id. name ) {
30
27
if let Some ( attr) = attribute {
31
28
msg. attributes
32
29
. iter ( )
33
30
. find_map ( |a| {
34
31
if a. id . name == attr. name {
35
- Some ( scope. track ( w , & a. value , self ) )
32
+ Some ( scope. track ( context , & a. value , self ) )
36
33
} else {
37
34
None
38
35
}
39
36
} )
40
- . unwrap_or_else ( || scope. write_ref_error ( w, self ) )
37
+ . unwrap_or_else ( || {
38
+ scope. add_error ( self . into ( ) ) ;
39
+ context. error ( self , true )
40
+ } )
41
41
} else {
42
42
msg. value
43
43
. as_ref ( )
44
- . map ( |value| scope. track ( w , value, self ) )
44
+ . map ( |value| scope. track ( context , value, self ) )
45
45
. unwrap_or_else ( || {
46
46
scope. add_error ( ResolverError :: NoValue ( id. name . to_string ( ) ) ) ;
47
- w. write_char ( '{' ) ?;
48
- self . write_error ( w) ?;
49
- w. write_char ( '}' )
47
+ context. error ( self , true )
50
48
} )
51
49
}
52
50
} else {
53
- scope. write_ref_error ( w, self )
51
+ scope. add_error ( self . into ( ) ) ;
52
+ context. error ( self , true )
54
53
}
55
54
}
56
- Self :: NumberLiteral { value } => FluentValue :: try_number ( value) . write ( w, scope) ,
55
+ Self :: NumberLiteral { value } => {
56
+ context. value ( scope, Cow :: Owned ( FluentValue :: try_number ( value) ) )
57
+ }
57
58
Self :: TermReference {
58
59
id,
59
60
attribute,
@@ -69,16 +70,19 @@ impl<'bundle> WriteValue<'bundle> for ast::InlineExpression<&'bundle str> {
69
70
if let Some ( attr) = attribute {
70
71
term. attributes . iter ( ) . find_map ( |a| {
71
72
if a. id . name == attr. name {
72
- Some ( scope. track ( w , & a. value , self ) )
73
+ Some ( scope. track ( context , & a. value , self ) )
73
74
} else {
74
75
None
75
76
}
76
77
} )
77
78
} else {
78
- Some ( scope. track ( w , & term. value , self ) )
79
+ Some ( scope. track ( context , & term. value , self ) )
79
80
}
80
81
} )
81
- . unwrap_or_else ( || scope. write_ref_error ( w, self ) ) ;
82
+ . unwrap_or_else ( || {
83
+ scope. add_error ( self . into ( ) ) ;
84
+ context. error ( self , true )
85
+ } ) ;
82
86
scope. local_args = None ;
83
87
result
84
88
}
@@ -90,30 +94,31 @@ impl<'bundle> WriteValue<'bundle> for ast::InlineExpression<&'bundle str> {
90
94
91
95
if let Some ( func) = func {
92
96
let result = func ( resolved_positional_args. as_slice ( ) , & resolved_named_args) ;
93
- if let FluentValue :: Error = result {
94
- self . write_error ( w )
97
+ if matches ! ( result , FluentValue :: Error ) {
98
+ context . error ( self , false )
95
99
} else {
96
- w . write_str ( & result . into_string ( scope) )
100
+ context . value ( scope, Cow :: Owned ( result ) )
97
101
}
98
102
} else {
99
- scope. write_ref_error ( w, self )
103
+ scope. add_error ( self . into ( ) ) ;
104
+ context. error ( self , true )
100
105
}
101
106
}
102
107
Self :: VariableReference { id } => {
103
- let args = scope. local_args . as_ref ( ) . or ( scope. args ) ;
104
-
105
- if let Some ( arg) = args. and_then ( |args| args. get ( id. name ) ) {
106
- arg. write ( w, scope)
107
- } else {
108
- if scope. local_args . is_none ( ) {
109
- scope. add_error ( self . into ( ) ) ;
108
+ if let Some ( local_args) = & scope. local_args {
109
+ if let Some ( arg) = local_args. get ( id. name ) {
110
+ return context. value ( scope, Cow :: Borrowed ( arg) ) ;
110
111
}
111
- w. write_char ( '{' ) ?;
112
- self . write_error ( w) ?;
113
- w. write_char ( '}' )
112
+ } else if let Some ( arg) = scope. args . and_then ( |args| args. get ( id. name ) ) {
113
+ return context. value ( scope, Cow :: Owned ( arg. into_owned ( ) ) ) ;
114
+ }
115
+
116
+ if scope. local_args . is_none ( ) {
117
+ scope. add_error ( self . into ( ) ) ;
114
118
}
119
+ context. error ( self , true )
115
120
}
116
- Self :: Placeable { expression } => expression. write ( w , scope ) ,
121
+ Self :: Placeable { expression } => expression. write_or_resolve ( scope , context ) ,
117
122
}
118
123
}
119
124
@@ -146,51 +151,3 @@ impl<'bundle> WriteValue<'bundle> for ast::InlineExpression<&'bundle str> {
146
151
}
147
152
}
148
153
}
149
-
150
- impl < ' bundle > ResolveValue < ' bundle > for ast:: InlineExpression < & ' bundle str > {
151
- fn resolve < ' ast , ' args , ' errors , R , M > (
152
- & ' ast self ,
153
- scope : & mut Scope < ' bundle , ' ast , ' args , ' errors , R , M > ,
154
- ) -> FluentValue < ' bundle >
155
- where
156
- R : Borrow < FluentResource > ,
157
- M : MemoizerKind ,
158
- {
159
- match self {
160
- Self :: StringLiteral { value } => unescape_unicode_to_string ( value) . into ( ) ,
161
- Self :: NumberLiteral { value } => FluentValue :: try_number ( value) ,
162
- Self :: VariableReference { id } => {
163
- if let Some ( local_args) = & scope. local_args {
164
- if let Some ( arg) = local_args. get ( id. name ) {
165
- return arg. clone ( ) ;
166
- }
167
- } else if let Some ( arg) = scope. args . and_then ( |args| args. get ( id. name ) ) {
168
- return arg. into_owned ( ) ;
169
- }
170
-
171
- if scope. local_args . is_none ( ) {
172
- scope. add_error ( self . into ( ) ) ;
173
- }
174
- FluentValue :: Error
175
- }
176
- Self :: FunctionReference { id, arguments } => {
177
- let ( resolved_positional_args, resolved_named_args) =
178
- scope. get_arguments ( Some ( arguments) ) ;
179
-
180
- let func = scope. bundle . get_entry_function ( id. name ) ;
181
-
182
- if let Some ( func) = func {
183
- let result = func ( resolved_positional_args. as_slice ( ) , & resolved_named_args) ;
184
- result
185
- } else {
186
- FluentValue :: Error
187
- }
188
- }
189
- _ => {
190
- let mut result = String :: new ( ) ;
191
- self . write ( & mut result, scope) . expect ( "Failed to write" ) ;
192
- result. into ( )
193
- }
194
- }
195
- }
196
- }
0 commit comments