{"id":50973040,"url":"https://github.com/dabevlohn/some-patterns","last_synced_at":"2026-06-19T04:30:33.453Z","repository":{"id":350033018,"uuid":"1205014995","full_name":"dabevlohn/some-patterns","owner":"dabevlohn","description":null,"archived":false,"fork":false,"pushed_at":"2026-04-08T15:25:40.000Z","size":16,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-08T17:10:40.786Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dabevlohn.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-08T14:51:56.000Z","updated_at":"2026-04-08T15:28:35.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/dabevlohn/some-patterns","commit_stats":null,"previous_names":["dabevlohn/some-patterns"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/dabevlohn/some-patterns","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dabevlohn%2Fsome-patterns","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dabevlohn%2Fsome-patterns/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dabevlohn%2Fsome-patterns/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dabevlohn%2Fsome-patterns/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dabevlohn","download_url":"https://codeload.github.com/dabevlohn/some-patterns/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dabevlohn%2Fsome-patterns/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34517748,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-19T02:00:06.005Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-19T04:30:30.642Z","updated_at":"2026-06-19T04:30:33.440Z","avatar_url":"https://github.com/dabevlohn.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Паттерны ООП и парсер-комбинаторная библиотека в Rust\n\n## Пример: Парсер nom\n\n```\ncargo run --examples combine\n```\n\n### Ключевые паттерны композиции\n\n| Комбинатор       | Назначение                | Пример                                        |\n| :--------------- | :------------------------ | :-------------------------------------------- |\n| `alt`            | Выбор (ИЛИ)               | `alt((parse_number, parse_parens))`           |\n| `pair` / `tuple` | Последовательность (И)    | `pair(char('+'), parse_term)`                 |\n| `preceded`       | A затем B (результат B)   | `preceded(space0, digit1)`                    |\n| `map`            | Трансформация результата  | `map(digit1, \\|s\\| s.parse())`                |\n| `fold_many0`     | Повторение с аккумуляцией | `fold_many0(pair(op, factor), init, fold_fn)` |\n\n### Современный стиль с трейтом `Parser`\n\nНачиная с `nom 7`, можно использовать более эргономичный стиль через трейт `Parser`:\n\n```rust\nuse nom::{Parser, character::complete::digit1, IResult};\n\nfn parse_number(input: \u0026str) -\u003e IResult\u003c\u0026str, i32\u003e {\n    digit1\n        .map(|s: \u0026str| s.parse::\u003ci32\u003e().unwrap())\n        .parse(input)\n}\n```\n\nЭтот подход позволяет строить парсеры как конвейеры функций, где каждый комбинатор — это функция высшего порядка, принимающая один или несколько парсеров и возвращающая новый, более сложный парсер.\n\n## Пример: Десериализация структуры\n\n```\ncargo run --example visitor\n```\n\n### Ключевые моменты\n\n1. **`Visitor` определяет `type Value`** — тип, который будет построен после посещения.\n2. **`Deserializer` вызывает метод `visit_*`** в зависимости от фактического типа данных (double dispatch).\n3. **`expecting`** предоставляет человеко-читаемое сообщение об ошибке для отладки.\n4. **`deserialize_any`** позволяет десериализатору самому выбрать, какой метод `visit_*` вызвать.\n\nЭтот паттерн лежит в основе всей системы десериализации `serde` и позволяет обрабатывать полиморфные данные, union-типы и кастомные форматы.\n\n## Пример: Древовидная структура маршрутов API\n\n```\ncargo run --examples compose\n```\n\n### Ключевые преимущества\n\n1. **Единый интерфейс**\n2. **Рекурсивная композиция**\n3. **Инкапсуляция**\n\nЭтот подход особенно полезен для больших API с вложенной структурой маршрутов, где нужно динамически собирать конфигурацию из модулей.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdabevlohn%2Fsome-patterns","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdabevlohn%2Fsome-patterns","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdabevlohn%2Fsome-patterns/lists"}