From 56bddabbe1abda0ff0009a0a3d280c06b23dd38e Mon Sep 17 00:00:00 2001 From: Mikhail Kilin Date: Sun, 1 Feb 2026 02:23:17 +0300 Subject: [PATCH] feat: add optional feature flags for clipboard and url-open (P5.15) Implemented feature flags to make dependencies optional: - clipboard feature: controls arboard dependency - url-open feature: controls open dependency - Both enabled by default for backward compatibility Changes: - Cargo.toml: Added [features] section with optional deps - src/input/main_input.rs: Conditional compilation for open::that() and copy_to_clipboard() - tests/copy.rs: Clipboard tests only compile with feature enabled - Graceful degradation: user-friendly error messages when features disabled Benefits: - Smaller binary size when features disabled - Modular functionality - Better platform compatibility Progress: Priority 5: 1/3 tasks, Total: 17/20 (85%) Co-Authored-By: Claude Sonnet 4.5 --- CONTEXT.md | 19 ++++++++++++------- Cargo.toml | 9 +++++++-- REFACTORING_ROADMAP.md | 25 ++++++++++++++++++++----- src/input/main_input.rs | 30 +++++++++++++++++++++++------- tests/copy.rs | 2 +- 5 files changed, 63 insertions(+), 22 deletions(-) diff --git a/CONTEXT.md b/CONTEXT.md index 95d6228..6746988 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -903,16 +903,21 @@ let message = MessageBuilder::new(MessageId::new(123)) - ✅ Priority 1: 3/3 (100%) - ✅ Priority 2: 5/5 (100%) - ✅ Priority 3: 4/4 (100%) 🎉 -- ⏳ Priority 4: 1/4 (25%, P4.12 частично) -- ⏳ Priority 5: 0/3 +- ✅ Priority 4: 4/4 (100%) 🎉 +- ⏳ Priority 5: 1/3 (33%, P5.15 завершено) -**Общий прогресс: 12/17 задач (71%)** +**Общий прогресс: 17/20 задач (85%)** + +**Последние изменения (1 февраля 2026)**: +- ✅ **P5.15 — Feature flags для зависимостей** (2026-02-01) + - Добавлены опциональные features `clipboard` и `url-open` в Cargo.toml + - Зависимости `arboard` и `open` теперь опциональные + - Условная компиляция в коде с graceful degradation + - Преимущества: уменьшение размера бинарника, модульность **Следующие шаги**: -- Продолжить P4.12: добавить rustdoc для остальных модулей -- P4.11: Добавить юнит-тесты для utils -- P4.13: Улучшить config validation -- P4.14: Проверить async/await консистентность +- P5.16: LRU cache обобщение +- P5.17: Tracing вместо println! ## Известные проблемы diff --git a/Cargo.toml b/Cargo.toml index dfcbc31..ff0dfbd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,11 @@ repository = "https://github.com/your-username/tele-tui" keywords = ["telegram", "tui", "terminal", "cli"] categories = ["command-line-utilities"] +[features] +default = ["clipboard", "url-open"] +clipboard = ["dep:arboard"] +url-open = ["dep:open"] + [dependencies] ratatui = "0.29" crossterm = "0.28" @@ -18,8 +23,8 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" dotenvy = "0.15" chrono = "0.4" -open = "5.0" -arboard = "3.4" +open = { version = "5.0", optional = true } +arboard = { version = "3.4", optional = true } toml = "0.8" dirs = "5.0" thiserror = "1.0" diff --git a/REFACTORING_ROADMAP.md b/REFACTORING_ROADMAP.md index e3dce98..dc59992 100644 --- a/REFACTORING_ROADMAP.md +++ b/REFACTORING_ROADMAP.md @@ -696,7 +696,7 @@ async fn load_messages() { ## Приоритет 5: Опциональные улучшения -### 15. Feature flags для зависимостей +### 15. Feature flags для зависимостей ✅ ЗАВЕРШЕНО **Проблема**: Все зависимости всегда включены. @@ -706,11 +706,25 @@ async fn load_messages() { default = ["clipboard", "url-open"] clipboard = ["dep:arboard"] url-open = ["dep:open"] + +[dependencies] +arboard = { version = "3.4", optional = true } +open = { version = "5.0", optional = true } ``` +**Реализовано**: +- ✅ Добавлены feature flags в Cargo.toml +- ✅ Зависимости `arboard` и `open` сделаны опциональными +- ✅ Условная компиляция в `src/input/main_input.rs`: + - `#[cfg(feature = "url-open")]` для `open::that()` + - `#[cfg(feature = "clipboard")]` / `#[cfg(not(feature = "clipboard"))]` для `copy_to_clipboard()` +- ✅ Условная компиляция в `tests/copy.rs`: + - `#[cfg(all(test, feature = "clipboard"))]` для clipboard тестов + **Преимущества**: -- Уменьшение размера бинарника -- Опциональная функциональность +- ✅ Уменьшение размера бинарника +- ✅ Опциональная функциональность +- ✅ Graceful degradation при отключении фич --- @@ -767,9 +781,10 @@ tracing-subscriber = "0.3" - [x] P4.12 — Rustdoc ✅ - [x] P4.13 — Config validation ✅ - [x] P4.14 — Async/await consistency ✅ -- [ ] Priority 5: 0/3 задач +- [ ] Priority 5: 1/3 задач + - [x] P5.15 — Feature flags ✅ -**Всего**: 16/17 задач (94%) +**Всего**: 17/20 задач (85%) --- diff --git a/src/input/main_input.rs b/src/input/main_input.rs index bcbca22..614a821 100644 --- a/src/input/main_input.rs +++ b/src/input/main_input.rs @@ -138,15 +138,24 @@ pub async fn handle(app: &mut App, key: KeyEvent) { "https://t.me/{}", username.trim_start_matches('@') ); - match open::that(&url) { - Ok(_) => { - app.status_message = Some(format!("Открыто: {}", url)); - } - Err(e) => { - app.error_message = - Some(format!("Ошибка открытия браузера: {}", e)); + #[cfg(feature = "url-open")] + { + match open::that(&url) { + Ok(_) => { + app.status_message = Some(format!("Открыто: {}", url)); + } + Err(e) => { + app.error_message = + Some(format!("Ошибка открытия браузера: {}", e)); + } } } + #[cfg(not(feature = "url-open"))] + { + app.error_message = Some( + "Открытие URL недоступно (требуется feature 'url-open')".to_string() + ); + } } return; } @@ -1057,6 +1066,7 @@ fn get_available_actions_count(profile: &crate::tdlib::ProfileInfo) -> usize { } /// Копирует текст в системный буфер обмена +#[cfg(feature = "clipboard")] fn copy_to_clipboard(text: &str) -> Result<(), String> { use arboard::Clipboard; @@ -1069,6 +1079,12 @@ fn copy_to_clipboard(text: &str) -> Result<(), String> { Ok(()) } +/// Заглушка для copy_to_clipboard когда feature "clipboard" выключена +#[cfg(not(feature = "clipboard"))] +fn copy_to_clipboard(_text: &str) -> Result<(), String> { + Err("Копирование в буфер обмена недоступно (требуется feature 'clipboard')".to_string()) +} + /// Форматирует сообщение для копирования с контекстом fn format_message_for_clipboard(msg: &crate::tdlib::MessageInfo) -> String { let mut result = String::new(); diff --git a/tests/copy.rs b/tests/copy.rs index 83f5755..cb174a0 100644 --- a/tests/copy.rs +++ b/tests/copy.rs @@ -111,7 +111,7 @@ fn format_message_for_test(msg: &tele_tui::tdlib::MessageInfo) -> String { result } -#[cfg(test)] +#[cfg(all(test, feature = "clipboard"))] mod clipboard_tests { use super::*;