1use {
5 cssparser::{serialize_identifier, CowRcStr, ToCss},
6 precomputed_hash::PrecomputedHash,
7 std::{
8 borrow::{Borrow, Cow},
9 collections::hash_map::DefaultHasher,
10 fmt::{self, Display, Formatter},
11 hash::{Hash, Hasher},
12 ops::Deref,
13 str::FromStr,
14 },
15};
16
17#[derive(Default, Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
19pub struct Atom(pub String);
20
21impl Deref for Atom {
22 type Target = str;
23
24 #[inline(always)]
25 fn deref(&self) -> &Self::Target {
26 &self.0
27 }
28}
29
30impl ToCss for Atom {
31 #[inline(always)]
32 fn to_css<W: fmt::Write>(&self, dest: &mut W) -> fmt::Result {
33 serialize_identifier(&self.0, dest)
34 }
35}
36
37impl Display for Atom {
38 #[inline(always)]
39 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
40 self.0.fmt(f)
41 }
42}
43
44impl From<String> for Atom {
45 #[inline(always)]
46 fn from(value: String) -> Self {
47 Atom(value)
48 }
49}
50
51impl<'a> From<&'a str> for Atom {
52 #[inline(always)]
53 fn from(value: &'a str) -> Self {
54 Atom(value.to_owned())
55 }
56}
57
58impl<'i> From<CowRcStr<'i>> for Atom {
59 #[inline(always)]
60 fn from(value: CowRcStr<'i>) -> Self {
61 Atom::from(value.as_ref())
62 }
63}
64
65impl<'a> From<Cow<'a, str>> for Atom {
66 #[inline(always)]
67 fn from(value: Cow<'a, str>) -> Self {
68 Atom(value.into_owned())
69 }
70}
71
72impl<'a, 'i> From<&'a CowRcStr<'i>> for Atom {
73 #[inline(always)]
74 fn from(value: &'a CowRcStr<'i>) -> Self {
75 Atom::from(value.as_ref())
76 }
77}
78
79impl FromStr for Atom {
80 type Err = ();
81
82 #[inline(always)]
83 fn from_str(s: &str) -> Result<Self, Self::Err> {
84 Ok(Atom(s.to_owned()))
85 }
86}
87
88impl Borrow<str> for Atom {
89 #[inline(always)]
90 fn borrow(&self) -> &str {
91 self.deref()
92 }
93}
94
95impl PrecomputedHash for Atom {
96 #[inline(always)]
97 fn precomputed_hash(&self) -> u32 {
98 let mut state = DefaultHasher::new();
99 self.0.hash(&mut state);
100 state.finish() as u32
101 }
102}
103
104impl Atom {
105 #[inline(always)]
106 pub fn is_ascii(&self) -> bool {
107 self.0.is_ascii()
108 }
109
110 #[inline(always)]
111 pub fn eq_ignore_ascii_case(&self, name: &str) -> bool {
112 self.deref().eq_ignore_ascii_case(name)
113 }
114}