Files
QRGen/gui/src/lib.rs
T

133 lines
3.4 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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> {
if margin > 100 {
return Err("边距过大(最大 100".into());
}
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> {
if margin > 100 {
return Err("边距过大(最大 100".into());
}
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))?;
qr.to_png_bytes(module_size).map_err(|e| format!("PNG 导出失败: {}", e))
}
/// 保存历史记录条目
#[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 失败");
}