Упражнение: трейт Logger
Давайте спроектируем простую утилиту логирования с трейтом Logger, у которого есть метод log. Код, который может записывать ход своей работы, затем может принимать &impl Logger. В тестах это может записывать сообщения в файл журнала тестов, а в рабочей (production) сборке — отправлять сообщения на сервер логов.
Однако приведённый ниже StderrLogger записывает все сообщения независимо от уровня подробности. Ваша задача — написать тип VerbosityFilter, который будет игнорировать сообщения выше заданного максимального уровня подробности.
Это распространённый паттерн: структура, которая оборачивает реализацию трейта, сама реализует тот же трейт и при этом добавляет поведение. В сегменте «Обобщения» мы увидим, как сделать обёртку обобщённой по обёрнутому типу.
// Copyright 2023 Google LLC
// SPDX-License-Identifier: Apache-2.0
trait Logger {
/// Записывает сообщение с заданным уровнем подробности.
fn log(&self, verbosity: u8, message: &str);
}
struct StderrLogger;
impl Logger for StderrLogger {
fn log(&self, verbosity: u8, message: &str) {
eprintln!("verbosity={verbosity}: {message}");
}
}
/// Записывает только сообщения до заданного уровня подробности.
struct VerbosityFilter {
max_verbosity: u8,
inner: StderrLogger,
}
// TODO: Реализуйте трейт `Logger` для `VerbosityFilter`.
fn main() {
let logger = VerbosityFilter { max_verbosity: 3, inner: StderrLogger };
logger.log(5, "FYI");
logger.log(2, "Uhoh");
}