diesel-derive-enum 0.2.1

Derive diesel boilerplate for using enums in Postgres
Documentation

diesel-derive-enum

crates.io Build Status

This crate allows one to automatically derive the Diesel boilerplate necessary to use Rust enums directly with Postgres databases.

It is a fairly literal translation of this code from the Diesel test suite.

Example usage:

// define your enum
#[derive(PgEnum)]
pub enum MyEnum {      // All enum variants must be fieldless
    Foo,
    Bar,
    BazQuxx,
}

// define your table
table! {
    use diesel::types::Integer;
    use super::MyEnumMapping;
    my_table {
        id -> Integer,
        some_enum -> MyEnumMapping, // Generated Diesel type - see below for explanation
    }
}

// define a struct with which to populate/query the table
#[derive(Insertable, Queryable, Identifiable, Debug, PartialEq)]
#[table_name = "my_table"]
struct  MyRow {
    id: i32,
    some_enum: MyEnum,
}

SQL to create corresponding table:

-- by default the postgres ENUM values correspond to snake_cased Rust enum variant names
CREATE TYPE my_enum AS ENUM ('foo', 'bar', 'baz_quxx');

CREATE TABLE my_table (
  id SERIAL PRIMARY KEY,
  some_enum my_enum NOT NULL
);

Now we can insert and retrieve MyEnum directly:

let data = vec![
    MyRow {
        id: 1,
        some_enum: MyEnum::Foo,
    },
    MyRow {
        id: 2,
        some_enum: MyEnum::BazQuxx,
    },
];
let connection = PgConnection::establish(/*...*/).unwrap();
let inserted = insert_into(my_table::table)
    .values(&data)
    .get_results(&connection)
    .unwrap();
assert_eq!(data, inserted);

See this test for a full working example.

What's up with the naming?

Diesel maintains a set of internal types which correspond one-to-one to the types available in Postgres (and other databases). Each internal type then maps to some kind of Rust native type. e.g. diesel::types::Integer maps to i32. So, when we create a new type in Postgres with CREATE TYPE ..., we must also create a corresponding type in Diesel, and then create a mapping to some native Rust type (our enum). Hence there are three types we need to be aware of.

By default, the Postgres and Diesel internal types are inferred from the name of the Rust enum. Specifically, we assume MyEnum corresponds to my_enum in Postgres and MyEnumMapping in Diesel. (The Diesel type is created by the plugin, the Postgres type must be created in SQL).

These defaults can be overridden with the attributes #[PgType = "..."] and #[DieselType = "..."].

Similarly, we assume that the Postgres ENUM variants are simply the Rust enum variants translated to snake_case. These can be renamed with the inline annotation #[pg_rename = "..."].

See this test for an example of renaming.

License

Licensed under either of these: