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