Skip to content

Commit d0b04c8

Browse files
committed
add a macro to generate enums from pg integers
1 parent c959e6c commit d0b04c8

File tree

4 files changed

+50
-54
lines changed

4 files changed

+50
-54
lines changed

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ pub mod sql;
5252
pub mod ssh;
5353
pub mod swirl;
5454
mod test_util;
55+
#[macro_use]
5556
pub mod util;
5657
pub mod worker;
5758

src/models/action.rs

Lines changed: 8 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +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-
101
use crate::models::{ApiToken, User, Version};
112
use crate::schema::*;
3+
use chrono::NaiveDateTime;
4+
use diesel::prelude::*;
125

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

2214
impl From<VersionAction> for &'static str {
@@ -37,23 +29,6 @@ impl From<VersionAction> for String {
3729
}
3830
}
3931

40-
impl FromSql<Integer, Pg> for VersionAction {
41-
fn from_sql(bytes: diesel::pg::PgValue<'_>) -> deserialize::Result<Self> {
42-
match <i32 as FromSql<Integer, Pg>>::from_sql(bytes)? {
43-
0 => Ok(VersionAction::Publish),
44-
1 => Ok(VersionAction::Yank),
45-
2 => Ok(VersionAction::Unyank),
46-
n => Err(format!("unknown version action: {n}").into()),
47-
}
48-
}
49-
}
50-
51-
impl ToSql<Integer, Pg> for VersionAction {
52-
fn to_sql(&self, out: &mut Output<'_, '_, Pg>) -> serialize::Result {
53-
ToSql::<Integer, Pg>::to_sql(&(*self as i32), &mut out.reborrow())
54-
}
55-
}
56-
5732
#[derive(Debug, Clone, Copy, Queryable, Identifiable, Associations)]
5833
#[diesel(
5934
table_name = version_owner_actions,

src/models/dependency.rs

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use diesel::deserialize::{self, FromSql};
2-
use diesel::pg::Pg;
31
use diesel::sql_types::{Integer, Text};
42

53
use crate::models::{Crate, Version};
@@ -36,14 +34,12 @@ pub struct ReverseDependency {
3634
pub name: String,
3735
}
3836

39-
#[derive(Copy, Clone, Serialize, Deserialize, Debug, FromSqlRow)]
40-
#[serde(rename_all = "lowercase")]
41-
#[repr(u32)]
42-
pub enum DependencyKind {
43-
Normal = 0,
44-
Build = 1,
45-
Dev = 2,
46-
// if you add a kind here, be sure to update `from_row` below.
37+
pg_enum! {
38+
pub enum DependencyKind {
39+
Normal = 0,
40+
Build = 1,
41+
Dev = 2,
42+
}
4743
}
4844

4945
impl From<IndexDependencyKind> for DependencyKind {
@@ -65,14 +61,3 @@ impl From<DependencyKind> for IndexDependencyKind {
6561
}
6662
}
6763
}
68-
69-
impl FromSql<Integer, Pg> for DependencyKind {
70-
fn from_sql(bytes: diesel::pg::PgValue<'_>) -> deserialize::Result<Self> {
71-
match <i32 as FromSql<Integer, Pg>>::from_sql(bytes)? {
72-
0 => Ok(DependencyKind::Normal),
73-
1 => Ok(DependencyKind::Build),
74-
2 => Ok(DependencyKind::Dev),
75-
n => Err(format!("unknown kind: {n}").into()),
76-
}
77-
}
78-
}

src/util.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,38 @@ impl Maximums {
3232
}
3333
}
3434
}
35+
36+
#[macro_export]
37+
macro_rules! pg_enum {
38+
(
39+
$vis:vis enum $name:ident {
40+
$($item:ident = $int:expr,)*
41+
}
42+
) => {
43+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize, FromSqlRow, AsExpression)]
44+
#[diesel(sql_type = diesel::sql_types::Integer)]
45+
#[serde(rename_all = "snake_case")]
46+
#[repr(i32)]
47+
$vis enum $name {
48+
$($item = $int,)*
49+
}
50+
51+
impl diesel::deserialize::FromSql<diesel::sql_types::Integer, diesel::pg::Pg> for $name {
52+
fn from_sql(bytes: diesel::pg::PgValue<'_>) -> diesel::deserialize::Result<Self> {
53+
match <i32 as diesel::deserialize::FromSql<diesel::sql_types::Integer, diesel::pg::Pg>>::from_sql(bytes)? {
54+
$($int => Ok(Self::$item),)*
55+
n => Err(format!("unknown value: {}", n).into()),
56+
}
57+
}
58+
}
59+
60+
impl diesel::serialize::ToSql<diesel::sql_types::Integer, diesel::pg::Pg> for $name {
61+
fn to_sql(
62+
&self,
63+
out: &mut diesel::serialize::Output<'_, '_, diesel::pg::Pg>,
64+
) -> diesel::serialize::Result {
65+
diesel::serialize::ToSql::<diesel::sql_types::Integer, diesel::pg::Pg>::to_sql(&(*self as i32), &mut out.reborrow())
66+
}
67+
}
68+
}
69+
}

0 commit comments

Comments
 (0)