iowo/src/namespace/typedef.rs

123 lines
4 KiB
Rust

use std::fmt::Debug;
use std::fmt::Display;
use super::TypeNamespaceId;
use super::GlobalNamespace;
use super::r#trait::Trait;
use super::r#type::Type;
pub enum TypeDef<'a> {
Type(Type<'a>),
Trait(Trait<'a>),
List(Vec<TypeDef<'a>>),
Record(Vec<(String, TypeDef<'a>)>),
}
impl<'a> TypeDef<'a> {
pub(super) fn from_internal(ns: &'a GlobalNamespace, def: &InternalTypeDef) -> TypeDef<'a> {
match def {
InternalTypeDef::Single(id) => match id {
// safe to unwrap because this is only used with internal representations
TypeNamespaceId::Types(id) => TypeDef::Type(
ns.get_type(*id)
.expect("Incorrect internal type id. This is a bug."),
),
TypeNamespaceId::Traits(id) => TypeDef::Trait(
ns.get_trait(*id)
.expect("Incorrect internal trait id. This is a bug."),
),
},
InternalTypeDef::List(list) => TypeDef::List(
list.iter()
.map(|def| Self::from_internal(ns, def))
.collect(),
),
InternalTypeDef::Record(rec) => TypeDef::Record(
rec.iter()
.map(|(name, def)| (name.clone(), Self::from_internal(ns, def)))
.collect(),
),
}
}
}
impl Display for TypeDef<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
TypeDef::Type(t) => Display::fmt(&t, f),
TypeDef::Trait(t) => Display::fmt(&t, f),
TypeDef::List(l) => {
f.write_str("[ ")?;
for (i, item) in l.iter().enumerate() {
if i != 0 {
f.write_str(", ")?;
}
Display::fmt(&item, f)?;
}
f.write_str(" ]")
}
TypeDef::Record(rec) => {
f.write_str("{ ")?;
for (i, item) in rec.iter().enumerate() {
if i != 0 {
f.write_str(", ")?;
}
f.write_fmt(format_args!("{}: {}", item.0, item.1))?;
}
f.write_str(" }")
}
}
}
}
impl Debug for TypeDef<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
TypeDef::Type(t) => Debug::fmt(&t, f),
TypeDef::Trait(t) => Debug::fmt(&t, f),
TypeDef::List(l) => {
f.write_str("[ ")?;
for (i, item) in l.iter().enumerate() {
if i != 0 {
f.write_str(", ")?;
}
Debug::fmt(&item, f)?;
}
f.write_str(" ]")
}
TypeDef::Record(rec) => {
f.write_str("{ ")?;
for (i, item) in rec.iter().enumerate() {
if i != 0 {
f.write_str(", ")?;
}
f.write_fmt(format_args!("{:?}: {:?}", item.0, item.1))?;
}
f.write_str(" }")
}
}
}
}
pub(super) enum InternalTypeDef {
Single(TypeNamespaceId),
List(Vec<InternalTypeDef>),
Record(Vec<(String, InternalTypeDef)>),
}
impl From<TypeDef<'_>> for InternalTypeDef {
fn from(value: TypeDef) -> Self {
match value {
TypeDef::Type(val) => Self::Single(TypeNamespaceId::Types(val.id)),
TypeDef::Trait(val) => Self::Single(TypeNamespaceId::Traits(val.id)),
TypeDef::List(list) => Self::List(list.into_iter().map(std::convert::Into::into).collect()),
TypeDef::Record(rec) => Self::Record(
rec.into_iter()
.map(|(name, typ)| (name, typ.into()))
.collect(),
),
}
}
}