分类目录归档:Rust

Rust图形用户界面(GUI)推荐

iced

A cross-platform GUI library for Rust focused on simplicity and type-safety. Inspired by Elm.


struct Counter {
    // The counter value
    value: i32,
}

#[derive(Debug, Clone, Copy)]
pub enum Message {
    IncrementPressed,
    DecrementPressed,
}

use iced::widget::{button, column, text, Column};

impl Counter {
    pub fn view(&self) -> Column<Message> {
        // We use a column: a simple vertical layout
        column![
            // The increment button. We tell it to produce an
            // `IncrementPressed` message when pressed
            button("+").on_press(Message::IncrementPressed),

            // We show the value of the counter here
            text(self.value).size(50),

            // The decrement button. We tell it to produce a
            // `DecrementPressed` message when pressed
            button("-").on_press(Message::DecrementPressed),
        ]
    }

    pub fn update(&mut self, message: Message) {
        match message {
            Message::IncrementPressed => {
                self.value += 1;
            }
            Message::DecrementPressed => {
                self.value -= 1;
            }
        }
    }
}

Features

  • Simple, easy-to-use, batteries-included API
  • Type-safe, reactive programming model
  • Cross-platform support (Windows, macOS, Linux, and the Web)
  • Responsive layout
  • Built-in widgets (including text inputs, scrollables, and more!)
  • Custom widget support (create your own!)
  • Debug overlay with performance metrics
  • First-class support for async actions (use futures!)
  • Modular ecosystem split into reusable parts:
    • A renderer-agnostic native runtime enabling integration with existing systems
    • Two built-in renderers leveraging wgpu and glow
      • iced_wgpu supporting Vulkan, Metal and DX12
      • iced_glow supporting OpenGL 2.1+ and OpenGL ES 2.0+
    • A windowing shell
    • A web runtime leveraging the DOM

dioxus

Dioxus 是一个可移植的、高性能的、符合人体工程学的框架,使用 Rust 语言构建跨平台的用户界面。

fn app(cx: Scope) -> Element {
    let mut count = use_state(cx, || 0);

    cx.render(rsx! {
        h1 { "High-Five counter: {count}" }
        button { onclick: move |_| count += 1, "Up high!" }
        button { onclick: move |_| count -= 1, "Down low!" }
    })
}

Dioxus 可用于生成 网页前端、桌面应用、静态网站、移动端应用、TUI程序、等多类平台应用。

如果你能够熟悉使用 React 框架,那 Dioxus 对你来说将非常简单。

独特的特性:

  1. 桌面程序完全基于本地环境运行(并非 Electron 的封装)
  2. 符合人体工程学的设计以及拥有强大的状态管理
  3. 全面的内联文档 – 包含所有 HTML 元素、监听器 和 事件 指南。
  4. 极快的运行效率和极高的内存效率
  5. 智能项目热更新和高效的项目迭代
  6. 一流的异步支持fire
  7. 更多内容请查看 版本发布信息.

tauri

Build smaller, faster, and more secure desktop applications with a web frontend.

Features

  • Desktop Bundler (.app, .dmg, .deb, AppImage, .msi)
  • Self Updater
  • App Signing
  • Native Notifications (toast)
  • App Tray
  • Core Plugin System
  • Scoped Filesystem
  • Sidecar

Security Features

  • localhost-free (:fire:)
  • custom protocol for secure mode
  • Dynamic ahead of Time Compilation (dAoT) with functional tree-shaking
  • functional Address Space Layout Randomization
  • OTP salting of function names and messages at runtime
  • CSP Injection

Utilities

  • Rust-based CLI
  • GH Action for creating binaries for all platforms
  • VS Code Extension

egui

egui: an easy-to-use immediate mode GUI in Rust that runs on both web and native

ui.heading("My egui Application");
ui.horizontal(|ui| {
    ui.label("Your name: ");
    ui.text_edit_singleline(&mut name);
});
ui.add(egui::Slider::new(&mut age, 0..=120).text("age"));
if ui.button("Click each year").clicked() {
    age += 1;
}
ui.label(format!("Hello '{}', age {}", name, age));

yew

A framework for creating reliable and efficient web applications.

use yew::prelude::*;

#[function_component]
fn App() -> Html {
    let counter = use_state(|| 0);
    let onclick = {
        let counter = counter.clone();
        move |_| {
            let value = *counter + 1;
            counter.set(value);
        }
    };

    html! {
        <div>
            <button {onclick}>{ "+1" }</button>
            <p>{ *counter }</p>
        </div>
    }
}

fn main() {
    yew::Renderer::<App>::new().render();
}

slint

Design Goals

We use the following design goals as a guide when developing Slint:

  • Scalable: Run on any screen connected to a device, from desktop computers to low end embedded systems.
  • Lightweight: Fit into a few hundred kilobytes of RAM and require little processing power.
  • Intuitive: Both developers and designers should feel productive and enjoy the design and development process. The APIs should be consistent and easy to use, no matter the target language.
  • Native: Slint apps should match the users’ expectations of a native application. Various target platforms such as embedded devices, desktops, mobile and web should be supported so that both the user and the developer feel comfortable on their platform of choice.

Rust两个小型ORM–Cherry和Akita

Rust使用比较多的ORM是SeaORMDiesel,本文介绍两个轻量级的。

Cherry

https://github.com/bitlabx/cherry

use cherry::{DataSource, PoolConfig};

pub async fn setup() -> Result<(), Box<dyn Error>> {
    let conn = PoolConfig {
        url: "mysql://root:12345678@localhost:3306/foo".to_owned(),
        ..Default::default()
    };

    Foo::setup(conn).await?;

    let result: Option<User> = Foo::select()
        .and_where_eq("id", 123)
        .fetch()
        .await?;

    Ok(())
}

pub struct Foo;

impl DataSource for Foo {}

// You can setup more than one DataSources if you need.
// pub struct Bar;
// impl DataSource for Bar {}

Akita

https://github.com/wslongchen/akita

fn main() {
    let cfg = AkitaConfig::new(String::from("mysql://root:password@localhost:3306/akita"))
        .set_connection_timeout(Duration::from_secs(6))
        .set_log_level(LogLevel::Info).set_max_size(6);
    let akita = Akita::new(cfg).expect("must be ok");
    // CRUD with Entity
    let model = User::default();
    // insert
    let insert_id = model.insert::<Option<i32>, _>(&akita).unwrap();
    // update
    let res = model.update_by_id::<_>(&akita).unwrap();
    // delete
    let res = model.delete_by_id::<i32,_>(&akita, 1).unwrap();
    // list
    let list = User::list::<_>(Wrapper::new().eq("name", "Jack"), &akita).unwrap();
    // page
    let page = User::page::<_>(pageNo, pageSize, Wrapper::new().eq("name", "Jack"), &akita).unwrap();
}