diff --git a/cynic-parser/src/values/const_lists.rs b/cynic-parser/src/values/const_lists.rs index 044d2368..40974efb 100644 --- a/cynic-parser/src/values/const_lists.rs +++ b/cynic-parser/src/values/const_lists.rs @@ -5,9 +5,9 @@ use crate::{common::IdRange, AstLookup, Span}; use super::{const_value::ConstValue, iter::Iter, ConstValueId}; #[derive(Clone, Copy)] -pub struct ConstListValue<'a>(pub(super) super::Cursor<'a, ConstValueId>); +pub struct ConstList<'a>(pub(super) super::Cursor<'a, ConstValueId>); -impl<'a> ConstListValue<'a> { +impl<'a> ConstList<'a> { pub fn is_empty(&self) -> bool { self.len() == 0 } @@ -33,7 +33,7 @@ impl<'a> ConstListValue<'a> { } } -impl fmt::Debug for ConstListValue<'_> { +impl fmt::Debug for ConstList<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_list().entries(self.items()).finish() } diff --git a/cynic-parser/src/values/const_value.rs b/cynic-parser/src/values/const_value.rs index 003d0979..06edaf2d 100644 --- a/cynic-parser/src/values/const_value.rs +++ b/cynic-parser/src/values/const_value.rs @@ -1,7 +1,7 @@ use crate::{AstLookup, Span}; use super::{ - const_lists::ConstListValue, + const_lists::ConstList, const_objects::ConstObject, enums::EnumValue, iter::{Iter, ValueStoreReader}, @@ -18,7 +18,7 @@ pub enum ConstValue<'a> { Boolean(BooleanValue<'a>), Null(NullValue<'a>), Enum(EnumValue<'a>), - List(ConstListValue<'a>), + List(ConstList<'a>), Object(ConstObject<'a>), } @@ -99,7 +99,7 @@ impl<'a> ConstValue<'a> { matches!(self, Self::List(_)) } - pub fn as_list(&self) -> Option> { + pub fn as_list(&self) -> Option> { match self { Self::List(inner) => Some(*inner), _ => None, @@ -176,8 +176,56 @@ impl super::ValueStoreId for ConstValueId { ValueKind::Boolean(_) => ConstValue::Boolean(BooleanValue(value_cursor)), ValueKind::Null => ConstValue::Null(NullValue(value_cursor)), ValueKind::Enum(_) => ConstValue::Enum(EnumValue(value_cursor)), - ValueKind::List(_) => ConstValue::List(ConstListValue(cursor)), + ValueKind::List(_) => ConstValue::List(ConstList(cursor)), ValueKind::Object(_) => ConstValue::Object(ConstObject(cursor)), } } } + +impl<'a> TryFrom> for ConstValue<'a> { + type Error = (); + + fn try_from(value: Value<'a>) -> Result { + if !const_safe(value) { + return Err(()); + } + + Ok(match value { + Value::Variable(_) => unreachable!(), + Value::Int(int_value) => ConstValue::Int(int_value), + Value::Float(float_value) => ConstValue::Float(float_value), + Value::String(string_value) => ConstValue::String(string_value), + Value::Boolean(boolean_value) => ConstValue::Boolean(boolean_value), + Value::Null(null_value) => ConstValue::Null(null_value), + Value::Enum(enum_value) => ConstValue::Enum(enum_value), + Value::List(list_value) => { + let id = ConstValueId::new(list_value.0.id.get()); + ConstValue::List(ConstList(Cursor { + id, + store: list_value.0.store, + })) + } + Value::Object(object) => { + let id = ConstValueId::new(object.0.id.get()); + ConstValue::Object(ConstObject(Cursor { + id, + store: object.0.store, + })) + } + }) + } +} + +fn const_safe(value: Value<'_>) -> bool { + match value { + Value::Variable(_) => false, + Value::Int(_) + | Value::Float(_) + | Value::String(_) + | Value::Boolean(_) + | Value::Null(_) + | Value::Enum(_) => true, + Value::List(items) => items.items().any(const_safe), + Value::Object(object) => object.fields().any(|field| const_safe(field.value())), + } +} diff --git a/cynic-parser/src/values/lists.rs b/cynic-parser/src/values/lists.rs index d13becd4..ff3fd0fc 100644 --- a/cynic-parser/src/values/lists.rs +++ b/cynic-parser/src/values/lists.rs @@ -2,12 +2,12 @@ use std::fmt; use crate::{AstLookup, Span}; -use super::{const_lists::ConstListValue, ids::ValueId, iter::Iter, value::Value, Cursor}; +use super::{const_lists::ConstList, ids::ValueId, iter::Iter, value::Value, Cursor}; #[derive(Clone, Copy)] -pub struct ListValue<'a>(pub(super) super::Cursor<'a, ValueId>); +pub struct List<'a>(pub(super) super::Cursor<'a, ValueId>); -impl<'a> ListValue<'a> { +impl<'a> List<'a> { pub fn is_empty(&self) -> bool { self.len() == 0 } @@ -28,24 +28,24 @@ impl<'a> ListValue<'a> { } } -impl PartialEq for ListValue<'_> { +impl PartialEq for List<'_> { fn eq(&self, other: &Self) -> bool { self.len() == other.len() && self.items().zip(other.items()).all(|(lhs, rhs)| lhs == rhs) } } -impl fmt::Debug for ListValue<'_> { +impl fmt::Debug for List<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_list().entries(self.items()).finish() } } -impl<'a> From> for ListValue<'a> { - fn from(value: ConstListValue<'a>) -> Self { +impl<'a> From> for List<'a> { + fn from(value: ConstList<'a>) -> Self { let Cursor { id, store } = value.0; let id = id.into(); - ListValue(Cursor { id, store }) + List(Cursor { id, store }) } } diff --git a/cynic-parser/src/values/mod.rs b/cynic-parser/src/values/mod.rs index fd3b8168..2ed31161 100644 --- a/cynic-parser/src/values/mod.rs +++ b/cynic-parser/src/values/mod.rs @@ -15,11 +15,11 @@ pub mod writer; use std::sync::Arc; pub use self::{ - const_lists::ConstListValue, + const_lists::ConstList, const_objects::{ConstObject, ConstObjectField}, const_value::ConstValue, enums::EnumValue, - lists::ListValue, + lists::List, objects::{Object, ObjectField}, scalars::{BooleanValue, FloatValue, IntValue, NullValue, StringValue}, value::Value, diff --git a/cynic-parser/src/values/value.rs b/cynic-parser/src/values/value.rs index c098f3c4..f8862385 100644 --- a/cynic-parser/src/values/value.rs +++ b/cynic-parser/src/values/value.rs @@ -5,7 +5,7 @@ use super::{ enums::EnumValue, ids::{FieldId, StringId}, iter::{Iter, ValueStoreReader}, - lists::ListValue, + lists::List, objects::Object, scalars::{BooleanValue, FloatValue, IntValue, NullValue, StringValue}, variables::VariableValue, @@ -21,7 +21,7 @@ pub enum Value<'a> { Boolean(BooleanValue<'a>), Null(NullValue<'a>), Enum(EnumValue<'a>), - List(ListValue<'a>), + List(List<'a>), Object(Object<'a>), } @@ -133,7 +133,7 @@ impl<'a> Value<'a> { matches!(self, Value::List(_)) } - pub fn as_list(&self) -> Option> { + pub fn as_list(&self) -> Option> { match self { Self::List(inner) => Some(*inner), _ => None, @@ -201,7 +201,7 @@ impl super::ValueStoreId for ValueId { ValueKind::Boolean(_) => Value::Boolean(BooleanValue(cursor)), ValueKind::Null => Value::Null(NullValue(cursor)), ValueKind::Enum(_) => Value::Enum(EnumValue(cursor)), - ValueKind::List(_) => Value::List(ListValue(cursor)), + ValueKind::List(_) => Value::List(List(cursor)), ValueKind::Object(_) => Value::Object(Object(cursor)), } }