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}