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 quote::quote! (
941 #[test]
942 #[cfg(any(
943 feature = "sqlx-mysql",
944 feature = "sqlx-sqlite",
945 feature = "sqlx-postgres",
946 ))]
947 #(#attrs)*
948 fn #name() #ret {
949 let _ = ::tracing_subscriber::fmt()
950 .with_max_level(::tracing::Level::DEBUG)
951 .with_test_writer()
952 .try_init();
953 crate::block_on!(async { #body })
954 }
955 )
956 .into()
957}
958
959/// Creates a new type that iterates of the variants of an enum.
960///
961/// Iterate over the variants of an Enum. Any additional data on your variants will be set to `Default::default()`.
962/// The macro implements `strum::IntoEnumIterator` on your enum and creates a new type called `YourEnumIter` that is the iterator object.
963/// You cannot derive `EnumIter` on any type with a lifetime bound (`<'a>`) because the iterator would surely
964/// create [unbounded lifetimes](https://doc.rust-lang.org/nightly/nomicon/unbounded-lifetimes.html).
965#[cfg(feature = "strum")]
966#[proc_macro_derive(EnumIter, attributes(strum))]
967pub fn enum_iter(input: TokenStream) -> TokenStream {
968 let ast = parse_macro_input!(input as DeriveInput);
969
970 strum::enum_iter::enum_iter_inner(&ast)
971 .unwrap_or_else(Error::into_compile_error)
972 .into()
973}
974
975/// Implements traits for types that wrap a database value type.
976///
977/// This procedure macro implements `From<T> for Value`, `sea_orm::TryGetTable`, and
978/// `sea_query::ValueType` for the wrapper type `T`.
979///
980/// The wrapped type must be `sea_orm::Value` compatible.
981///
982/// ## Usage
983///
984/// ```rust
985/// use sea_orm::DeriveValueType;
986///
987/// #[derive(DeriveValueType)]
988/// struct MyString(String);
989///
990/// #[derive(DeriveValueType)]
991/// struct MyNumber(i32);
992/// ```
993///
994/// It's also possible to derive value type for enum-strings.
995/// Basically the underlying type is String, and the custom must implement methods `to_str` and `from_str`.
996///
997/// ## Example
998///
999/// ```rust
1000/// use sea_orm::{DeriveValueType, sea_query::ValueTypeErr};
1001///
1002/// #[derive(DeriveValueType)]
1003/// #[sea_orm(value_type = "String")]
1004/// pub enum Tag {
1005/// Hard,
1006/// Soft,
1007/// }
1008///
1009/// impl std::fmt::Display for Tag {
1010/// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1011/// write!(
1012/// f,
1013/// "{}",
1014/// match self {
1015/// Self::Hard => "hard",
1016/// Self::Soft => "soft",
1017/// }
1018/// )
1019/// }
1020/// }
1021///
1022/// impl std::str::FromStr for Tag {
1023/// type Err = ValueTypeErr;
1024///
1025/// fn from_str(s: &str) -> Result<Self, Self::Err> {
1026/// Ok(match s {
1027/// "hard" => Self::Hard,
1028/// "soft" => Self::Soft,
1029/// _ => return Err(ValueTypeErr),
1030/// })
1031/// }
1032/// }
1033/// ```
1034///
1035/// `from_str` defaults to `std::str::FromStr::from_str`. `to_str` defaults to `std::string::ToString::to_string`.
1036/// They can be overridden with custom functions.
1037///
1038/// ```rust
1039/// use sea_orm::{DeriveValueType, sea_query::ValueTypeErr};
1040///
1041/// #[derive(DeriveValueType)]
1042/// #[sea_orm(
1043/// value_type = "String",
1044/// from_str = "Tag::from_str",
1045/// to_str = "Tag::to_str"
1046/// )]
1047/// pub enum Tag {
1048/// Color,
1049/// Grey,
1050/// }
1051///
1052/// impl Tag {
1053/// fn to_str(&self) -> &'static str {
1054/// match self {
1055/// Self::Color => "color",
1056/// Self::Grey => "grey",
1057/// }
1058/// }
1059///
1060/// fn from_str(s: &str) -> Result<Self, ValueTypeErr> {
1061/// Ok(match s {
1062/// "color" => Self::Color,
1063/// "grey" => Self::Grey,
1064/// _ => return Err(ValueTypeErr),
1065/// })
1066/// }
1067/// }
1068/// ```
1069#[cfg(feature = "derive")]
1070#[proc_macro_derive(DeriveValueType, attributes(sea_orm))]
1071pub fn derive_value_type(input: TokenStream) -> TokenStream {
1072 let derive_input = parse_macro_input!(input as DeriveInput);
1073 match derives::expand_derive_value_type(derive_input) {
1074 Ok(token_stream) => token_stream.into(),
1075 Err(e) => e.to_compile_error().into(),
1076 }
1077}
1078
1079#[cfg(feature = "derive")]
1080#[proc_macro_derive(DeriveDisplay, attributes(sea_orm))]
1081pub fn derive_active_enum_display(input: TokenStream) -> TokenStream {
1082 let input = parse_macro_input!(input as DeriveInput);
1083 match derives::expand_derive_active_enum_display(input) {
1084 Ok(ts) => ts.into(),
1085 Err(e) => e.to_compile_error().into(),
1086 }
1087}
1088
1089/// The DeriveIden derive macro will implement `sea_orm::Iden` for simplify Iden implementation.
1090///
1091/// ## Usage
1092///
1093/// ```rust
1094/// use sea_orm::{DeriveIden, Iden};
1095///
1096/// #[derive(DeriveIden)]
1097/// pub enum MyClass {
1098/// Table, // this is a special case, which maps to the enum's name
1099/// Id,
1100/// #[sea_orm(iden = "turtle")]
1101/// Title,
1102/// Text,
1103/// }
1104///
1105/// #[derive(DeriveIden)]
1106/// struct MyOther;
1107///
1108/// assert_eq!(MyClass::Table.to_string(), "my_class");
1109/// assert_eq!(MyClass::Id.to_string(), "id");
1110/// assert_eq!(MyClass::Title.to_string(), "turtle"); // renamed!
1111/// assert_eq!(MyClass::Text.to_string(), "text");
1112/// assert_eq!(MyOther.to_string(), "my_other");
1113/// ```
1114#[cfg(feature = "derive")]
1115#[proc_macro_derive(DeriveIden, attributes(sea_orm))]
1116pub fn derive_iden(input: TokenStream) -> TokenStream {
1117 let derive_input = parse_macro_input!(input as DeriveInput);
1118
1119 match derives::expand_derive_iden(derive_input) {
1120 Ok(token_stream) => token_stream.into(),
1121 Err(e) => e.to_compile_error().into(),
1122 }
1123}
1124
1125#[proc_macro]
1126pub fn raw_sql(input: TokenStream) -> TokenStream {
1127 match raw_sql::expand(input) {
1128 Ok(token_stream) => token_stream.into(),
1129 Err(e) => e.to_compile_error().into(),
1130 }
1131}
1132
1133#[cfg(feature = "derive")]
1134#[proc_macro_attribute]
1135pub fn sea_orm_model(_attr: TokenStream, input: TokenStream) -> TokenStream {
1136 let input = parse_macro_input!(input as syn::ItemStruct);
1137
1138 match derives::expand_sea_orm_model(input, false) {
1139 Ok(token_stream) => token_stream.into(),
1140 Err(e) => e.to_compile_error().into(),
1141 }
1142}
1143
1144#[cfg(feature = "derive")]
1145#[proc_macro_attribute]
1146pub fn sea_orm_compact_model(_attr: TokenStream, input: TokenStream) -> TokenStream {
1147 let input = parse_macro_input!(input as syn::ItemStruct);
1148
1149 match derives::expand_sea_orm_model(input, true) {
1150 Ok(token_stream) => token_stream.into(),
1151 Err(e) => e.to_compile_error().into(),
1152 }
1153}