sqlx_scylladb_core/
value.rs1use std::{borrow::Cow, sync::LazyLock};
2
3use bytes::Bytes;
4use scylla::{
5 cluster::metadata::ColumnType,
6 deserialize::{FrameSlice, value::DeserializeValue},
7};
8use sqlx::{Value, ValueRef};
9use sqlx_core::ext::ustr::UStr;
10
11use crate::{ScyllaDB, ScyllaDBError, ScyllaDBTypeInfo};
12
13#[derive(Debug, Clone)]
15pub struct ScyllaDBValue {
16 column_name: UStr,
17 raw_value: Bytes,
18 column_type: ColumnType<'static>,
19 type_info: ScyllaDBTypeInfo,
20}
21
22impl Value for ScyllaDBValue {
23 type Database = ScyllaDB;
24
25 fn as_ref(&self) -> ScyllaDBValueRef<'_> {
26 ScyllaDBValueRef {
27 column_name: self.column_name.clone(),
28 raw_value: &self.raw_value,
29 column_type: &self.column_type,
30 type_info: self.type_info.clone(),
31 }
32 }
33
34 fn type_info(&self) -> Cow<'_, ScyllaDBTypeInfo> {
35 Cow::Borrowed(&self.type_info)
36 }
37
38 fn is_null(&self) -> bool {
39 self.type_info == ScyllaDBTypeInfo::Null
40 }
41}
42
43#[derive(Debug, Clone)]
45pub struct ScyllaDBValueRef<'r> {
46 column_name: UStr,
47 raw_value: &'r Bytes,
48 column_type: &'r ColumnType<'r>,
49 type_info: ScyllaDBTypeInfo,
50}
51
52impl<'r> ScyllaDBValueRef<'r> {
53 #[inline(always)]
54 pub(crate) fn new(
55 column_name: UStr,
56 type_info: ScyllaDBTypeInfo,
57 raw_value: &'r Bytes,
58 column_type: &'r ColumnType<'r>,
59 ) -> ScyllaDBValueRef<'r> {
60 Self {
61 column_name,
62 raw_value,
63 column_type,
64 type_info,
65 }
66 }
67
68 #[inline(always)]
69 pub(crate) fn null(column_name: UStr, column_type: &'r ColumnType<'r>) -> Self {
70 static EMPTY: LazyLock<Bytes> = LazyLock::new(|| Bytes::new());
71 Self {
72 column_name,
73 raw_value: &EMPTY,
74 column_type,
75 type_info: ScyllaDBTypeInfo::Null,
76 }
77 }
78
79 pub(crate) fn is_null(&self) -> bool {
80 self.type_info == ScyllaDBTypeInfo::Null
81 }
82
83 #[inline(always)]
85 pub fn column_name(&self) -> UStr {
86 self.column_name.clone()
87 }
88
89 #[inline(always)]
91 pub fn column_type(&self) -> ColumnType<'static> {
92 self.column_type.clone().into_owned()
93 }
94
95 #[inline(always)]
97 pub fn deserialize<T>(&self) -> Result<T, ScyllaDBError>
98 where
99 T: DeserializeValue<'r, 'r>,
100 {
101 let val = if !self.is_null() {
102 let frame_slice = FrameSlice::new(self.raw_value);
103 <_ as DeserializeValue>::deserialize(self.column_type, Some(frame_slice))?
104 } else {
105 <_ as DeserializeValue>::deserialize(self.column_type, None)?
106 };
107
108 Ok(val)
109 }
110}
111
112impl<'r> ValueRef<'r> for ScyllaDBValueRef<'r> {
113 type Database = ScyllaDB;
114
115 fn to_owned(&self) -> ScyllaDBValue {
116 ScyllaDBValue {
117 column_name: self.column_name.clone(),
118 column_type: self.column_type.clone().into_owned(),
119 raw_value: self.raw_value.clone(),
120 type_info: self.type_info.clone(),
121 }
122 }
123
124 fn type_info(&self) -> Cow<'_, ScyllaDBTypeInfo> {
125 Cow::Borrowed(&self.type_info)
126 }
127
128 fn is_null(&self) -> bool {
129 self.type_info == ScyllaDBTypeInfo::Null
130 }
131}