@@ -234,6 +234,48 @@ pub fn fallback_fluent_bundle(
234
234
/// Identifier for the Fluent message/attribute corresponding to a diagnostic message.
235
235
type FluentId = Cow < ' static , str > ;
236
236
237
+ /// Abstraction over a message in a subdiagnostic (i.e. label, note, help, etc) to support both
238
+ /// translatable and non-translatable diagnostic messages.
239
+ ///
240
+ /// Translatable messages for subdiagnostics are typically attributes attached to a larger Fluent
241
+ /// message so messages of this type must be combined with a `DiagnosticMessage` (using
242
+ /// `DiagnosticMessage::with_subdiagnostic_message`) before rendering. However, subdiagnostics from
243
+ /// the `SessionSubdiagnostic` derive refer to Fluent identifiers directly.
244
+ pub enum SubdiagnosticMessage {
245
+ /// Non-translatable diagnostic message.
246
+ // FIXME(davidtwco): can a `Cow<'static, str>` be used here?
247
+ Str ( String ) ,
248
+ /// Identifier of a Fluent message. Instances of this variant are generated by the
249
+ /// `SessionSubdiagnostic` derive.
250
+ FluentIdentifier ( FluentId ) ,
251
+ /// Attribute of a Fluent message. Needs to be combined with a Fluent identifier to produce an
252
+ /// actual translated message. Instances of this variant are generated by the `fluent_messages`
253
+ /// macro.
254
+ ///
255
+ /// <https://projectfluent.org/fluent/guide/attributes.html>
256
+ FluentAttr ( FluentId ) ,
257
+ }
258
+
259
+ impl SubdiagnosticMessage {
260
+ /// Create a `SubdiagnosticMessage` for the provided Fluent attribute.
261
+ pub fn attr ( id : impl Into < FluentId > ) -> Self {
262
+ SubdiagnosticMessage :: FluentAttr ( id. into ( ) )
263
+ }
264
+
265
+ /// Create a `SubdiagnosticMessage` for the provided Fluent identifier.
266
+ pub fn message ( id : impl Into < FluentId > ) -> Self {
267
+ SubdiagnosticMessage :: FluentIdentifier ( id. into ( ) )
268
+ }
269
+ }
270
+
271
+ /// `From` impl that enables existing diagnostic calls to functions which now take
272
+ /// `impl Into<SubdiagnosticMessage>` to continue to work as before.
273
+ impl < S : Into < String > > From < S > for SubdiagnosticMessage {
274
+ fn from ( s : S ) -> Self {
275
+ SubdiagnosticMessage :: Str ( s. into ( ) )
276
+ }
277
+ }
278
+
237
279
/// Abstraction over a message in a diagnostic to support both translatable and non-translatable
238
280
/// diagnostic messages.
239
281
///
@@ -252,6 +294,29 @@ pub enum DiagnosticMessage {
252
294
}
253
295
254
296
impl DiagnosticMessage {
297
+ /// Given a `SubdiagnosticMessage` which may contain a Fluent attribute, create a new
298
+ /// `DiagnosticMessage` that combines that attribute with the Fluent identifier of `self`.
299
+ ///
300
+ /// - If the `SubdiagnosticMessage` is non-translatable then return the message as a
301
+ /// `DiagnosticMessage`.
302
+ /// - If `self` is non-translatable then return `self`'s message.
303
+ pub fn with_subdiagnostic_message ( & self , sub : SubdiagnosticMessage ) -> Self {
304
+ let attr = match sub {
305
+ SubdiagnosticMessage :: Str ( s) => return DiagnosticMessage :: Str ( s. clone ( ) ) ,
306
+ SubdiagnosticMessage :: FluentIdentifier ( id) => {
307
+ return DiagnosticMessage :: FluentIdentifier ( id, None ) ;
308
+ }
309
+ SubdiagnosticMessage :: FluentAttr ( attr) => attr,
310
+ } ;
311
+
312
+ match self {
313
+ DiagnosticMessage :: Str ( s) => DiagnosticMessage :: Str ( s. clone ( ) ) ,
314
+ DiagnosticMessage :: FluentIdentifier ( id, _) => {
315
+ DiagnosticMessage :: FluentIdentifier ( id. clone ( ) , Some ( attr) )
316
+ }
317
+ }
318
+ }
319
+
255
320
/// Returns the `String` contained within the `DiagnosticMessage::Str` variant, assuming that
256
321
/// this diagnostic message is of the legacy, non-translatable variety. Panics if this
257
322
/// assumption does not hold.
@@ -266,14 +331,9 @@ impl DiagnosticMessage {
266
331
}
267
332
268
333
/// Create a `DiagnosticMessage` for the provided Fluent identifier.
269
- pub fn fluent ( id : impl Into < FluentId > ) -> Self {
334
+ pub fn new ( id : impl Into < FluentId > ) -> Self {
270
335
DiagnosticMessage :: FluentIdentifier ( id. into ( ) , None )
271
336
}
272
-
273
- /// Create a `DiagnosticMessage` for the provided Fluent identifier and attribute.
274
- pub fn fluent_attr ( id : impl Into < FluentId > , attr : impl Into < FluentId > ) -> Self {
275
- DiagnosticMessage :: FluentIdentifier ( id. into ( ) , Some ( attr. into ( ) ) )
276
- }
277
337
}
278
338
279
339
/// `From` impl that enables existing diagnostic calls to functions which now take
0 commit comments