wgsl-parser 0.5.0

A zero-copy recursive-descent parser for WebGPU shading language
Documentation
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)
	}
}

// FIXME
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"), // TODO
				},
				_ => write!(f, "ERR"), // TODO
			}?;

			if idx < len - 1 {
				write!(f, ", ")?;
			}
		}

		write!(f, "{}", self.brace_close)
	}
}