125 lines
3.2 KiB
Rust
125 lines
3.2 KiB
Rust
use qr_core::qr::{QrCode, QrConfig, VersionMode};
|
|
use qr_core::version::EcLevel;
|
|
use serde::{Deserialize, Serialize};
|
|
use std::sync::Mutex;
|
|
|
|
/// QR 编码响应
|
|
#[derive(Debug, Serialize, Clone)]
|
|
struct QrResponse {
|
|
svg: String,
|
|
version: u8,
|
|
size: u8,
|
|
mask: u8,
|
|
}
|
|
|
|
/// 历史记录条目
|
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
|
struct HistoryEntry {
|
|
id: String,
|
|
mode: String,
|
|
content: String,
|
|
timestamp: u64,
|
|
}
|
|
|
|
/// 应用状态
|
|
struct AppState {
|
|
history: Mutex<Vec<HistoryEntry>>,
|
|
}
|
|
|
|
/// 编码 QR 码,返回 SVG + 元信息
|
|
#[tauri::command]
|
|
fn encode_qr(text: String, level: String, margin: u8) -> Result<QrResponse, String> {
|
|
let ec_level = match level.to_uppercase().as_str() {
|
|
"L" => EcLevel::L,
|
|
"M" => EcLevel::M,
|
|
"Q" => EcLevel::Q,
|
|
"H" => EcLevel::H,
|
|
_ => return Err(format!("无效纠错级别: {}", level)),
|
|
};
|
|
|
|
let config = QrConfig {
|
|
level: ec_level,
|
|
version: VersionMode::Auto,
|
|
margin,
|
|
};
|
|
|
|
let qr = QrCode::encode(&text, config).map_err(|e| format!("编码失败: {}", e))?;
|
|
|
|
let svg = qr.to_svg();
|
|
|
|
Ok(QrResponse {
|
|
svg,
|
|
version: qr.version.0,
|
|
size: qr.size(),
|
|
mask: qr.mask,
|
|
})
|
|
}
|
|
|
|
/// 导出 PNG bytes
|
|
#[tauri::command]
|
|
fn export_png(text: String, level: String, margin: u8, module_size: u8) -> Result<Vec<u8>, String> {
|
|
let ec_level = match level.to_uppercase().as_str() {
|
|
"L" => EcLevel::L,
|
|
"M" => EcLevel::M,
|
|
"Q" => EcLevel::Q,
|
|
"H" => EcLevel::H,
|
|
_ => return Err(format!("无效纠错级别: {}", level)),
|
|
};
|
|
|
|
let config = QrConfig {
|
|
level: ec_level,
|
|
version: VersionMode::Auto,
|
|
margin,
|
|
};
|
|
|
|
let qr = QrCode::encode(&text, config).map_err(|e| format!("编码失败: {}", e))?;
|
|
|
|
Ok(qr.to_png_bytes(module_size))
|
|
}
|
|
|
|
/// 保存历史记录条目
|
|
#[tauri::command]
|
|
fn save_history(state: tauri::State<AppState>, entry: HistoryEntry) -> Result<(), String> {
|
|
let mut history = state.history.lock().map_err(|e| e.to_string())?;
|
|
history.push(entry);
|
|
if history.len() > 50 {
|
|
history.remove(0);
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
/// 加载全部历史记录
|
|
#[tauri::command]
|
|
fn load_history(state: tauri::State<AppState>) -> Result<Vec<HistoryEntry>, String> {
|
|
let history = state.history.lock().map_err(|e| e.to_string())?;
|
|
Ok(history.clone())
|
|
}
|
|
|
|
/// 清空历史记录
|
|
#[tauri::command]
|
|
fn clear_history(state: tauri::State<AppState>) -> Result<(), String> {
|
|
let mut history = state.history.lock().map_err(|e| e.to_string())?;
|
|
history.clear();
|
|
Ok(())
|
|
}
|
|
|
|
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
|
pub fn run() {
|
|
tauri::Builder::default()
|
|
.plugin(tauri_plugin_store::Builder::new().build())
|
|
.plugin(tauri_plugin_dialog::init())
|
|
.plugin(tauri_plugin_clipboard_manager::init())
|
|
.manage(AppState {
|
|
history: Mutex::new(Vec::new()),
|
|
})
|
|
.invoke_handler(tauri::generate_handler![
|
|
encode_qr,
|
|
export_png,
|
|
save_history,
|
|
load_history,
|
|
clear_history,
|
|
])
|
|
.run(tauri::generate_context!())
|
|
.expect("启动 QRGen GUI 失败");
|
|
}
|