@@ -234,6 +234,48 @@ pub fn fallback_fluent_bundle(
234234/// Identifier for the Fluent message/attribute corresponding to a diagnostic message.
235235type FluentId = Cow < ' static , str > ;
236236
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+
237279/// Abstraction over a message in a diagnostic to support both translatable and non-translatable
238280/// diagnostic messages.
239281///
@@ -252,6 +294,29 @@ pub enum DiagnosticMessage {
252294}
253295
254296impl 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+
255320 /// Returns the `String` contained within the `DiagnosticMessage::Str` variant, assuming that
256321 /// this diagnostic message is of the legacy, non-translatable variety. Panics if this
257322 /// assumption does not hold.
@@ -266,14 +331,9 @@ impl DiagnosticMessage {
266331 }
267332
268333 /// 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 {
270335 DiagnosticMessage :: FluentIdentifier ( id. into ( ) , None )
271336 }
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- }
277337}
278338
279339/// `From` impl that enables existing diagnostic calls to functions which now take
0 commit comments