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