use crate::sql::order_direction::Direction;
#[derive(Debug, Clone)]
pub enum GraphqlOrderDirection {
Single(Direction),
Multiple(Vec<Direction>),
}
impl Default for GraphqlOrderDirection {
fn default() -> Self {
Self::new()
}
}
impl GraphqlOrderDirection {
pub const fn new() -> Self {
Self::asc()
}
pub const fn desc() -> Self {
Self::Single(Direction::Desc)
}
pub const fn asc() -> Self {
Self::Single(Direction::Asc)
}
pub fn first_direction(&self) -> Direction {
match self {
Self::Single(d) => *d,
Self::Multiple(v) => v.first().copied().unwrap_or_else(Direction::default),
}
}
}
impl async_graphql::InputType for GraphqlOrderDirection {
type RawValueType = Self;
fn type_name() -> std::borrow::Cow<'static, str> {
"OrderDirection".into()
}
fn create_type_info(registry: &mut async_graphql::registry::Registry) -> String {
registry.create_input_type::<Self, _>(async_graphql::registry::MetaTypeId::Enum, |_| {
async_graphql::registry::MetaType::Enum {
name: Self::type_name().to_string(),
description: Some("Defines the order direction, either ascending or descending".into()),
enum_values: {
let mut map = async_graphql::indexmap::IndexMap::new();
map.insert("asc".to_string(), async_graphql::registry::MetaEnumValue {
name: "asc".into(),
description: Some("asc for ascending".into()),
deprecation: async_graphql::registry::Deprecation::NoDeprecated,
visible: None,
inaccessible: false,
tags: vec![],
directive_invocations: vec![],
});
map.insert("desc".to_string(), async_graphql::registry::MetaEnumValue {
name: "desc".into(),
description: Some("desc for descending".into()),
deprecation: async_graphql::registry::Deprecation::NoDeprecated,
visible: None,
inaccessible: false,
tags: vec![],
directive_invocations: vec![],
});
map
},
visible: None,
rust_typename: Some(std::any::type_name::<Self>()),
inaccessible: false,
tags: vec![],
directive_invocations: vec![],
}
})
}
fn parse(value: Option<async_graphql::Value>) -> async_graphql::InputValueResult<Self> {
match value {
Some(val) => match val {
async_graphql::Value::String(d) => d
.parse::<Direction>()
.map(Self::Single)
.map_err(async_graphql::InputValueError::custom),
async_graphql::Value::Enum(d) => d
.parse::<Direction>()
.map(Self::Single)
.map_err(async_graphql::InputValueError::custom),
async_graphql::Value::List(directions) => {
let mut set = async_graphql::indexmap::IndexSet::with_capacity(directions.len());
for d in directions {
set.insert(
Direction::parse(Some(d)).map_err(async_graphql::InputValueError::propagate)?,
);
}
let mut v = set.into_iter().collect::<Vec<_>>();
if v.len() == 1 {
return Ok(Self::Single(v.pop().unwrap()));
}
Ok(Self::Multiple(v))
}
x => async_graphql::Result::Err(async_graphql::InputValueError::expected_type(x)),
},
None => async_graphql::Result::Err(async_graphql::InputValueError::expected_type(
value.unwrap_or_default(),
)),
}
}
fn to_value(&self) -> async_graphql::Value {
match self {
GraphqlOrderDirection::Single(direction) => {
async_graphql::Value::Enum(async_graphql::Name::new(direction))
}
GraphqlOrderDirection::Multiple(directions) => async_graphql::Value::List(
directions
.iter()
.map(|d| async_graphql::Value::Enum(async_graphql::Name::new(d)))
.collect(),
),
}
}
fn as_raw_value(&self) -> Option<&Self::RawValueType> {
Some(self)
}
}
impl async_graphql::InputObjectType for GraphqlOrderDirection {}
#[test]
fn test_order_direction() {
use async_graphql::{InputType, value};
let asc = Direction::parse(Some(value!("asc"))).unwrap();
assert_eq!(asc, Direction::Asc);
let desc = Direction::parse(Some(value!("desc"))).unwrap();
assert_eq!(desc, Direction::Desc);
}