123 lines
4 KiB
Rust
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(),
|
|
),
|
|
}
|
|
}
|
|
}
|