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