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