Exercise: Logger Trait

トレイト Loggerlog メソッドを使用して、シンプルなロギングユーティリティを設計してみましょう。進行状況をログに記録するコードは、その後に &impl Logger を受け取ることができます。この場合、テストではテストログファイルにメッセージが書き込まれますが、本番環境ビルドではログサーバーにメッセージが送信されます。

However, the StdoutLogger given below logs all messages, regardless of verbosity. Your task is to write a VerbosityFilter type that will ignore messages above a maximum verbosity.

これは一般的なパターンです。つまり、トレイト実装をラップして同じトレイトを実装し、その過程で挙動を追加していく構造体です。ロギングユーティリティでは他にどのような種類のラッパーが役立つでしょうか。

pub trait Logger {
    /// 指定された詳細度レベルでメッセージをログに記録します。
    fn log(&self, verbosity: u8, message: &str);
}

struct StdoutLogger;

impl Logger for StdoutLogger {
    fn log(&self, verbosity: u8, message: &str) {
        println!("verbosity={verbosity}: {message}");
    }
}

// TODO: `VerbosityFilter` を定義して実装します。

fn main() {
    let logger = VerbosityFilter { max_verbosity: 3, inner: StdoutLogger };
    logger.log(5, "FYI");
    logger.log(2, "Uhoh");
}