Iced là một thư viện giao diện người dùng (GUI) mã nguồn mở viết bằng Rust, lấy cảm hứng từ kiến trúc Elm. Nó cung cấp cơ chế truy cập bộ nhớ tạm (clipboard) đồng nhất trên nhiều hệ điều hành — bao gồm Windows, Linux, macOS và môi trường Web — giúp các ứng dụng dễ dàng chia sẻ dữ liệu giữa các tiến trình hoặc ứng dụng khác.
1. Kiến trúc mô-đun clipboard trong Iced
Mô-đun `clipboard` được thiết kế như một lớp trừu tượng hóa phía trên các thư viện nền tảng cụ thể:
- Trên Windows: sử dụng
clipboard-win - Trên Linux (Wayland/X11): dựa vào
wl-clipboard-rshoặcx11-clipboard - Trên macOS: tích hợp với
pasteboardthông quaobjcbindings - Trong trình duyệt (WASM): khai thác API
navigator.clipboardcủa Web Platform
Các thao tác đều được đóng gói dưới dạng Task<Result<T, clipboard::Error>>, phù hợp với mô hình phản ứng không đồng bộ của Iced.
2. Các kiểu nội dung hỗ trợ
Thư viện định nghĩa kiểu Content dưới dạng enum để biểu diễn các loại dữ liệu khả dụng:
enum Content {
Text(String),
Html(String),
Files(Vec<PathBuf>),
Image { data: Vec<u8>, width: u32, height: u32 },
}
Lưu ý: Khả năng đọc/ghi ảnh yêu cầu bật tính năng image trong Cargo.toml:
[dependencies.iced]
version = "0.13"
features = ["image"]
3. Ví dụ minh họa: Sao chép và dán văn bản
Dưới đây là đoạn mã xử lý sự kiện nút "Dán" trong một ứng dụng Iced đơn giản:
use iced::{clipboard, Command, Element, Task};
#[derive(Debug, Clone)]
pub enum Message {
PasteRequested,
PasteResult(Result<String, clipboard::Error>),
}
impl Application for MyApp {
// ... triển khai các phương thức bắt buộc
fn update(&mut self, message: Self::Message) -> Command<Self::Message> {
match message {
Message::PasteRequested => {
// Tạo task đọc nội dung văn bản từ bộ nhớ tạm
clipboard::read_text().map(Message::PasteResult)
}
Message::PasteResult(Ok(text)) => {
self.buffer = text;
Command::none()
}
Message::PasteResult(Err(e)) => {
eprintln!("Lỗi khi đọc bộ nhớ tạm: {:?}", e);
Command::none()
}
}
}
}
4. Ghi dữ liệu vào bộ nhớ tạm
Để sao chép văn bản ra ngoài, bạn gọi clipboard::write() với đối tượng Content:
let content = clipboard::Content::Text("Dữ liệu từ Iced".to_string());
Command::perform(clipboard::write(content), |_| Message::WriteCompleted);
Hàm này trả về một Command, do đó có thể tích hợp trực tiếp vào luồng cập nhật trạng thái mà không cần xử lý thủ công luồng async.
5. Xử lý lỗi phổ biến
Các giá trị lỗi được định nghĩa rõ ràng trong clipboard::Error:
ClipboardUnavailable: Hệ thống không cung cấp dịch vụ bộ nhớ tạm (ví dụ: WASM thiếu quyền)ContentNotSupported: Định dạng yêu cầu không được nền tảng hỗ trợ (ví dụ: ảnh trên Web)PermissionDenied: Người dùng từ chối cấp quyền truy cập (chỉ trên Web)
6. Ứng dụng thực tế
Một số tình huống thường gặp khi tích hợp clipboard:
- Trình soạn thảo văn bản: Hỗ trợ tổ hợp phím Ctrl+V/Ctrl+C thông qua
Event::Keyboard - Quản lý tệp: Đọc danh sách đường dẫn từ
Content::Filessau thao tác kéo-thả - Ứng dụng đồ họa: Chèn ảnh từ clipboard vào canvas bằng cách giải mã
Vec<u8>thànhImage<Handle>