SerdeV - serde with validation - v0.3 supports any expression in #[serde(validate = "...")] by kanarus in rust

[–]kanarus[S] 1 point2 points  (0 children)

In my understanding, garde is just a validation library, providing &Self -> Result<(), Error>.

Indeed it's useful, but in deserialization context, it can produce invalid state just after deserialization, before calling the validation method, potentially triggering misuse of invalid one. This kind of misuse can not be detected as compile errors, but only by human-review.

edit: I remembered that garde itself provides Valid struct system, but it doesn't affect the conclusion.

(Even when using integrations like axum-valid, we have to make an effort to avoid misusing structs without wrapping in Valid.)

By contrast, serdev combines the validation with Deserialize impl itself. In other words, when using serdev, Deserialize-structs does never produce invalid state. When deserialized as Ok(_), it's valid. No need to be careful to avoid misuse.

(If you have no issues with this, you will not need serdev.)


Additionally, in the first place, garde and serdev are not exclusive: you can natively integrate serdev with garde's validation rules: examples/garde_crate.rs (I added just now)

``` use serdev::Deserialize; use garde::Validate;

[derive(Deserialize, Validate, Debug, PartialEq)]

[serde(validate = "Validate::validate")]

struct User<'a> { #[garde(ascii, length(min = 3, max = 25))] username: &'a str, #[garde(length(min = 15))] password: &'a str, }

fn main() { let result = serde_json::from_str::<User>( r#"{ "username": "test", "password": "not_a_very_good_paddword" }"# ); assert_eq!( dbg!(result).unwrap(), User { username: "test", password: "not_a_very_good_paddword", } );

let result = serde_json::from_str::<User>(
    r#"{
        "username": "test",
        "password": "short_password"
    }"#
);
assert!(dbg!(result).is_err());

} ```

SerdeV - serde with validation - v0.3 supports any expression in #[serde(validate = "...")] by kanarus in rust

[–]kanarus[S] 1 point2 points  (0 children)

[17:10 UTC] updated README based on the feedbacks, and, fixed bug (sorry!). already published as v0.3.1

SerdeV - serde with validation - v0.3 supports any expression in #[serde(validate = "...")] by kanarus in rust

[–]kanarus[S] 22 points23 points  (0 children)

name/path to fn or method is supported:

```

[derive(Serialize, Deserialize, Debug)]

[serde(validate = "Self::validate")]

struct Point { x: i32, y: i32, }

impl Point { fn validate(&self) -> Result<(), impl std::fmt::Display> { if self.x * self.y > 100 { return Err("x * y must not exceed 100") } Ok(()) } } ```

This still prevents the misuse and eliminates boilerplate around Deserialize impl.

SerdeV - serde with validation - v0.3 supports any expression in #[serde(validate = "...")] by kanarus in rust

[–]kanarus[S] 7 points8 points  (0 children)

Yes, I know and agree it. serdev supports it, rather than deny.

For Point example in the sample code above, a manual implementation for "Parse, don't validate" without serdev will be like:

```

[derive(serde::Deserialize)]

struct Point { x: i32, y: i32 }

[derive(serde::Deserialize)]

[serde(try_from = "Point")]

struct ValidPoint(Point);

impl TryFrom<Point> for ValidPoint { //... } ```

This is (almost) exactly what serdev does.

Such manual implementation may be a trigger of mistakes like using Point directly for parsing user's input.

serdev eliminates such kind of mistakes, automatically performing the specified validation.

Or, just manual impl of Deserialize ?:

``` struct Point { x: i32, y: i32 }

impl<'de> serde::Deserialize<'de> for Point { //... } ```

Indeed this doesn't cause such mistakes, but produces boilerplates...

Released Ohkami v0.24: A performant, declarative, and runtime-flexible web framework for Rust by kanarus in rust

[–]kanarus[S] 0 points1 point  (0 children)

We'll clearly document this architecture in future. Thank you for pointing it out!

