hdbconnect_impl/base/
row.rs1use crate::{
2 HdbResult,
3 base::{OAM, RsCore},
4 conn::AmConnCore,
5 protocol::parts::{HdbValue, ResultSetMetadata},
6 usage_err,
7};
8use serde_db::de::DeserializableRow;
9use std::sync::Arc;
10
11pub struct Row {
19 metadata: Arc<ResultSetMetadata>,
20 value_iter: <Vec<HdbValue<'static>> as IntoIterator>::IntoIter,
21}
22
23impl Row {
24 pub(crate) fn new(metadata: Arc<ResultSetMetadata>, values: Vec<HdbValue<'static>>) -> Self {
26 Self {
27 metadata,
28 value_iter: values.into_iter(),
29 }
30 }
31
32 pub fn try_into<'de, T>(self) -> HdbResult<T>
38 where
39 T: serde::de::Deserialize<'de>,
40 {
41 trace!("Row::into_typed()");
42 Ok(DeserializableRow::try_into(self)?)
43 }
44
45 pub fn next_value(&mut self) -> Option<HdbValue<'static>> {
47 self.value_iter.next()
48 }
49
50 pub fn next_try_into<'de, T>(&mut self) -> HdbResult<T>
58 where
59 T: serde::de::Deserialize<'de>,
60 {
61 self.next_value()
62 .ok_or_else(|| usage_err!("no more value"))?
63 .try_into()
64 }
65
66 #[must_use]
68 pub fn len(&self) -> usize {
69 trace!("Row::len()");
70 self.value_iter.len()
71 }
72
73 #[must_use]
75 pub fn is_empty(&self) -> bool {
76 self.value_iter.as_slice().is_empty()
77 }
78
79 pub fn into_single_value(mut self) -> HdbResult<HdbValue<'static>> {
85 if self.len() > 1 {
86 Err(usage_err!("Row has more than one field"))
87 } else {
88 Ok(self
89 .next_value()
90 .ok_or_else(|| usage_err!("Row is empty"))?)
91 }
92 }
93
94 #[must_use]
96 pub fn metadata(&self) -> &ResultSetMetadata {
97 trace!("Row::metadata()");
98 &(self.metadata)
99 }
100
101 #[allow(clippy::ref_option)]
102 #[cfg(feature = "sync")]
103 pub(crate) fn parse_sync(
104 md: Arc<ResultSetMetadata>,
105 o_am_rscore: &OAM<RsCore>,
106 am_conn_core: &AmConnCore,
107 rdr: &mut std::io::Cursor<Vec<u8>>,
108 ) -> HdbResult<Self> {
109 let mut values = Vec::<HdbValue>::new();
110
111 let md0 = Arc::as_ref(&md);
112
113 for col_md in &**md0 {
115 let value = HdbValue::parse_sync(
116 col_md.type_id(),
117 col_md.is_array_type(),
118 col_md.scale(),
119 col_md.is_nullable(),
120 am_conn_core,
121 o_am_rscore,
122 rdr,
123 )?;
124 values.push(value);
125 }
126 let row = Self::new(md, values);
127 Ok(row)
128 }
129
130 #[allow(clippy::ref_option)]
131 #[cfg(feature = "async")]
132 pub(crate) async fn parse_async(
133 md: Arc<ResultSetMetadata>,
134 o_am_rscore: &OAM<RsCore>,
135 am_conn_core: &AmConnCore,
136 rdr: &mut std::io::Cursor<Vec<u8>>,
137 ) -> HdbResult<Self> {
138 let mut values = Vec::<HdbValue>::new();
139
140 let md0 = Arc::as_ref(&md);
141
142 for col_md in &**md0 {
144 let value = HdbValue::parse_async(
145 col_md.type_id(),
146 col_md.is_array_type(),
147 col_md.scale(),
148 col_md.is_nullable(),
149 am_conn_core,
150 o_am_rscore,
151 rdr,
152 )
153 .await?;
154 values.push(value);
155 }
156 let row = Self::new(md, values);
157 Ok(row)
158 }
159}
160
161impl std::ops::Index<usize> for Row {
163 type Output = HdbValue<'static>;
164 fn index(&self, idx: usize) -> &HdbValue<'static> {
165 &self.value_iter.as_slice()[idx]
166 }
167}
168
169impl std::ops::IndexMut<usize> for Row {
170 fn index_mut(&mut self, idx: usize) -> &mut Self::Output {
171 &mut self.value_iter.as_mut_slice()[idx]
172 }
173}
174
175impl Iterator for Row {
177 type Item = HdbValue<'static>;
178 fn next(&mut self) -> Option<HdbValue<'static>> {
179 self.next_value()
180 }
181}
182
183impl std::fmt::Display for Row {
184 fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
185 for v in self.value_iter.as_slice() {
186 write!(fmt, "{v}, ")?;
187 }
188 Ok(())
189 }
190}
191
192impl std::fmt::Debug for Row {
193 fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
194 for (v, md) in self.value_iter.as_slice().iter().zip(self.metadata.iter()) {
195 write!(fmt, "{v:?}:[{}], ", md.type_id())?;
196 }
197 Ok(())
198 }
199}