1use crate::type_info::PgTypeInfo;
2use bytes::Buf;
3use rbdc::Error;
4use std::borrow::Cow;
5use std::str::from_utf8;
6
7#[derive(Debug, Clone, Copy, Eq, PartialEq)]
8#[repr(u8)]
9pub enum PgValueFormat {
10 Text = 0,
11 Binary = 1,
12}
13
14#[derive(Clone)]
16pub struct PgValueRef<'r> {
17 pub(crate) value: Option<&'r [u8]>,
18 pub(crate) type_info: PgTypeInfo,
19 pub(crate) format: PgValueFormat,
20 pub(crate) timezone_sec: Option<i32>,
22}
23
24#[derive(Clone)]
26pub struct PgValue {
27 pub(crate) value: Option<Vec<u8>>,
28 pub(crate) type_info: PgTypeInfo,
29 pub(crate) format: PgValueFormat,
30 pub(crate) timezone_sec: Option<i32>,
32}
33
34impl<'r> PgValueRef<'r> {
35 pub(crate) fn get(buf: &mut &'r [u8], format: PgValueFormat, ty: PgTypeInfo, timezone_sec: Option<i32>) -> Self {
36 let mut element_len = buf.get_i32();
37
38 let element_val = if element_len == -1 {
39 element_len = 0;
40 None
41 } else {
42 Some(&buf[..(element_len as usize)])
43 };
44
45 buf.advance(element_len as usize);
46
47 PgValueRef {
48 value: element_val,
49 type_info: ty,
50 format,
51 timezone_sec,
52 }
53 }
54
55 pub fn format(&self) -> PgValueFormat {
56 self.format
57 }
58
59 pub fn as_bytes(&self) -> Result<&'r [u8], Error> {
60 match &self.value {
61 Some(v) => Ok(v),
62 None => Err(Error::from("UnexpectedNullError")),
63 }
64 }
65
66 pub fn as_str(&self) -> Result<&'r str, Error> {
67 Ok(from_utf8(self.as_bytes()?)?)
68 }
69}
70
71impl PgValue {
72 pub fn get(buf: &mut &[u8], format: PgValueFormat, ty: PgTypeInfo, timezone_sec: Option<i32>) -> Self {
73 let mut element_len = buf.get_i32();
74
75 let element_val = if element_len == -1 {
76 element_len = 0;
77 None
78 } else {
79 Some(buf[..(element_len as usize)].to_vec())
80 };
81
82 buf.advance(element_len as usize);
83
84 PgValue {
85 value: element_val,
86 type_info: ty,
87 format,
88 timezone_sec,
89 }
90 }
91
92 #[inline]
93 pub fn as_ref(&self) -> PgValueRef<'_> {
94 PgValueRef {
95 value: self.value.as_deref(),
96 type_info: self.type_info.clone(),
97 format: self.format,
98 timezone_sec: self.timezone_sec,
99 }
100 }
101
102 pub fn type_info(&self) -> Cow<'_, PgTypeInfo> {
103 Cow::Borrowed(&self.type_info)
104 }
105
106 pub fn is_null(&self) -> bool {
107 self.value.is_none()
108 }
109
110 pub fn format(&self) -> PgValueFormat {
111 self.format
112 }
113 pub fn as_str(&self) -> Result<&str, Error> {
114 Ok(from_utf8(self.as_bytes()?)?)
115 }
116
117 pub fn as_bytes(&self) -> Result<&[u8], Error> {
118 match &self.value {
119 Some(v) => Ok(v),
120 None => Err(Error::from("UnexpectedNullError")),
121 }
122 }
123
124 pub fn into_bytes(self) -> Result<Vec<u8>, Error> {
125 match self.value {
126 Some(v) => Ok(v),
127 None => Err(Error::from("UnexpectedNullError")),
128 }
129 }
130}
131
132impl<'r> PgValueRef<'r> {
133 pub fn to_owned(&self) -> PgValue {
134 let value = match self.value {
135 Some(value) => Some(value.to_vec()),
136 _ => None,
137 };
138 PgValue {
139 value: value,
140 format: self.format,
141 type_info: self.type_info.clone(),
142 timezone_sec: self.timezone_sec,
143 }
144 }
145
146 pub fn type_info(&self) -> Cow<'_, PgTypeInfo> {
147 Cow::Borrowed(&self.type_info)
148 }
149
150 pub fn is_null(&self) -> bool {
151 self.value.is_none()
152 }
153}