sea_orm_macros/lib.rs
1extern crate proc_macro;
2
3use proc_macro::TokenStream;
4
5use syn::{parse_macro_input, DeriveInput, Error};
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) -> &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) -> &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/// Derive a column if column names are not in snake-case
262///
263/// ### Usage
264///
265/// ```
266/// use sea_orm::entity::prelude::*;
267///
268/// #[derive(Copy, Clone, Debug, EnumIter, DeriveCustomColumn)]
269/// pub enum Column {
270/// Id,
271/// Name,
272/// VendorId,
273/// }
274///
275/// impl IdenStatic for Column {
276/// fn as_str(&self) -> &str {
277/// match self {
278/// Self::Id => "id",
279/// _ => self.default_as_str(),
280/// }
281/// }
282/// }
283/// ```
284#[cfg(feature = "derive")]
285#[proc_macro_derive(DeriveCustomColumn)]
286pub fn derive_custom_column(input: TokenStream) -> TokenStream {
287 let DeriveInput { ident, data, .. } = parse_macro_input!(input);
288
289 match derives::expand_derive_custom_column(&ident, &data) {
290 Ok(ts) => ts.into(),
291 Err(e) => e.to_compile_error().into(),
292 }
293}
294
295/// The DeriveModel derive macro will implement ModelTrait for Model,
296/// which provides setters and getters for all attributes in the mod
297/// It also implements FromQueryResult to convert a query result into the corresponding Model.
298///
299/// ### Usage
300///
301/// ```
302/// use sea_orm::entity::prelude::*;
303///
304/// #[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel)]
305/// pub struct Model {
306/// pub id: i32,
307/// pub name: String,
308/// }
309///
310/// # #[derive(Copy, Clone, Default, Debug, DeriveEntity)]
311/// # pub struct Entity;
312/// #
313/// # impl EntityName for Entity {
314/// # fn table_name(&self) -> &str {
315/// # "cake"
316/// # }
317/// # }
318/// #
319/// # #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
320/// # pub enum Column {
321/// # Id,
322/// # Name,
323/// # }
324/// #
325/// # #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]
326/// # pub enum PrimaryKey {
327/// # Id,
328/// # }
329/// #
330/// # impl PrimaryKeyTrait for PrimaryKey {
331/// # type ValueType = i32;
332/// #
333/// # fn auto_increment() -> bool {
334/// # true
335/// # }
336/// # }
337/// #
338/// # #[derive(Copy, Clone, Debug, EnumIter)]
339/// # pub enum Relation {}
340/// #
341/// # impl ColumnTrait for Column {
342/// # type EntityName = Entity;
343/// #
344/// # fn def(&self) -> ColumnDef {
345/// # match self {
346/// # Self::Id => ColumnType::Integer.def(),
347/// # Self::Name => ColumnType::String(StringLen::None).def(),
348/// # }
349/// # }
350/// # }
351/// #
352/// # impl RelationTrait for Relation {
353/// # fn def(&self) -> RelationDef {
354/// # panic!("No Relation");
355/// # }
356/// # }
357/// #
358/// # impl ActiveModelBehavior for ActiveModel {}
359/// ```
360#[cfg(feature = "derive")]
361#[proc_macro_derive(DeriveModel, attributes(sea_orm))]
362pub fn derive_model(input: TokenStream) -> TokenStream {
363 let input = parse_macro_input!(input as DeriveInput);
364 derives::expand_derive_model(input)
365 .unwrap_or_else(Error::into_compile_error)
366 .into()
367}
368
369/// The DeriveActiveModel derive macro will implement ActiveModelTrait for ActiveModel
370/// which provides setters and getters for all active values in the active model.
371///
372/// ### Usage
373///
374/// ```
375/// use sea_orm::entity::prelude::*;
376///
377/// #[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel)]
378/// pub struct Model {
379/// pub id: i32,
380/// pub name: String,
381/// }
382///
383/// # #[derive(Copy, Clone, Default, Debug, DeriveEntity)]
384/// # pub struct Entity;
385/// #
386/// # impl EntityName for Entity {
387/// # fn table_name(&self) -> &str {
388/// # "cake"
389/// # }
390/// # }
391/// #
392/// # #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
393/// # pub enum Column {
394/// # Id,
395/// # Name,
396/// # }
397/// #
398/// # #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]
399/// # pub enum PrimaryKey {
400/// # Id,
401/// # }
402/// #
403/// # impl PrimaryKeyTrait for PrimaryKey {
404/// # type ValueType = i32;
405/// #
406/// # fn auto_increment() -> bool {
407/// # true
408/// # }
409/// # }
410/// #
411/// # #[derive(Copy, Clone, Debug, EnumIter)]
412/// # pub enum Relation {}
413/// #
414/// # impl ColumnTrait for Column {
415/// # type EntityName = Entity;
416/// #
417/// # fn def(&self) -> ColumnDef {
418/// # match self {
419/// # Self::Id => ColumnType::Integer.def(),
420/// # Self::Name => ColumnType::String(StringLen::None).def(),
421/// # }
422/// # }
423/// # }
424/// #
425/// # impl RelationTrait for Relation {
426/// # fn def(&self) -> RelationDef {
427/// # panic!("No Relation");
428/// # }
429/// # }
430/// #
431/// # impl ActiveModelBehavior for ActiveModel {}
432/// ```
433#[cfg(feature = "derive")]
434#[proc_macro_derive(DeriveActiveModel, attributes(sea_orm))]
435pub fn derive_active_model(input: TokenStream) -> TokenStream {
436 let DeriveInput { ident, data, .. } = parse_macro_input!(input);
437
438 match derives::expand_derive_active_model(ident, data) {
439 Ok(ts) => ts.into(),
440 Err(e) => e.to_compile_error().into(),
441 }
442}
443
444/// Derive into an active model
445#[cfg(feature = "derive")]
446#[proc_macro_derive(DeriveIntoActiveModel, attributes(sea_orm))]
447pub fn derive_into_active_model(input: TokenStream) -> TokenStream {
448 let input = parse_macro_input!(input as DeriveInput);
449 derives::expand_into_active_model(input)
450 .unwrap_or_else(Error::into_compile_error)
451 .into()
452}
453
454/// Models that a user can override
455///
456/// ### Usage
457///
458/// ```
459/// use sea_orm::entity::prelude::*;
460///
461/// #[derive(
462/// Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, DeriveActiveModelBehavior,
463/// )]
464/// pub struct Model {
465/// pub id: i32,
466/// pub name: String,
467/// }
468///
469/// # #[derive(Copy, Clone, Default, Debug, DeriveEntity)]
470/// # pub struct Entity;
471/// #
472/// # impl EntityName for Entity {
473/// # fn table_name(&self) -> &str {
474/// # "cake"
475/// # }
476/// # }
477/// #
478/// # #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
479/// # pub enum Column {
480/// # Id,
481/// # Name,
482/// # }
483/// #
484/// # #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]
485/// # pub enum PrimaryKey {
486/// # Id,
487/// # }
488/// #
489/// # impl PrimaryKeyTrait for PrimaryKey {
490/// # type ValueType = i32;
491/// #
492/// # fn auto_increment() -> bool {
493/// # true
494/// # }
495/// # }
496/// #
497/// # #[derive(Copy, Clone, Debug, EnumIter)]
498/// # pub enum Relation {}
499/// #
500/// # impl ColumnTrait for Column {
501/// # type EntityName = Entity;
502/// #
503/// # fn def(&self) -> ColumnDef {
504/// # match self {
505/// # Self::Id => ColumnType::Integer.def(),
506/// # Self::Name => ColumnType::String(StringLen::None).def(),
507/// # }
508/// # }
509/// # }
510/// #
511/// # impl RelationTrait for Relation {
512/// # fn def(&self) -> RelationDef {
513/// # panic!("No Relation");
514/// # }
515/// # }
516/// ```
517#[cfg(feature = "derive")]
518#[proc_macro_derive(DeriveActiveModelBehavior)]
519pub fn derive_active_model_behavior(input: TokenStream) -> TokenStream {
520 let DeriveInput { ident, data, .. } = parse_macro_input!(input);
521
522 match derives::expand_derive_active_model_behavior(ident, data) {
523 Ok(ts) => ts.into(),
524 Err(e) => e.to_compile_error().into(),
525 }
526}
527
528/// A derive macro to implement `sea_orm::ActiveEnum` trait for enums.
529///
530/// # Limitations
531///
532/// This derive macros can only be used on enums.
533///
534/// # Macro Attributes
535///
536/// All macro attributes listed below have to be annotated in the form of `#[sea_orm(attr = value)]`.
537///
538/// - For enum
539/// - `rs_type`: Define `ActiveEnum::Value`
540/// - Possible values: `String`, `i8`, `i16`, `i32`, `i64`, `u8`, `u16`, `u32`, `u64`
541/// - Note that value has to be passed as string, i.e. `rs_type = "i8"`
542/// - `db_type`: Define `ColumnType` returned by `ActiveEnum::db_type()`
543/// - Possible values: all available enum variants of `ColumnType`, e.g. `String(StringLen::None)`, `String(StringLen::N(1))`, `Integer`
544/// - Note that value has to be passed as string, i.e. `db_type = "Integer"`
545/// - `enum_name`: Define `String` returned by `ActiveEnum::name()`
546/// - This attribute is optional with default value being the name of enum in camel-case
547/// - Note that value has to be passed as string, i.e. `enum_name = "MyEnum"`
548///
549/// - For enum variant
550/// - `string_value` or `num_value`:
551/// - For `string_value`, value should be passed as string, i.e. `string_value = "A"`
552/// - Due to the way internal Enums are automatically derived, the following restrictions apply:
553/// - members cannot share identical `string_value`, case-insensitive.
554/// - in principle, any future Titlecased Rust keywords are not valid `string_value`.
555/// - For `num_value`, value should be passed as integer, i.e. `num_value = 1` or `num_value = 1i32`
556/// - Note that only one of it can be specified, and all variants of an enum have to annotate with the same `*_value` macro attribute
557///
558/// # Usage
559///
560/// ```
561/// use sea_orm::{entity::prelude::*, DeriveActiveEnum};
562///
563/// #[derive(EnumIter, DeriveActiveEnum)]
564/// #[sea_orm(rs_type = "i32", db_type = "Integer")]
565/// pub enum Color {
566/// Black = 0,
567/// White = 1,
568/// }
569/// ```
570#[cfg(feature = "derive")]
571#[proc_macro_derive(DeriveActiveEnum, attributes(sea_orm))]
572pub fn derive_active_enum(input: TokenStream) -> TokenStream {
573 let input = parse_macro_input!(input as DeriveInput);
574 match derives::expand_derive_active_enum(input) {
575 Ok(ts) => ts.into(),
576 Err(e) => e.to_compile_error().into(),
577 }
578}
579
580/// Convert a query result into the corresponding Model.
581///
582/// ### Attributes
583/// - `skip`: Will not try to pull this field from the query result. And set it to the default value of the type.
584///
585/// ### Usage
586///
587/// ```
588/// use sea_orm::{entity::prelude::*, FromQueryResult};
589///
590/// #[derive(Debug, FromQueryResult)]
591/// struct SelectResult {
592/// name: String,
593/// num_of_fruits: i32,
594/// #[sea_orm(skip)]
595/// skip_me: i32,
596/// }
597/// ```
598#[cfg(feature = "derive")]
599#[proc_macro_derive(FromQueryResult, attributes(sea_orm))]
600pub fn derive_from_query_result(input: TokenStream) -> TokenStream {
601 let derive_input = parse_macro_input!(input);
602
603 match derives::expand_derive_from_query_result(derive_input) {
604 Ok(token_stream) => token_stream.into(),
605 Err(e) => e.to_compile_error().into(),
606 }
607}
608
609/// The DeriveRelation derive macro will implement RelationTrait for Relation.
610///
611/// ### Usage
612///
613/// ```
614/// # use sea_orm::tests_cfg::fruit::Entity;
615/// use sea_orm::entity::prelude::*;
616///
617/// #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
618/// pub enum Relation {
619/// #[sea_orm(
620/// belongs_to = "sea_orm::tests_cfg::cake::Entity",
621/// from = "sea_orm::tests_cfg::fruit::Column::CakeId",
622/// to = "sea_orm::tests_cfg::cake::Column::Id"
623/// )]
624/// Cake,
625/// #[sea_orm(
626/// belongs_to = "sea_orm::tests_cfg::cake_expanded::Entity",
627/// from = "sea_orm::tests_cfg::fruit::Column::CakeId",
628/// to = "sea_orm::tests_cfg::cake_expanded::Column::Id"
629/// )]
630/// CakeExpanded,
631/// }
632/// ```
633#[cfg(feature = "derive")]
634#[proc_macro_derive(DeriveRelation, attributes(sea_orm))]
635pub fn derive_relation(input: TokenStream) -> TokenStream {
636 let input = parse_macro_input!(input as DeriveInput);
637 derives::expand_derive_relation(input)
638 .unwrap_or_else(Error::into_compile_error)
639 .into()
640}
641
642/// The DeriveRelatedEntity derive macro will implement seaography::RelationBuilder for RelatedEntity enumeration.
643///
644/// ### Usage
645///
646/// ```ignore
647/// use sea_orm::entity::prelude::*;
648///
649/// // ...
650/// // Model, Relation enum, etc.
651/// // ...
652///
653/// #[derive(Copy, Clone, Debug, EnumIter, DeriveRelatedEntity)]
654/// pub enum RelatedEntity {
655/// #[sea_orm(entity = "super::address::Entity")]
656/// Address,
657/// #[sea_orm(entity = "super::payment::Entity")]
658/// Payment,
659/// #[sea_orm(entity = "super::rental::Entity")]
660/// Rental,
661/// #[sea_orm(entity = "Entity", def = "Relation::SelfRef.def()")]
662/// SelfRef,
663/// #[sea_orm(entity = "super::store::Entity")]
664/// Store,
665/// #[sea_orm(entity = "Entity", def = "Relation::SelfRef.def().rev()")]
666/// SelfRefRev,
667/// }
668/// ```
669#[cfg(feature = "derive")]
670#[proc_macro_derive(DeriveRelatedEntity, attributes(sea_orm))]
671pub fn derive_related_entity(input: TokenStream) -> TokenStream {
672 let input = parse_macro_input!(input as DeriveInput);
673 derives::expand_derive_related_entity(input)
674 .unwrap_or_else(Error::into_compile_error)
675 .into()
676}
677
678/// The DeriveMigrationName derive macro will implement `sea_orm_migration::MigrationName` for a migration.
679///
680/// ### Usage
681///
682/// ```ignore
683/// #[derive(DeriveMigrationName)]
684/// pub struct Migration;
685/// ```
686///
687/// The derive macro above will provide following implementation,
688/// given the file name is `m20220120_000001_create_post_table.rs`.
689///
690/// ```ignore
691/// impl MigrationName for Migration {
692/// fn name(&self) -> &str {
693/// "m20220120_000001_create_post_table"
694/// }
695/// }
696/// ```
697#[cfg(feature = "derive")]
698#[proc_macro_derive(DeriveMigrationName)]
699pub fn derive_migration_name(input: TokenStream) -> TokenStream {
700 let input = parse_macro_input!(input as DeriveInput);
701 derives::expand_derive_migration_name(input)
702 .unwrap_or_else(Error::into_compile_error)
703 .into()
704}
705
706#[cfg(feature = "derive")]
707#[proc_macro_derive(FromJsonQueryResult)]
708pub fn derive_from_json_query_result(input: TokenStream) -> TokenStream {
709 let DeriveInput { ident, .. } = parse_macro_input!(input);
710
711 match derives::expand_derive_from_json_query_result(ident) {
712 Ok(ts) => ts.into(),
713 Err(e) => e.to_compile_error().into(),
714 }
715}
716
717/// The DerivePartialModel derive macro will implement `sea_orm::PartialModelTrait` for simplify partial model queries.
718///
719/// ## Usage
720///
721/// ```rust
722/// use sea_orm::{entity::prelude::*, sea_query::Expr, DerivePartialModel, FromQueryResult};
723/// use serde::{Deserialize, Serialize};
724///
725/// #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Deserialize, Serialize)]
726/// #[sea_orm(table_name = "posts")]
727/// pub struct Model {
728/// #[sea_orm(primary_key)]
729/// pub id: i32,
730/// pub title: String,
731/// #[sea_orm(column_type = "Text")]
732/// pub text: String,
733/// }
734/// # #[derive(Copy, Clone, Debug, EnumIter)]
735/// # pub enum Relation {}
736/// #
737/// # impl RelationTrait for Relation {
738/// # fn def(&self) -> RelationDef {
739/// # panic!("No Relation");
740/// # }
741/// # }
742/// #
743/// # impl ActiveModelBehavior for ActiveModel {}
744///
745/// #[derive(Debug, FromQueryResult, DerivePartialModel)]
746/// #[sea_orm(entity = "Entity")]
747/// struct SelectResult {
748/// title: String,
749/// #[sea_orm(from_col = "text")]
750/// content: String,
751/// #[sea_orm(from_expr = "Expr::val(1).add(1)")]
752/// sum: i32,
753/// }
754/// ```
755///
756/// If all fields in the partial model is `from_expr`, the specifying the `entity` can be skipped.
757/// ```
758/// use sea_orm::{entity::prelude::*, sea_query::Expr, DerivePartialModel, FromQueryResult};
759///
760/// #[derive(Debug, FromQueryResult, DerivePartialModel)]
761/// struct SelectResult {
762/// #[sea_orm(from_expr = "Expr::val(1).add(1)")]
763/// sum: i32,
764/// }
765/// ```
766///
767/// It is possible to nest structs deriving `FromQueryResult` and `DerivePartialModel`, including
768/// optionally, which is useful for specifying columns from tables added via left joins, as well as
769/// when building up complicated queries programmatically.
770/// ```
771/// use sea_orm::{entity::prelude::*, sea_query::Expr, DerivePartialModel, FromQueryResult};
772///
773/// #[derive(Debug, FromQueryResult, DerivePartialModel)]
774/// struct Inner {
775/// #[sea_orm(from_expr = "Expr::val(1).add(1)")]
776/// sum: i32,
777/// }
778///
779/// #[derive(Debug, FromQueryResult, DerivePartialModel)]
780/// struct Outer {
781/// #[sea_orm(nested)]
782/// inner: Inner,
783/// #[sea_orm(nested)]
784/// inner_opt: Option<Inner>,
785/// }
786/// ```
787///
788/// A field cannot have attributes `from_col`, `from_expr` or `nested` at the same time.
789/// Or, it will result in a compile error.
790///
791/// ```compile_fail
792/// use sea_orm::{entity::prelude::*, FromQueryResult, DerivePartialModel, sea_query::Expr};
793///
794/// #[derive(Debug, FromQueryResult, DerivePartialModel)]
795/// #[sea_orm(entity = "Entity")]
796/// struct SelectResult {
797/// #[sea_orm(from_expr = "Expr::val(1).add(1)", from_col = "foo")]
798/// sum: i32
799/// }
800/// ```
801#[cfg(feature = "derive")]
802#[proc_macro_derive(DerivePartialModel, attributes(sea_orm))]
803pub fn derive_partial_model(input: TokenStream) -> TokenStream {
804 let derive_input = parse_macro_input!(input);
805
806 match derives::expand_derive_partial_model(derive_input) {
807 Ok(token_stream) => token_stream.into(),
808 Err(e) => e.to_compile_error().into(),
809 }
810}
811
812#[doc(hidden)]
813#[cfg(feature = "derive")]
814#[proc_macro_attribute]
815pub fn test(_: TokenStream, input: TokenStream) -> TokenStream {
816 let input = parse_macro_input!(input as syn::ItemFn);
817
818 let ret = &input.sig.output;
819 let name = &input.sig.ident;
820 let body = &input.block;
821 let attrs = &input.attrs;
822
823 quote::quote! (
824 #[test]
825 #[cfg(any(
826 feature = "sqlx-mysql",
827 feature = "sqlx-sqlite",
828 feature = "sqlx-postgres",
829 ))]
830 #(#attrs)*
831 fn #name() #ret {
832 let _ = ::tracing_subscriber::fmt()
833 .with_max_level(::tracing::Level::DEBUG)
834 .with_test_writer()
835 .try_init();
836 crate::block_on!(async { #body })
837 }
838 )
839 .into()
840}
841
842/// Creates a new type that iterates of the variants of an enum.
843///
844/// Iterate over the variants of an Enum. Any additional data on your variants will be set to `Default::default()`.
845/// The macro implements `strum::IntoEnumIterator` on your enum and creates a new type called `YourEnumIter` that is the iterator object.
846/// You cannot derive `EnumIter` on any type with a lifetime bound (`<'a>`) because the iterator would surely
847/// create [unbounded lifetimes](https://doc.rust-lang.org/nightly/nomicon/unbounded-lifetimes.html).
848#[cfg(feature = "strum")]
849#[proc_macro_derive(EnumIter, attributes(strum))]
850pub fn enum_iter(input: TokenStream) -> TokenStream {
851 let ast = parse_macro_input!(input as DeriveInput);
852
853 strum::enum_iter::enum_iter_inner(&ast)
854 .unwrap_or_else(Error::into_compile_error)
855 .into()
856}
857
858/// Implements traits for types that wrap a database value type.
859///
860/// This procedure macro implements `From<T> for Value`, `sea_orm::TryGetTable`, and
861/// `sea_query::ValueType` for the wrapper type `T`.
862///
863/// ## Usage
864///
865/// ```rust
866/// use sea_orm::DeriveValueType;
867///
868/// #[derive(DeriveValueType)]
869/// struct MyString(String);
870/// ```
871#[cfg(feature = "derive")]
872#[proc_macro_derive(DeriveValueType, attributes(sea_orm))]
873pub fn derive_value_type(input: TokenStream) -> TokenStream {
874 let derive_input = parse_macro_input!(input as DeriveInput);
875 match derives::expand_derive_value_type(derive_input) {
876 Ok(token_stream) => token_stream.into(),
877 Err(e) => e.to_compile_error().into(),
878 }
879}
880
881#[cfg(feature = "derive")]
882#[proc_macro_derive(DeriveDisplay, attributes(sea_orm))]
883pub fn derive_active_enum_display(input: TokenStream) -> TokenStream {
884 let input = parse_macro_input!(input as DeriveInput);
885 match derives::expand_derive_active_enum_display(input) {
886 Ok(ts) => ts.into(),
887 Err(e) => e.to_compile_error().into(),
888 }
889}
890
891/// The DeriveIden derive macro will implement `sea_orm::sea_query::Iden` for simplify Iden implementation.
892///
893/// ## Usage
894///
895/// ```rust
896/// use sea_orm::{DeriveIden, Iden};
897///
898/// #[derive(DeriveIden)]
899/// pub enum MyClass {
900/// Table, // this is a special case, which maps to the enum's name
901/// Id,
902/// #[sea_orm(iden = "turtle")]
903/// Title,
904/// Text,
905/// }
906///
907/// #[derive(DeriveIden)]
908/// struct MyOther;
909///
910/// assert_eq!(MyClass::Table.to_string(), "my_class");
911/// assert_eq!(MyClass::Id.to_string(), "id");
912/// assert_eq!(MyClass::Title.to_string(), "turtle"); // renamed!
913/// assert_eq!(MyClass::Text.to_string(), "text");
914/// assert_eq!(MyOther.to_string(), "my_other");
915/// ```
916#[cfg(feature = "derive")]
917#[proc_macro_derive(DeriveIden, attributes(sea_orm))]
918pub fn derive_iden(input: TokenStream) -> TokenStream {
919 let derive_input = parse_macro_input!(input as DeriveInput);
920
921 match derives::expand_derive_iden(derive_input) {
922 Ok(token_stream) => token_stream.into(),
923 Err(e) => e.to_compile_error().into(),
924 }
925}