1use crate::arguments::XuguArgumentValue;
2use crate::protocol::text::{ColumnFlags, ColumnType};
3use crate::{Xugu, XuguTypeInfo, XuguValueRef};
4use sqlx_core::decode::Decode;
5use sqlx_core::encode::{Encode, IsNull};
6use sqlx_core::error::BoxDynError;
7use sqlx_core::types::Type;
8use std::borrow::Cow;
9
10impl Type<Xugu> for bool {
11 fn type_info() -> XuguTypeInfo {
12 XuguTypeInfo {
13 r#type: ColumnType::BOOLEAN,
14 flags: ColumnFlags::empty(),
15 }
16 }
17
18 fn compatible(ty: &XuguTypeInfo) -> bool {
19 matches!(
20 ty.r#type,
21 ColumnType::BOOLEAN
22 | ColumnType::TINYINT
23 | ColumnType::SMALLINT
24 | ColumnType::INTEGER
25 | ColumnType::BIGINT
26 | ColumnType::BIT
27 | ColumnType::CHAR
28 | ColumnType::BINARY
29 ) && !ty.flags.contains(ColumnFlags::IS_LOB)
30 }
31}
32
33impl Encode<'_, Xugu> for bool {
34 fn encode_by_ref(&self, args: &mut Vec<XuguArgumentValue<'_>>) -> Result<IsNull, BoxDynError> {
35 let buf = if *self { b"\x01" } else { b"\x00" };
36 args.push(XuguArgumentValue::Bin(Cow::Borrowed(buf)));
37
38 Ok(IsNull::No)
39 }
40}
41
42impl Decode<'_, Xugu> for bool {
43 fn decode(value: XuguValueRef<'_>) -> Result<Self, BoxDynError> {
44 match value.type_info.r#type {
46 ColumnType::TINYINT
47 | ColumnType::SMALLINT
48 | ColumnType::INTEGER
49 | ColumnType::BIGINT => return <i64 as Decode<Xugu>>::decode(value).map(|x| x != 0),
50 _ => {}
51 }
52
53 match value.as_bytes()?[0] {
54 b'T' | b't' => Ok(true),
55 b'1' | 0x01 => Ok(true),
56 b'U' | b'u' => Ok(true),
57
58 b'F' | b'f' => Ok(false),
59 b'0' | 0x00 => Ok(false),
60 s => Err(format!("unexpected value '{}' for boolean", s as char).into()),
61 }
62 }
63}