1use {
2 crate::{data::Value, executor::RowContext, result::Result},
3 serde::Serialize,
4 std::{collections::BTreeMap, fmt::Debug, sync::Arc},
5 thiserror::Error,
6};
7
8#[derive(Error, Serialize, Debug, PartialEq, Eq)]
9pub enum RowError {
10 #[error("conflict - vec expected but map row found")]
11 ConflictOnUnexpectedMapRowFound,
12
13 #[error("conflict - map expected but vec row found")]
14 ConflictOnUnexpectedVecRowFound,
15}
16
17#[derive(Clone, Debug, PartialEq)]
18pub enum Row {
19 Vec {
20 columns: Arc<[String]>,
21 values: Vec<Value>,
22 },
23 Map(BTreeMap<String, Value>),
24}
25
26impl Row {
27 pub fn get_value(&self, ident: &str) -> Option<&Value> {
28 match self {
29 Self::Vec { columns, values } => columns
30 .iter()
31 .position(|column| column == ident)
32 .and_then(|index| values.get(index)),
33 Self::Map(values) => Some(values.get(ident).unwrap_or(&Value::Null)),
34 }
35 }
36
37 pub fn iter(&self) -> impl Iterator<Item = (&String, &Value)> {
38 #[derive(iter_enum::Iterator)]
39 enum Entries<I1, I2> {
40 Vec(I1),
41 Map(I2),
42 }
43
44 match self {
45 Self::Vec { columns, values } => Entries::Vec(columns.iter().zip(values.iter())),
46 Self::Map(values) => Entries::Map(values.iter()),
47 }
48 }
49
50 pub fn try_into_vec(self) -> Result<Vec<Value>> {
51 match self {
52 Self::Vec { values, .. } => Ok(values),
53 Self::Map(_) => Err(RowError::ConflictOnUnexpectedMapRowFound.into()),
54 }
55 }
56
57 pub fn try_into_map(self) -> Result<BTreeMap<String, Value>> {
58 match self {
59 Self::Vec { .. } => Err(RowError::ConflictOnUnexpectedVecRowFound.into()),
60 Self::Map(values) => Ok(values),
61 }
62 }
63
64 pub fn as_context(&self) -> RowContext<'_> {
65 match self {
66 Self::Vec { columns, values } => RowContext::RefVecData { columns, values },
67 Self::Map(values) => RowContext::RefMapData(values),
68 }
69 }
70}