cynic_parser/type_system/
types.rsuse crate::{
common::{TypeWrappers, WrappingType},
type_system::ids::TypeId,
AstLookup, Span,
};
use super::{iter::Iter, Definition, ReadContext, StringId, TypeDefinition, TypeSystemId};
pub struct TypeRecord {
pub name: StringId,
pub name_start: usize,
pub wrappers: TypeWrappers,
pub span: Span,
}
#[derive(Clone, Copy)]
pub struct Type<'a>(ReadContext<'a, TypeId>);
impl PartialEq for Type<'_> {
fn eq(&self, other: &Self) -> bool {
self.name() == other.name() && self.wrappers().eq(other.wrappers())
}
}
impl Eq for Type<'_> {}
impl<'a> Type<'a> {
pub fn name(&self) -> &'a str {
self.0
.document
.lookup(self.0.document.lookup(self.0.id).name)
}
pub fn name_span(&self) -> Span {
let record = self.0.document.lookup(self.0.id);
Span::new(
record.name_start,
record.name_start + self.0.document.lookup(record.name).len(),
)
}
pub fn is_list(&self) -> bool {
self.wrappers().any(|wrapper| wrapper == WrappingType::List)
}
pub fn is_non_null(&self) -> bool {
self.wrappers().next() == Some(WrappingType::NonNull)
}
pub fn span(&self) -> Span {
self.0.document.lookup(self.0.id).span
}
pub fn wrappers(&self) -> impl Iterator<Item = WrappingType> + 'a {
self.0.document.lookup(self.0.id).wrappers.iter()
}
pub fn definitions(&self) -> NamedTypeDefinitions<'a> {
let document = self.0.document;
NamedTypeDefinitions {
name: self.name(),
iter: document.definitions(),
}
}
}
impl std::fmt::Display for Type<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let ast = &self.0.document;
let TypeRecord { name, wrappers, .. } = ast.lookup(self.0.id);
let wrappers = wrappers.iter().collect::<Vec<_>>();
for wrapping in &wrappers {
if let WrappingType::List = wrapping {
write!(f, "[")?;
}
}
write!(f, "{}", ast.lookup(*name))?;
for wrapping in wrappers.iter().rev() {
match wrapping {
WrappingType::NonNull => write!(f, "!")?,
WrappingType::List => write!(f, "]")?,
}
}
Ok(())
}
}
impl std::fmt::Debug for Type<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("Type").field(&self.to_string()).finish()
}
}
impl TypeSystemId for TypeId {
type Reader<'a> = Type<'a>;
fn read(self, document: &super::TypeSystemDocument) -> Self::Reader<'_> {
Type(ReadContext { id: self, document })
}
}
impl<'a> From<ReadContext<'a, TypeId>> for Type<'a> {
fn from(value: ReadContext<'a, TypeId>) -> Self {
Self(value)
}
}
#[derive(Clone)]
pub struct NamedTypeDefinitions<'a> {
name: &'a str,
iter: Iter<'a, Definition<'a>>,
}
pub enum NamedTypeDefinition<'a> {
Definition(TypeDefinition<'a>),
Extension(TypeDefinition<'a>),
}
impl<'a> Iterator for NamedTypeDefinitions<'a> {
type Item = NamedTypeDefinition<'a>;
fn next(&mut self) -> Option<Self::Item> {
loop {
match self.iter.next()? {
Definition::Type(type_definition) if type_definition.name() == self.name => {
return Some(NamedTypeDefinition::Definition(type_definition))
}
Definition::TypeExtension(type_definition)
if type_definition.name() == self.name =>
{
return Some(NamedTypeDefinition::Extension(type_definition))
}
_ => continue,
}
}
}
}