Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Упражнение: трейт 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");
}