Skip to main content

neuro_sama/game/
glue.rs

1//! Just a bunch of boilerplate
2use std::{borrow::Cow, marker::PhantomData};
3
4use serde::{
5    de::{EnumAccess, VariantAccess},
6    Deserialize, Deserializer,
7};
8
9use crate::schema;
10
11use super::Action;
12
13/// A trait that has to be implemented by action enums. It can be automatically implemented with
14/// `#[derive(neuro_sama::derive::Actions)]`.
15pub trait Actions<'de>: Sized {
16    fn deserialize<D: Deserializer<'de>>(discriminant: &str, de: D) -> Result<Self, D::Error>;
17}
18
19impl<'de, T: 'de + Deserialize<'de>> Actions<'de> for T {
20    fn deserialize<D: Deserializer<'de>>(discriminant: &str, de: D) -> Result<Self, D::Error> {
21        struct DeserWrapper<'a, 'de, D: Deserializer<'de>>(D, &'a str, PhantomData<&'de ()>);
22        macro_rules! impl_visitor {
23            ($($a:tt),*) => {
24                $(fn $a<V>(self, visitor: V) -> Result<V::Value, Self::Error>
25                    where
26                        V: serde::de::Visitor<'de> {
27                            self.deserialize_any(visitor)
28                })*
29            };
30        }
31        impl<'de, D: Deserializer<'de>> VariantAccess<'de> for DeserWrapper<'_, 'de, D> {
32            type Error = D::Error;
33            fn struct_variant<V>(
34                self,
35                fields: &'static [&'static str],
36                visitor: V,
37            ) -> Result<V::Value, Self::Error>
38            where
39                V: serde::de::Visitor<'de>,
40            {
41                self.0.deserialize_struct("", fields, visitor)
42            }
43            fn unit_variant(self) -> Result<(), Self::Error> {
44                Deserialize::deserialize(self.0)
45            }
46            fn tuple_variant<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
47            where
48                V: serde::de::Visitor<'de>,
49            {
50                self.0.deserialize_tuple(len, visitor)
51            }
52            fn newtype_variant<T>(self) -> Result<T, Self::Error>
53            where
54                T: Deserialize<'de>,
55            {
56                Deserialize::deserialize(self.0)
57            }
58            fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error>
59            where
60                T: serde::de::DeserializeSeed<'de>,
61            {
62                seed.deserialize(self.0)
63            }
64        }
65        impl<'de, D: Deserializer<'de>> EnumAccess<'de> for DeserWrapper<'_, 'de, D> {
66            type Error = D::Error;
67            type Variant = Self;
68            fn variant<V>(self) -> Result<(V, Self::Variant), Self::Error>
69            where
70                V: Deserialize<'de>,
71            {
72                Ok((
73                    V::deserialize(serde::de::value::StrDeserializer::new(self.1))?,
74                    self,
75                ))
76            }
77            fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error>
78            where
79                V: serde::de::DeserializeSeed<'de>,
80            {
81                Ok((
82                    seed.deserialize(serde::de::value::StrDeserializer::new(self.1))?,
83                    self,
84                ))
85            }
86        }
87        impl<'de, D: Deserializer<'de>> Deserializer<'de> for DeserWrapper<'_, 'de, D> {
88            type Error = D::Error;
89            impl_visitor!(
90                deserialize_i8,
91                deserialize_i16,
92                deserialize_i32,
93                deserialize_i64,
94                deserialize_u8,
95                deserialize_u16,
96                deserialize_u32,
97                deserialize_u64,
98                deserialize_bool,
99                deserialize_f32,
100                deserialize_f64,
101                deserialize_char,
102                deserialize_str,
103                deserialize_string,
104                deserialize_bytes,
105                deserialize_byte_buf,
106                deserialize_option,
107                deserialize_unit,
108                deserialize_seq,
109                deserialize_map,
110                deserialize_identifier,
111                deserialize_ignored_any
112            );
113            fn deserialize_enum<V>(
114                self,
115                _name: &'static str,
116                _variants: &'static [&'static str],
117                visitor: V,
118            ) -> Result<V::Value, Self::Error>
119            where
120                V: serde::de::Visitor<'de>,
121            {
122                self.deserialize_any(visitor)
123            }
124            fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
125            where
126                V: serde::de::Visitor<'de>,
127            {
128                self.deserialize_any(visitor)
129            }
130            fn deserialize_struct<V>(
131                self,
132                _name: &'static str,
133                _fields: &'static [&'static str],
134                visitor: V,
135            ) -> Result<V::Value, Self::Error>
136            where
137                V: serde::de::Visitor<'de>,
138            {
139                self.deserialize_any(visitor)
140            }
141            fn deserialize_unit_struct<V>(
142                self,
143                _name: &'static str,
144                visitor: V,
145            ) -> Result<V::Value, Self::Error>
146            where
147                V: serde::de::Visitor<'de>,
148            {
149                self.deserialize_any(visitor)
150            }
151            fn deserialize_tuple_struct<V>(
152                self,
153                _name: &'static str,
154                _len: usize,
155                visitor: V,
156            ) -> Result<V::Value, Self::Error>
157            where
158                V: serde::de::Visitor<'de>,
159            {
160                self.deserialize_any(visitor)
161            }
162            fn deserialize_newtype_struct<V>(
163                self,
164                _name: &'static str,
165                visitor: V,
166            ) -> Result<V::Value, Self::Error>
167            where
168                V: serde::de::Visitor<'de>,
169            {
170                self.deserialize_any(visitor)
171            }
172            fn is_human_readable(&self) -> bool {
173                self.0.is_human_readable()
174            }
175            fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
176            where
177                V: serde::de::Visitor<'de>,
178            {
179                visitor.visit_enum(self)
180            }
181        }
182        let wrapper = DeserWrapper(de, discriminant, PhantomData);
183        <Self as Deserialize<'_>>::deserialize(wrapper)
184    }
185}
186
187/// A trait that has to be implemented by sets of type-level action metadata. A set of action
188/// metadata is something that you can register or unregister to tell Neuro which actions are or
189/// aren't available. To put it simpy, this trait is implemented by actions, action enums, and
190/// tuples of actions, and by passing any type that implements this trait as the type parameter to
191/// `register_action` or `unregister_action`, you can register/unregister actions in a type-safe
192/// way.
193pub trait ActionMetadata {
194    fn actions() -> Vec<schema::Action>;
195    fn names() -> Vec<Cow<'static, str>>;
196}
197
198impl<T: Action> ActionMetadata for T {
199    fn actions() -> Vec<schema::Action> {
200        vec![schema::Action {
201            name: Self::name().into(),
202            description: Self::description().into(),
203            schema: schemars::schema_for!(Self),
204        }]
205    }
206    fn names() -> Vec<Cow<'static, str>> {
207        vec![Self::name().into()]
208    }
209}
210macro_rules! tuple_actions {
211    ($($a:tt),*) => {
212        impl<$($a: Action),*> ActionMetadata for ($($a,)*) {
213            fn actions() -> Vec<schema::Action> {
214                vec![$(schema::Action {
215                    name: $a::name().into(),
216                    description: $a::description().into(),
217                    schema: schemars::schema_for!($a),
218                }),*]
219            }
220            fn names() -> Vec<Cow<'static, str>> {
221                vec![$($a::name().into()),*]
222            }
223        }
224    };
225}
226tuple_actions!();
227tuple_actions!(A);
228tuple_actions!(A, B);
229tuple_actions!(A, B, C);
230tuple_actions!(A, B, C, D);
231tuple_actions!(A, B, C, D, E);
232tuple_actions!(A, B, C, D, E, F);
233tuple_actions!(A, B, C, D, E, F, G);
234tuple_actions!(A, B, C, D, E, F, G, H);
235tuple_actions!(A, B, C, D, E, F, G, H, I);
236tuple_actions!(A, B, C, D, E, F, G, H, I, J);
237tuple_actions!(A, B, C, D, E, F, G, H, I, J, K);
238tuple_actions!(A, B, C, D, E, F, G, H, I, J, K, L);
239tuple_actions!(A, B, C, D, E, F, G, H, I, J, K, L, M);
240tuple_actions!(A, B, C, D, E, F, G, H, I, J, K, L, M, N);
241tuple_actions!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O);
242tuple_actions!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P);
243tuple_actions!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q);
244tuple_actions!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R);
245tuple_actions!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S);
246tuple_actions!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T);
247tuple_actions!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U);
248tuple_actions!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V);
249tuple_actions!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W);
250tuple_actions!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X);
251tuple_actions!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y);
252tuple_actions!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z);
253tuple_actions!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, A0);