async_graphql/resolver_utils/
enum.rs

1use crate::{InputType, InputValueError, InputValueResult, Name, Value};
2
3/// A variant of an enum.
4pub struct EnumItem<T> {
5    /// The name of the variant.
6    pub name: &'static str,
7    /// The value of the variant.
8    pub value: T,
9}
10
11/// A GraphQL enum.
12pub trait EnumType: Sized + Eq + Send + Copy + Sized + 'static {
13    /// Get a list of possible variants of the enum and their values.
14    fn items() -> &'static [EnumItem<Self>];
15}
16
17/// Parse a value as an enum value.
18///
19/// This can be used to implement `InputType::parse`.
20pub fn parse_enum<T: EnumType + InputType>(value: Value) -> InputValueResult<T> {
21    let value = match &value {
22        Value::Enum(s) => s,
23        Value::String(s) => s.as_str(),
24        _ => return Err(InputValueError::expected_type(value)),
25    };
26
27    T::items()
28        .iter()
29        .find(|item| item.name == value)
30        .map(|item| item.value)
31        .ok_or_else(|| {
32            InputValueError::custom(format_args!(
33                r#"Enumeration type does not contain value "{}"."#,
34                value,
35            ))
36        })
37}
38
39/// Convert the enum value into a GraphQL value.
40///
41/// This can be used to implement `InputType::to_value` or
42/// `OutputType::resolve`.
43pub fn enum_value<T: EnumType>(value: T) -> Value {
44    let item = T::items().iter().find(|item| item.value == value).unwrap();
45    Value::Enum(Name::new(item.name))
46}