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

Краткая шпаргалка

Краткая справка по всем 14+ паттернам корректности по построению с блок-схемой выбора, каталогом паттернов, правилами композиции, сопоставлением с крейтами и шпаргалкой по гарантиям на уровне типов.

Перекрёстные ссылки: все главы: это таблица для поиска по всей книге.

Краткая справка: паттерны корректности по построению

Руководство по выбору паттерна

Ошибка катастрофична, если её пропустить?
├── Да → Её можно закодировать в типах?
│         ├── Да → ИСПОЛЬЗУЙТЕ КОРРЕКТНОСТЬ ПО ПОСТРОЕНИЮ
│         └── Нет → Проверка во время выполнения + обширное тестирование
└── Нет → Проверка во время выполнения подойдёт

Каталог паттернов

№ПаттернКлючевой трейт/типПредотвращаетСтоимость во время выполненияГлава
1Типизированные командыtrait IpmiCmd { type Response; }Неверный тип ответаНулеваягл. 02
2Одноразовые типыstruct Nonce (не Clone/Copy)Повторное использование nonce/ключаНулеваягл. 03
3Capability-токеныstruct AdminToken { _private: () }Несанкционированный доступНулеваягл. 04
4TypestateSession<Active>Нарушения протоколаНулеваягл. 05
5Размерные типыstruct Celsius(f64)Путаница единицНулеваягл. 06
6Проверенные границыstruct ValidFru (через TryFrom)Использование непроверенных данныхРазбор один разгл. 07
7Capability-миксиныtrait FanDiagMixin: HasSpi + HasI2cОтсутствие доступа к шинеНулеваягл. 08
8Phantom-типыRegister<Width16>Несоответствие ширины/направленияНулеваягл. 09
9Sentinel → OptionOption<u8> (не 0xFF)Ошибки «sentinel как значение»Нулеваягл. 11
10Sealed-трейтыtrait Cmd: private::SealedНебезопасные внешние реализацииНулеваягл. 11
11Non-exhaustive enum#[non_exhaustive] enum SkuТихое проваливание в matchНулеваягл. 11
12Билдер с typestateDerBuilder<Set, Missing>Неполное создание объектаНулеваягл. 11
13Валидация через FromStrimpl FromStr for DiagLevelНепроверенный строковый вводРазбор один разгл. 11
14Размер через const-обобщенияRegisterBank<const N: usize>Несоответствие размера буфераНулеваягл. 11
15Безопасная обёртка unsafeMmioRegion::read_u32()Непроверенный MMIO/FFIНулеваягл. 11
16Async typestateAsyncSession<Active>Нарушения async-протоколаНулеваягл. 11
17Const-утвержденияSdrSensorId<const N: u8>Недопустимые ID на этапе компиляцииНулеваягл. 11
18Сессионные типыChan<SendRequest>Операции с каналом не по порядкуНулеваягл. 11
19Самоссылочный PinPin<Box<StreamParser>>Висячий внутренний указательНулеваягл. 11
20RAII / Dropimpl Drop for SessionУтечка ресурса при любом пути выходаНулеваягл. 11
21Иерархия типов ошибок#[derive(Error)] enum DiagErrorТихое проглатывание ошибокНулеваягл. 11
22#[must_use]#[must_use] struct TokenТихо отброшенные значенияНулеваягл. 11

Правила композиции

Capability-токен + Typestate = Авторизованные переходы состояний
Типизированная команда + Размерный тип = Физически типизированные ответы
Проверенная граница + Phantom-тип = Типизированный доступ к регистрам по проверенной конфигурации
Capability-миксин + Типизированная команда = Типизированные операции с учётом шин
Одноразовый тип + Typestate = Протоколы «потребляется при переходе»
Sealed-трейт + Типизированная команда = Закрытый, корректный набор команд
Sentinel → Option + Проверенная граница = Чистый конвейер «разбор один раз»
Билдер с typestate + Capability-токен = Доказательство полного создания
FromStr + #[non_exhaustive] = Развиваемый разбор enum с быстрым отказом
Размер через const-обобщения + Проверенная граница = Размерные, проверенные протокольные буферы
Безопасная обёртка unsafe + Phantom-тип = Типизированный и безопасный доступ к MMIO
Async typestate + Capability-токен = Авторизованные async-переходы
Сессионные типы + Типизированная команда = Полностью типизированные каналы «запрос — ответ»
Pin + Typestate = Самоссылочные автоматы состояний, которые не могут переместиться
RAII (Drop) + Typestate = Гарантии очистки, зависящей от состояния
Иерархия ошибок + Проверенная граница = Типизированные ошибки разбора с исчерпывающей обработкой
#[must_use] + Одноразовый тип = Токены, которые трудно игнорировать и трудно переиспользовать

