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:
52
Cargo.toml
Normal file
52
Cargo.toml
Normal 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
69
src/config/mod.rs
Normal 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
43
src/core/document.rs
Normal 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
9
src/core/mod.rs
Normal 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
30
src/core/translation.rs
Normal 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")
|
||||||
|
}
|
||||||
|
}
|
||||||
7
src/infrastructure/mod.rs
Normal file
7
src/infrastructure/mod.rs
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
//! 基础设施模块
|
||||||
|
//!
|
||||||
|
//! 包含文件 I/O、缓存、事件总线等
|
||||||
|
|
||||||
|
pub mod storage;
|
||||||
|
|
||||||
|
pub use storage::Storage;
|
||||||
25
src/infrastructure/storage.rs
Normal file
25
src/infrastructure/storage.rs
Normal 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
37
src/main.rs
Normal 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
20
src/ui/mod.rs
Normal 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!" }
|
||||||
|
// })
|
||||||
|
// }
|
||||||
Reference in New Issue
Block a user