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