Skip to main content

sea_orm_macros/
lib.rs

1extern crate proc_macro;
2
3use proc_macro::TokenStream;
4
5use syn::{DeriveInput, Error, parse_macro_input};
6
7#[cfg(feature = "derive")]
8mod derives;
9
10#[cfg(feature = "strum")]
11mod strum;
12
13mod raw_sql;
14
15#[proc_macro]
16pub fn raw_sql(input: TokenStream) -> TokenStream {
17    match raw_sql::expand(input) {
18        Ok(token_stream) => token_stream.into(),
19        Err(e) => e.to_compile_error().into(),
20    }
21}
22
23/// Create an Entity
24///
25/// ### Usage
26///
27/// ```
28/// use sea_orm::entity::prelude::*;
29///
30/// #[derive(Copy, Clone, Default, Debug, DeriveEntity)]
31/// pub struct Entity;
32///
33/// # impl EntityName for Entity {
34/// #     fn table_name(&self) -> &'static str {
35/// #         "cake"
36/// #     }
37/// # }
38/// #
39/// # #[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel)]
40/// # pub struct Model {
41/// #     pub id: i32,
42/// #     pub name: String,
43/// # }
44/// #
45/// # #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
46/// # pub enum Column {
47/// #     Id,
48/// #     Name,
49/// # }
50/// #
51/// # #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]
52/// # pub enum PrimaryKey {
53/// #     Id,
54/// # }
55/// #
56/// # impl PrimaryKeyTrait for PrimaryKey {
57/// #     type ValueType = i32;
58/// #
59/// #     fn auto_increment() -> bool {
60/// #         true
61/// #     }
62/// # }
63/// #
64/// # #[derive(Copy, Clone, Debug, EnumIter)]
65/// # pub enum Relation {}
66/// #
67/// # impl ColumnTrait for Column {
68/// #     type EntityName = Entity;
69/// #
70/// #     fn def(&self) -> ColumnDef {
71/// #         match self {
72/// #             Self::Id => ColumnType::Integer.def(),
73/// #             Self::Name => ColumnType::String(StringLen::None).def(),
74/// #         }
75/// #     }
76/// # }
77/// #
78/// # impl RelationTrait for Relation {
79/// #     fn def(&self) -> RelationDef {
80/// #         panic!("No Relation");
81/// #     }
82/// # }
83/// #
84/// # impl ActiveModelBehavior for ActiveModel {}
85/// ```
86#[cfg(feature = "derive")]
87#[proc_macro_derive(DeriveEntity, attributes(sea_orm))]
88pub fn derive_entity(input: TokenStream) -> TokenStream {
89    let input = parse_macro_input!(input as DeriveInput);
90    derives::expand_derive_entity(input)
91        .unwrap_or_else(Error::into_compile_error)
92        .into()
93}
94
95/// This derive macro is the 'almighty' macro which automatically generates
96/// Entity, Column, and PrimaryKey from a given Model.
97///
98/// ### Usage
99///
100/// ```
101/// use sea_orm::entity::prelude::*;
102/// use serde::{Deserialize, Serialize};
103///
104/// #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Deserialize, Serialize)]
105/// #[sea_orm(table_name = "posts")]
106/// pub struct Model {
107///     #[sea_orm(primary_key)]
108///     pub id: i32,
109///     pub title: String,
110///     #[sea_orm(column_type = "Text")]
111///     pub text: String,
112/// }
113///
114/// # #[derive(Copy, Clone, Debug, EnumIter)]
115/// # pub enum Relation {}
116/// #
117/// # impl RelationTrait for Relation {
118/// #     fn def(&self) -> RelationDef {
119/// #         panic!("No Relation");
120/// #     }
121/// # }
122/// #
123/// # impl ActiveModelBehavior for ActiveModel {}
124/// ```
125///
126/// Entity should always have a primary key.
127/// Or, it will result in a compile error.
128/// See <https://github.com/SeaQL/sea-orm/issues/485> for details.
129///
130/// ```compile_fail
131/// use sea_orm::entity::prelude::*;
132///
133/// #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
134/// #[sea_orm(table_name = "posts")]
135/// pub struct Model {
136///     pub title: String,
137///     #[sea_orm(column_type = "Text")]
138///     pub text: String,
139/// }
140///
141/// # #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
142/// # pub enum Relation {}
143/// #
144/// # impl ActiveModelBehavior for ActiveModel {}
145/// ```
146#[cfg(feature = "derive")]
147#[proc_macro_derive(DeriveEntityModel, attributes(sea_orm, seaography))]
148pub fn derive_entity_model(input: TokenStream) -> TokenStream {
149    let DeriveInput {
150        vis,
151        ident,
152        data,
153        attrs,
154        ..
155    } = parse_macro_input!(input as DeriveInput);
156
157    if ident != "Model" {
158        panic!("Struct name must be Model");
159    }
160
161    let mut ts: TokenStream = derives::expand_derive_entity_model(&vis, &data, &attrs)
162        .unwrap_or_else(Error::into_compile_error)
163        .into();
164
165    ts.extend::<TokenStream>(
166        derives::expand_derive_model(&ident, &data, &attrs)
167            .unwrap_or_else(Error::into_compile_error)
168            .into(),
169    );
170
171    ts.extend::<TokenStream>(
172        derives::expand_derive_active_model(&vis, &ident, &data)
173            .unwrap_or_else(Error::into_compile_error)
174            .into(),
175    );
176
177    ts
178}
179
180/// Derive a complex model with relational fields
181#[cfg(feature = "derive")]
182#[proc_macro_derive(DeriveModelEx, attributes(sea_orm, seaography))]
183pub fn derive_model_ex(input: TokenStream) -> TokenStream {
184    let DeriveInput {
185        vis,
186        ident,
187        data,
188        attrs,
189        ..
190    } = parse_macro_input!(input as DeriveInput);
191
192    if ident != "ModelEx" {
193        panic!("Struct name must be ModelEx");
194    }
195
196    derives::expand_derive_model_ex(&vis, ident, data, attrs)
197        .unwrap_or_else(Error::into_compile_error)
198        .into()
199}
200
201/// Derive a complex active model with relational fields
202#[cfg(feature = "derive")]
203#[proc_macro_derive(DeriveActiveModelEx, attributes(sea_orm, seaography))]
204pub fn derive_active_model_ex(input: TokenStream) -> TokenStream {
205    let DeriveInput {
206        vis,
207        ident,
208        data,
209        attrs,
210        ..
211    } = parse_macro_input!(input as DeriveInput);
212
213    if ident != "ModelEx" {
214        panic!("Struct name must be ModelEx");
215    }
216
217    derives::expand_derive_active_model_ex(&vis, &ident, &data, &attrs)
218        .unwrap_or_else(Error::into_compile_error)
219        .into()
220}
221
222/// The DerivePrimaryKey derive macro will implement [PrimaryKeyToColumn]
223/// for PrimaryKey which defines tedious mappings between primary keys and columns.
224/// The [EnumIter] is also derived, allowing iteration over all enum variants.
225///
226/// ### Usage
227///
228/// ```
229/// use sea_orm::entity::prelude::*;
230///
231/// #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]
232/// pub enum PrimaryKey {
233///     CakeId,
234///     FillingId,
235/// }
236///
237/// # #[derive(Copy, Clone, Default, Debug, DeriveEntity)]
238/// # pub struct Entity;
239/// #
240/// # impl EntityName for Entity {
241/// #     fn table_name(&self) -> &'static str {
242/// #         "cake"
243/// #     }
244/// # }
245/// #
246/// # #[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel)]
247/// # pub struct Model {
248/// #     pub cake_id: i32,
249/// #     pub filling_id: i32,
250/// # }
251/// #
252/// # #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
253/// # pub enum Column {
254/// #     CakeId,
255/// #     FillingId,
256/// # }
257/// #
258/// # #[derive(Copy, Clone, Debug, EnumIter)]
259/// # pub enum Relation {}
260/// #
261/// # impl ColumnTrait for Column {
262/// #     type EntityName = Entity;
263/// #
264/// #     fn def(&self) -> ColumnDef {
265/// #         match self {
266/// #             Self::CakeId => ColumnType::Integer.def(),
267/// #             Self::FillingId => ColumnType::Integer.def(),
268/// #         }
269/// #     }
270/// # }
271/// #
272/// # impl PrimaryKeyTrait for PrimaryKey {
273/// #     type ValueType = (i32, i32);
274/// #
275/// #     fn auto_increment() -> bool {
276/// #         false
277/// #     }
278/// # }
279/// #
280/// # impl RelationTrait for Relation {
281/// #     fn def(&self) -> RelationDef {
282/// #         panic!("No Relation");
283/// #     }
284/// # }
285/// #
286/// # impl ActiveModelBehavior for ActiveModel {}
287/// ```
288#[cfg(feature = "derive")]
289#[proc_macro_derive(DerivePrimaryKey, attributes(sea_orm))]
290pub fn derive_primary_key(input: TokenStream) -> TokenStream {
291    let DeriveInput { ident, data, .. } = parse_macro_input!(input);
292
293    match derives::expand_derive_primary_key(&ident, &data) {
294        Ok(ts) => ts.into(),
295        Err(e) => e.to_compile_error().into(),
296    }
297}
298
299/// The DeriveColumn derive macro will implement [ColumnTrait] for Columns.
300/// It defines the identifier of each column by implementing Iden and IdenStatic.
301/// The EnumIter is also derived, allowing iteration over all enum variants.
302///
303/// ### Usage
304///
305/// ```
306/// use sea_orm::entity::prelude::*;
307///
308/// #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
309/// pub enum Column {
310///     CakeId,
311///     FillingId,
312/// }
313/// ```
314#[cfg(feature = "derive")]
315#[proc_macro_derive(DeriveColumn, attributes(sea_orm))]
316pub fn derive_column(input: TokenStream) -> TokenStream {
317    let DeriveInput { ident, data, .. } = parse_macro_input!(input);
318
319    match derives::expand_derive_column(&ident, &data) {
320        Ok(ts) => ts.into(),
321        Err(e) => e.to_compile_error().into(),
322    }
323}
324
325/// The DeriveModel derive macro will implement ModelTrait for Model,
326/// which provides setters and getters for all attributes in the mod
327/// It also implements FromQueryResult to convert a query result into the corresponding Model.
328///
329/// ### Usage
330///
331/// ```
332/// use sea_orm::entity::prelude::*;
333///
334/// #[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel)]
335/// pub struct Model {
336///     pub id: i32,
337///     pub name: String,
338/// }
339///
340/// # #[derive(Copy, Clone, Default, Debug, DeriveEntity)]
341/// # pub struct Entity;
342/// #
343/// # impl EntityName for Entity {
344/// #     fn table_name(&self) -> &'static str {
345/// #         "cake"
346/// #     }
347/// # }
348/// #
349/// # #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
350/// # pub enum Column {
351/// #     Id,
352/// #     Name,
353/// # }
354/// #
355/// # #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]
356/// # pub enum PrimaryKey {
357/// #     Id,
358/// # }
359/// #
360/// # impl PrimaryKeyTrait for PrimaryKey {
361/// #     type ValueType = i32;
362/// #
363/// #     fn auto_increment() -> bool {
364/// #         true
365/// #     }
366/// # }
367/// #
368/// # #[derive(Copy, Clone, Debug, EnumIter)]
369/// # pub enum Relation {}
370/// #
371/// # impl ColumnTrait for Column {
372/// #     type EntityName = Entity;
373/// #
374/// #     fn def(&self) -> ColumnDef {
375/// #         match self {
376/// #             Self::Id => ColumnType::Integer.def(),
377/// #             Self::Name => ColumnType::String(StringLen::None).def(),
378/// #         }
379/// #     }
380/// # }
381/// #
382/// # impl RelationTrait for Relation {
383/// #     fn def(&self) -> RelationDef {
384/// #         panic!("No Relation");
385/// #     }
386/// # }
387/// #
388/// # impl ActiveModelBehavior for ActiveModel {}
389/// ```
390#[cfg(feature = "derive")]
391#[proc_macro_derive(DeriveModel, attributes(sea_orm))]
392pub fn derive_model(input: TokenStream) -> TokenStream {
393    let DeriveInput {
394        ident, data, attrs, ..
395    } = parse_macro_input!(input as DeriveInput);
396
397    derives::expand_derive_model(&ident, &data, &attrs)
398        .unwrap_or_else(Error::into_compile_error)
399        .into()
400}
401
402/// The DeriveActiveModel derive macro will implement ActiveModelTrait for ActiveModel
403/// which provides setters and getters for all active values in the active model.
404///
405/// ### Usage
406///
407/// ```
408/// use sea_orm::entity::prelude::*;
409///
410/// #[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel)]
411/// pub struct Model {
412///     pub id: i32,
413///     pub name: String,
414/// }
415///
416/// # #[derive(Copy, Clone, Default, Debug, DeriveEntity)]
417/// # pub struct Entity;
418/// #
419/// # impl EntityName for Entity {
420/// #     fn table_name(&self) -> &'static str {
421/// #         "cake"
422/// #     }
423/// # }
424/// #
425/// # #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
426/// # pub enum Column {
427/// #     Id,
428/// #     Name,
429/// # }
430/// #
431/// # #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]
432/// # pub enum PrimaryKey {
433/// #     Id,
434/// # }
435/// #
436/// # impl PrimaryKeyTrait for PrimaryKey {
437/// #     type ValueType = i32;
438/// #
439/// #     fn auto_increment() -> bool {
440/// #         true
441/// #     }
442/// # }
443/// #
444/// # #[derive(Copy, Clone, Debug, EnumIter)]
445/// # pub enum Relation {}
446/// #
447/// # impl ColumnTrait for Column {
448/// #     type EntityName = Entity;
449/// #
450/// #     fn def(&self) -> ColumnDef {
451/// #         match self {
452/// #             Self::Id => ColumnType::Integer.def(),
453/// #             Self::Name => ColumnType::String(StringLen::None).def(),
454/// #         }
455/// #     }
456/// # }
457/// #
458/// # impl RelationTrait for Relation {
459/// #     fn def(&self) -> RelationDef {
460/// #         panic!("No Relation");
461/// #     }
462/// # }
463/// #
464/// # impl ActiveModelBehavior for ActiveModel {}
465/// ```
466#[cfg(feature = "derive")]
467#[proc_macro_derive(DeriveActiveModel, attributes(sea_orm))]
468pub fn derive_active_model(input: TokenStream) -> TokenStream {
469    let DeriveInput {
470        vis, ident, data, ..
471    } = parse_macro_input!(input);
472
473    match derives::expand_derive_active_model(&vis, &ident, &data) {
474        Ok(ts) => ts.into(),
475        Err(e) => e.to_compile_error().into(),
476    }
477}
478
479/// Will implement [`IntoActiveModel`] for a struct, allowing conversion into an ActiveModel.
480/// This is useful for "form" or "input" structs (like from API requests) that turn into
481/// an entity's ActiveModel but may omit some fields or provide optional values with defaults.
482///
483/// ## Usage:
484///
485/// ```rust
486/// # mod fruit {
487/// #     use sea_orm::entity::prelude::*;
488/// #     #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
489/// #     #[sea_orm(table_name = "fruit")]
490/// #     pub struct Model {
491/// #         #[sea_orm(primary_key)]
492/// #         pub id: i32,
493/// #         pub name: String,
494/// #         pub cake_id: Option<i32>,
495/// #     }
496/// #     #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
497/// #     pub enum Relation {}
498/// #     impl ActiveModelBehavior for ActiveModel {}
499/// # }
500/// use sea_orm::entity::prelude::*;
501///
502/// #[derive(DeriveIntoActiveModel)]
503/// #[sea_orm(active_model = "fruit::ActiveModel")]
504/// struct NewFruit {
505///     name: String,
506///     // `id` and `cake_id` are omitted - they become `NotSet`
507/// }
508/// ```
509///
510/// ## `set(...)` - always set absent ActiveModel fields
511///
512/// ```rust
513/// # mod fruit {
514/// #     use sea_orm::entity::prelude::*;
515/// #     #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
516/// #     #[sea_orm(table_name = "fruit")]
517/// #     pub struct Model {
518/// #         #[sea_orm(primary_key)]
519/// #         pub id: i32,
520/// #         pub name: String,
521/// #         pub cake_id: Option<i32>,
522/// #     }
523/// #     #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
524/// #     pub enum Relation {}
525/// #     impl ActiveModelBehavior for ActiveModel {}
526/// # }
527/// use sea_orm::entity::prelude::*;
528///
529/// #[derive(DeriveIntoActiveModel)]
530/// #[sea_orm(active_model = "fruit::ActiveModel", set(cake_id = "None"))]
531/// struct NewFruit {
532///     name: String,
533///     // `cake_id` is not on the struct, but will always be `Set(None)`
534/// }
535/// ```
536///
537/// ## `default = "expr"` - fallback for `Option<T>` struct fields
538///
539/// ```rust
540/// # mod fruit {
541/// #     use sea_orm::entity::prelude::*;
542/// #     #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
543/// #     #[sea_orm(table_name = "fruit")]
544/// #     pub struct Model {
545/// #         #[sea_orm(primary_key)]
546/// #         pub id: i32,
547/// #         pub name: String,
548/// #         pub cake_id: Option<i32>,
549/// #     }
550/// #     #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
551/// #     pub enum Relation {}
552/// #     impl ActiveModelBehavior for ActiveModel {}
553/// # }
554/// use sea_orm::entity::prelude::*;
555///
556/// #[derive(DeriveIntoActiveModel)]
557/// #[sea_orm(active_model = "fruit::ActiveModel")]
558/// struct UpdateFruit {
559///     /// `Some("Apple")` -> `Set("Apple")`, `None` ->`Set("Unnamed")`
560///     #[sea_orm(default = "String::from(\"Unnamed\")")]
561///     name: Option<String>,
562/// }
563/// ```
564///
565/// ## Combining `set(...)`, `default`, `ignore`, and `exhaustive`
566///
567/// ```rust
568/// # mod fruit {
569/// #     use sea_orm::entity::prelude::*;
570/// #     #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
571/// #     #[sea_orm(table_name = "fruit")]
572/// #     pub struct Model {
573/// #         #[sea_orm(primary_key)]
574/// #         pub id: i32,
575/// #         pub name: String,
576/// #         pub cake_id: Option<i32>,
577/// #     }
578/// #     #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
579/// #     pub enum Relation {}
580/// #     impl ActiveModelBehavior for ActiveModel {}
581/// # }
582/// use sea_orm::entity::prelude::*;
583///
584/// #[derive(DeriveIntoActiveModel)]
585/// #[sea_orm(active_model = "fruit::ActiveModel", exhaustive, set(cake_id = "None"))]
586/// struct NewFruit {
587///     id: i32,
588///     #[sea_orm(default = "String::from(\"Unnamed\")")]
589///     name: Option<String>,
590/// }
591/// ```
592#[cfg(feature = "derive")]
593#[proc_macro_derive(DeriveIntoActiveModel, attributes(sea_orm))]
594pub fn derive_into_active_model(input: TokenStream) -> TokenStream {
595    let input = parse_macro_input!(input as DeriveInput);
596    derives::expand_into_active_model(input)
597        .unwrap_or_else(Error::into_compile_error)
598        .into()
599}
600
601/// Models that a user can override
602///
603/// ### Usage
604///
605/// ```
606/// use sea_orm::entity::prelude::*;
607///
608/// #[derive(
609///     Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, DeriveActiveModelBehavior,
610/// )]
611/// pub struct Model {
612///     pub id: i32,
613///     pub name: String,
614/// }
615///
616/// # #[derive(Copy, Clone, Default, Debug, DeriveEntity)]
617/// # pub struct Entity;
618/// #
619/// # impl EntityName for Entity {
620/// #     fn table_name(&self) -> &'static str {
621/// #         "cake"
622/// #     }
623/// # }
624/// #
625/// # #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
626/// # pub enum Column {
627/// #     Id,
628/// #     Name,
629/// # }
630/// #
631/// # #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]
632/// # pub enum PrimaryKey {
633/// #     Id,
634/// # }
635/// #
636/// # impl PrimaryKeyTrait for PrimaryKey {
637/// #     type ValueType = i32;
638/// #
639/// #     fn auto_increment() -> bool {
640/// #         true
641/// #     }
642/// # }
643/// #
644/// # #[derive(Copy, Clone, Debug, EnumIter)]
645/// # pub enum Relation {}
646/// #
647/// # impl ColumnTrait for Column {
648/// #     type EntityName = Entity;
649/// #
650/// #     fn def(&self) -> ColumnDef {
651/// #         match self {
652/// #             Self::Id => ColumnType::Integer.def(),
653/// #             Self::Name => ColumnType::String(StringLen::None).def(),
654/// #         }
655/// #     }
656/// # }
657/// #
658/// # impl RelationTrait for Relation {
659/// #     fn def(&self) -> RelationDef {
660/// #         panic!("No Relation");
661/// #     }
662/// # }
663/// ```
664#[cfg(feature = "derive")]
665#[proc_macro_derive(DeriveActiveModelBehavior)]
666pub fn derive_active_model_behavior(input: TokenStream) -> TokenStream {
667    let DeriveInput { ident, data, .. } = parse_macro_input!(input);
668
669    match derives::expand_derive_active_model_behavior(ident, data) {
670        Ok(ts) => ts.into(),
671        Err(e) => e.to_compile_error().into(),
672    }
673}
674
675/// A derive macro to implement `sea_orm::ActiveEnum` trait for enums.
676///
677/// # Limitations
678///
679/// This derive macros can only be used on enums.
680///
681/// # Macro Attributes
682///
683/// All macro attributes listed below have to be annotated in the form of `#[sea_orm(attr = value)]`.
684///
685/// - For enum
686///     - `rs_type`: Define `ActiveEnum::Value` for non-native enums (`db_type != "Enum"`)
687///         - Possible values: `String`, `i8`, `i16`, `i32`, `i64`, `u8`, `u16`, `u32`, `u64`
688///         - Note that value has to be passed as string, i.e. `rs_type = "i8"`
689///     - `db_type`: Define `ColumnType` returned by `ActiveEnum::db_type()`
690///         - Possible values: all available enum variants of `ColumnType`, e.g. `Enum`, `String(StringLen::None)`, `String(StringLen::N(1))`, `Integer`
691///         - Note that value has to be passed as string, i.e. `db_type = "Integer"`
692///     - `enum_name`: Define `String` returned by `ActiveEnum::name()`
693///         - This attribute is optional with default value being the name of enum in camel-case
694///         - Note that value has to be passed as string, i.e. `enum_name = "MyEnum"`
695///     - Constraints for native enums (`db_type = "Enum"`):
696///         - `rs_type` is optional; it defaults to `Enum`. If specified it must be `String` or `Enum`.
697///         - `num_value` and numeric discriminants are not allowed.
698///
699/// - For enum variant
700///     - `string_value` or `num_value`:
701///         - For `string_value`, value should be passed as string, i.e. `string_value = "A"`
702///             - Due to the way internal Enums are automatically derived, the following restrictions apply:
703///                 - members cannot share identical `string_value`, case-insensitive.
704///                 - in principle, any future Titlecased Rust keywords are not valid `string_value`.
705///         - For `num_value`, value should be passed as integer, i.e. `num_value = 1` or `num_value = 1i32`
706///         - Note that only one of it can be specified, and all variants of an enum have to annotate with the same `*_value` macro attribute
707///
708/// # Usage
709///
710/// ```
711/// use sea_orm::{DeriveActiveEnum, entity::prelude::*};
712///
713/// #[derive(EnumIter, DeriveActiveEnum)]
714/// #[sea_orm(rs_type = "i32", db_type = "Integer")]
715/// pub enum Color {
716///     Black = 0,
717///     White = 1,
718/// }
719/// ```
720#[cfg(feature = "derive")]
721#[proc_macro_derive(DeriveActiveEnum, attributes(sea_orm))]
722pub fn derive_active_enum(input: TokenStream) -> TokenStream {
723    let input = parse_macro_input!(input as DeriveInput);
724
725    match derives::expand_derive_active_enum(input) {
726        Ok(ts) => ts.into(),
727        Err(e) => e.to_compile_error().into(),
728    }
729}
730
731/// Convert a query result into the corresponding Model.
732///
733/// ### Attributes
734///
735/// - `skip`: will not try to pull this field from the query result. And set it to the default value of the type.
736/// - `nested`: allows nesting models. can be any type that implements `FromQueryResult`
737/// - `alias` / `from_alias`: get the value from this column alias
738///
739/// ### Usage
740///
741/// For more complete examples, please refer to https://github.com/SeaQL/sea-orm/blob/master/tests/from_query_result_tests.rs
742///
743/// ```
744/// use sea_orm::{FromQueryResult, entity::prelude::*};
745///
746/// #[derive(FromQueryResult)]
747/// struct Cake {
748///     id: i32,
749///     name: String,
750///     #[sea_orm(nested)]
751///     bakery: Option<CakeBakery>,
752///     #[sea_orm(skip)]
753///     skip_me: i32,
754/// }
755///
756/// #[derive(FromQueryResult)]
757/// struct CakeBakery {
758///     #[sea_orm(alias = "bakery_id")]
759///     id: i32,
760///     #[sea_orm(alias = "bakery_name")]
761///     title: String,
762/// }
763/// ```
764///
765/// You can compose this with regular Models, if there's no column collision:
766///
767/// ```ignore
768/// #[derive(FromQueryResult)]
769/// struct CakePlain {
770///     id: i32,
771///     name: String,
772///     price: Decimal,
773///     #[sea_orm(nested)]
774///     baker: Option<cakes_bakers::Model>,
775/// }
776/// ```
777#[cfg(feature = "derive")]
778#[proc_macro_derive(FromQueryResult, attributes(sea_orm))]
779pub fn derive_from_query_result(input: TokenStream) -> TokenStream {
780    let derive_input = parse_macro_input!(input);
781
782    match derives::expand_derive_from_query_result(derive_input) {
783        Ok(token_stream) => token_stream.into(),
784        Err(e) => e.to_compile_error().into(),
785    }
786}
787
788/// The DeriveRelation derive macro will implement RelationTrait for Relation.
789///
790/// ### Usage
791///
792/// ```
793/// # use sea_orm::tests_cfg::fruit::Entity;
794/// use sea_orm::entity::prelude::*;
795///
796/// #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
797/// pub enum Relation {
798///     #[sea_orm(
799///         belongs_to = "sea_orm::tests_cfg::cake::Entity",
800///         from = "sea_orm::tests_cfg::fruit::Column::CakeId",
801///         to = "sea_orm::tests_cfg::cake::Column::Id"
802///     )]
803///     Cake,
804///     #[sea_orm(
805///         belongs_to = "sea_orm::tests_cfg::cake_expanded::Entity",
806///         from = "sea_orm::tests_cfg::fruit::Column::CakeId",
807///         to = "sea_orm::tests_cfg::cake_expanded::Column::Id"
808///     )]
809///     CakeExpanded,
810/// }
811/// ```
812#[cfg(feature = "derive")]
813#[proc_macro_derive(DeriveRelation, attributes(sea_orm))]
814pub fn derive_relation(input: TokenStream) -> TokenStream {
815    let input = parse_macro_input!(input as DeriveInput);
816    derives::expand_derive_relation(input)
817        .unwrap_or_else(Error::into_compile_error)
818        .into()
819}
820
821/// The DeriveRelatedEntity derive macro will implement seaography::RelationBuilder for RelatedEntity enumeration.
822///
823/// ### Usage
824///
825/// ```ignore
826/// use sea_orm::entity::prelude::*;
827///
828/// // ...
829/// // Model, Relation enum, etc.
830/// // ...
831///
832/// #[derive(Copy, Clone, Debug, EnumIter, DeriveRelatedEntity)]
833/// pub enum RelatedEntity {
834///     #[sea_orm(entity = "super::address::Entity")]
835///     Address,
836///     #[sea_orm(entity = "super::payment::Entity")]
837///     Payment,
838///     #[sea_orm(entity = "super::rental::Entity")]
839///     Rental,
840///     #[sea_orm(entity = "Entity", def = "Relation::SelfRef.def()")]
841///     SelfRef,
842///     #[sea_orm(entity = "super::store::Entity")]
843///     Store,
844///     #[sea_orm(entity = "Entity", def = "Relation::SelfRef.def().rev()")]
845///     SelfRefRev,
846/// }
847/// ```
848#[cfg(feature = "derive")]
849#[proc_macro_derive(DeriveRelatedEntity, attributes(sea_orm))]
850pub fn derive_related_entity(input: TokenStream) -> TokenStream {
851    let input = parse_macro_input!(input as DeriveInput);
852    derives::expand_derive_related_entity(input)
853        .unwrap_or_else(Error::into_compile_error)
854        .into()
855}
856
857/// The DeriveMigrationName derive macro will implement `sea_orm_migration::MigrationName` for a migration.
858///
859/// ### Usage
860///
861/// ```ignore
862/// #[derive(DeriveMigrationName)]
863/// pub struct Migration;
864/// ```
865///
866/// The derive macro above will provide following implementation,
867/// given the file name is `m20220120_000001_create_post_table.rs`.
868///
869/// ```ignore
870/// impl MigrationName for Migration {
871///     fn name(&self) -> &str {
872///         "m20220120_000001_create_post_table"
873///     }
874/// }
875/// ```
876#[cfg(feature = "derive")]
877#[proc_macro_derive(DeriveMigrationName)]
878pub fn derive_migration_name(input: TokenStream) -> TokenStream {
879    let input = parse_macro_input!(input as DeriveInput);
880    derives::expand_derive_migration_name(input)
881        .unwrap_or_else(Error::into_compile_error)
882        .into()
883}
884
885#[cfg(feature = "derive")]
886#[proc_macro_derive(FromJsonQueryResult)]
887pub fn derive_from_json_query_result(input: TokenStream) -> TokenStream {
888    let DeriveInput { ident, .. } = parse_macro_input!(input);
889
890    match derives::expand_derive_from_json_query_result(ident) {
891        Ok(ts) => ts.into(),
892        Err(e) => e.to_compile_error().into(),
893    }
894}
895
896/// The DerivePartialModel derive macro will implement [`sea_orm::PartialModelTrait`] for simplify partial model queries.
897/// Since 2.0, this macro cannot be used with the `FromQueryResult` macro.
898///
899/// ## Usage
900///
901/// For more complete examples, please refer to https://github.com/SeaQL/sea-orm/blob/master/tests/partial_model_tests.rs
902///
903/// ```rust
904/// use sea_orm::sea_query::ExprTrait;
905/// use sea_orm::{DerivePartialModel, entity::prelude::*};
906///
907/// #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
908/// #[sea_orm(table_name = "posts")]
909/// pub struct Model {
910///     #[sea_orm(primary_key)]
911///     pub id: i32,
912///     pub title: String,
913///     #[sea_orm(column_type = "Text")]
914///     pub text: String,
915/// }
916/// # #[derive(Copy, Clone, Debug, DeriveRelation, EnumIter)]
917/// # pub enum Relation {}
918/// # impl ActiveModelBehavior for ActiveModel {}
919///
920/// #[derive(Debug, DerivePartialModel)]
921/// #[sea_orm(entity = "Entity")]
922/// struct SelectResult {
923///     title: String,
924///     #[sea_orm(from_col = "text")]
925///     content: String,
926///     #[sea_orm(from_expr = "Expr::val(1).add(1)")]
927///     sum: i32,
928/// }
929/// ```
930///
931/// If all fields in the partial model is `from_expr`, the specifying the `entity` can be skipped.
932/// ```
933/// use sea_orm::{
934///     DerivePartialModel,
935///     entity::prelude::*,
936///     sea_query::{Expr, ExprTrait},
937/// };
938///
939/// #[derive(Debug, DerivePartialModel)]
940/// struct SelectResult {
941///     #[sea_orm(from_expr = "Expr::val(1).add(1)")]
942///     sum: i32,
943/// }
944/// ```
945///
946/// Since SeaORM 1.1.7, `DerivePartialModel` can also derive `FromQueryResult`.
947/// This is necessary to support nested partial models.
948/// Since 2.0, `from_query_result` is implemented by default, unless `from_query_result = "false"`.
949///
950/// ```
951/// use sea_orm::DerivePartialModel;
952/// #
953/// # mod cake {
954/// # use sea_orm::entity::prelude::*;
955/// # #[derive(Clone, Debug, DeriveEntityModel)]
956/// # #[sea_orm(table_name = "cake")]
957/// # pub struct Model {
958/// #     #[sea_orm(primary_key)]
959/// #     pub id: i32,
960/// #     pub name: String,
961/// # }
962/// # #[derive(Copy, Clone, Debug, DeriveRelation, EnumIter)]
963/// # pub enum Relation {}
964/// # impl ActiveModelBehavior for ActiveModel {}
965/// # }
966/// #
967/// # mod bakery {
968/// # use sea_orm::entity::prelude::*;
969/// # #[derive(Clone, Debug, DeriveEntityModel)]
970/// # #[sea_orm(table_name = "bakery")]
971/// # pub struct Model {
972/// #     #[sea_orm(primary_key)]
973/// #     pub id: i32,
974/// #     pub name: String,
975/// # }
976/// # #[derive(Copy, Clone, Debug, DeriveRelation, EnumIter)]
977/// # pub enum Relation {}
978/// # impl ActiveModelBehavior for ActiveModel {}
979/// # }
980///
981/// #[derive(DerivePartialModel)]
982/// #[sea_orm(entity = "cake::Entity")]
983/// struct Cake {
984///     id: i32,
985///     name: String,
986///     #[sea_orm(nested)]
987///     bakery: Option<Bakery>,
988///     #[sea_orm(skip)]
989///     ignore: String,
990/// }
991///
992/// #[derive(DerivePartialModel)]
993/// #[sea_orm(entity = "bakery::Entity")]
994/// struct Bakery {
995///     id: i32,
996///     #[sea_orm(from_col = "Name")]
997///     title: String,
998/// }
999///
1000/// // In addition, there's an `alias` attribute to select the columns from an alias:
1001///
1002/// #[derive(DerivePartialModel)]
1003/// #[sea_orm(entity = "bakery::Entity", alias = "factory")]
1004/// struct Factory {
1005///     id: i32,
1006///     #[sea_orm(from_col = "name")]
1007///     plant: String,
1008/// }
1009///
1010/// #[derive(DerivePartialModel)]
1011/// #[sea_orm(entity = "cake::Entity")]
1012/// struct CakeFactory {
1013///     id: i32,
1014///     name: String,
1015///     #[sea_orm(nested)]
1016///     bakery: Option<Factory>,
1017/// }
1018/// ```
1019///
1020/// ```ignore
1021/// let cake: CakeFactory = cake::Entity::find()
1022///     .join_as(
1023///         JoinType::LeftJoin,
1024///         cake::Relation::Bakery.def(),
1025///         "factory",
1026///     )
1027///     .order_by_asc(cake::Column::Id)
1028///     .into_partial_model()
1029///     .one(&db)
1030///     .await
1031///     .unwrap()
1032///     .unwrap()
1033///
1034/// SELECT
1035///     "cake"."id" AS "id", "cake"."name" AS "name",
1036///     "factory"."id" AS "bakery_id", "factory"."name" AS "bakery_plant"
1037/// FROM "cake"
1038/// LEFT JOIN "bakery" AS "factory" ON "cake"."bakery_id" = "factory"."id"
1039/// LIMIT 1
1040/// ```
1041///
1042/// A field cannot have attributes `from_col`, `from_expr` or `nested` at the same time.
1043/// Or, it will result in a compile error.
1044///
1045/// ```compile_fail
1046/// use sea_orm::{entity::prelude::*, DerivePartialModel, sea_query::Expr};
1047///
1048/// #[derive(Debug, DerivePartialModel)]
1049/// #[sea_orm(entity = "Entity")]
1050/// struct SelectResult {
1051///     #[sea_orm(from_expr = "Expr::val(1).add(1)", from_col = "foo")]
1052///     sum: i32,
1053/// }
1054/// ```
1055#[cfg(feature = "derive")]
1056#[proc_macro_derive(DerivePartialModel, attributes(sea_orm))]
1057pub fn derive_partial_model(input: TokenStream) -> TokenStream {
1058    let derive_input = parse_macro_input!(input);
1059
1060    match derives::expand_derive_partial_model(derive_input) {
1061        Ok(token_stream) => token_stream.into(),
1062        Err(e) => e.to_compile_error().into(),
1063    }
1064}
1065
1066#[doc(hidden)]
1067#[cfg(feature = "derive")]
1068#[proc_macro_attribute]
1069pub fn test(_: TokenStream, input: TokenStream) -> TokenStream {
1070    let input = parse_macro_input!(input as syn::ItemFn);
1071
1072    let ret = &input.sig.output;
1073    let name = &input.sig.ident;
1074    let body = &input.block;
1075    let attrs = &input.attrs;
1076
1077    if cfg!(feature = "async") {
1078        quote::quote! (
1079            #[test]
1080            #[cfg(any(
1081                feature = "sqlx-mysql",
1082                feature = "sqlx-sqlite",
1083                feature = "sqlx-postgres",
1084            ))]
1085            #(#attrs)*
1086            fn #name() #ret {
1087                let _ = ::tracing_subscriber::fmt()
1088                    .with_max_level(::tracing::Level::DEBUG)
1089                    .with_test_writer()
1090                    .try_init();
1091                crate::block_on!(async { #body })
1092            }
1093        )
1094        .into()
1095    } else {
1096        quote::quote! (
1097            #[test]
1098            #[cfg(any(
1099                feature = "rusqlite",
1100            ))]
1101            #(#attrs)*
1102            fn #name() #ret {
1103                let _ = ::tracing_subscriber::fmt()
1104                    .with_max_level(::tracing::Level::DEBUG)
1105                    .with_test_writer()
1106                    .try_init();
1107                #body
1108            }
1109        )
1110        .into()
1111    }
1112}
1113
1114/// Creates a new type that iterates of the variants of an enum.
1115///
1116/// Iterate over the variants of an Enum. Any additional data on your variants will be set to `Default::default()`.
1117/// The macro implements `strum::IntoEnumIterator` on your enum and creates a new type called `YourEnumIter` that is the iterator object.
1118/// You cannot derive `EnumIter` on any type with a lifetime bound (`<'a>`) because the iterator would surely
1119/// create [unbounded lifetimes](https://doc.rust-lang.org/nightly/nomicon/unbounded-lifetimes.html).
1120#[cfg(feature = "strum")]
1121#[proc_macro_derive(EnumIter, attributes(strum))]
1122pub fn enum_iter(input: TokenStream) -> TokenStream {
1123    let ast = parse_macro_input!(input as DeriveInput);
1124
1125    strum::enum_iter::enum_iter_inner(&ast)
1126        .unwrap_or_else(Error::into_compile_error)
1127        .into()
1128}
1129
1130/// Implements traits for types that wrap a database value type.
1131///
1132/// This procedure macro implements `From<T> for Value`, `sea_orm::TryGetTable`, and
1133/// `sea_query::ValueType` for the wrapper type `T`.
1134///
1135/// It also implements `sea_query::postgres_array::NotU8`.
1136/// It implements `TryFromU64` if the wrapped types are recognized primitives, i.e.
1137/// `"i8" | "i16" | "i32" | "i64" | "u8" | "u16" | "u32" | "u64"`.
1138///
1139/// The wrapped type must be `sea_orm::Value` compatible.
1140///
1141/// ## Usage
1142///
1143/// ```rust
1144/// use sea_orm::DeriveValueType;
1145///
1146/// #[derive(DeriveValueType)]
1147/// struct MyString(String);
1148///
1149/// #[derive(DeriveValueType)]
1150/// struct MyNumber(i32);
1151/// ```
1152///
1153/// It's also possible to derive value type for enum-strings.
1154/// Basically the underlying type is String, and the custom must implement methods `to_str` and `from_str`.
1155///
1156/// ## Example
1157///
1158/// ```rust
1159/// use sea_orm::{DeriveValueType, sea_query::ValueTypeErr};
1160///
1161/// #[derive(DeriveValueType)]
1162/// #[sea_orm(value_type = "String")]
1163/// pub enum Tag {
1164///     Hard,
1165///     Soft,
1166/// }
1167///
1168/// impl std::fmt::Display for Tag {
1169///     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1170///         write!(
1171///             f,
1172///             "{}",
1173///             match self {
1174///                 Self::Hard => "hard",
1175///                 Self::Soft => "soft",
1176///             }
1177///         )
1178///     }
1179/// }
1180///
1181/// impl std::str::FromStr for Tag {
1182///     type Err = ValueTypeErr;
1183///
1184///     fn from_str(s: &str) -> Result<Self, Self::Err> {
1185///         Ok(match s {
1186///             "hard" => Self::Hard,
1187///             "soft" => Self::Soft,
1188///             _ => return Err(ValueTypeErr),
1189///         })
1190///     }
1191/// }
1192/// ```
1193///
1194/// `from_str` defaults to `std::str::FromStr::from_str`. `to_str` defaults to `std::string::ToString::to_string`.
1195/// They can be overridden with custom functions.
1196///
1197/// ```rust
1198/// use sea_orm::{DeriveValueType, sea_query::ValueTypeErr};
1199///
1200/// #[derive(DeriveValueType)]
1201/// #[sea_orm(
1202///     value_type = "String",
1203///     from_str = "Tag::from_str",
1204///     to_str = "Tag::to_str"
1205/// )]
1206/// pub enum Tag {
1207///     Color,
1208///     Grey,
1209/// }
1210///
1211/// impl Tag {
1212///     fn to_str(&self) -> &'static str {
1213///         match self {
1214///             Self::Color => "color",
1215///             Self::Grey => "grey",
1216///         }
1217///     }
1218///
1219///     fn from_str(s: &str) -> Result<Self, ValueTypeErr> {
1220///         Ok(match s {
1221///             "color" => Self::Color,
1222///             "grey" => Self::Grey,
1223///             _ => return Err(ValueTypeErr),
1224///         })
1225///     }
1226/// }
1227/// ```
1228#[cfg(feature = "derive")]
1229#[proc_macro_derive(DeriveValueType, attributes(sea_orm))]
1230pub fn derive_value_type(input: TokenStream) -> TokenStream {
1231    let derive_input = parse_macro_input!(input as DeriveInput);
1232    match derives::expand_derive_value_type(derive_input) {
1233        Ok(token_stream) => token_stream.into(),
1234        Err(e) => e.to_compile_error().into(),
1235    }
1236}
1237
1238#[cfg(feature = "derive")]
1239#[proc_macro_derive(DeriveDisplay, attributes(sea_orm))]
1240pub fn derive_active_enum_display(input: TokenStream) -> TokenStream {
1241    let input = parse_macro_input!(input as DeriveInput);
1242    match derives::expand_derive_active_enum_display(input) {
1243        Ok(ts) => ts.into(),
1244        Err(e) => e.to_compile_error().into(),
1245    }
1246}
1247
1248/// The DeriveIden derive macro will implement `sea_orm::Iden` for simplify Iden implementation.
1249///
1250/// ## Usage
1251///
1252/// ```rust
1253/// use sea_orm::{DeriveIden, Iden};
1254///
1255/// #[derive(DeriveIden)]
1256/// pub enum MyClass {
1257///     Table, // this is a special case, which maps to the enum's name
1258///     Id,
1259///     #[sea_orm(iden = "turtle")]
1260///     Title,
1261///     Text,
1262/// }
1263///
1264/// #[derive(DeriveIden)]
1265/// struct MyOther;
1266///
1267/// assert_eq!(MyClass::Table.to_string(), "my_class");
1268/// assert_eq!(MyClass::Id.to_string(), "id");
1269/// assert_eq!(MyClass::Title.to_string(), "turtle"); // renamed!
1270/// assert_eq!(MyClass::Text.to_string(), "text");
1271/// assert_eq!(MyOther.to_string(), "my_other");
1272/// ```
1273#[cfg(feature = "derive")]
1274#[proc_macro_derive(DeriveIden, attributes(sea_orm))]
1275pub fn derive_iden(input: TokenStream) -> TokenStream {
1276    let derive_input = parse_macro_input!(input as DeriveInput);
1277
1278    match derives::expand_derive_iden(derive_input) {
1279        Ok(token_stream) => token_stream.into(),
1280        Err(e) => e.to_compile_error().into(),
1281    }
1282}
1283
1284/// The DeriveArrowSchema derive macro generates an `arrow_schema()` method
1285/// that returns an Apache Arrow schema from a SeaORM entity definition.
1286///
1287/// This macro is automatically applied when `#[sea_orm(arrow_schema)]` is specified
1288/// on a model. You typically don't need to use this derive macro directly.
1289///
1290/// ## Usage
1291///
1292/// ```rust,ignore
1293/// use sea_orm::entity::prelude::*;
1294///
1295/// #[sea_orm::model]
1296/// #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
1297/// #[sea_orm(table_name = "user", arrow_schema)]
1298/// pub struct Model {
1299///     #[sea_orm(primary_key)]
1300///     pub id: i64,
1301///     pub name: String,
1302///     #[sea_orm(column_type = "Decimal(Some((20, 4)))")]
1303///     pub amount: Decimal,
1304/// }
1305/// ```
1306#[cfg(feature = "derive")]
1307#[proc_macro_derive(DeriveArrowSchema, attributes(sea_orm))]
1308pub fn derive_arrow_schema(input: TokenStream) -> TokenStream {
1309    let derive_input = parse_macro_input!(input as DeriveInput);
1310
1311    match derives::expand_derive_arrow_schema(
1312        derive_input.ident,
1313        derive_input.data,
1314        derive_input.attrs,
1315    ) {
1316        Ok(token_stream) => token_stream.into(),
1317        Err(e) => e.to_compile_error().into(),
1318    }
1319}
1320
1321#[cfg(feature = "derive")]
1322#[proc_macro_attribute]
1323pub fn sea_orm_model(_attr: TokenStream, input: TokenStream) -> TokenStream {
1324    let input = parse_macro_input!(input as syn::ItemStruct);
1325
1326    match derives::expand_sea_orm_model(input, false) {
1327        Ok(token_stream) => token_stream.into(),
1328        Err(e) => e.to_compile_error().into(),
1329    }
1330}
1331
1332#[cfg(feature = "derive")]
1333#[proc_macro_attribute]
1334pub fn sea_orm_compact_model(_attr: TokenStream, input: TokenStream) -> TokenStream {
1335    let input = parse_macro_input!(input as syn::ItemStruct);
1336
1337    match derives::expand_sea_orm_model(input, true) {
1338        Ok(token_stream) => token_stream.into(),
1339        Err(e) => e.to_compile_error().into(),
1340    }
1341}