about summary refs log tree commit diff stats
path: root/crates/rocie-server/src/storage/sql/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/rocie-server/src/storage/sql/mod.rs')
-rw-r--r--crates/rocie-server/src/storage/sql/mod.rs95
1 files changed, 94 insertions, 1 deletions
diff --git a/crates/rocie-server/src/storage/sql/mod.rs b/crates/rocie-server/src/storage/sql/mod.rs
index edce187..a44fbad 100644
--- a/crates/rocie-server/src/storage/sql/mod.rs
+++ b/crates/rocie-server/src/storage/sql/mod.rs
@@ -2,7 +2,100 @@ pub(crate) mod get;
 pub(crate) mod insert;
 
 // Types
+pub(crate) mod barcode;
 pub(crate) mod product;
 pub(crate) mod product_amount;
 pub(crate) mod unit;
-pub(crate) mod barcode;
+pub(crate) mod unit_property;
+
+macro_rules! mk_id {
+    ($name:ident and $stub_name:ident) => {
+        mk_id!($name and $stub_name with uuid::Uuid, "uuid::Uuid");
+    };
+    ($name:ident and $stub_name:ident with $inner:path, $inner_string:literal $($args:meta)*) => {
+        #[derive(
+            serde::Deserialize,
+            serde::Serialize,
+            Debug,
+            Default,
+            utoipa::ToSchema,
+            Clone,
+            Copy,
+            PartialEq,
+            Eq,
+            PartialOrd,
+            Ord,
+        )]
+        pub(crate) struct $name {
+            value: $inner,
+        }
+
+        #[derive(Deserialize, Serialize, Debug, Clone, Copy)]
+        #[serde(from = $inner_string)]
+        pub(crate) struct $stub_name {
+            value: $inner,
+        }
+
+        impl $name {
+            pub(crate) fn from_db(id: &str) -> Self {
+                use std::str::FromStr;
+
+                Self {
+                    value: <$inner as FromStr>::from_str(id)
+                        .expect(
+                            concat!(
+                                "We put an ",
+                                $inner_string,
+                                " into the db, it should also go out again"
+                            )
+                        ),
+                }
+            }
+        }
+
+        impl std::fmt::Display for $name {
+            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+                write!(f, "{}", self.value)
+            }
+        }
+
+        impl From<$inner> for $name {
+            fn from(value: $inner) -> Self {
+                Self { value }
+            }
+        }
+        impl From<$inner> for $stub_name {
+            fn from(value: $inner) -> Self {
+                Self { value }
+            }
+        }
+        impl From<$stub_name> for $name {
+            fn from(value: $stub_name) -> Self {
+                Self { value: value.value }
+            }
+        }
+
+        impl<'q, DB: sqlx::Database> sqlx::Encode<'q, DB> for $name
+        where
+            String: sqlx::Encode<'q, DB>,
+        {
+            fn encode_by_ref(
+                &self,
+                buf: &mut <DB as sqlx::Database>::ArgumentBuffer<'q>,
+            ) -> Result<sqlx::encode::IsNull, sqlx::error::BoxDynError> {
+                let inner = self.value.to_string();
+                sqlx::Encode::<DB>::encode_by_ref(&inner, buf)
+            }
+        }
+        impl<DB: sqlx::Database> sqlx::Type<DB> for $name
+        where
+            String: sqlx::Type<DB>,
+        {
+            fn type_info() -> DB::TypeInfo {
+                <String as sqlx::Type<DB>>::type_info()
+            }
+        }
+    };
+}
+
+pub(crate) use mk_id;