-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
custom_types.rs
86 lines (78 loc) · 1.95 KB
/
custom_types.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
use diesel::connection::SimpleConnection;
use diesel::deserialize::{self, FromSql};
use diesel::pg::Pg;
use diesel::serialize::{self, IsNull, Output, ToSql};
use diesel::*;
use schema::*;
use std::io::Write;
table! {
use diesel::sql_types::*;
use super::MyType;
custom_types {
id -> Integer,
custom_enum -> MyType,
}
}
#[derive(SqlType)]
#[postgres(type_name = "my_type")]
pub struct MyType;
#[derive(Debug, PartialEq, FromSqlRow, AsExpression)]
#[sql_type = "MyType"]
pub enum MyEnum {
Foo,
Bar,
}
impl ToSql<MyType, Pg> for MyEnum {
fn to_sql<W: Write>(&self, out: &mut Output<W, Pg>) -> serialize::Result {
match *self {
MyEnum::Foo => out.write_all(b"foo")?,
MyEnum::Bar => out.write_all(b"bar")?,
}
Ok(IsNull::No)
}
}
impl FromSql<MyType, Pg> for MyEnum {
fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result<Self> {
match not_none!(bytes) {
b"foo" => Ok(MyEnum::Foo),
b"bar" => Ok(MyEnum::Bar),
_ => Err("Unrecognized enum variant".into()),
}
}
}
#[derive(Insertable, Queryable, Identifiable, Debug, PartialEq)]
#[table_name = "custom_types"]
struct HasCustomTypes {
id: i32,
custom_enum: MyEnum,
}
#[test]
fn custom_types_round_trip() {
let data = vec![
HasCustomTypes {
id: 1,
custom_enum: MyEnum::Foo,
},
HasCustomTypes {
id: 2,
custom_enum: MyEnum::Bar,
},
];
let connection = connection();
connection
.batch_execute(
r#"
CREATE TYPE my_type AS ENUM ('foo', 'bar');
CREATE TABLE custom_types (
id SERIAL PRIMARY KEY,
custom_enum my_type NOT NULL
);
"#,
)
.unwrap();
let inserted = insert_into(custom_types::table)
.values(&data)
.get_results(&connection)
.unwrap();
assert_eq!(data, inserted);
}