1use faststr::FastStr;
2use heck::{ToSnakeCase, ToUpperCamelCase};
3use quote::{format_ident, IdentFragment};
4use std::fmt::Display;
5use std::ops::Deref;
6
7crate::newtype_index! {
8 pub struct DefId { .. }
9}
10
11crate::newtype_index! {
12 pub struct TagId { .. }
13}
14
15#[derive(Hash, PartialEq, Eq, Clone, Debug)]
16pub struct Symbol(pub FastStr);
17
18impl std::borrow::Borrow<str> for Symbol {
19 fn borrow(&self) -> &str {
20 self
21 }
22}
23
24impl Deref for Symbol {
25 type Target = str;
26
27 fn deref(&self) -> &Self::Target {
28 &self.0
29 }
30}
31
32impl<T> From<T> for Symbol
33where
34 T: Into<FastStr>,
35{
36 fn from(t: T) -> Self {
37 Symbol(t.into())
38 }
39}
40
41impl IdentFragment for Symbol {
42 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
43 write!(f, "{self}")
44 }
45}
46
47impl Display for Symbol {
48 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
49 self.0.fmt(f)
50 }
51}
52
53#[derive(Hash, PartialEq, Eq, Clone, Debug)]
54pub struct Ident {
55 pub sym: Symbol,
56}
57
58impl Ident {
59 pub fn new(sym: Symbol) -> Self {
60 Ident { sym }
61 }
62}
63
64impl Deref for Ident {
65 type Target = Symbol;
66
67 fn deref(&self) -> &Self::Target {
68 &self.sym
69 }
70}
71
72impl IdentFragment for Ident {
73 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
74 quote::IdentFragment::fmt(&self.sym, f)
75 }
76}
77
78impl Display for Ident {
79 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
80 std::fmt::Display::fmt(&self.sym, f)
81 }
82}
83
84impl<T> From<T> for Ident
85where
86 T: Into<FastStr>,
87{
88 fn from(t: T) -> Self {
89 Ident {
90 sym: Symbol(t.into()),
91 }
92 }
93}
94
95pub trait IdentName {
96 fn upper_camel_ident(&self) -> FastStr;
97
98 fn snake_ident(&self) -> FastStr;
99
100 fn as_syn_ident(&self) -> syn::Ident;
101}
102
103fn str2ident(s: &str) -> syn::Ident {
104 format_ident!("{}", s)
105}
106
107impl IdentName for &str {
108 fn upper_camel_ident(&self) -> FastStr {
109 self.to_upper_camel_case().into()
110 }
111
112 fn snake_ident(&self) -> FastStr {
113 self.to_snake_case().into()
114 }
115
116 fn as_syn_ident(&self) -> syn::Ident {
117 str2ident(self)
118 }
119}
120
121impl IdentName for FastStr {
122 fn upper_camel_ident(&self) -> FastStr {
123 (&**self).upper_camel_ident()
124 }
125
126 fn snake_ident(&self) -> FastStr {
127 (&**self).snake_ident()
128 }
129
130 fn as_syn_ident(&self) -> syn::Ident {
131 str2ident(self)
132 }
133}