Sign in

Cot.rs

@cot.rs
27 followers 5 following 28 posts

The Rust web framework for lazy developers

PostsRepliesMedia
Cot.rs @cot.rs · 13/07/2026
ProjectConfig now has a catch-all extra field that captures any configuration keys Cot doesn’t recognise. This is the idiomatic way to add project-specific settings to the standard config TOML files without fighting the parser.
# config/base.toml
[my_app]
analytics_key = "UA-XXXXXXXXX-1"
feature_flags = ["dark_mode", "beta_ui"]

use cot::config::ProjectConfig;
use serde::Deserialize;

#[derive(Deserialize)]
struct MyAppConfig {
    analytics_key: String,
    feature_flags: Vec<String>,
}

async fn handler(config: ProjectConfig) -> cot::Result<Html> {
    let app_config: MyAppConfig = config
        .extra
        .get("my_app")
        .expect("missing [my_app] section")
        .clone()
        .try_into()?;

    // ...
}
100
Cot.rs @cot.rs · 13/07/2026
Foreign key fields now let you control referential integrity policies directly from the model definition. Previously, Cot always generated RESTRICT for both policies. Now you can choose any standard option giving you full control over what happens when a referenced row is updated or deleted.
use cot::db::{ForeignKey, ForeignKeyOnDeletePolicy, ForeignKeyOnUpdatePolicy};

#[model]
struct Comment {
    #[model(primary_key)]
    id: Auto<i32>,

    #[model(
        on_delete = ForeignKeyOnDeletePolicy::Cascade,
        on_update = ForeignKeyOnUpdatePolicy::Cascade,
    )]
    post: ForeignKey<Post>,

    body: String,
}
110
Cot.rs @cot.rs · 13/07/2026
Forms are central to almost every web app, and in v0.7 we’ve made Cot’s form system more expressive. All the major field types: String, Password, Email, Url, number, and float fields, now expose a much larger set of HTML attributes that you can configure through field options
use cot::form::fields::{AutoComplete, List, StringFieldOptions};

#[derive(Form)]
struct ProfileForm {
    #[form(opts(
        max_length = 100,
        placeholder = "Your full name",
        autocomplete = AutoComplete::Name,
        list = List::new(["Alice", "Bob", "Charlie"]),
    ))]
    name: String,

    #[form(opts(
        placeholder = "you@example.com",
        autocomplete = AutoComplete::Email,
        readonly = true,
    ))]
    email: String,
}
100
Cot.rs @cot.rs · 19/03/2026
While we're at the ORM topic, a small, yet useful fix is that now you can use raw Rust identifiers in model and field names. You can now name your fields, models, and tables however you want!
A screenshot of Cot.rs's model declaration with raw identifiers everywhere
100
Cot.rs @cot.rs · 19/03/2026
One of the long-awaited change in the ORM was the custom migrations. With Cot v0.6, you can now generate a migration template that executes arbitrary Rust code! Do you want to change format of your blog posts titles in the database? Now you can!
A screenshot of Cot.rs's custom migration code
100
Cot.rs @cot.rs · 11/09/2025
The new `FromRequestParts` derive macro cuts down on repetitive code. Instead of listing `Urls`, `StaticFiles`, and `RouteName` in every handler signature, you can bundle them into one struct. Small quality of life improvement that really adds up.
A screenshot of code showcasing FromRequestParts derive macro in use.
110
Cot.rs @cot.rs · 11/09/2025
Session stores are now pluggable, so you can switch between backends without touching your code. Use in-memory for development, Redis for production, or the new database-backed store, which is now the default since it's good enough until you need Redis performance.
A screenshot of TOML configuration showing usage of redis as a backend for cache for session store.
100
Cot.rs @cot.rs · 11/09/2025
Forms are much more capable now. File uploads work out of the box just by using a pre-defined special type! Full chrono support means date and time pickers actually work properly, and you can configure HTML attributes programmatically with restrictions like "images only".
An HTML form showing Cot support for chrono types in forms.
100
Cot.rs @cot.rs · 11/09/2025
Error handling got a complete redesign. Before, you mostly got 404s and 500s; now you get proper HTTP status codes for different error types. The new system uses a single error handler instead of separate ones, and we managed to shrink error structs from 110+ bytes down to just 8 bytes.
Nicely-looking error page on the Cot site.
100