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