@@ -3,6 +3,7 @@ use crate::fluent_bundle::FluentResource;
3
3
use crate :: snippet:: Style ;
4
4
use crate :: { DiagnosticArg , DiagnosticMessage , FluentBundle } ;
5
5
use fluent:: FluentBundle as RawFluentBundle ;
6
+ use md5:: { Digest , Md5 } ;
6
7
use rustc_data_structures:: sync:: Lrc ;
7
8
use rustc_error_messages:: FluentArgs ;
8
9
use std:: borrow:: Cow ;
@@ -68,24 +69,69 @@ pub trait Translate {
68
69
return Ok ( Cow :: Borrowed ( msg) ) ;
69
70
}
70
71
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 ( ) ) ;
83
82
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
+ } ;
86
131
}
87
132
DiagnosticMessage :: FluentIdentifier ( identifier, attr) => ( identifier, attr) ,
88
133
} ;
134
+ // FIXME(yukang): remove this part for fluent resource id after all diagnostics are migrated to Fluent
89
135
let translate_with_bundle =
90
136
|bundle : & ' a FluentBundle | -> Result < Cow < ' _ , str > , TranslateError < ' _ > > {
91
137
let message = bundle
0 commit comments