use core::fmt;
use super::{Comment, List, Type, TypeRef};
#[derive(Debug, Clone, Eq)]
pub struct Field<'a> {
name: &'a str,
ty: TypeRef<'a>,
comments: List<'a, Comment<'a>>,
}
pub type Parameter<'a> = Field<'a>;
impl<'a> Field<'a> {
pub const fn new(name: &'a str, ty: &'a Type<'a>, comments: &'a [&'a Comment<'a>]) -> Self {
Self {
name,
ty: TypeRef::new(ty),
comments: List::Borrowed(comments),
}
}
pub fn new_owned(name: &'a str, ty: Type<'a>, comments: alloc::vec::Vec<Comment<'a>>) -> Self {
Self {
name,
ty: TypeRef::new_owned(ty),
comments: List::from(comments),
}
}
pub fn name(&self) -> &'a str {
self.name
}
pub fn ty(&self) -> &Type<'a> {
self.ty.inner()
}
pub fn comments(&self) -> impl Iterator<Item = &Comment<'a>> {
self.comments.iter()
}
}
impl<'a> fmt::Display for Field<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for comment in self.comments.iter() {
writeln!(f, "{comment}")?;
}
write!(f, "{}: {}", self.name, self.ty)
}
}
impl<'a> PartialEq for Field<'a> {
fn eq(&self, other: &Self) -> bool {
self.name == other.name && self.ty == other.ty
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::idl::Type;
#[test]
fn field_creation() {
let field = Field::new("age", &Type::Int, &[]);
assert_eq!(field.name(), "age");
assert_eq!(field.ty(), &Type::Int);
}
#[test]
fn parameter_alias() {
let param: Parameter<'_> = Field::new("input", &Type::String, &[]);
assert_eq!(param.name(), "input");
assert_eq!(param.ty(), &Type::String);
}
#[test]
fn display_with_comments() {
use crate::idl::Comment;
use core::fmt::Write;
let comment1 = Comment::new("User's email address");
let comment2 = Comment::new("Must be valid format");
let comments = [&comment1, &comment2];
let field = Field::new("email", &Type::String, &comments);
let mut displayed = String::new();
write!(&mut displayed, "{}", field).unwrap();
assert_eq!(
displayed,
"# User's email address\n# Must be valid format\nemail: string"
);
}
}