Skip to main content

tank_tests/
enums.rs

1#![allow(unused_imports)]
2use rust_decimal::{Decimal, prelude::FromPrimitive};
3use std::{
4    borrow::Cow,
5    cell::{Cell, RefCell},
6    i128,
7    ops::Deref,
8    pin::pin,
9    sync::{Arc, LazyLock},
10};
11use tank::{
12    AsValue, Driver, DynQuery, Entity, Error, Executor, FixedDecimal, Query, QueryBuilder,
13    QueryResult, RawQuery, Result, RowsAffected, SqlWriter, Value, cols, expr,
14    stream::{StreamExt, TryStreamExt},
15};
16use time::{Date, Time, macros::date};
17use tokio::sync::Mutex;
18use uuid::Uuid;
19
20static MUTEX: LazyLock<Mutex<()>> = LazyLock::new(|| Mutex::new(()));
21
22#[derive(Clone, Copy, PartialEq, Eq, Debug)]
23enum SomeEnum {
24    FirstValue,
25    SecondValue,
26}
27impl AsValue for SomeEnum {
28    fn as_empty_value() -> Value {
29        Value::Varchar(None)
30    }
31    fn as_value(self) -> Value {
32        match self {
33            Self::FirstValue => Value::Varchar(Some("first".into())),
34            Self::SecondValue => Value::Varchar(Some("second".into())),
35        }
36    }
37    fn try_from_value(value: Value) -> Result<Self>
38    where
39        Self: Sized,
40    {
41        if let Value::Varchar(Some(v), ..) = value.try_as(&Value::Varchar(None))? {
42            match v.deref() {
43                "first" => return Ok(Self::FirstValue),
44                "second" => return Ok(Self::SecondValue),
45                _ => {}
46            }
47        }
48        Err(Error::msg("Could not decode SomeEnum from value"))
49    }
50}
51
52#[derive(Clone, Copy, PartialEq, Eq, Debug)]
53enum AnotherEnum {
54    Alpha,
55    Bravo,
56    Charlie,
57    Delta,
58}
59impl AsValue for AnotherEnum {
60    fn as_empty_value() -> Value {
61        Value::Int8(None)
62    }
63    fn as_value(self) -> Value {
64        match self {
65            Self::Alpha => Value::Int8(Some(0)),
66            Self::Bravo => Value::Int8(Some(1)),
67            Self::Charlie => Value::Int8(Some(2)),
68            Self::Delta => Value::Int8(Some(3)),
69        }
70    }
71    fn try_from_value(value: Value) -> Result<Self>
72    where
73        Self: Sized,
74    {
75        if let Value::Int8(Some(v), ..) = value.try_as(&Value::Int8(None))? {
76            match v {
77                0 => return Ok(Self::Alpha),
78                1 => return Ok(Self::Bravo),
79                2 => return Ok(Self::Charlie),
80                3 => return Ok(Self::Delta),
81                _ => {}
82            }
83        }
84        Err(Error::msg("Could not decode AnotherEnum from value"))
85    }
86}
87
88#[derive(Debug, Entity, PartialEq)]
89#[tank(primary_key = (id, another_enum))]
90struct Entry {
91    id: i32,
92    some_enum: Option<SomeEnum>,
93    #[tank(clustering_key)]
94    another_enum: AnotherEnum,
95}
96
97pub async fn enums<E: Executor>(executor: &mut E) {
98    let _lock = MUTEX.lock().await;
99
100    // Setup
101    Entry::drop_table(executor, true, false)
102        .await
103        .expect("Failed to drop Table table");
104    Entry::create_table(executor, true, true)
105        .await
106        .expect("Failed to create Table table");
107
108    // Operations
109    let mut entry = Entry {
110        id: 1,
111        some_enum: Some(SomeEnum::FirstValue),
112        another_enum: AnotherEnum::Delta,
113    };
114    entry.save(executor).await.expect("Failed to save entry");
115    let value = Entry::find_one(executor, true)
116        .await
117        .expect("Failed to read entry");
118    assert_eq!(
119        value,
120        Some(Entry {
121            id: 1,
122            some_enum: Some(SomeEnum::FirstValue),
123            another_enum: AnotherEnum::Delta,
124        })
125    );
126
127    entry.some_enum = None;
128    entry
129        .save(executor)
130        .await
131        .expect("Failed to save again entry");
132    Entry::insert_many(
133        executor,
134        &[
135            Entry {
136                id: 1,
137                some_enum: Some(SomeEnum::SecondValue),
138                another_enum: AnotherEnum::Charlie,
139            },
140            Entry {
141                id: 1,
142                some_enum: None,
143                another_enum: AnotherEnum::Bravo,
144            },
145        ],
146    )
147    .await
148    .expect("Could not insert multiple entities");
149    let entries = executor
150        .fetch(
151            QueryBuilder::new()
152                .select(cols!(*))
153                .from(Entry::table())
154                .where_expr(expr!(id == 1))
155                .order_by(cols!(Entry::another_enum ASC))
156                .build(&executor.driver()),
157        )
158        .map_ok(Entry::from_row)
159        .map(Result::flatten)
160        .try_collect::<Vec<_>>()
161        .await
162        .expect("Could not query multiple entities");
163    assert_eq!(
164        entries,
165        [
166            Entry {
167                id: 1,
168                some_enum: None,
169                another_enum: AnotherEnum::Bravo,
170            },
171            Entry {
172                id: 1,
173                some_enum: Some(SomeEnum::SecondValue),
174                another_enum: AnotherEnum::Charlie,
175            },
176            Entry {
177                id: 1,
178                some_enum: None,
179                another_enum: AnotherEnum::Delta,
180            },
181        ]
182    );
183}