Антипаттерны, которых следует избегать

АнтипаттернПочему это неверноПравильная альтернатива
fn read_sensor() -> f64Без единиц: может быть °C, °F или об/минfn read_sensor() -> Celsius
fn encrypt(nonce: &[u8; 12])Nonce можно переиспользовать (заимствование)fn encrypt(nonce: Nonce) (перемещение)
fn admin_op(is_admin: bool)Вызывающий может соврать (true)fn admin_op(_: &AdminToken)
fn send(session: &Session)Нет гарантии состоянияfn send(session: &Session<Active>)
fn process(data: &[u8])Не провереноfn process(data: &ValidFru)
Clone для эфемерных ключейСводит на нет гарантию одноразовостиНе выводите Clone
let vendor_id: u16 = 0xFFFFSentinel хранится внутриlet vendor_id: Option<u16> = None
fn route(level: &str) с запасным вариантомОпечатки тихо заменяются значением по умолчаниюlet level: DiagLevel = s.parse()?
Builder::new().finish() без полейСоздаётся неполный объектБилдер с typestate: finish() открывается при Set
let buf: Vec<u8> для аппаратного буфера фиксированного размераРазмер проверяется только во время выполненияRegisterBank<4096> (const-обобщение)
Разбросанный сырой unsafe { ptr::read(...) }Риск UB, не поддаётся аудитуMmioRegion::read_u32(): безопасная обёртка
async fn transition(&mut self)Изменяемые заимствования не обеспечивают состояниеasync fn transition(self) -> NextState
fn cleanup(), вызываемая вручнуюЗабывается при раннем возврате или паникеimpl Drop: компилятор вставляет вызов
fn op() -> Result<T, String>Непрозрачная ошибка, нельзя сопоставить вариантыfn op() -> Result<T, DiagError>: enum

Сопоставление с кодовой базой диагностики

МодульПрименимые паттерны
protocol_libТипизированные команды, сессии с typestate
thermal_diagCapability-миксины, размерные типы
accel_diagПроверенные границы, phantom-регистры
network_diagTypestate (обучение линка), capability-токены
pci_topologyPhantom-типы (ширина регистра), проверенная конфигурация, sentinel → Option
event_handlerОдноразовые токены аудита, capability-токены, FromStr (Component)
event_logПроверенные границы (разбор записей SEL)
compute_diagРазмерные типы (температура, частота)
memory_diagПроверенные границы (данные SPD), размерные типы
switch_diagTypestate (перечисление портов), phantom-типы
config_loaderFromStr (DiagLevel, FaultStatus, DiagAction)
log_analyzerПроверенные границы (CompiledPatterns)
diag_frameworkБилдер с typestate (DerBuilder), сессионные типы (оркестратор ↔ воркер)
topology_libConst-обобщённые банки регистров, безопасные обёртки MMIO

Типы как гарантии — краткое соответствие

ГарантияЭквивалент в RustПример
«Это доказательство существует»ТипAdminToken
«У меня есть доказательство»Значение этого типаlet tok = authenticate()?;
«A влечёт B»Функция fn(A) -> Bfn activate(AdminToken) -> Session<Active>
«И A, и B»Кортеж (A, B) или несколько параметровfn op(a: &AdminToken, b: &LinkTrained)
«Либо A, либо B»enum { A(A), B(B) } или Result<A, B>Result<Session<Active>, Error>
«Всегда истинно»() (тип unit)Всегда конструируется
«Невозможно»! (тип never) или enum Void {}Никогда не может быть сконструирована