feat: 项目基础框架搭建 - Phase 1 Issue #1

- 创建 Cargo.toml 依赖配置
- 实现配置管理模块 (config/)
- 实现核心服务模块 (core/)
  - 文档处理引擎
  - 翻译服务
- 实现基础设施模块 (infrastructure/)
  - 存储模块
- 实现 UI 模块 (ui/)
- 集成 logging (tracing)

项目结构:
├── Cargo.toml
├── src/
│   ├── main.rs
│   ├── config/mod.rs
│   ├── core/
│   │   ├── mod.rs
│   │   ├── document.rs
│   │   └── translation.rs
│   ├── infrastructure/
│   │   ├── mod.rs
│   │   └── storage.rs
│   └── ui/
│       └── mod.rs
This commit is contained in:
Rong
2026-03-08 23:58:43 +08:00
parent 8dc2be2108
commit 28be3b8509
9 changed files with 292 additions and 0 deletions

52
Cargo.toml Normal file
View File

@@ -0,0 +1,52 @@
[package]
name = "readflow"
version = "0.1.0"
edition = "2021"
authors = ["damai <damai@foshanhuiya.com>"]
description = "ReadFlow - 面向开发者和知识工作者的阅读工具"
repository = "http://192.168.120.110:4000/damai/readflow"
license = "MIT"
[dependencies]
# 核心框架
dioxus = { version = "0.5", features = ["desktop"] }
dioxus-router = "0.5"
tauri = { version = "2", optional = true }
# 异步运行时
tokio = { version = "1", features = ["full"] }
# 文档处理
pdfium-render = "0.8"
epub = "2.0"
mobi = "0.2"
# Markdown 与代码高亮
pulldown-cmark = "0.9"
syntect = "5.1"
tree-sitter = { version = "0.20", optional = true }
# 数据存储
sled = "0.34"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
# 配置管理
config = "0.14"
anyhow = "1.0"
tracing = "0.1"
tracing-subscriber = "0.3"
# 工具
rayon = "1.8" # 并行计算
[features]
default = ["desktop"]
desktop = ["dioxus/desktop"]
tauri = ["dep:tauri"]
wasm = ["dioxus/web"]
[profile.release]
opt-level = 3
lto = true
codegen-units = 1

69
src/config/mod.rs Normal file
View File

