sift_query_core/cursor/
value.rs1use super::invalid_cursor;
2use crate::{ParamError, RowValue, ScalarValue};
3
4#[derive(Debug, Clone, PartialEq)]
5pub enum CursorValue {
6 Null,
7 Scalar(ScalarValue),
8}
9
10pub trait IntoCursorValue {
11 fn to_cursor_value(&self) -> CursorValue;
12}
13
14macro_rules! impl_cursor_value {
15 ($type:ty, $variant:ident) => {
16 impl IntoCursorValue for $type {
17 fn to_cursor_value(&self) -> CursorValue {
18 CursorValue::Scalar(ScalarValue::$variant(self.clone()))
19 }
20 }
21 };
22}
23
24impl_cursor_value!(bool, Bool);
25impl_cursor_value!(i32, I32);
26impl_cursor_value!(i64, I64);
27impl_cursor_value!(f32, F32);
28impl_cursor_value!(f64, F64);
29impl_cursor_value!(String, Text);
30impl_cursor_value!(Vec<u8>, Bytes);
31#[cfg(feature = "decimal")]
32impl_cursor_value!(rust_decimal::Decimal, Decimal);
33#[cfg(feature = "chrono")]
34impl_cursor_value!(chrono::NaiveDate, Date);
35#[cfg(feature = "chrono")]
36impl_cursor_value!(chrono::NaiveTime, Time);
37#[cfg(feature = "chrono")]
38impl_cursor_value!(chrono::NaiveDateTime, DateTime);
39#[cfg(feature = "chrono")]
40impl_cursor_value!(chrono::DateTime<chrono::Utc>, Timestamp);
41#[cfg(feature = "uuid")]
42impl_cursor_value!(uuid::Uuid, Uuid);
43
44impl<T: IntoCursorValue> IntoCursorValue for Option<T> {
45 fn to_cursor_value(&self) -> CursorValue {
46 self.as_ref()
47 .map_or(CursorValue::Null, IntoCursorValue::to_cursor_value)
48 }
49}
50
51#[derive(Debug, Clone, PartialEq)]
52pub struct Cursor {
53 pub(super) values: Vec<CursorValue>,
54}
55
56impl Cursor {
57 #[must_use]
58 pub fn values(&self) -> &[CursorValue] {
59 &self.values
60 }
61}
62
63impl CursorValue {
64 pub fn from_row_value(value: &RowValue) -> Result<Self, ParamError> {
65 Ok(match value {
66 RowValue::List(_) => return Err(invalid_cursor("lists cannot be cursor keys")),
67 #[cfg(feature = "postgres-types")]
68 RowValue::ArrayI64(_)
69 | RowValue::ArrayText(_)
70 | RowValue::Int8Range(_)
71 | RowValue::Network(_) => {
72 return Err(invalid_cursor("native types cannot be cursor keys"));
73 }
74 RowValue::Null => Self::Null,
75 RowValue::Bool(value) => Self::Scalar(ScalarValue::Bool(*value)),
76 RowValue::I32(value) => Self::Scalar(ScalarValue::I32(*value)),
77 RowValue::I64(value) => Self::Scalar(ScalarValue::I64(*value)),
78 RowValue::F32(value) => Self::Scalar(ScalarValue::F32(*value)),
79 RowValue::F64(value) => Self::Scalar(ScalarValue::F64(*value)),
80 #[cfg(feature = "decimal")]
81 RowValue::Decimal(value) => Self::Scalar(ScalarValue::Decimal(*value)),
82 RowValue::Text(value) => Self::Scalar(ScalarValue::Text(value.clone())),
83 RowValue::Bytes(value) => Self::Scalar(ScalarValue::Bytes(value.clone())),
84 #[cfg(feature = "chrono")]
85 RowValue::Date(value) => Self::Scalar(ScalarValue::Date(*value)),
86 #[cfg(feature = "chrono")]
87 RowValue::Time(value) => Self::Scalar(ScalarValue::Time(*value)),
88 #[cfg(feature = "chrono")]
89 RowValue::DateTime(value) => Self::Scalar(ScalarValue::DateTime(*value)),
90 #[cfg(feature = "chrono")]
91 RowValue::Timestamp(value) => Self::Scalar(ScalarValue::Timestamp(*value)),
92 #[cfg(feature = "uuid")]
93 RowValue::Uuid(value) => Self::Scalar(ScalarValue::Uuid(*value)),
94 #[cfg(feature = "json")]
95 RowValue::Json(_) => return Err(invalid_cursor("JSON cannot be a cursor key")),
96 })
97 }
98}