Skip to content

Commit

Permalink
Allow deriving PrimaryKeyType (#245)
Browse files Browse the repository at this point in the history
  • Loading branch information
jayvdb authored Apr 18, 2024
1 parent b8d9df4 commit 58e7fdc
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 11 deletions.
2 changes: 1 addition & 1 deletion butane/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#![deny(missing_docs)]

pub use butane_codegen::{butane_type, dataresult, model, FieldType};
pub use butane_codegen::{butane_type, dataresult, model, FieldType, PrimaryKeyType};
pub use butane_core::custom;
pub use butane_core::fkey::ForeignKey;
pub use butane_core::internal;
Expand Down
16 changes: 16 additions & 0 deletions butane_codegen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -433,3 +433,19 @@ fn derive_field_type_with_json(struct_name: &Ident) -> TokenStream {
fn derive_field_type_with_json(_struct_name: &Ident) -> TokenStream {
panic!("Feature 'json' is required to derive FieldType")
}

/// Derive macro for marker trait `PrimaryKeyType`.
/// E.g.
/// ```ignore
/// #[derive(FieldType, PrimaryKeyType)]
/// pub struct PostId(pub uuid::Uuid);
/// ```
#[proc_macro_derive(PrimaryKeyType)]
pub fn derive_primary_key_type(input: TokenStream) -> TokenStream {
let derive_input = syn::parse_macro_input!(input as syn::DeriveInput);
let ident = &derive_input.ident;
quote!(
impl butane::PrimaryKeyType for #ident {}
)
.into()
}
10 changes: 4 additions & 6 deletions docs/newtype.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,15 @@ Create `src/models.rs` with a `BlogId` and `PostId` struct wrapping a `uuid`.
use butane::{FieldType, PrimaryKeyType};
use serde::{Deserialize, Serialize};

#[derive(Clone, Debug, Default, Deserialize, Serialize, FieldType, PartialEq, Eq)]
#[derive(Clone, Debug, Default, Deserialize, Eq, FieldType, PartialEq, PrimaryKeyType, Serialize)]
pub struct BlogId(pub uuid::Uuid);
impl PrimaryKeyType for BlogId {}

#[derive(Clone, Debug, Default, Deserialize, Serialize, FieldType, PartialEq, Eq)]
#[derive(Clone, Debug, Default, Deserialize, Eq, FieldType, PartialEq, PrimaryKeyType, Serialize)]
pub struct PostId(pub uuid::Uuid);
impl PrimaryKeyType for PostId {}
```

For each, `FieldType` is derived, and they implement the marker trait `PrimaryKeyType`
to allow their use as a primary key.
For each, `FieldType` is derived to generate code to describe how the field will be stored, and
the marker trait `PrimaryKeyType` is derived to allow their use as a primary key.

As Butane natively supports `uuid`, these newtypes will be stored in the butane metadata as
"Blob" type, which is stored in the database using an appropriate column type based on the
Expand Down
10 changes: 6 additions & 4 deletions examples/newtype/src/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@ use garde::Validate;
use serde::{Deserialize, Serialize};

/// Blog identifier.
#[derive(Clone, Debug, Default, Deserialize, Eq, FieldType, PartialEq, Serialize)]
#[derive(
Clone, Debug, Default, Deserialize, Eq, FieldType, PartialEq, PrimaryKeyType, Serialize,
)]
pub struct BlogId(pub uuid::Uuid);
impl PrimaryKeyType for BlogId {}

/// Post identifier.
#[derive(Clone, Debug, Default, Deserialize, Eq, FieldType, PartialEq, Serialize)]
#[derive(
Clone, Debug, Default, Deserialize, Eq, FieldType, PartialEq, PrimaryKeyType, Serialize,
)]
pub struct PostId(pub uuid::Uuid);
impl PrimaryKeyType for PostId {}

/// Blog name.
#[derive(Clone, Debug, Default, Deserialize, Eq, FieldType, PartialEq, Serialize, Validate)]
Expand Down

0 comments on commit 58e7fdc

Please sign in to comment.