1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
use std::fmt;
/// The Value type represents available values you could give as an input.
///
/// *Value*:
/// Variable | IntValue | FloatValue | StringValue | BooleanValue |
/// NullValue | EnumValue | ListValue | ObjectValue
///
/// Detailed documentation can be found in [GraphQL spec](https://spec.graphql.org/October2021/#Value).
#[derive(Debug, PartialEq, Clone)]
pub enum Value {
/// Name of a variable example: `varName`
Variable(String),
/// Int value example: `7`
Int(i32),
/// Float value example: `25.4`
Float(f64),
/// String value example: `"My string"`
String(String),
/// Boolean value example: `false`
Boolean(bool),
/// Null value example: `null`
Null,
/// Enum value example: `"VARIANT_EXAMPLE"`
Enum(String),
/// List value example: `[1, 2, 3]`
List(Vec<Value>),
/// Object value example: `{ first: 1, second: 2 }`
Object(Vec<(String, Value)>),
}
impl fmt::Display for Value {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Variable(v) => write!(f, "${v}"),
Self::Int(i) => write!(f, "{i}"),
Self::Float(fl) => write!(f, "{fl}"),
Self::String(s) => {
if s.contains('"') | s.contains('\n') | s.contains('\r') {
write!(f, r#""""{s}""""#)
} else {
write!(f, r#""{s}""#)
}
}
Self::Boolean(b) => write!(f, "{b}"),
Self::Null => write!(f, "null"),
Self::Enum(val) => write!(f, "{val}"),
Self::List(list) => write!(
f,
"[{}]",
list.iter()
.map(|elt| format!("{elt}"))
.collect::<Vec<String>>()
.join(", ")
),
Self::Object(obj) => write!(
f,
"{{ {} }}",
obj.iter()
.map(|(k, v)| format!("{}: {v}", String::from(k)))
.collect::<Vec<String>>()
.join(", ")
),
}
}
}
macro_rules! to_number_value {
($ty: path, $inner_type: path, $value_variant: ident) => {
impl From<$ty> for Value {
fn from(val: $ty) -> Self {
Self::$value_variant(val as $inner_type)
}
}
};
($({$ty: path, $inner_type: path, $value_variant: ident}),+) => {
$(
to_number_value!($ty, $inner_type, $value_variant);
)+
};
}
// Numbers
to_number_value!(
{i64, i32, Int},
{i32, i32, Int},
{i16, i32, Int},
{i8, i32, Int},
{isize, i32, Int},
{u64, i32, Int},
{u32, i32, Int},
{u16, i32, Int},
{u8, i32, Int},
{usize, i32, Int},
{f64, f64, Float},
{f32, f64, Float}
);
impl From<String> for Value {
fn from(val: String) -> Self {
Self::String(val)
}
}
impl From<&str> for Value {
fn from(val: &str) -> Self {
Self::String(val.to_string())
}
}
impl From<bool> for Value {
fn from(val: bool) -> Self {
Self::Boolean(val)
}
}