visit_rs/
lib.rs

1use std::marker::PhantomData;
2
3use futures::Stream;
4
5pub use visit_rs_derive::*;
6
7#[cfg(feature = "serde")]
8pub mod serde;
9
10pub mod lib {
11    pub use async_stream;
12    pub use futures;
13}
14
15pub trait Visitor {
16    type Result;
17}
18
19pub trait Visit<V: Visitor> {
20    fn visit(&self, visitor: &mut V) -> V::Result;
21}
22
23pub trait VisitAsync<V: Visitor> {
24    fn visit_async<'a>(&'a self, visitor: &'a mut V) -> impl Future<Output = V::Result> + Send + 'a
25    where
26        V: Send,
27        V::Result: Send;
28}
29
30pub trait StructInfo {
31    const DATA: StructInfoData;
32}
33
34#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
35pub struct StructInfoData {
36    pub name: &'static str,
37    pub named_fields: bool,
38    pub field_count: usize,
39}
40
41pub trait VisitFields<V: Visitor>: StructInfo {
42    fn visit_fields<'a>(&'a self, visitor: &'a mut V) -> impl Iterator<Item = V::Result> + 'a;
43}
44
45pub trait VisitFieldsCovered<V: Visitor>: StructInfo {
46    fn visit_fields_covered<'a>(
47        &'a self,
48        visitor: &'a mut V,
49    ) -> impl Iterator<Item = V::Result> + 'a;
50}
51
52pub trait VisitFieldsStatic<V: Visitor>: StructInfo {
53    fn visit_fields_static<'a>(visitor: &'a mut V) -> impl Iterator<Item = V::Result> + 'a;
54}
55
56pub trait VisitFieldsAsync<V: Visitor>: StructInfo {
57    fn visit_fields_async<'a>(
58        &'a self,
59        visitor: &'a mut V,
60    ) -> impl Stream<Item = V::Result> + Send + 'a
61    where
62        V: Send,
63        V::Result: Send;
64}
65
66pub trait VisitFieldsCoveredAsync<V: Visitor>: StructInfo {
67    fn visit_fields_covered_async<'a>(
68        &'a self,
69        visitor: &'a mut V,
70    ) -> impl Stream<Item = V::Result> + Send + 'a
71    where
72        V: Send,
73        V::Result: Send;
74}
75
76pub trait VisitFieldsStaticAsync<V: Visitor>: StructInfo {
77    fn visit_fields_static_async<'a>(visitor: &'a mut V) -> impl Stream<Item = V::Result> + 'a
78    where
79        V: Send,
80        V::Result: Send;
81}
82
83pub trait VisitFieldsNamed<V: Visitor>: StructInfo {
84    fn visit_fields_named<'a>(&'a self, visitor: &'a mut V)
85        -> impl Iterator<Item = V::Result> + 'a;
86}
87
88pub trait VisitFieldsStaticNamed<V: Visitor>: StructInfo {
89    fn visit_fields_static_named<'a>(visitor: &'a mut V) -> impl Iterator<Item = V::Result> + 'a;
90}
91
92pub trait VisitFieldsNamedAsync<V: Visitor>: StructInfo {
93    fn visit_fields_named_async<'a>(
94        &'a self,
95        visitor: &'a mut V,
96    ) -> impl Stream<Item = V::Result> + Send + 'a
97    where
98        V: Send,
99        V::Result: Send;
100}
101
102pub trait VisitFieldsStaticNamedAsync<V: Visitor>: StructInfo {
103    fn visit_fields_static_named_async<'a>(
104        visitor: &'a mut V,
105    ) -> impl Stream<Item = V::Result> + Send + 'a
106    where
107        V: Send,
108        V::Result: Send;
109}
110
111#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
112pub struct Named<'a, T: ?Sized> {
113    pub name: Option<&'static str>,
114    pub value: &'a T,
115}
116
117#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
118pub struct Covered<'a, T: ?Sized>(pub &'a T);
119
120pub struct Static<T: ?Sized> {
121    _phantom: PhantomData<T>,
122}
123impl<T: ?Sized> std::fmt::Debug for Static<T> {
124    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
125        f.debug_struct(std::any::type_name::<Self>()).finish()
126    }
127}
128unsafe impl<T: ?Sized> Send for Static<T> {}
129unsafe impl<T: ?Sized> Sync for Static<T> {}
130impl<T: ?Sized> Default for Static<T> {
131    fn default() -> Self {
132        Static::new()
133    }
134}
135impl<T: ?Sized> Clone for Static<T> {
136    fn clone(&self) -> Self {
137        Self::new()
138    }
139}
140impl<T: ?Sized> Copy for Static<T> {}
141impl<T: ?Sized + 'static, U: ?Sized + 'static> PartialEq<Static<U>> for Static<T> {
142    fn eq(&self, _: &Static<U>) -> bool {
143        std::any::TypeId::of::<T>() == std::any::TypeId::of::<U>()
144    }
145}
146impl<T: ?Sized + 'static> Eq for Static<T> {}
147
148impl<T: ?Sized> Static<T> {
149    pub const fn new() -> Self {
150        Static {
151            _phantom: PhantomData,
152        }
153    }
154    pub const fn new_ref() -> &'static Self {
155        const STATIC: Static<()> = Static::new();
156        // SAFETY: Safe to transmute because it is always just a phantom
157        unsafe { std::mem::transmute(&STATIC) }
158    }
159}
160
161pub trait EnumInfo {
162    const DATA: EnumInfoData;
163    fn variants() -> impl IntoIterator<Item = StructInfoData> + Send + Sync + 'static;
164    fn variant_info(&self) -> StructInfoData;
165    fn variant_info_by_name(name: &str) -> Option<StructInfoData>;
166}
167
168#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
169pub struct EnumInfoData {
170    pub name: &'static str,
171    pub variant_count: usize,
172}
173
174#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
175pub struct Variant<'a, T: ?Sized> {
176    pub info: StructInfoData,
177    pub value: &'a T,
178}
179
180pub trait VisitVariant<V: Visitor>: EnumInfo {
181    fn visit_variant(&self, visitor: &mut V) -> V::Result;
182}
183
184pub trait VisitVariantsStatic<V: Visitor>: EnumInfo {
185    fn visit_variants_static<'a>(visitor: &'a mut V) -> impl Iterator<Item = V::Result> + 'a;
186}
187
188pub trait VisitVariantFields<V: Visitor>: EnumInfo {
189    fn visit_variant_fields<'a>(
190        &'a self,
191        visitor: &'a mut V,
192    ) -> impl Iterator<Item = V::Result> + 'a;
193}
194
195pub trait VisitVariantFieldsCovered<V: Visitor>: EnumInfo {
196    fn visit_variant_fields_covered<'a>(
197        &'a self,
198        visitor: &'a mut V,
199    ) -> impl Iterator<Item = V::Result> + 'a;
200}
201
202pub trait VisitVariantFieldsStatic<V: Visitor>: EnumInfo {
203    fn visit_variant_fields_static<'a>(
204        info: &'a StructInfoData,
205        visitor: &'a mut V,
206    ) -> impl Iterator<Item = V::Result> + 'a;
207}
208
209pub trait VisitVariantFieldsAsync<V: Visitor>: EnumInfo {
210    fn visit_variant_fields_async<'a>(
211        &'a self,
212        visitor: &'a mut V,
213    ) -> impl Stream<Item = V::Result> + Send + 'a
214    where
215        V: Send,
216        V::Result: Send;
217}
218
219pub trait VisitVariantFieldsCoveredAsync<V: Visitor>: EnumInfo {
220    fn visit_variant_fields_covered_async<'a>(
221        &'a self,
222        visitor: &'a mut V,
223    ) -> impl Stream<Item = V::Result> + Send + 'a
224    where
225        V: Send,
226        V::Result: Send;
227}
228
229pub trait VisitVariantFieldsStaticAsync<V: Visitor>: EnumInfo {
230    fn visit_variant_fields_static_async<'a>(
231        info: &'a StructInfoData,
232        visitor: &'a mut V,
233    ) -> impl Stream<Item = V::Result> + 'a
234    where
235        V: Send,
236        V::Result: Send;
237}
238
239pub trait VisitVariantFieldsNamed<V: Visitor>: EnumInfo {
240    fn visit_variant_fields_named<'a>(
241        &'a self,
242        visitor: &'a mut V,
243    ) -> impl Iterator<Item = V::Result> + 'a;
244}
245
246pub trait VisitVariantFieldsStaticNamed<V: Visitor>: EnumInfo {
247    fn visit_variant_fields_static_named<'a>(
248        info: &'a StructInfoData,
249        visitor: &'a mut V,
250    ) -> impl Iterator<Item = V::Result> + 'a;
251}
252
253pub trait VisitVariantFieldsNamedAsync<V: Visitor>: EnumInfo {
254    fn visit_variant_fields_named_async<'a>(
255        &'a self,
256        visitor: &'a mut V,
257    ) -> impl Stream<Item = V::Result> + Send + 'a
258    where
259        V: Send,
260        V::Result: Send;
261}
262
263pub trait VisitVariantFieldsStaticNamedAsync<V: Visitor>: EnumInfo {
264    fn visit_variant_fields_static_named_async<'a>(
265        info: &'a StructInfoData,
266        visitor: &'a mut V,
267    ) -> impl Stream<Item = V::Result> + Send + 'a
268    where
269        V: Send,
270        V::Result: Send;
271}