Derive Macro exemplar::Model

source ·
#[derive(Model)]
{
    // Attributes available to this derive:
    #[table]
    #[check]
    #[bind]
    #[extr]
    #[column]
}
Expand description

Derive macro for the Model trait.

Requirements

Model can only be derived for structs with suitable named fields.

TypeExampleSupported?
Standard structstruct Person { name: String }
Tuple structstruct Point(i64, i64)
Unit/ZST structstruct Unit; or struct Unit {}
enumsenum Direction { Up, Down }
unionsunion Number { i: i32, f: f32 }

(Note, however, that any non-supported type can be used in a Model assuming it meets the below requirements.)

All fields in a Model derivee must either:

  • Implement ToSql and FromSql. Most common types will meet this requirement.
  • Have #[bind] and #[extr] attributes on fields that do not meet the first requirement.
    • This escape hatch is designed to enable compatibility with certain std types like PathBuf and third-party crate types.

Usage

Most of the time, deriving Model is easy. The only thing you need to specify is the table name:

#[derive(Model)]
#[table("people")] // <-- Required
pub struct Person {
    pub name: String,
    pub age: u16,
}

For more complicated types and schemas, you may need to make use of some of the attributes recognized by the macro:

#[derive(Model)]
#[table("users")]
#[check("schema.sql")]
struct User {
   username: String,
   #[bind(bind_path)]
   #[extr(extr_path)]
   home_dir: PathBuf,
   #[column("pwd")]
   password: Vec<u8>,
}

Attributes

The Model derive macro recognizes several attributes.

#[check]

Usage:

#[check("path_to_schema")]
pub struct T { ... }

The check attribute automatically generates a test that checks the derived Model implementation against a provided schema.

More specifically, the generated test verifies that:

  • The specified table exists.
  • All specified columns/fields exist.

It does not verify the validity of column types, nor does it test actual insertion/retrieval.

#[bind]/#[extr]

Usage:

#[bind(path::to::fn)]
#[extr(path::to::fn)]
field: T,

The bind and extr attributes specify functions used to convert the annotated field to and from an SQL-friendly representation. This is primarily intended as an escape hatch for when you can’t implement ToSql and FromSql yourself.

Both attributes take as their argument a path to a free function used to do the conversion.

In both cases T is the type of the field being annotated. For some types (e.g. PathBuf) you may also be able to use a type it derefs to, like Path.

#[column]

Usage:

#[column("name")]
field: T,

The column attribute overrides the column name Exemplar maps the annotated field to. By default, the field name is assumed to directly map to the underlying schema - #[column] is how you alter this behavior.

Notes

Any type that derives Model also has an implementation of TryFrom<Row> derived, making models usable in some generic contexts.