Skip to main content

modql_macros/
lib.rs

1// region:    --- Modules
2
3mod derives_field;
4mod derives_filter;
5mod utils;
6
7use crate::derives_filter::derive_filter_nodes_inner;
8use proc_macro::TokenStream;
9
10// endregion: --- Modules
11
12#[proc_macro_derive(FilterNodes, attributes(modql))]
13pub fn derive_filter_nodes(input: TokenStream) -> TokenStream {
14	derive_filter_nodes_inner(input)
15}
16
17// region:    --- with-seaquery
18
19#[cfg(feature = "with-sea-query")]
20mod derives_sea;
21
22#[proc_macro_derive(Fields, attributes(field, modql))]
23pub fn derive_fields(input: TokenStream) -> TokenStream {
24	derives_field::derive_fields_inner(input)
25}
26
27/// Implements `From<T> for sea_query::Value` and `sea_query::Nullable for T`
28/// where T is the struct or enum annotated with `#[derive(Field)]` for simple
29/// tuple structs or enums.
30///
31/// For more complex types, implement both of these traits for the type.
32///
33/// For example:
34///
35/// - On simple type and single element tuple struct
36/// ```rust,norun
37/// #[derive(modql::field::Field)]
38/// pub struct EpochTime(pub(in crate::time) i64);
39/// ```
40/// Will generate something like
41/// ```rust,norun
42/// impl From<EpochTime> for sea_query::Value {
43///   fn from(value: EpochTime) -> Self {
44///     Self::BigInt(Some(value.0))
45///   }
46/// }
47/// impl sea_query::Nullable for EpochTime {
48///   fn null() -> sea_query::Value {
49///     sea_query::Value::BigInt(None)
50///   }
51/// }
52/// ```
53/// Notes:
54///   - Supports only primitive types (no array yet)
55///   - Supports only one tuple field.
56///
57/// - On Simple enum (plain variant only).
58/// ```rust,norun
59/// #[derive(modql::field::SeaFieldValue)]
60/// pub enum Kind {
61///   Md,
62///   Pdf,
63///   Unknown,
64/// }
65/// ```
66/// Notes:
67///   - Will be treated a sea_query::Value::String with the name of the variant.
68///   - No rename for now.
69#[cfg(feature = "with-sea-query")]
70#[proc_macro_derive(SeaFieldValue)]
71pub fn derive_field_sea_value(input: TokenStream) -> TokenStream {
72	derives_sea::derive_field_sea_value_inner(input)
73}
74
75// endregion: --- with-seaquery
76
77// region:    --- with-rusqlite
78
79#[cfg(feature = "with-rusqlite")]
80mod derives_rusqlite;
81
82#[cfg(feature = "with-rusqlite")]
83#[proc_macro_derive(SqliteFromRow, attributes(field, fields))]
84pub fn derive_sqlite_from_row(input: TokenStream) -> TokenStream {
85	derives_rusqlite::derive_sqlite_from_row_inner(input)
86}
87
88/// Will implement the `rusqlite::types::FromSql` for the annotated type.
89///
90/// For example:
91///
92/// - For simple enum (with variant name only)
93/// ```rust,norun
94/// pub enum Kind {
95///   Md,
96///   Pdf,
97///   Unknown,
98/// }
99/// ```
100/// Will generate something like:
101/// ```rust,norun
102///  impl rusqlite::types::FromSql for Kind {
103///    fn column_result(value: rusqlite::types::ValueRef<'_>) -> rusqlite::types::FromSqlResult<Self> {
104///      let txt: String = rusqlite::types::FromSql::column_result(value)?;
105///      match txt.as_str() {
106///        "Md"      => Ok(Kind::Md),
107///        "Pdf"     => Ok(Kind::Pdf),
108///        "Unknown" => Ok(Kind::Unknown),
109///        _ => Err(rusqlite::types::FromSqlError::Other(
110///        format!("Invalid enum variant string '{}'", txt).into(),
111///        )),
112///      }
113///    }
114///  }
115/// ```
116///
117/// - For simple tuple struct (one value that already implement the FromSqlt)
118/// ```rust,norun
119/// #[derive(modql::FromSqliteType)]
120/// pub struct EpochTime(i64);
121/// ```
122/// Will generate something like:
123/// ```rust,norun
124/// impl rusqlite::types::FromSql for EpochTime {
125///   fn column_result(value: rusqlite::types::ValueRef<'_>) -> rusqlite::types::FromSqlResult<Self> {
126///     let val = i64::column_result(value)?;
127///     Ok(EpochTime(val))
128///   }
129/// }
130/// ````
131///
132#[cfg(feature = "with-rusqlite")]
133#[proc_macro_derive(SqliteFromValue)]
134pub fn derive_sqlite_from_value(input: TokenStream) -> TokenStream {
135	derives_rusqlite::derive_from_sqlite_value_inner(input)
136}
137
138/// This will implement the rusqlite ToSql and the From<RustType> to rustqlite Value
139#[cfg(feature = "with-rusqlite")]
140#[proc_macro_derive(SqliteToValue)]
141pub fn derive_sqlite_to_value(input: TokenStream) -> TokenStream {
142	derives_rusqlite::derive_sqlite_to_value_inner(input)
143}
144
145// endregion: --- with-rusqlite
146
147// region:    --- with-rusqlite Deprecated
148
149#[deprecated(note = "use SqliteFromRow")]
150#[cfg(feature = "with-rusqlite")]
151#[proc_macro_derive(FromSqliteRow, attributes(field, fields))]
152pub fn derive_sqlite_from_row_deprecated(input: TokenStream) -> TokenStream {
153	derives_rusqlite::derive_sqlite_from_row_inner(input)
154}
155
156#[deprecated(note = "use SqliteFromValue")]
157#[cfg(feature = "with-rusqlite")]
158#[proc_macro_derive(FromSqliteValue)]
159pub fn derive_sqlite_from_value_deprecated(input: TokenStream) -> TokenStream {
160	derives_rusqlite::derive_from_sqlite_value_inner(input)
161}
162
163#[deprecated(note = "use SqliteToValue")]
164#[cfg(feature = "with-rusqlite")]
165#[proc_macro_derive(ToSqliteValue)]
166pub fn derive_sqlite_to_value_depcreated(input: TokenStream) -> TokenStream {
167	derives_rusqlite::derive_sqlite_to_value_inner(input)
168}
169// endregion: --- with-rusqlite Deprecated