11use 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 } ;
93
104use crate :: entry:: GetEntry ;
115use crate :: memoizer:: MemoizerKind ;
126use crate :: resource:: FluentResource ;
137use crate :: types:: FluentValue ;
8+ use fluent_syntax:: ast;
9+ use std:: borrow:: { Borrow , Cow } ;
10+ use std:: fmt;
1411
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 > (
1714 & ' ast self ,
18- w : & mut W ,
1915 scope : & mut Scope < ' bundle , ' ast , ' args , ' errors , R , M > ,
20- ) -> fmt:: Result
16+ context : & mut T ,
17+ ) -> T :: Result
2118 where
22- W : fmt:: Write ,
2319 R : Borrow < FluentResource > ,
2420 M : MemoizerKind ,
21+ T : WriteOrResolveContext < ' bundle > ,
2522 {
2623 match self {
27- Self :: StringLiteral { value } => unescape_unicode ( w , value) ,
24+ Self :: StringLiteral { value } => context . unescape ( value) ,
2825 Self :: MessageReference { id, attribute } => {
2926 if let Some ( msg) = scope. bundle . get_entry_message ( id. name ) {
3027 if let Some ( attr) = attribute {
3128 msg. attributes
3229 . iter ( )
3330 . find_map ( |a| {
3431 if a. id . name == attr. name {
35- Some ( scope. track ( w , & a. value , self ) )
32+ Some ( scope. track ( context , & a. value , self ) )
3633 } else {
3734 None
3835 }
3936 } )
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+ } )
4141 } else {
4242 msg. value
4343 . as_ref ( )
44- . map ( |value| scope. track ( w , value, self ) )
44+ . map ( |value| scope. track ( context , value, self ) )
4545 . unwrap_or_else ( || {
4646 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 )
5048 } )
5149 }
5250 } else {
53- scope. write_ref_error ( w, self )
51+ scope. add_error ( self . into ( ) ) ;
52+ context. error ( self , true )
5453 }
5554 }
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+ }
5758 Self :: TermReference {
5859 id,
5960 attribute,
@@ -69,16 +70,19 @@ impl<'bundle> WriteValue<'bundle> for ast::InlineExpression<&'bundle str> {
6970 if let Some ( attr) = attribute {
7071 term. attributes . iter ( ) . find_map ( |a| {
7172 if a. id . name == attr. name {
72- Some ( scope. track ( w , & a. value , self ) )
73+ Some ( scope. track ( context , & a. value , self ) )
7374 } else {
7475 None
7576 }
7677 } )
7778 } else {
78- Some ( scope. track ( w , & term. value , self ) )
79+ Some ( scope. track ( context , & term. value , self ) )
7980 }
8081 } )
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+ } ) ;
8286 scope. local_args = None ;
8387 result
8488 }
@@ -90,30 +94,31 @@ impl<'bundle> WriteValue<'bundle> for ast::InlineExpression<&'bundle str> {
9094
9195 if let Some ( func) = func {
9296 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 )
9599 } else {
96- w . write_str ( & result . into_string ( scope) )
100+ context . value ( scope, Cow :: Owned ( result ) )
97101 }
98102 } else {
99- scope. write_ref_error ( w, self )
103+ scope. add_error ( self . into ( ) ) ;
104+ context. error ( self , true )
100105 }
101106 }
102107 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) ) ;
110111 }
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 ( ) ) ;
114118 }
119+ context. error ( self , true )
115120 }
116- Self :: Placeable { expression } => expression. write ( w , scope ) ,
121+ Self :: Placeable { expression } => expression. write_or_resolve ( scope , context ) ,
117122 }
118123 }
119124
@@ -146,51 +151,3 @@ impl<'bundle> WriteValue<'bundle> for ast::InlineExpression<&'bundle str> {
146151 }
147152 }
148153}
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