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