rune_core/item/
into_component.rs
1use core::hash::{self, Hash};
2
3#[cfg(feature = "alloc")]
4use crate::alloc::alloc::Allocator;
5#[cfg(feature = "alloc")]
6use crate::alloc::borrow::Cow;
7#[cfg(feature = "alloc")]
8use crate::alloc::clone::TryClone;
9#[cfg(feature = "alloc")]
10use crate::alloc::{self, Box, String, Vec};
11
12#[cfg(feature = "alloc")]
13use crate::item::Component;
14use crate::item::{internal, ComponentRef};
15
16pub trait IntoComponent: Sized {
18 fn as_component_ref(&self) -> ComponentRef<'_>;
20
21 #[inline]
23 #[cfg(feature = "alloc")]
24 fn into_component(self) -> alloc::Result<Component> {
25 into_component(self.as_component_ref())
26 }
27
28 #[inline]
30 #[doc(hidden)]
31 #[cfg(feature = "alloc")]
32 fn write_component<A: Allocator>(self, output: &mut Vec<u8, A>) -> alloc::Result<()> {
33 write_component(self.as_component_ref(), output)
34 }
35
36 #[inline]
38 #[doc(hidden)]
39 fn hash_component<H>(self, hasher: &mut H)
40 where
41 H: hash::Hasher,
42 {
43 hash_component(self.as_component_ref(), hasher)
44 }
45}
46
47impl<T> IntoComponent for [T; 1]
49where
50 T: IntoComponent,
51{
52 fn as_component_ref(&self) -> ComponentRef<'_> {
53 let [this] = self;
54 this.as_component_ref()
55 }
56
57 #[inline]
58 #[cfg(feature = "alloc")]
59 fn into_component(self) -> alloc::Result<Component> {
60 let [this] = self;
61 this.into_component()
62 }
63
64 #[inline]
65 #[doc(hidden)]
66 #[cfg(feature = "alloc")]
67 fn write_component<A: Allocator>(self, output: &mut Vec<u8, A>) -> alloc::Result<()> {
68 let [this] = self;
69 this.write_component(output)
70 }
71
72 #[inline]
73 fn hash_component<H>(self, hasher: &mut H)
74 where
75 H: hash::Hasher,
76 {
77 let [this] = self;
78 this.hash_component(hasher)
79 }
80}
81
82impl IntoComponent for ComponentRef<'_> {
83 #[inline]
84 fn as_component_ref(&self) -> ComponentRef<'_> {
85 *self
86 }
87
88 #[inline]
89 #[cfg(feature = "alloc")]
90 fn into_component(self) -> alloc::Result<Component> {
91 into_component(self)
92 }
93}
94
95impl IntoComponent for &ComponentRef<'_> {
96 #[inline]
97 fn as_component_ref(&self) -> ComponentRef<'_> {
98 **self
99 }
100
101 #[inline]
102 #[cfg(feature = "alloc")]
103 fn into_component(self) -> alloc::Result<Component> {
104 into_component(*self)
105 }
106}
107
108#[cfg(feature = "alloc")]
109impl IntoComponent for Component {
110 #[inline]
111 fn as_component_ref(&self) -> ComponentRef<'_> {
112 Component::as_component_ref(self)
113 }
114
115 #[inline]
116 fn into_component(self) -> alloc::Result<Component> {
117 Ok(self)
118 }
119}
120
121#[cfg(feature = "alloc")]
122impl IntoComponent for &Component {
123 #[inline]
124 fn as_component_ref(&self) -> ComponentRef<'_> {
125 Component::as_component_ref(self)
126 }
127
128 #[inline]
129 fn into_component(self) -> alloc::Result<Component> {
130 self.try_clone()
131 }
132}
133
134macro_rules! impl_into_component_for_str {
135 ($ty:ty, $slf:ident, $into:expr) => {
136 impl IntoComponent for $ty {
137 fn as_component_ref(&self) -> ComponentRef<'_> {
138 ComponentRef::Str(self.as_ref())
139 }
140
141 #[cfg(feature = "alloc")]
142 fn into_component($slf) -> alloc::Result<Component> {
143 Ok(Component::Str($into))
144 }
145
146 #[cfg(feature = "alloc")]
147 fn write_component<A: Allocator>(self, output: &mut Vec<u8, A>) -> alloc::Result<()> {
148 internal::write_str(self.as_ref(), output)
149 }
150
151 fn hash_component<H>(self, hasher: &mut H)
152 where
153 H: hash::Hasher,
154 {
155 internal::hash_str(self.as_ref(), hasher);
156 }
157 }
158 }
159}
160
161impl_into_component_for_str!(&str, self, self.try_into()?);
162impl_into_component_for_str!(&&str, self, (*self).try_into()?);
163#[cfg(feature = "alloc")]
164impl_into_component_for_str!(String, self, self.as_str().try_into()?);
165#[cfg(feature = "alloc")]
166impl_into_component_for_str!(&String, self, self.as_str().try_into()?);
167#[cfg(feature = "alloc")]
168impl_into_component_for_str!(Box<str>, self, self);
169#[cfg(feature = "alloc")]
170impl_into_component_for_str!(&Box<str>, self, self.try_clone()?);
171#[cfg(feature = "alloc")]
172impl_into_component_for_str!(Cow<'_, str>, self, self.as_ref().try_into()?);
173#[cfg(feature = "alloc")]
174impl_into_component_for_str!(
175 ::rust_alloc::borrow::Cow<'_, str>,
176 self,
177 self.as_ref().try_into()?
178);
179
180#[cfg(feature = "alloc")]
182fn into_component(component: ComponentRef<'_>) -> alloc::Result<Component> {
183 Ok(match component {
184 ComponentRef::Crate(s) => Component::Crate(s.try_into()?),
185 ComponentRef::Str(s) => Component::Str(s.try_into()?),
186 ComponentRef::Id(n) => Component::Id(n),
187 })
188}
189
190#[cfg(feature = "alloc")]
192fn write_component<A: Allocator>(
193 component: ComponentRef<'_>,
194 output: &mut Vec<u8, A>,
195) -> alloc::Result<()> {
196 match component {
197 ComponentRef::Crate(s) => internal::write_crate(s, output),
198 ComponentRef::Str(s) => internal::write_str(s, output),
199 ComponentRef::Id(c) => internal::write_tag(output, internal::ID, c),
200 }
201}
202
203fn hash_component<H>(component: ComponentRef<'_>, hasher: &mut H)
205where
206 H: hash::Hasher,
207{
208 match component {
209 ComponentRef::Crate(s) => {
210 internal::CRATE.hash(hasher);
211 s.hash(hasher);
212 }
213 ComponentRef::Str(s) => {
214 internal::STRING.hash(hasher);
215 s.hash(hasher);
216 }
217 ComponentRef::Id(c) => {
218 internal::ID.hash(hasher);
219 c.hash(hasher);
220 }
221 }
222}