use std::fmt::{self, Debug, Display};
use crate::common::name::Name;
use crate::common::source::Span;
use crate::ty2::prelude::*;
use crate::ty2::Subtype;
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub enum TypeName {
Name(Name),
Span(Span),
}
impl From<Name> for TypeName {
fn from(name: Name) -> TypeName {
TypeName::Name(name)
}
}
impl From<Span> for TypeName {
fn from(span: Span) -> TypeName {
TypeName::Span(span)
}
}
impl TypeName {
pub fn to_string(self) -> String {
match self {
TypeName::Name(name) => name.into(),
TypeName::Span(span) => span.extract(),
}
}
pub fn as_name(self) -> Option<Name> {
match self {
TypeName::Name(name) => Some(name),
_ => None,
}
}
pub fn as_span(self) -> Option<Span> {
match self {
TypeName::Span(span) => Some(span),
_ => None,
}
}
}
impl Display for TypeName {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
TypeName::Name(name) => write!(f, "{}", name),
TypeName::Span(span) => write!(f, "{}", span.extract()),
}
}
}
impl Debug for TypeName {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Display::fmt(self, f)
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct TypeDecl<'t> {
name: TypeName,
ty: &'t Type,
}
impl<'t> TypeDecl<'t> {
pub fn new<N: Into<TypeName>>(name: N, ty: &'t Type) -> TypeDecl<'t> {
TypeDecl {
name: name.into(),
ty: ty,
}
}
pub fn name(&self) -> TypeName {
self.name
}
pub fn ty(&self) -> &'t Type {
self.ty
}
}
impl<'t> Type for TypeDecl<'t> {
fn is_scalar(&self) -> bool {
self.ty.is_scalar()
}
fn is_discrete(&self) -> bool {
self.ty.is_discrete()
}
fn is_numeric(&self) -> bool {
self.ty.is_numeric()
}
fn is_composite(&self) -> bool {
self.ty.is_composite()
}
fn into_owned<'a>(self) -> OwnedType<'a>
where
Self: 'a,
{
self.ty.to_owned()
}
fn to_owned<'a>(&self) -> OwnedType<'a>
where
Self: 'a,
{
self.ty.to_owned()
}
fn as_any(&self) -> AnyType {
self.ty.as_any()
}
}
impl<'t> Display for TypeDecl<'t> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "type {} is {}", self.name, self.ty)
}
}
#[derive(Clone, Copy, Debug)]
pub struct SubtypeDecl<'t> {
name: TypeName,
ty: &'t Subtype, }
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct TypeMark<'t> {
name: TypeName,
ty: &'t Type,
}
impl<'t> TypeMark<'t> {
pub fn new<N: Into<TypeName>>(name: N, ty: &'t Type) -> TypeMark<'t> {
TypeMark {
name: name.into(),
ty: ty,
}
}
pub fn name(&self) -> TypeName {
self.name
}
pub fn ty(&self) -> &'t Type {
self.ty
}
}
impl<'t> Type for TypeMark<'t> {
fn is_scalar(&self) -> bool {
self.ty.is_scalar()
}
fn is_discrete(&self) -> bool {
self.ty.is_discrete()
}
fn is_numeric(&self) -> bool {
self.ty.is_numeric()
}
fn is_composite(&self) -> bool {
self.ty.is_composite()
}
fn into_owned<'a>(self) -> OwnedType<'a>
where
Self: 'a,
{
self.ty.to_owned()
}
fn to_owned<'a>(&self) -> OwnedType<'a>
where
Self: 'a,
{
self.ty.to_owned()
}
fn as_any(&self) -> AnyType {
self.ty.as_any()
}
}
impl<'t> Display for TypeMark<'t> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.name)
}
}