Skip to main content

MessageFormatter

Trait MessageFormatter 

Source
pub trait MessageFormatter {
    // Required method
    fn format_message<'a>(&self, err: &'a Error) -> Cow<'a, str>;

    // Provided methods
    fn localizer(&self) -> &dyn Localizer { ... }
    fn format_standalone_message<'a>(&self, err: &'a Error) -> Cow<'a, str> { ... }
}
Expand description

Formats error messages (not including locations/snippets).

This is the core customization hook for deferred rendering. The error value remains structured data; the formatter decides what message text to show (developer-oriented, user-oriented, localized, etc.).

Important: implementations must NOT call err.to_string() / Display for Error to avoid recursion once Display delegates to Error::render().

§Example

Override a couple of messages, returning Cow::Borrowed for a fixed string and Cow::Owned for a formatted message, while delegating all other cases to UserMessageFormatter.

use serde_saphyr::{Error, Location, MessageFormatter, UserMessageFormatter};
use std::borrow::Cow;

struct PoliteFormatter;

impl MessageFormatter for PoliteFormatter {
    fn format_message<'a>(&self, err: &'a Error) -> Cow<'a, str> {
        // `UserMessageFormatter` is a zero-sized type, so it is cheap to instantiate.
        let fallback = UserMessageFormatter;

        match err {
            // Fixed string => `Cow::Borrowed`
            Error::Eof { .. } => Cow::Borrowed("could you please provide a YAML document?"),

            // Formatted string => `Cow::Owned`
            Error::UnknownAnchor { .. } => {
                Cow::Borrowed("sorry but unknown reference")
            }

            // Everything else => delegate
            _ => fallback.format_message(err),
        }
    }
}

let err = serde_saphyr::from_str::<String>("").unwrap_err();
assert!(err.render_with_formatter(&PoliteFormatter).contains("please provide"));

let err = Error::UnknownAnchor {
    location: Location::UNKNOWN,
};
assert!(err
    .render_with_formatter(&PoliteFormatter)
    .contains("unknown reference"));

Required Methods§

Source

fn format_message<'a>(&self, err: &'a Error) -> Cow<'a, str>

Return the message text for err.

The returned string should NOT include location suffixes like "at line X, column Y"; those are added by the renderer.

Rendering entrypoints unwrap Error::AliasError and Error::WithSnippet before calling this method, so the formatter receives the original error. Alias locations are composed separately by the renderer.

Rendering entrypoints such as Error::render neutralize control characters in this text before composing their own layout. Implementations should therefore not use control characters, including line breaks, for message layout.

Calling this low-level method directly bypasses that rendering boundary. Before writing its result to a terminal or log, sanitize it with str::escape_debug or an equivalent encoding.

Provided Methods§

Source

fn localizer(&self) -> &dyn Localizer

Return the Localizer used by the renderer.

This controls wording that is produced outside of MessageFormatter::format_message, such as location suffixes and snippet/validation labels.

Source

fn format_standalone_message<'a>(&self, err: &'a Error) -> Cow<'a, str>

Return the complete message for a standalone diagnostic, such as a Miette report, that does not retain the original error’s source chain.

The default preserves Self::format_message unchanged. Built-in formatters also include I/O causes here. Custom formatters control whether to include, translate, or omit those details; delegate this hook to a built-in formatter when its standalone behavior is desired for fallback cases.

The same wrapper-unwrapping and sanitization rules as Self::format_message apply. Ordinary Error::render and Display still use format_message.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§