postgres-derive-codegen

Crates.iopostgres-derive-codegen
lib.rspostgres-derive-codegen
version0.2.2
sourcesrc
created_at2016-02-20 22:06:38.983983
updated_at2016-11-19 21:05:30.307427
descriptionDeriving codegen support for Postgres enum, domain, and composite types
homepage
repositoryhttps://github.com/sfackler/rust-postgres-derive
max_upload_size
id4229
size3,919
cargo publish (github:servo:cargo-publish)

documentation

README

postgres-derive

Build Status

Syntax extensions to automatically derive FromSql and ToSql implementations for Postgres enum, domain, and composite types.

The generated code requires rust-postgres 0.12.0 or higher and Rust 1.10.0 or higher.

Usage

postgres-derive can be used both as a syntax extension with a nightly build of the compiler, or as a code generator with stable builds.

Nightlies

Simply depend on the postgres-derive-macros crate and register it as a plugin:

Cargo.toml

# ...

[dependencies]
postgres-derive-macros = "0.2"
postgres = "0.12"

lib.rs

#![feature(proc_macro)]

#[macro_use]
extern crate postgres;
#[macro_use]
extern crate postgres_derive;

#[derive(Debug, ToSql, FromSql)]
pub enum Mood {
    Sad,
    Ok,
    Happy,
}

// ...

Stable

Use postgres-derive-codegen in a build script:

Cargo.toml

[package]
# ...
build = "build.rs"

[build-dependencies]
postgres-derive-codegen = "0.2"

[dependencies]
postgres = "0.12"

build.rs

extern crate postgres_derive_codegen;

use std::env;
use std::path::Path;

pub fn main() {
    let out_dir = env::var_os("OUT_DIR").unwrap();
    let src = Path::new("src/types.rs.in");
    let dst = Path::new(&out_dir).join("types.rs");

    postgres_derive_codegen::expand(src, dst).unwrap();
}

types.rs.in

#[derive(Debug, ToSql, FromSql)]
pub enum Mood {
    Sad,
    Ok,
    Happy,
}

lib.rs

#[macro_use]
extern crate postgres;

include!(concat!(env!("OUT_DIR"), "/types.rs"));

// ...

Types

Enums

Postgres enums correspond to C-like enums in Rust:

CREATE TYPE "Mood" AS ENUM (
    'Sad',
    'Ok',
    'Happy'
);
#[derive(Debug, ToSql, FromSql)]
enum Mood {
    Sad,
    Ok,
    Happy,
}

The implementations will expect exact matches between the type names and variants. The #[postgres(...)] attribute can be used to adjust the names used on the Postgres side:

CREATE TYPE mood AS ENUM (
    'sad',
    'ok',
    'happy'
);
#[derive(Debug, ToSql, FromSql)]
#[postgres(name = "mood")]
enum Mood {
    #[postgres(name = "sad")]
    Sad,
    #[postgres(name = "ok")]
    Ok,
    #[postgres(name = "happy")]
    Happy,
}

Domains

Postgres domains correspond to tuple structs with one member in Rust:

CREATE DOMAIN "SessionId" AS BYTEA CHECK(octet_length(VALUE) = 16);
#[derive(Debug, FromSql, ToSql)]
struct SessionId(Vec<u8>);

As above, the implementations will expect an exact match between the Rust and Postgres type names, and the #[postgres(...)] attribute can be used to adjust that behavior:

CREATE DOMAIN session_id AS BYTEA CHECK(octet_length(VALUE) = 16);
#[derive(Debug, FromSql, ToSql)]
#[postgres(name = "session_id")]
struct SessionId(Vec<u8>);

Composites

Postgres composite types correspond to structs in Rust:

CREATE TYPE "InventoryItem" AS (
    name TEXT,
    supplier_id INT,
    price DOUBLE PRECISION
);
#[derive(Debug, FromSql, ToSql)]
struct InventoryItem {
    name: String,
    supplier_id: i32,
    price: Option<f64>,
}

Again, the implementations will expect an exact match between the names of the Rust and Postgres types and fields, which can be adjusted via the #[postgres(...)] attribute:

CREATE TYPE inventory_item AS (
    name TEXT,
    supplier_id INT,
    the_price DOUBLE PRECISION
);
#[derive(Debug, FromSql, ToSql)]
#[postgres(name = "inventory_item")]
struct InventoryItem {
    name: String,
    supplier_id: i32,
    #[postgres(name = "the_price")]
    price: Option<f64>,
}

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Commit count: 131

cargo fmt