Why did we make Diesel?

Preventing Runtime Errors

We don't want to waste time tracking down runtime errors. We achieve this by having Diesel eliminate the possibility of incorrect database interactions at compile time.

Built for Performance

Diesel offers a high level query builder and lets you think about your problems in Rust, not SQL. Our focus on zero-cost abstractions allows Diesel to run your query and load your data even faster than C.

Productive and Extensible

Unlike Active Record and other ORMs, Diesel is designed to be abstracted over. Diesel enables you to write reusable code and think in terms of your problem domain and not SQL.

See some examples

Simple queries are a complete breeze. Loading all users from a database:

Rust code
users::table.load(&connection)
Executed SQL
SELECT * FROM users;

Loading all the posts for a user:

Rust code
Post::belonging_to(user).load(&connection)
Executed SQL
SELECT * FROM posts WHERE user_id = 1;

Diesel's powerful query builder helps you construct queries as simple or complex as you need, at 0 cost.

Rust code
let versions = Version::belonging_to(krate)
  .select(id)
  .order(num.desc())
  .limit(5);
let downloads = try!(version_downloads
  .filter(date.gt(now - 90.days()))
  .filter(version_id.eq(any(versions)))
  .order(date)
  .load::<Download>(&conn));
Executed SQL
SELECT version_downloads.*
  WHERE date > (NOW() - '90 days')
    AND version_id = ANY(
      SELECT id FROM versions
        WHERE crate_id = 1
        ORDER BY num DESC
        LIMIT 5
    )
  ORDER BY date

Diesel codegen generates boilerplate for you. It lets you focus on your business logic, not mapping to and from SQL rows.

That means you can write this:

With Diesel
#[derive(Queryable)]
pub struct Download {
    id: i32,
    version_id: i32,
    downloads: i32,
    counted: i32,
    date: SystemTime,
}

Instead of this:

Without Diesel
pub struct Download {
    id: i32,
    version_id: i32,
    downloads: i32,
    counted: i32,
    date: SystemTime,
}

impl Download {
    fn from_row(row: &Row) -> Download {
        Download {
            id: row.get("id"),
            version_id: row.get("version_id"),
            downloads: row.get("downloads"),
            counted: row.get("counted"),
            date: row.get("date"),
        }
    }
}

It's just about reading data. Diesel makes it easy to use structs for new records.

Rust code
#[insertable_into(users)]
struct NewUser<'a> {
    name: &'a str,
    hair_color: Option<&'a str>,
}

let new_users = vec![
    NewUser { name: "Sean", hair_color: Some("Black") },
    NewUser { name: "Gordon", hair_color: None },
];
insert(&new_users).into(users::table)
    .execute(&connection);
Executed SQL
INSERT INTO users (name, hair_color) VALUES
  ('Sean', 'Black'),
  ('Gordon', DEFAULT)

If you need data from the rows you inserted, just change `execute` to `get_result` or `get_results`. Diesel will take care of the rest.

Rust code
let new_users = vec![
    NewUser { name: "Sean", hair_color: Some("Black") },
    NewUser { name: "Gordon", hair_color: None },
];
let inserted_users = insert(&new_users).into(users::table)
    .get_results::<User>(&connection);
Executed SQL
INSERT INTO users (name, hair_color) VALUES
  ('Sean', 'Black'),
  ('Gordon', DEFAULT)
  RETURNING *

Diesel's codegen can generate several ways to update a row, letting you encapsulate your logic in the way that makes sense for your app.

Modifying a struct
post.published = true;
post.save_changes(&connection);
One-off batch changes
update(users.filter(email.like("%@spammer.com")))
    .set(banned.eq(true))
    .execute(&connection)
Using a struct for encapsulation
update(Settings::belonging_to(current_user))
    .set(&settings_form)
    .execute(&connection)