1use crate::{kw, SolIdent, Spanned, Type};
2use proc_macro2::Span;
3use std::{
4 fmt,
5 hash::{Hash, Hasher},
6};
7use syn::{
8 parse::{Parse, ParseStream},
9 Attribute, Result, Token,
10};
11
12#[derive(Clone)]
17pub struct ItemUdt {
18 pub attrs: Vec<Attribute>,
19 pub type_token: Token![type],
20 pub name: SolIdent,
21 pub is_token: kw::is,
22 pub ty: Type,
23 pub semi_token: Token![;],
24}
25
26impl fmt::Display for ItemUdt {
27 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
28 write!(f, "type {} is {};", self.name, self.ty)
29 }
30}
31
32impl fmt::Debug for ItemUdt {
33 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
34 f.debug_struct("ItemUdt")
35 .field("attrs", &self.attrs)
36 .field("name", &self.name)
37 .field("ty", &self.ty)
38 .finish()
39 }
40}
41
42impl PartialEq for ItemUdt {
43 fn eq(&self, other: &Self) -> bool {
44 self.name == other.name && self.ty == other.ty
45 }
46}
47
48impl Eq for ItemUdt {}
49
50impl Hash for ItemUdt {
51 fn hash<H: Hasher>(&self, state: &mut H) {
52 self.name.hash(state);
53 self.ty.hash(state);
54 }
55}
56
57impl Parse for ItemUdt {
58 fn parse(input: ParseStream<'_>) -> Result<Self> {
59 let this = Self {
60 attrs: input.call(Attribute::parse_outer)?,
61 type_token: input.parse()?,
62 name: input.parse()?,
63 is_token: input.parse()?,
64 ty: input.parse()?,
65 semi_token: input.parse()?,
66 };
67
68 if this.ty.has_custom() {
70 return Err(syn::Error::new(
71 this.ty.span(),
72 "the underlying type for a user-defined value type has to be an elementary value type",
73 ));
74 }
75
76 Ok(this)
77 }
78}
79
80impl Spanned for ItemUdt {
81 fn span(&self) -> Span {
82 self.name.span()
83 }
84
85 fn set_span(&mut self, span: Span) {
86 self.type_token.span = span;
87 self.name.set_span(span);
88 self.is_token.span = span;
89 self.ty.set_span(span);
90 self.semi_token.span = span;
91 }
92}