{"id":50973038,"url":"https://github.com/dabevlohn/tsv-csv-bufparser","last_synced_at":"2026-06-19T04:30:32.503Z","repository":{"id":356381796,"uuid":"1232150578","full_name":"dabevlohn/tsv-csv-bufparser","owner":"dabevlohn","description":null,"archived":false,"fork":false,"pushed_at":"2026-05-07T19:43:11.000Z","size":871,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-07T21:32:42.145Z","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-05-07T16:30:58.000Z","updated_at":"2026-05-07T19:43:15.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/dabevlohn/tsv-csv-bufparser","commit_stats":null,"previous_names":["dabevlohn/tsv-csv-bufparser"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/dabevlohn/tsv-csv-bufparser","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dabevlohn%2Ftsv-csv-bufparser","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dabevlohn%2Ftsv-csv-bufparser/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dabevlohn%2Ftsv-csv-bufparser/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dabevlohn%2Ftsv-csv-bufparser/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dabevlohn","download_url":"https://codeload.github.com/dabevlohn/tsv-csv-bufparser/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dabevlohn%2Ftsv-csv-bufparser/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.059Z","updated_at":"2026-06-19T04:30:32.496Z","avatar_url":"https://github.com/dabevlohn.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Архитектура приложения: единый потоковый парсер с расширяемой поддержкой форматов\n\nПриложение реализовано как универсальный потоковый парсер транзакций с **абстрактным интерфейсом**, позволяющим добавлять новые форматы без изменения consumer-кода.\n\n### **Единый API для всех форматов**\n```rust\nlet mut parser = Parser::new(file, RecordFormat::Csv);  // или Tsv, Binary\nfor trans in parser.transactions() {\n    match trans {\n        Ok(t) =\u003e process(t),  // Один код для всех!\n        Err(e) =\u003e log(e),\n    }\n}\n```\n**Consumer не знает о формате** — всегда получает `Iterator\u003cResult\u003cTransaction, Error\u003e\u003e`.\n\n### **Логика работы (Core Flow)**\n\n1. **Инициализация**: `Parser::new(reader, format)`\n   - Создаёт `BufReader\u003cR\u003e`\n   - Сохраняет `format: RecordFormat` для диспетчеризации\n\n2. **Запуск итератора**: `parser.transactions() → ParserTransactions`\n   ```rust\n   impl Iterator for ParserTransactions {\n       fn next(\u0026mut self) → Option\u003cResult\u003cTransaction, ParseError\u003e\u003e {\n           match self.parser.format {\n               Csv | Tsv  → self.next_text(),    // Текстовые ветки\n               Binary    → self.next_binary(),   // Бинарная ветка\n           }\n       }\n   }\n   ```\n\n3. **Диспетчеризация по формату** (расширяемость!):\n\n![](docs/flow.png)\n\n4. **Парсинг → Transaction** (единая точка):\n   ```rust\n   fn parse_*_line/record(line/bytes) → Result\u003cTransaction, Error\u003e\n   ```\n   Все форматы **гарантированно возвращают** `Transaction {date, category, kind, amount}`.\n\n### **Расширяемость: добавление нового формата за 10 строк**\n\n```rust\n#[derive(Debug, Copy, Clone)]\nenum RecordFormat {\n    Csv, Tsv, Binary, JsonLines, // ← Новый!\n}\n\nimpl\u003c'a, R: Read\u003e ParserTransactions\u003c'a, R\u003e {\n    fn next_json(\u0026mut self) → Option\u003cResult\u003cTransaction, ParseError\u003e\u003e {\n        // serde_json::from_str(line) → Transaction\n        // или ручной парсер JSONL\n    }\n    \n    fn next(\u0026mut self) → Option\u003cResult\u003cTransaction, Error\u003e\u003e {\n        match self.parser.format {\n            RecordFormat::JsonLines =\u003e self.next_json(),\n            // ... остальные\n        }\n    }\n}\n```\n\n**Преимущества**:\n- **Consumer неизменён** — `for trans in parser.transactions()`\n- **Добавление формата** = 1 enum вариант + 1 метод `next_*()`\n- **Ошибки унифицированы** — `ParseError` для всех\n- **Потоковость сохранена** — O(1) память для любого формата\n\n### **Внутренняя архитектура Parser**\n```rust\npub struct Parser\u003cR: Read\u003e {\n    reader:   BufReader\u003cR\u003e,     // Универсальный источник\n    format:   RecordFormat,     // Диспетчер\n    buffer:   String,           // Для текста\n    line_num: usize,            // Для ошибок\n}\n```\n\n### **Почему это масштабируемо**\n1. **Декомпозиция**: `next() → next_format() → parse_format() → Transaction`\n2. **Плейсхолдеры**: Легко добавить `next_protobuf()`, `next_avro()`\n3. **Типобезопасность**: Компилятор гарантирует `Result\u003cTransaction\u003e`\n4. **Производительность**: Нативный парсинг, потоковый, без аллоков кроме результата\n\n**Итог**: **Архитектура \"Strategy Pattern\" через enum**: один интерфейс, бесконечные форматы, нулевые изменения в бизнес-логике! \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdabevlohn%2Ftsv-csv-bufparser","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdabevlohn%2Ftsv-csv-bufparser","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdabevlohn%2Ftsv-csv-bufparser/lists"}