1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
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 product_parent;
pub(crate) mod recipe;
pub(crate) mod unit;
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",
to_string {|val: &uuid::Uuid| val.to_string()},
copy Copy
);
};
(
$name:ident and $stub_name:ident,
with $inner:path $(=> $($args:meta)* )?, $inner_string:literal,
to_string $to_string:expr,
$(copy $copy:path)?
) => {
#[derive(
serde::Deserialize,
serde::Serialize,
Debug,
Default,
utoipa::ToSchema,
Clone,
PartialEq,
Eq,
PartialOrd,
Ord,
$($copy,)?
)]
pub(crate) struct $name {
$(
$(
#[$args]
)*
)?
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, "{}", $to_string(&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 = $to_string(&self.value);
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;
|