Skip to content

Commit 418185f

Browse files
committed
add a macro to generate enums from pg integers
1 parent 1bec6a9 commit 418185f

File tree

4 files changed

+49
-56
lines changed

4 files changed

+49
-56
lines changed

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ pub mod schema;
5050
pub mod tasks;
5151
mod test_util;
5252
pub mod uploaders;
53+
#[macro_use]
5354
pub mod util;
5455

5556
pub mod controllers;

src/models/action.rs

Lines changed: 8 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,14 @@
1-
use chrono::NaiveDateTime;
2-
use diesel::prelude::*;
3-
use diesel::{
4-
deserialize::{self, FromSql},
5-
pg::Pg,
6-
serialize::{self, Output, ToSql},
7-
sql_types::Integer,
8-
};
9-
use std::io::Write;
10-
111
use crate::models::{ApiToken, User, Version};
122
use crate::schema::*;
3+
use chrono::NaiveDateTime;
4+
use diesel::prelude::*;
135

14-
#[derive(Debug, Clone, Copy, PartialEq, FromSqlRow, AsExpression)]
15-
#[repr(i32)]
16-
#[sql_type = "Integer"]
17-
pub enum VersionAction {
18-
Publish = 0,
19-
Yank = 1,
20-
Unyank = 2,
6+
pg_enum! {
7+
pub enum VersionAction {
8+
Publish = 0,
9+
Yank = 1,
10+
Unyank = 2,
11+
}
2112
}
2213

2314
impl From<VersionAction> for &'static str {
@@ -38,23 +29,6 @@ impl From<VersionAction> for String {
3829
}
3930
}
4031

41-
impl FromSql<Integer, Pg> for VersionAction {
42-
fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result<Self> {
43-
match <i32 as FromSql<Integer, Pg>>::from_sql(bytes)? {
44-
0 => Ok(VersionAction::Publish),
45-
1 => Ok(VersionAction::Yank),
46-
2 => Ok(VersionAction::Unyank),
47-
n => Err(format!("unknown version action: {}", n).into()),
48-
}
49-
}
50-
}
51-
52-
impl ToSql<Integer, Pg> for VersionAction {
53-
fn to_sql<W: Write>(&self, out: &mut Output<'_, W, Pg>) -> serialize::Result {
54-
ToSql::<Integer, Pg>::to_sql(&(*self as i32), out)
55-
}
56-
}
57-
5832
#[derive(Debug, Clone, Copy, Queryable, Identifiable, Associations)]
5933
#[belongs_to(Version)]
6034
#[belongs_to(User, foreign_key = "user_id")]

src/models/dependency.rs

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
use diesel::deserialize::{self, FromSql};
2-
use diesel::pg::Pg;
3-
use diesel::sql_types::Integer;
4-
51
use crate::models::{Crate, Version};
62
use crate::schema::*;
73

@@ -32,23 +28,10 @@ pub struct ReverseDependency {
3228
pub name: String,
3329
}
3430

35-
#[derive(Copy, Clone, Serialize, Deserialize, Debug, FromSqlRow)]
36-
#[serde(rename_all = "lowercase")]
37-
#[repr(u32)]
38-
pub enum DependencyKind {
39-
Normal = 0,
40-
Build = 1,
41-
Dev = 2,
42-
// if you add a kind here, be sure to update `from_row` below.
43-
}
44-
45-
impl FromSql<Integer, Pg> for DependencyKind {
46-
fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result<Self> {
47-
match <i32 as FromSql<Integer, Pg>>::from_sql(bytes)? {
48-
0 => Ok(DependencyKind::Normal),
49-
1 => Ok(DependencyKind::Build),
50-
2 => Ok(DependencyKind::Dev),
51-
n => Err(format!("unknown kind: {}", n).into()),
52-
}
31+
pg_enum! {
32+
pub enum DependencyKind {
33+
Normal = 0,
34+
Build = 1,
35+
Dev = 2,
5336
}
5437
}

src/util.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,38 @@ impl Maximums {
5353
}
5454
}
5555
}
56+
57+
#[macro_export]
58+
macro_rules! pg_enum {
59+
(
60+
$vis:vis enum $name:ident {
61+
$($item:ident = $int:expr,)*
62+
}
63+
) => {
64+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize, FromSqlRow, AsExpression)]
65+
#[sql_type = "diesel::sql_types::Integer"]
66+
#[serde(rename_all = "snake_case")]
67+
#[repr(i32)]
68+
$vis enum $name {
69+
$($item = $int,)*
70+
}
71+
72+
impl diesel::deserialize::FromSql<diesel::sql_types::Integer, diesel::pg::Pg> for $name {
73+
fn from_sql(bytes: Option<&[u8]>) -> diesel::deserialize::Result<Self> {
74+
match <i32 as diesel::deserialize::FromSql<diesel::sql_types::Integer, diesel::pg::Pg>>::from_sql(bytes)? {
75+
$($int => Ok(Self::$item),)*
76+
n => Err(format!("unknown value: {}", n).into()),
77+
}
78+
}
79+
}
80+
81+
impl diesel::serialize::ToSql<diesel::sql_types::Integer, diesel::pg::Pg> for $name {
82+
fn to_sql<W: std::io::Write>(
83+
&self,
84+
out: &mut diesel::serialize::Output<'_, W, diesel::pg::Pg>,
85+
) -> diesel::serialize::Result {
86+
diesel::serialize::ToSql::<diesel::sql_types::Integer, diesel::pg::Pg>::to_sql(&(*self as i32), out)
87+
}
88+
}
89+
}
90+
}

0 commit comments

Comments
 (0)