Skip to main content

tank_tests/
custom.rs

1use crate::silent_logs;
2use std::{
3    num::{FpCategory, NonZeroI32},
4    sync::LazyLock,
5};
6use tank::{AsValue, Entity, Error, Executor, Result, Value, expr};
7use tokio::sync::Mutex;
8
9static MUTEX: LazyLock<Mutex<()>> = LazyLock::new(|| Mutex::new(()));
10
11#[derive(Entity, PartialEq, Debug)]
12pub struct CustomValues {
13    #[tank(primary_key)]
14    pk: NonZeroI32,
15    #[tank(conversion_type = FpCategoryWrap)]
16    category: FpCategory,
17}
18pub struct FpCategoryWrap(pub FpCategory);
19impl AsValue for FpCategoryWrap {
20    fn as_empty_value() -> Value {
21        Value::Varchar(None)
22    }
23    fn as_value(self) -> Value {
24        format!("{:?}", self.0).as_value()
25    }
26
27    fn try_from_value(value: Value) -> Result<Self>
28    where
29        Self: Sized,
30    {
31        let make_error = || Error::msg(format!("Could not conver `{value:?}` to FpCategory"));
32        let Value::Varchar(Some(value), ..) = &value else {
33            return Err(make_error());
34        };
35        Ok(match value.as_ref() {
36            "Nan" => FpCategory::Nan,
37            "Infinite" => FpCategory::Infinite,
38            "Zero" => FpCategory::Zero,
39            "Subnormal" => FpCategory::Subnormal,
40            "Normal" => FpCategory::Normal,
41            _ => return Err(make_error()),
42        }
43        .into())
44    }
45}
46impl From<FpCategory> for FpCategoryWrap {
47    fn from(value: FpCategory) -> Self {
48        Self(value)
49    }
50}
51impl From<FpCategoryWrap> for FpCategory {
52    fn from(value: FpCategoryWrap) -> Self {
53        value.0
54    }
55}
56
57pub async fn custom(executor: &mut impl Executor) {
58    let _lock = MUTEX.lock().await;
59
60    // Setup
61    silent_logs! {
62        // Silent logs for Valkey/Redis
63        CustomValues::drop_table(executor, true, false)
64            .await
65            .expect("Failed to drop SimpleNullFields table");
66    }
67    CustomValues::create_table(executor, true, true)
68        .await
69        .expect("Failed to create SimpleNullFields table");
70
71    // Query
72    CustomValues::insert_many(
73        executor,
74        &[
75            CustomValues {
76                pk: 50.try_into().unwrap(),
77                category: FpCategory::Subnormal,
78            },
79            CustomValues {
80                pk: 51.try_into().unwrap(),
81                category: FpCategory::Infinite,
82            },
83        ],
84    )
85    .await
86    .expect("Failed to insert values");
87    CustomValues {
88        pk: 52.try_into().unwrap(),
89        category: FpCategory::Nan,
90    }
91    .save(executor)
92    .await
93    .expect("Failed to save");
94    let value = CustomValues::find_one(executor, expr!(CustomValues::pk == 52))
95        .await
96        .expect("Failed to find");
97    assert_eq!(
98        value,
99        Some(CustomValues {
100            pk: 52.try_into().unwrap(),
101            category: FpCategory::Nan
102        })
103    );
104}