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