@@ -0,0 +1,69 @@
//! 配置管理模块
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Config {
pub theme: ThemeConfig,
pub reader: ReaderConfig,
pub translation: TranslationConfig,
pub storage: StorageConfig,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ThemeConfig {
pub mode: String, // "light" or "dark"
pub font_size: u32,
pub font_family: String,
pub line_height: f32,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ReaderConfig {
pub default_format: String,
pub scroll_smooth: bool,
pub show_toc: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TranslationConfig {
pub provider: String, // "google", "deepl", "ollama"
pub api_key: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct StorageConfig {
pub library_path: String,
pub cache_path: String,
}
impl Default for Config {
fn default() -> Self {
Self {
theme: ThemeConfig {
mode: "light".to_string(),
font_size: 16,
font_family: "system".to_string(),
line_height: 1.5,
},
reader: ReaderConfig {
default_format: "pdf".to_string(),
scroll_smooth: true,
show_toc: true,
},
translation: TranslationConfig {
provider: "ollama".to_string(),
api_key: None,
},
storage: StorageConfig {
library_path: "./library".to_string(),
cache_path: "./cache".to_string(),
},
}
}
}
pub fn load() -> Config {
// 后续从文件加载配置
Config::default()
}

43
src/core/document.rs Normal file
View File

@@ -0,0 +1,43 @@
//! 文档处理引擎
use anyhow::Result;
pub enum DocumentFormat {
Pdf,
Epub,
Mobi,
Azw3,
Txt,
Markdown,
Code,
}
pub struct Document {
pub format: DocumentFormat,
pub title: String,
pub path: String,
pub content: Vec<u8>,
}
pub struct DocumentEngine;
impl DocumentEngine {
pub fn new() -> Self {
Self
}
pub fn open(&self, path: &str) -> Result<Document> {
// 后续实现:基于文件扩展名判断格式并解析
todo!("Implement document opening for: {}", path)
}
pub fn render(&self, doc: &Document) -> Result<String> {
// 后续实现:渲染文档内容
todo!("Implement document rendering")
}
pub fn search(&self, doc: &Document, query: &str) -> Result<Vec<usize>> {
// 后续实现:全文搜索
todo!("Implement search functionality")
}
}

9
src/core/mod.rs Normal file
View File

@@ -0,0 +1,9 @@
//! 核心服务模块
//!
//! 包含文档处理、翻译等功能
pub mod document;
pub mod translation;
pub use document::DocumentEngine;
pub use translation::TranslationService;

30
src/core/translation.rs Normal file
View File

@@ -0,0 +1,30 @@
//! 翻译服务模块
use anyhow::Result;
pub enum TranslationProvider {
Google,
DeepL,
Ollama,
}
pub struct TranslationService {
provider: TranslationProvider,
api_key: Option<String>,
}
impl TranslationService {
pub fn new(provider: TranslationProvider, api_key: Option<String>) -> Self {
Self { provider, api_key }
}
pub fn translate(&self, text: &str, from: &str, to: &str) -> Result<String> {
// 后续实现:调用翻译 API
todo!("Implement translation for: {}", text)
}
pub fn detect_language(&self, text: &str) -> Result<String> {
// 后续实现:语言检测
todo!("Implement language detection")
}
}

View File

@@ -0,0 +1,7 @@
//! 基础设施模块
//!
//! 包含文件 I/O、缓存、事件总线等
pub mod storage;
pub use storage::Storage;

View File

@@ -0,0 +1,25 @@
//! 存储模块
use anyhow::Result;
pub struct Storage {
path: String,
}
impl Storage {
pub fn new(path: &str) -> Self {
Self {
path: path.to_string(),
}
}
pub fn save(&self, key: &str, value: &[u8]) -> Result<()> {
// 后续实现:使用 sled 存储
todo!("Implement storage save for key: {}", key)
}
pub fn load(&self, key: &str) -> Result<Vec<u8>> {
// 后续实现:使用 sled 加载
todo!("Implement storage load for key: {}", key)
}
}

37
src/main.rs Normal file
View File

@@ -0,0 +1,37 @@
//! ReadFlow - 面向开发者和知识工作者的阅读工具
//!
//! 项目主页: http://192.168.120.110:4000/damai/readflow
use std::env;
use tracing::info;
use tracing_subscriber::{fmt, prelude::*, EnvFilter};
mod config;
mod core;
mod infrastructure;
mod ui;
fn setup_logging() {
let filter = EnvFilter::try_from_default_env()
.unwrap_or_else(|_| EnvFilter::new("info"));
tracing_subscriber::registry()
.with(fmt::layer())
.with(filter)
.init();
}
fn main() {
setup_logging();
info!("Starting ReadFlow v{}", env!("CARGO_PKG_VERSION"));
info!("Project: {}", env!("CARGO_PKG_NAME"));
info!("Description: {}", env!("CARGO_PKG_DESCRIPTION"));
// 初始化配置
let config = config::load();
info!("Configuration loaded");
// 启动 UI
ui::run(config);
}

20
src/ui/mod.rs Normal file
View File

@@ -0,0 +1,20 @@
//! UI 模块
//!
//! 使用 Dioxus 构建跨平台 UI
use crate::config::Config;
pub fn run(config: Config) {
println!("Starting UI with config: {:?}", config.theme);
// 后续实现Dioxus UI 启动
// 示例:
// dioxus::launch(App);
}
// 后续实现Dioxus 组件
// pub fn App(cx: Scope) -> Element {
// cx.render(rsx! {
// div { "Hello, ReadFlow!" }
// })
// }