https://github.com/dabevlohn/some-patterns
https://github.com/dabevlohn/some-patterns
Last synced: about 1 month ago
JSON representation
- Host: GitHub
- URL: https://github.com/dabevlohn/some-patterns
- Owner: dabevlohn
- Created: 2026-04-08T14:51:56.000Z (4 months ago)
- Default Branch: main
- Last Pushed: 2026-04-08T15:25:40.000Z (4 months ago)
- Last Synced: 2026-04-08T17:10:40.786Z (4 months ago)
- Language: Rust
- Size: 15.6 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Паттерны ООП и парсер-комбинаторная библиотека в Rust
## Пример: Парсер nom
```
cargo run --examples combine
```
### Ключевые паттерны композиции
| Комбинатор | Назначение | Пример |
| :--------------- | :------------------------ | :-------------------------------------------- |
| `alt` | Выбор (ИЛИ) | `alt((parse_number, parse_parens))` |
| `pair` / `tuple` | Последовательность (И) | `pair(char('+'), parse_term)` |
| `preceded` | A затем B (результат B) | `preceded(space0, digit1)` |
| `map` | Трансформация результата | `map(digit1, \|s\| s.parse())` |
| `fold_many0` | Повторение с аккумуляцией | `fold_many0(pair(op, factor), init, fold_fn)` |
### Современный стиль с трейтом `Parser`
Начиная с `nom 7`, можно использовать более эргономичный стиль через трейт `Parser`:
```rust
use nom::{Parser, character::complete::digit1, IResult};
fn parse_number(input: &str) -> IResult<&str, i32> {
digit1
.map(|s: &str| s.parse::().unwrap())
.parse(input)
}
```
Этот подход позволяет строить парсеры как конвейеры функций, где каждый комбинатор — это функция высшего порядка, принимающая один или несколько парсеров и возвращающая новый, более сложный парсер.
## Пример: Десериализация структуры
```
cargo run --example visitor
```
### Ключевые моменты
1. **`Visitor` определяет `type Value`** — тип, который будет построен после посещения.
2. **`Deserializer` вызывает метод `visit_*`** в зависимости от фактического типа данных (double dispatch).
3. **`expecting`** предоставляет человеко-читаемое сообщение об ошибке для отладки.
4. **`deserialize_any`** позволяет десериализатору самому выбрать, какой метод `visit_*` вызвать.
Этот паттерн лежит в основе всей системы десериализации `serde` и позволяет обрабатывать полиморфные данные, union-типы и кастомные форматы.
## Пример: Древовидная структура маршрутов API
```
cargo run --examples compose
```
### Ключевые преимущества
1. **Единый интерфейс**
2. **Рекурсивная композиция**
3. **Инкапсуляция**
Этот подход особенно полезен для больших API с вложенной структурой маршрутов, где нужно динамически собирать конфигурацию из модулей.