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