use super::{ArrayLen, NamedRef};
use crate::error::{
ExpectedTypeFoundConst, ExpectedTypeFoundService, InvalidKeyType, TypeNotFound,
};
use crate::grammar::Rule;
use crate::validate::Validate;
use crate::Span;
use pest::iterators::Pair;
use std::fmt;
#[derive(Debug, Clone)]
pub struct TypeName {
span: Span,
kind: TypeNameKind,
}
impl TypeName {
pub(crate) fn parse(pair: Pair<Rule>) -> Self {
assert_eq!(pair.as_rule(), Rule::type_name);
let span = Span::from_pair(&pair);
let mut pairs = pair.into_inner();
let pair = pairs.next().unwrap();
let kind = TypeNameKind::parse(pair);
Self { span, kind }
}
pub(crate) fn validate(&self, is_key_type: bool, validate: &mut Validate) {
self.kind.validate(is_key_type, validate);
}
pub fn span(&self) -> Span {
self.span
}
pub fn kind(&self) -> &TypeNameKind {
&self.kind
}
}
#[derive(Debug, Clone)]
pub enum TypeNameKind {
Bool,
U8,
I8,
U16,
I16,
U32,
I32,
U64,
I64,
F32,
F64,
String,
Uuid,
ObjectId,
ServiceId,
Value,
Option(Box<TypeName>),
Box(Box<TypeName>),
Vec(Box<TypeName>),
Bytes,
Map(Box<TypeName>, Box<TypeName>),
Set(Box<TypeName>),
Sender(Box<TypeName>),
Receiver(Box<TypeName>),
Lifetime,
Unit,
Result(Box<TypeName>, Box<TypeName>),
Array(Box<TypeName>, ArrayLen),
Ref(NamedRef),
}
impl TypeNameKind {
fn parse(pair: Pair<Rule>) -> Self {
match pair.as_rule() {
Rule::kw_bool => Self::Bool,
Rule::kw_u8 => Self::U8,
Rule::kw_i8 => Self::I8,
Rule::kw_u16 => Self::U16,
Rule::kw_i16 => Self::I16,
Rule::kw_u32 => Self::U32,
Rule::kw_i32 => Self::I32,
Rule::kw_u64 => Self::U64,
Rule::kw_i64 => Self::I64,
Rule::kw_f32 => Self::F32,
Rule::kw_f64 => Self::F64,
Rule::kw_string => Self::String,
Rule::kw_uuid => Self::Uuid,
Rule::kw_object_id => Self::ObjectId,
Rule::kw_service_id => Self::ServiceId,
Rule::kw_value => Self::Value,
Rule::kw_lifetime => Self::Lifetime,
Rule::kw_unit => Self::Unit,
Rule::option_type => {
let mut pairs = pair.into_inner();
pairs.next().unwrap(); pairs.next().unwrap(); let pair = pairs.next().unwrap();
Self::Option(Box::new(TypeName::parse(pair)))
}
Rule::box_type => {
let mut pairs = pair.into_inner();
pairs.next().unwrap(); pairs.next().unwrap(); let pair = pairs.next().unwrap();
Self::Box(Box::new(TypeName::parse(pair)))
}
Rule::vec_type => {
let mut pairs = pair.into_inner();
pairs.next().unwrap(); pairs.next().unwrap(); let pair = pairs.next().unwrap();
Self::Vec(Box::new(TypeName::parse(pair)))
}
Rule::kw_bytes => Self::Bytes,
Rule::map_type => {
let mut pairs = pair.into_inner();
pairs.next().unwrap(); pairs.next().unwrap(); let key_pair = pairs.next().unwrap();
pairs.next().unwrap(); let type_pair = pairs.next().unwrap();
Self::Map(
Box::new(TypeName::parse(key_pair)),
Box::new(TypeName::parse(type_pair)),
)
}
Rule::set_type => {
let mut pairs = pair.into_inner();
pairs.next().unwrap(); pairs.next().unwrap(); let pair = pairs.next().unwrap();
Self::Set(Box::new(TypeName::parse(pair)))
}
Rule::sender_type => {
let mut pairs = pair.into_inner();
pairs.next().unwrap(); pairs.next().unwrap(); let pair = pairs.next().unwrap();
Self::Sender(Box::new(TypeName::parse(pair)))
}
Rule::receiver_type => {
let mut pairs = pair.into_inner();
pairs.next().unwrap(); pairs.next().unwrap(); let pair = pairs.next().unwrap();
Self::Receiver(Box::new(TypeName::parse(pair)))
}
Rule::result_type => {
let mut pairs = pair.into_inner();
pairs.next().unwrap(); pairs.next().unwrap(); let ok_pair = pairs.next().unwrap();
pairs.next().unwrap(); let err_pair = pairs.next().unwrap();
Self::Result(
Box::new(TypeName::parse(ok_pair)),
Box::new(TypeName::parse(err_pair)),
)
}
Rule::array_type => {
let mut pairs = pair.into_inner();
pairs.next().unwrap(); let type_pair = pairs.next().unwrap();
pairs.next().unwrap(); let len_pair = pairs.next().unwrap();
Self::Array(
Box::new(TypeName::parse(type_pair)),
ArrayLen::parse(len_pair),
)
}
Rule::named_ref => Self::Ref(NamedRef::parse(pair)),
_ => unreachable!(),
}
}
fn validate(&self, is_key_type: bool, validate: &mut Validate) {
match self {
Self::Option(ty)
| Self::Box(ty)
| Self::Vec(ty)
| Self::Sender(ty)
| Self::Receiver(ty) => ty.validate(false, validate),
Self::Map(k, t) => {
InvalidKeyType::validate(k, validate);
k.validate(true, validate);
t.validate(false, validate);
}
Self::Set(ty) => {
InvalidKeyType::validate(ty, validate);
ty.validate(true, validate);
}
Self::Result(ok, err) => {
ok.validate(false, validate);
err.validate(false, validate);
}
Self::Array(ty, len) => {
ty.validate(false, validate);
len.validate(validate);
}
Self::Ref(ty) => {
TypeNotFound::validate(ty, is_key_type, validate);
ExpectedTypeFoundService::validate(ty, is_key_type, validate);
ExpectedTypeFoundConst::validate(ty, is_key_type, validate);
ty.validate(validate);
}
Self::Bool
| Self::U8
| Self::I8
| Self::U16
| Self::I16
| Self::U32
| Self::I32
| Self::U64
| Self::I64
| Self::F32
| Self::F64
| Self::String
| Self::Uuid
| Self::ObjectId
| Self::ServiceId
| Self::Value
| Self::Bytes
| Self::Lifetime
| Self::Unit => {}
}
}
}
impl fmt::Display for TypeNameKind {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::Bool => write!(f, "bool"),
Self::U8 => write!(f, "u8"),
Self::I8 => write!(f, "i8"),
Self::U16 => write!(f, "u16"),
Self::I16 => write!(f, "i16"),
Self::U32 => write!(f, "u32"),
Self::I32 => write!(f, "i32"),
Self::U64 => write!(f, "u64"),
Self::I64 => write!(f, "i64"),
Self::F32 => write!(f, "f32"),
Self::F64 => write!(f, "f64"),
Self::String => write!(f, "string"),
Self::Uuid => write!(f, "uuid"),
Self::ObjectId => write!(f, "object_id"),
Self::ServiceId => write!(f, "service_id"),
Self::Value => write!(f, "value"),
Self::Option(ty) => write!(f, "option<{}>", ty.kind()),
Self::Box(ty) => write!(f, "box<{}>", ty.kind()),
Self::Vec(ty) => write!(f, "vec<{}>", ty.kind()),
Self::Bytes => write!(f, "bytes"),
Self::Map(k, t) => write!(f, "map<{} -> {}>", k.kind(), t.kind()),
Self::Set(ty) => write!(f, "set<{}>", ty.kind()),
Self::Sender(ty) => write!(f, "sender<{}>", ty.kind()),
Self::Receiver(ty) => write!(f, "receiver<{}>", ty.kind()),
Self::Lifetime => write!(f, "lifetime"),
Self::Unit => write!(f, "unit"),
Self::Result(ok, err) => write!(f, "result<{}, {}>", ok.kind(), err.kind()),
Self::Array(ty, len) => write!(f, "[{}; {}]", ty.kind(), len.value()),
Self::Ref(ty) => ty.kind().fmt(f),
}
}
}