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