seaography/inputs/
order_input.rs

1use async_graphql::dynamic::{InputObject, InputValue, TypeRef, ValueAccessor};
2use sea_orm::{EntityTrait, Iterable};
3
4use crate::{BuilderContext, EntityObjectBuilder};
5
6/// The configuration structure for OrderInputBuilder
7pub struct OrderInputConfig {
8    /// used to format OrderInput object name
9    pub type_name: crate::SimpleNamingFn,
10}
11
12impl std::default::Default for OrderInputConfig {
13    fn default() -> Self {
14        OrderInputConfig {
15            type_name: Box::new(|object_name: &str| -> String {
16                format!("{object_name}OrderInput")
17            }),
18        }
19    }
20}
21
22/// This builder produces the OrderInput object of a SeaORM entity
23pub struct OrderInputBuilder {
24    pub context: &'static BuilderContext,
25}
26
27impl OrderInputBuilder {
28    /// used to get type name
29    pub fn type_name(&self, object_name: &str) -> String {
30        self.context.order_input.type_name.as_ref()(object_name)
31    }
32
33    /// used to get the OrderInput object of a SeaORM entity
34    pub fn to_object<T>(&self) -> InputObject
35    where
36        T: EntityTrait,
37        <T as EntityTrait>::Model: Sync,
38    {
39        let entity_object_builder = EntityObjectBuilder {
40            context: self.context,
41        };
42
43        let object_name = entity_object_builder.type_name::<T>();
44        let name = self.type_name(&object_name);
45
46        T::Column::iter().fold(InputObject::new(name), |object, column| {
47            object.field(InputValue::new(
48                entity_object_builder.column_name::<T>(&column),
49                TypeRef::named(&self.context.order_by_enum.type_name),
50            ))
51        })
52    }
53
54    pub fn parse_object<T>(
55        &self,
56        value: Option<ValueAccessor<'_>>,
57    ) -> Vec<(T::Column, sea_orm::sea_query::Order)>
58    where
59        T: EntityTrait,
60        <T as EntityTrait>::Model: Sync,
61    {
62        match value {
63            Some(value) => {
64                let mut data = Vec::new();
65
66                let order_by = value.object().unwrap();
67
68                let entity_object = EntityObjectBuilder {
69                    context: self.context,
70                };
71
72                for col in T::Column::iter() {
73                    let column_name = entity_object.column_name::<T>(&col);
74                    let order = order_by.get(&column_name);
75
76                    if let Some(order) = order {
77                        let order = order.enum_name().unwrap();
78
79                        let asc_variant = &self.context.order_by_enum.asc_variant;
80                        let desc_variant = &self.context.order_by_enum.desc_variant;
81
82                        if order.eq(asc_variant) {
83                            data.push((col, sea_orm::Order::Asc));
84                        } else if order.eq(desc_variant) {
85                            data.push((col, sea_orm::Order::Desc));
86                        } else {
87                            panic!("Cannot map enumeration")
88                        }
89                    }
90                }
91
92                data
93            }
94            None => Vec::new(),
95        }
96    }
97}