use proc_macro2::TokenStream;
use quote::{format_ident, quote};
use crate::TypespaceRenderer;
use crate::build::{Type, TypeCommon};
use crate::error::Error;
#[derive(Debug, Clone)]
pub struct TypeAlias<Id> {
pub(crate) common: TypeCommon,
pub(crate) target: Id,
}
impl<Id> TypeAlias<Id> {
pub fn new(target: Id) -> Self {
Self {
common: Default::default(),
target,
}
}
pub fn name(mut self, name: impl Into<String>) -> Self {
self.common.name = Some(name.into());
self
}
pub fn description(mut self, description: impl Into<String>) -> Self {
self.common.description = Some(description.into());
self
}
pub fn extra_attrs(mut self, attrs: impl IntoIterator<Item = impl Into<String>>) -> Self {
self.common
.extra_attrs
.extend(attrs.into_iter().map(Into::into));
self
}
pub fn build(self) -> Result<Type<Id>, Error<Id>>
where
Id: std::fmt::Debug + std::fmt::Display,
{
self.validate()?;
Ok(Type::TypeAlias(self))
}
pub(crate) fn validate(&self) -> Result<(), Error<Id>>
where
Id: std::fmt::Debug + std::fmt::Display,
{
self.common.validate_name("type alias")
}
pub fn get_name(&self) -> Option<&str> {
self.common.name()
}
pub fn get_description(&self) -> Option<&str> {
self.common.description()
}
pub fn get_extra_attrs(&self) -> &[String] {
self.common.extra_attrs()
}
pub fn get_target(&self) -> &Id {
&self.target
}
}
impl<Id: Clone + Ord + std::fmt::Debug + std::fmt::Display> TypeAlias<Id> {
pub(crate) fn children(&self) -> Vec<Id> {
vec![self.target.clone()]
}
pub(crate) fn render(&self, typespace: &TypespaceRenderer<'_, Id>) -> TokenStream {
let Self {
common:
TypeCommon {
name,
description,
built: _,
default: _,
extra_derives: _,
extra_attrs: _,
},
target: type_id,
} = self;
let name = name.as_deref().expect("validated type has a name");
let description = description.as_ref().map(|desc| quote! { #[doc = #desc ]});
let name_ident = format_ident!("{name}");
let target_ident = typespace.render_ident(type_id);
quote! {
#description
pub type #name_ident = #target_ident;
}
}
}