vantage_redb/
condition.rs1use vantage_expressions::{DeferredFn, ExpressiveEnum};
13
14use crate::types::AnyRedbType;
15
16#[derive(Clone)]
18pub enum RedbCondition {
19 Eq { column: String, value: AnyRedbType },
21 In {
23 column: String,
24 values: Vec<AnyRedbType>,
25 },
26 Deferred(DeferredFn<AnyRedbType>),
29}
30
31impl RedbCondition {
32 pub fn eq(column: impl Into<String>, value: impl Into<AnyRedbType>) -> Self {
33 Self::Eq {
34 column: column.into(),
35 value: value.into(),
36 }
37 }
38
39 pub fn in_<I, V>(column: impl Into<String>, values: I) -> Self
40 where
41 I: IntoIterator<Item = V>,
42 V: Into<AnyRedbType>,
43 {
44 Self::In {
45 column: column.into(),
46 values: values.into_iter().map(Into::into).collect(),
47 }
48 }
49
50 pub async fn resolve(self) -> vantage_core::Result<Self> {
53 match self {
54 Self::Deferred(d) => {
55 let resolved = d.call().await?;
56 let any = match resolved {
57 ExpressiveEnum::Scalar(v) => v,
58 other => {
59 return Err(vantage_core::error!(
60 "Deferred RedbCondition produced non-scalar",
61 kind = format!("{:?}", std::mem::discriminant(&other))
62 ));
63 }
64 };
65 match any.into_value() {
68 ciborium::Value::Array(parts) if parts.len() == 2 => {
69 let mut iter = parts.into_iter();
70 let col = match iter.next() {
71 Some(ciborium::Value::Text(s)) => s,
72 _ => {
73 return Err(vantage_core::error!(
74 "Deferred condition: expected column name as text"
75 ));
76 }
77 };
78 let values = match iter.next() {
79 Some(ciborium::Value::Array(items)) => items,
80 _ => {
81 return Err(vantage_core::error!(
82 "Deferred condition: expected values as array"
83 ));
84 }
85 };
86 Ok(Self::In {
87 column: col,
88 values: values.into_iter().map(AnyRedbType::untyped).collect(),
89 })
90 }
91 _ => Err(vantage_core::error!(
92 "Deferred condition: expected [column, values] tuple"
93 )),
94 }
95 }
96 other => Ok(other),
97 }
98 }
99
100 pub fn column(&self) -> Option<&str> {
102 match self {
103 Self::Eq { column, .. } | Self::In { column, .. } => Some(column.as_str()),
104 Self::Deferred(_) => None,
105 }
106 }
107}
108
109impl std::fmt::Debug for RedbCondition {
110 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
111 match self {
112 Self::Eq { column, value } => write!(f, "Eq({} = {})", column, value),
113 Self::In { column, values } => write!(f, "In({} ∈ {} values)", column, values.len()),
114 Self::Deferred(_) => write!(f, "Deferred(...)"),
115 }
116 }
117}