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