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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
use std::io::prelude::*;

use crate::deserialize::{self, FromSql, Queryable};
use crate::pg::{Pg, PgValue};
use crate::serialize::{self, IsNull, Output, ToSql};
use crate::sql_types;

#[cfg(feature = "postgres_backend")]
impl FromSql<sql_types::Bool, Pg> for bool {
    fn from_sql(bytes: PgValue<'_>) -> deserialize::Result<Self> {
        Ok(bytes.as_bytes()[0] != 0)
    }
}

#[cfg(feature = "postgres_backend")]
impl ToSql<sql_types::Bool, Pg> for bool {
    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Pg>) -> serialize::Result {
        out.write_all(&[*self as u8])
            .map(|_| IsNull::No)
            .map_err(Into::into)
    }
}

#[cfg(feature = "postgres_backend")]
impl FromSql<sql_types::CChar, Pg> for u8 {
    fn from_sql(bytes: PgValue<'_>) -> deserialize::Result<Self> {
        Ok(bytes.as_bytes()[0])
    }
}

#[cfg(feature = "postgres_backend")]
impl ToSql<sql_types::CChar, Pg> for u8 {
    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Pg>) -> serialize::Result {
        out.write_all(&[*self])
            .map(|_| IsNull::No)
            .map_err(Into::into)
    }
}

#[test]
fn cchar_to_sql() {
    use crate::query_builder::bind_collector::ByteWrapper;

    let mut buffer = Vec::new();
    let mut bytes = Output::test(ByteWrapper(&mut buffer));
    ToSql::<sql_types::CChar, Pg>::to_sql(&b'A', &mut bytes).unwrap();
    ToSql::<sql_types::CChar, Pg>::to_sql(&b'\xc4', &mut bytes).unwrap();
    assert_eq!(buffer, vec![65u8, 196u8]);
}

#[test]
fn cchar_from_sql() {
    let result = <u8 as FromSql<sql_types::CChar, Pg>>::from_nullable_sql(None);
    assert_eq!(
        result.unwrap_err().to_string(),
        "Unexpected null for non-null column"
    );
}

/// The returned pointer is *only* valid for the lifetime to the argument of
/// `from_sql`. This impl is intended for uses where you want to write a new
/// impl in terms of `String`, but don't want to allocate. We have to return a
/// raw pointer instead of a reference with a lifetime due to the structure of
/// `FromSql`
#[cfg(feature = "postgres_backend")]
impl FromSql<sql_types::Text, Pg> for *const str {
    fn from_sql(value: PgValue<'_>) -> deserialize::Result<Self> {
        use std::str;
        let string = str::from_utf8(value.as_bytes())?;
        Ok(string as *const _)
    }
}

#[cfg(feature = "postgres_backend")]
impl Queryable<sql_types::VarChar, Pg> for *const str {
    type Row = Self;

    fn build(row: Self::Row) -> deserialize::Result<Self> {
        Ok(row)
    }
}

#[cfg(feature = "postgres_backend")]
impl ToSql<sql_types::Citext, Pg> for String {
    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Pg>) -> serialize::Result {
        out.write_all(self.as_bytes())?;
        Ok(IsNull::No)
    }
}

#[cfg(feature = "postgres_backend")]
impl ToSql<sql_types::Citext, Pg> for str {
    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Pg>) -> serialize::Result {
        out.write_all(self.as_bytes())?;
        Ok(IsNull::No)
    }
}

#[cfg(feature = "postgres_backend")]
impl FromSql<sql_types::Citext, Pg> for String {
    fn from_sql(value: PgValue<'_>) -> deserialize::Result<Self> {
        let string = String::from_utf8(value.as_bytes().to_vec())?;
        Ok(string)
    }
}

/// The returned pointer is *only* valid for the lifetime to the argument of
/// `from_sql`. This impl is intended for uses where you want to write a new
/// impl in terms of `Vec<u8>`, but don't want to allocate. We have to return a
/// raw pointer instead of a reference with a lifetime due to the structure of
/// `FromSql`
#[cfg(feature = "postgres_backend")]
impl FromSql<sql_types::Binary, Pg> for *const [u8] {
    fn from_sql(value: PgValue<'_>) -> deserialize::Result<Self> {
        Ok(value.as_bytes() as *const _)
    }
}

#[cfg(feature = "postgres_backend")]
impl Queryable<sql_types::Binary, Pg> for *const [u8] {
    type Row = Self;

    fn build(row: Self::Row) -> deserialize::Result<Self> {
        Ok(row)
    }
}

#[test]
fn bool_to_sql() {
    use crate::query_builder::bind_collector::ByteWrapper;

    let mut buffer = Vec::new();
    let mut bytes = Output::test(ByteWrapper(&mut buffer));
    ToSql::<sql_types::Bool, Pg>::to_sql(&true, &mut bytes).unwrap();
    ToSql::<sql_types::Bool, Pg>::to_sql(&false, &mut bytes).unwrap();
    assert_eq!(buffer, vec![1u8, 0u8]);
}

#[test]
fn no_bool_from_sql() {
    let result = <bool as FromSql<sql_types::Bool, Pg>>::from_nullable_sql(None);
    assert_eq!(
        result.unwrap_err().to_string(),
        "Unexpected null for non-null column"
    );
}