目录
dependabot[bot]

Bump time from 0.3.44 to 0.3.47 (#2424)

Bumps time from 0.3.44 to 0.3.47.

Release notes

Sourced from time's releases.

v0.3.47

See the changelog for details.

v0.3.46

See the changelog for details.

v0.3.45

See the changelog for details.

Changelog

Sourced from time's changelog.

0.3.47 [2026-02-05]

Security

  • The possibility of a stack exhaustion denial of service attack when parsing RFC 2822 has been eliminated. Previously, it was possible to craft input that would cause unbounded recursion. Now, the depth of the recursion is tracked, causing an error to be returned if it exceeds a reasonable limit.

    This attack vector requires parsing user-provided input, with any type, using the RFC 2822 format.

Compatibility

  • Attempting to format a value with a well-known format (i.e. RFC 3339, RFC 2822, or ISO 8601) will error at compile time if the type being formatted does not provide sufficient information. This would previously fail at runtime. Similarly, attempting to format a value with ISO 8601 that is only configured for parsing (i.e. Iso8601::PARSING) will error at compile time.

Added

  • Builder methods for format description modifiers, eliminating the need for verbose initialization when done manually.
  • date!(2026-W01-2) is now supported. Previously, a space was required between W and 01.
  • [end] now has a trailing_input modifier which can either be prohibit (the default) or discard. When it is discard, all remaining input is ignored. Note that if there are components after [end], they will still attempt to be parsed, likely resulting in an error.

Changed

  • More performance gains when parsing.

Fixed

  • If manually formatting a value, the number of bytes written was one short for some components. This has been fixed such that the number of bytes written is always correct.
  • The possibility of integer overflow when parsing an owned format description has been effectively eliminated. This would previously wrap when overflow checks were disabled. Instead of storing the depth as u8, it is stored as u32. This would require multiple gigabytes of nested input to overflow, at which point we've got other problems and trivial mitigations are available by downstream users.

0.3.46 [2026-01-23]

Added

  • All possible panics are now documented for the relevant methods.
  • The need to use #[serde(default)] when using custom serde formats is documented. This applies only when deserializing an Option<T>.
  • Duration::nanoseconds_i128 has been made public, mirroring std::time::Duration::from_nanos_u128.

... (truncated)

Commits
  • d5144cd v0.3.47 release
  • f6206b0 Guard against integer overflow in release mode
  • 1c63dc7 Avoid denial of service when parsing Rfc2822
  • 5940df6 Add builder methods to avoid verbose construction
  • 00881a4 Manually format macros everywhere
  • bb723b6 Add trailing_input modifier to end
  • 31c4f8e Permit W12 in date! macro
  • 490a17b Mark error paths in well-known formats as cold
  • 6cb1896 Optimize Rfc2822 parsing
  • 6d264d5 Remove erroneous #[inline(never)] attributes
  • Additional commits viewable in compare view

Dependabot compatibility
score

Dependabot will resolve any conflicts with this PR as long as you don’t alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the Security Alerts page.

Signed-off-by: dependabot[bot] support@github.com Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

2个月前2498次提交

druid banner

A data-first Rust-native UI toolkit.

crates.io docs.rs license chat

Druid was an experimental Rust-native UI toolkit. Its main goal was to offer a polished user experience. There were many factors to this goal, including performance, a rich palette of interactions (hence a widget library to support them), and playing well with the native platform. See the goals section for more details.

We did periodic releases of Druid on crates.io. All changes were documented in the changelog.

For an overview of some key concepts, see the incomplete Druid book.

Project status

UNMAINTAINED

The Druid project has been discontinued.

New development effort moved on to Xilem, which has a lot of fundamental changes to allow for a wider variety of applications with better performance, but it also heavily inherits from Druid. We see Xilem as the future of Druid.

Druid is reasonably usable for some subset of applications and has a significant testing history, which ensures some stability and correctness. However, there will not be any new features or bug fixes coming to Druid. As such we don’t recommend using Druid for brand new applications. If you insist, then at least make sure your application doesn’t require a feature that Druid doesn’t have, e.g. accessibility or 3D support.

Contributions

As the Druid project has been discontinued, we will not be accepting any more contributions.

Please take a look at some of our other projects instead, especially the Druid successor Xilem.

Example

Here’s a simple counter example app:

use druid::widget::{Button, Flex, Label};
use druid::{AppLauncher, LocalizedString, PlatformError, Widget, WidgetExt, WindowDesc};

fn main() -> Result<(), PlatformError> {
    let main_window = WindowDesc::new(ui_builder());
    let data = 0_u32;
    AppLauncher::with_window(main_window)
        .log_to_console()
        .launch(data)
}

fn ui_builder() -> impl Widget<u32> {
    // The label text will be computed dynamically based on the current locale and count
    let text =
        LocalizedString::new("hello-counter").with_arg("count", |data: &u32, _env| (*data).into());
    let label = Label::new(text).padding(5.0).center();
    let button = Button::new("increment")
        .on_click(|_ctx, data, _env| *data += 1)
        .padding(5.0);

    Flex::column().with_child(label).with_child(button)
}

Check out the the examples folder for a more comprehensive demonstration of Druid’s existing functionality and widgets. Check druid_widget_nursery for more widgets.

Screenshots

calc.rs example flex.rs example custom_widget.rs example

Using Druid

An explicit goal of Druid was to be easy to build. Druid is available on crates.io and should work as a lone dependency (it re-exports all the parts of druid-shell, piet, and kurbo that you’ll need):

druid = "0.8.3"

Platform notes

Linux

On Linux, Druid requires gtk+3; see GTK installation page. (On ubuntu-based distro, running sudo apt-get install libgtk-3-dev from the terminal will do the job.)

OpenBSD

On OpenBSD, Druid requires gtk+3; install from packages:

pkg_add gtk+3

Alternatively, there is an X11 backend available, although it is currently missing quite a few features. You can try it out with --features=x11.

Goals

Druid’s goal was to make it easy to write and deploy high quality desktop applications with a smooth and polished user experience on all common platforms. In order to achieve this we strived for a variety of things:

  • Make it easy to build and package on all supported platforms.
  • Implement abstractions to avoid platform specific quirks.
  • Respect platform conventions and expectations.
  • Handle display resolution and scaling reliably with little effort.
  • Enable easy, yet powerful internationalization.
  • Offer robust accessibility support.
  • Produce small and fast binaries with low memory usage.
  • Have a small dependency tree, a high quality code base and good organization.
  • Focus on powerful, desktop-grade applications.
  • Provide a flexible set of layouts and common widgets.
  • Ease creation of custom components and application logic as needed.

Non-Goals

In order to fulfill those goals, we couldn’t support every use case. Luckily the Rust community is working on a variety of different libraries with different goals, so here are some of Druid’s non-goals and possible alternatives that can offer those capabilities:

  • Use the platform-native widgets or mimic them. (Relm, Slint)
  • Embed easily into custom render pipelines. (Conrod)
  • Adhere to a specific architectural style such as Elm. (Iced, Relm)
  • Support rendering to HTML when targeting the web. (Iced, Moxie)

Druid was just one of many ongoing Rust-native GUI experiments.

Concepts

druid-shell

The Druid toolkit uses druid-shell for a platform-abstracting application shell. druid-shell is responsible for starting a native platform runloop, listening to events, converting them into a platform-agnostic representation, and calling a user-provided handler with them.

While druid-shell was being developed with the Druid toolkit in mind, it was intended to be general enough that it could be reused by other projects interested in experimenting with Rust GUI. The druid-shell crate includes a couple of non-druid examples.

piet

Druid relies on the Piet library for drawing and text layout. Piet is a 2D graphics abstraction with multiple backends: piet-direct2d, piet-coregraphics, piet-cairo, piet-web, and piet-svg are currently available. In terms of Druid platform support via Piet, macOS uses piet-coregraphics, Linux/OpenBSD/FreeBSD use piet-cairo, Windows uses piet-direct2d, and web uses piet-web.

use druid::kurbo::{BezPath, Point, Rect};
use druid::piet::Color;

// Create an arbitrary bezier path
// (ctx.size() returns the size of the layout rect we're painting in)
let mut path = BezPath::new();
path.move_to(Point::ORIGIN);
path.quad_to(
    (80.0, 90.0),
    (ctx.size().width, ctx.size().height),
);
// Create a color
let stroke_color = Color::rgb8(0x00, 0x80, 0x00);
// Stroke the path with thickness 1.0
ctx.stroke(path, &stroke_color, 1.0);

// Rectangles: the path for practical people
let rect = Rect::from_origin_size((10., 10.), (100., 100.));
// Note the Color:rgba8 which includes an alpha channel (7F in this case)
let fill_color = Color::rgba8(0x00, 0x00, 0x00, 0x7F);
ctx.fill(rect, &fill_color);

widgets

Widgets in Druid (text boxes, buttons, layout components, etc.) are objects which implement the Widget trait. The trait is parametrized by a type (T) for associated data. All trait methods (event, lifecycle, update, paint, and layout) are provided with access to this data, and in the case of event the reference is mutable, so that events can directly update the data.

Whenever the application data changes, the framework traverses the widget hierarchy with an update method.

All the widget trait methods are provided with a corresponding context (EventCtx, LifeCycleCtx, UpdateCtx, LayoutCtx, PaintCtx). The widget can request things and cause actions by calling methods on that context.

In addition, all trait methods are provided with an environment Env, which includes the current theme parameters (colors, dimensions, etc.).

impl<T: Data> Widget<T> for Button<T> {
    fn event(&mut self, ctx: &mut EventCtx, event: &Event, data: &mut T, env: &Env) {
      ...
    }

    fn lifecycle(&mut self, ctx: &mut LifeCycleCtx, event: &LifeCycle, data: &T, env: &Env) {
      ...
    }

    fn update(&mut self, ctx: &mut UpdateCtx, old_data: &T, data: &T, env: &Env) {
      ...
    }

    fn layout(&mut self, ctx: &mut LayoutCtx, bc: &BoxConstraints, data: &T, env: &Env) -> Size {
      ...
    }

    fn paint(&mut self, ctx: &mut PaintCtx, data: &T, env: &Env) {
      ...
    }
}

Druid provides a number of basic utility and layout widgets and it’s easy to implement your own. You can also compose widgets into new widgets:

fn build_widget() -> impl Widget<u32> {
    let mut col = Flex::column();
    for i in 0..30 {
        let button = Button::new(format!("Button {}", i).padding(5.0);
        col.add_child(button);
    }
    Scroll::new(col)
}

layout

Druid’s layout protocol was strongly inspired by Flutter’s box layout model. In Druid, widgets are passed a BoxConstraint that provides them a minimum and maximum size for layout. Widgets are also responsible for computing appropriate constraints for their children if applicable.

data

Druid uses a Data trait to represent value types. These should be cheap to compare and cheap to clone.

In general, you can use derive to generate a Data impl for your types.

#[derive(Clone, Data)]
struct AppState {
    which: bool,
    value: f64,
}

lens

The Lens datatype gives access to a part of a larger data structure. Like Data, this can be derived. Derived lenses are accessed as associated constants with the same name as the field.

#[derive(Clone, Data, Lens)]
struct AppState {
    which: bool,
    value: f64,
}

To use the lens, wrap your widget with LensWrap (note the conversion of CamelCase to snake_case):

LensWrap::new(WidgetThatExpectsf64::new(), AppState::value);

Alternatively, lenses for structs, tuples, and indexable containers can be constructed on-demand with the lens macro:

LensWrap::new(WidgetThatExpectsf64::new(), lens!(AppState, value));

This is particularly useful when working with types defined in another crate.

Authors

The main authors are Raph Levien and Colin Rofls, with much support from an active and friendly community. See the AUTHORS file for more.

邀请码
    Gitlink(确实开源)
  • 加入我们
  • 官网邮箱:gitlink@ccf.org.cn
  • QQ群
  • QQ群
  • 公众号
  • 公众号

版权所有:中国计算机学会技术支持:开源发展技术委员会
京ICP备13000930号-9 京公网安备 11010802032778号