@@ -3,6 +3,7 @@ use crate::fluent_bundle::FluentResource;
33use crate :: snippet:: Style ;
44use crate :: { DiagnosticArg , DiagnosticMessage , FluentBundle } ;
55use fluent:: FluentBundle as RawFluentBundle ;
6+ use md5:: { Digest , Md5 } ;
67use rustc_data_structures:: sync:: Lrc ;
78use rustc_error_messages:: FluentArgs ;
89use std:: borrow:: Cow ;
@@ -68,24 +69,69 @@ pub trait Translate {
6869 return Ok ( Cow :: Borrowed ( msg) ) ;
6970 }
7071 DiagnosticMessage :: FluentRaw ( msg) => {
71- // FIXME(yukang): A hack for raw fluent content for new diagnostics proc format
72- let fluent_text = format ! ( "dummy = {}" , msg) ;
73- if let Ok ( resource) = FluentResource :: try_new ( fluent_text) {
74- let mut bundle = RawFluentBundle :: new ( vec ! [ langid!( "en-US" ) ] ) ;
75- bundle. add_resource ( resource) . unwrap ( ) ;
76- let mut errors = vec ! [ ] ;
77- let pattern = bundle. get_message ( "dummy" ) . unwrap ( ) . value ( ) . unwrap ( ) ;
78- let res = bundle. format_pattern ( & pattern, Some ( args) , & mut errors) ;
79- return Ok ( Cow :: Owned (
80- res. to_string ( ) . replace ( "\u{2068} " , "" ) . replace ( "\u{2069} " , "" ) ,
81- ) ) ;
82- }
72+ // FIXME(yukang): calculate the `slug` from the raw fluent content,
73+ // The fluent resources are generated by a simple standalone visitor:
74+ // https://github.com/chenyukang/fluent-utils/blob/main/src/visitor.rs#L13-L97
75+ // we may need to add fluent-utils into the tools directory of rustc
76+ let mut hasher = Md5 :: new ( ) ;
77+ hasher. update ( msg. to_string ( ) ) ;
78+ let digest = hasher. finalize ( ) ;
79+ let id = format ! ( "{:x}" , digest) ;
80+ let identifier = format ! ( "slug-{}" , id[ 0 ..8 ] . to_string( ) ) ;
81+ let id = Cow :: Borrowed ( identifier. as_str ( ) ) ;
8382
84- // If the message is not a valid Fluent resource, just return the original
85- return Ok ( Cow :: Borrowed ( msg) ) ;
83+ let translate_with_bundle =
84+ |bundle : & ' a FluentBundle | -> Result < Cow < ' _ , str > , TranslateError < ' _ > > {
85+ let message = bundle
86+ . get_message ( & identifier)
87+ . ok_or ( TranslateError :: message ( & id, args) ) ?;
88+ let value = message. value ( ) . ok_or ( TranslateError :: value ( & id, args) ) ?;
89+ debug ! ( ?message, ?value) ;
90+
91+ let mut errs = vec ! [ ] ;
92+ let translated = bundle. format_pattern ( value, Some ( args) , & mut errs) ;
93+ debug ! ( ?translated, ?errs) ;
94+ if errs. is_empty ( ) {
95+ Ok ( translated)
96+ } else {
97+ Err ( TranslateError :: fluent ( & id, args, errs) )
98+ }
99+ } ;
100+
101+ return {
102+ match self . fluent_bundle ( ) . map ( |b| translate_with_bundle ( b) ) {
103+ // The primary bundle was present and translation succeeded
104+ Some ( Ok ( t) ) => {
105+ // eprintln!("translated id OK: {} => {}", identifier, t);
106+ Ok ( t)
107+ }
108+
109+ // If `translate_with_bundle` returns `Err` with the primary bundle, this is likely
110+ // just that the primary bundle doesn't contain the message being translated, so
111+ // proceed to the fallback bundle.
112+ _ => {
113+ // fallback to en-US, we don't need fluent bundle for raw fluent content in English
114+ // here we just interpret the variables in the fluent content.
115+ let fluent_text = format ! ( "dummy = {}" , msg) ;
116+ if let Ok ( resource) = FluentResource :: try_new ( fluent_text) {
117+ let mut bundle = RawFluentBundle :: new ( vec ! [ langid!( "en-US" ) ] ) ;
118+ bundle. add_resource ( resource) . unwrap ( ) ;
119+ let mut errors = vec ! [ ] ;
120+ let pattern = bundle. get_message ( "dummy" ) . unwrap ( ) . value ( ) . unwrap ( ) ;
121+ let res = bundle. format_pattern ( & pattern, Some ( args) , & mut errors) ;
122+ Ok ( Cow :: Owned (
123+ res. to_string ( ) . replace ( "\u{2068} " , "" ) . replace ( "\u{2069} " , "" ) ,
124+ ) )
125+ } else {
126+ Ok ( Cow :: Owned ( msg. to_string ( ) ) )
127+ }
128+ }
129+ }
130+ } ;
86131 }
87132 DiagnosticMessage :: FluentIdentifier ( identifier, attr) => ( identifier, attr) ,
88133 } ;
134+ // FIXME(yukang): remove this part for fluent resource id after all diagnostics are migrated to Fluent
89135 let translate_with_bundle =
90136 |bundle : & ' a FluentBundle | -> Result < Cow < ' _ , str > , TranslateError < ' _ > > {
91137 let message = bundle
0 commit comments