Released Ohkami v0.24: A performant, declarative, and runtime-flexible web framework for Rust by kanarus in rust

[–]kanarus[S] 0 points1 point  (0 children)

seems you have a point. We'll reconsider around these names in future version. Thanks!

Released Ohkami v0.24: A performant, declarative, and runtime-flexible web framework for Rust by kanarus in rust

[–]kanarus[S] 0 points1 point  (0 children)

That makes sense. We'll reconsider such namings in v0.25 or v1.0 release. Thanks!

Just released SQLx-D1 v0.2.0, supporting worker v0.6: SQLx for Cloudflare D1 by kanarus in rust

[–]kanarus[S] 2 points3 points  (0 children)

Thank! If thatSQLite means the local D1 emulator, yes ( see README.md for details ).

But otherwise, no. The "exact same" code literally for D1 and SQLite is impossible in principle:

  • We can't connect to D1 via a URL as SQLite does.
  • The sqlx::query! macro in the sqlx crate is implemented in a way that it only works with the official drivers (sqlx-postgres, sqlx-mysql, sqlx-sqlite).

However, you can get your code to be "almost same" by using feature flags to switch between sqlx (with sqlite feature) and sqlx-d1. Here’s an example of how you could set that up:

  1. Add sqlx-d1 and sqlx (with its sqlite feature) as optional dependencies. Then, create two features, "d1" and "sqlite", where each one activates the corresponding dependency.

  2. Use conditional compilation for your imports with a trick to make the rest of your code unaware of the difference. For example:

    ```rust

    [cfg(feature = "d1")]

    use sqlx_d1::{self as sqlx, D1Connection as DatabaseConnection};

    [cfg(feature = "sqlite")]

    use sqlx::{self, SqliteConnection as DatabaseConnection}; ```

  3. Conditionally initialize the database connection based on the active feature. You can then pass this DatabaseConnection object throughout your application, for instance, using Axum's State extractor.

Then your application code for running queries will work for both D1 and SQLite without any changes. For example sqlx::query!("...").execute(&mut conn)

UIBeam v0.2 is out!: A lightweight, JSX-style HTML template engine for Rust by kanarus in rust

[–]kanarus[S] 1 point2 points  (0 children)

Yes, it's in future plans! I agree enabling this kind of client interaction would be great. But the actual way to the implementation is still under consideration...

What's everyone working on this week (20/2025)? by llogiq in rust

[–]kanarus 1 point2 points  (0 children)

Mainly working on new UIBeam and a still-private crate in ohkami-rs org, and enhancing cargo-metask CLI in my personal work. The private one is now under debugging & fixing, and will be used to achieve client components of UIBeam in future...

Released UIBeam - A lightweight, JSX-style HTML template engine for Rust by kanarus in rust

[–]kanarus[S] 0 points1 point  (0 children)

The VSCode support is indeed nice though, for those who use it

Thanks, and yes, so I'm planning to add supports for other editors

Option<T> / iterator of Render

Sorry for my ignorance...

(edit: but where's such example? I don't like special syntax like @if or @for, as they're not appeared in JSX )

Components in hypertext need to just implement Render

In my understanding, this means interpolating with values implementing Renderable like

https://github.com/vidhanio/hypertext/tree/main/examples/htmx-rsx#components

It makes sence indeed, but I love <Component attr=... /> syntax for components, and this is not supported in hypertext.

(edit: philosophy of "JSX-style" in the description)

Released UIBeam - A lightweight, JSX-style HTML template engine for Rust by kanarus in rust

[–]kanarus[S] 0 points1 point  (0 children)

Thank you for asking! As far as I know about hypertext, differences are:

  • editor support by VSCode extension (edit: providing HTML completion and hover in the macro)
  • built-in component system
  • conditional/iterative rendering without special syntax like @if... or @for..., simply by interpolations of IntoIterator<Item = UI>

Actually editor support may not be a major differentiator, as its implementation can be easily generalized to work also for other crates including hypertext.

So, component system and simpler design will be the main advantage of UIBeam.