use std::fmt;
use itertools::Itertools;
use crate::{
common::{ArgumentList, Attribute, AttributeList, TypeDecl},
decl::{Decl, FieldDecl},
expr::{Expr, IdentExpr, NamespacedIdent, PrimaryExpr},
};
use super::Tooltip;
impl fmt::Display for TypeDecl {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.name)?;
if let Some(ref child_ty) = self.child_ty {
write!(f, "<{}>", child_ty)?;
}
Ok(())
}
}
impl fmt::Display for Attribute {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "@{}", self.name)?;
if let Some(ref params) = self.params {
write!(f, "{params}")?;
}
Ok(())
}
}
impl fmt::Display for AttributeList {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let inner = self.attributes.iter().join(" ");
write!(f, "{}", inner)
}
}
impl fmt::Display for Decl {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Tooltip::fmt(self, f)
}
}
impl fmt::Display for FieldDecl {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if let Some(ref attributes) = self.attributes {
write!(f, "{} ", attributes)?;
}
write!(f, "{}: {}", self.name, self.ty)?;
if let Some(sep) = &self.separator {
write!(f, "{sep}")?;
}
Ok(())
}
}
impl fmt::Display for IdentExpr {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut this = self;
while let IdentExpr::Namespaced(NamespacedIdent { namespace, ident }) = this {
write!(f, "{namespace}::")?;
this = ident.as_ref();
}
let IdentExpr::Leaf(name) = this else {
unreachable!();
};
write!(f, "{name}")
}
}
impl fmt::Display for ArgumentList {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.brace_open)?;
let len = self.arguments.len();
for (idx, expr) in self.arguments.iter().enumerate() {
match expr {
Expr::Primary(PrimaryExpr {
expr,
postfix: None,
}) => match expr.as_ref() {
Expr::Ident(ident) => write!(f, "{ident}"),
Expr::Literal(literal) => write!(f, "{literal}"),
_ => write!(f, "ERR"), },
_ => write!(f, "ERR"), }?;
if idx < len - 1 {
write!(f, ", ")?;
}
}
write!(f, "{}", self.brace_close)
}
}