field_access/
lib.rs

1#![doc = include_str!("../README.md")]
2#![warn(missing_docs)]
3#![warn(clippy::pedantic)]
4#![allow(clippy::must_use_candidate)]
5#![no_std]
6
7#[cfg(feature = "alloc")]
8extern crate alloc;
9
10#[macro_use]
11mod macros;
12
13#[cfg(feature = "alloc")]
14use alloc::string::String;
15#[cfg(feature = "alloc")]
16use alloc::vec::Vec;
17use core::any::{Any, TypeId};
18use core::fmt;
19use core::iter::FusedIterator;
20use core::mem;
21use core::ops;
22use core::slice;
23use paste::paste;
24
25/// Derive macro for automatically implementing [`AnyFieldAccess`] on structs.
26#[cfg(feature = "derive")]
27pub use field_access_derive::FieldAccess;
28
29/// Low-level struct field access.
30///
31/// In most cases it is more convenient to use the methods of the [`FieldAccess`] trait which has a
32/// blanket implementation for any type implementing `AnyFieldAccess`.
33///
34/// Consider automatically implementing it via `#[derive(FieldAccess)]` for structs where you need
35/// dynamic field access.
36pub trait AnyFieldAccess: Any {
37    /// Provides an immutable reference to a struct field.
38    ///
39    /// Returns `Some(_)` if the field is accessible, otherwise `None`.
40    ///
41    /// # Example
42    ///
43    /// ```
44    /// use field_access::{AnyFieldAccess, FieldAccess};
45    ///
46    /// #[derive(FieldAccess)]
47    /// struct Foo {
48    ///     a: u8
49    /// }
50    ///
51    /// let foo = Foo { a: 1 };
52    /// let field = foo.field_as_any("a");
53    ///
54    /// assert!(field.is_some());
55    /// assert_eq!(field.unwrap().downcast_ref::<u8>(), Some(&1));
56    /// ```
57    fn field_as_any(&self, field: &str) -> Option<&dyn Any>;
58
59    /// Provides a mutable reference to a struct field.
60    ///
61    /// Returns `Some(_)` if the field is accessible, otherwise `None`.
62    ///
63    /// # Example
64    ///
65    /// ```
66    /// use field_access::{AnyFieldAccess, FieldAccess};
67    ///
68    /// #[derive(FieldAccess)]
69    /// struct Foo {
70    ///     a: u8
71    /// }
72    ///
73    /// let mut foo = Foo { a: 1 };
74    ///
75    /// if let Some(field) = foo.field_as_any_mut("a") {
76    ///     if let Some(value) = field.downcast_mut::<u8>() {
77    ///         *value = 2;
78    ///     }
79    /// }
80    ///
81    /// assert_eq!(foo.a, 2);
82    /// ```
83    fn field_as_any_mut(&mut self, field: &str) -> Option<&mut dyn Any>;
84
85    /// Provides the names of all accessible fields.
86    ///
87    /// The field name order is undefined and should not be relied upon.
88    ///
89    /// # Example
90    ///
91    /// ```
92    /// use field_access::{AnyFieldAccess, FieldAccess};
93    ///
94    /// #[derive(FieldAccess, Default)]
95    /// struct Foo {
96    ///     a: u8,
97    ///     b: bool,
98    /// }
99    ///
100    /// let foo = Foo::default();
101    ///
102    /// assert_eq!(foo.field_names(), &["a", "b"]);
103    /// ```
104    fn field_names(&self) -> &'static [&'static str];
105}
106
107/// High-level struct field access.
108///
109/// This trait is automatically implemented by any type implementing
110/// [`AnyFieldAccess`]. See its documentation for more details.
111pub trait FieldAccess: AnyFieldAccess {
112    /// Immutable field access.
113    ///
114    /// Returns `Some(_)` if the field is accessible, otherwise `None`.
115    ///
116    /// The returned [`Field`] provides methods to immutably interact with the field. See its
117    /// documentation for more.
118    ///
119    /// # Example
120    ///
121    /// ```
122    /// use field_access::FieldAccess;
123    ///
124    /// #[derive(FieldAccess)]
125    /// struct Foo {
126    ///     a: u8
127    /// }
128    ///
129    /// let foo = Foo { a: 1 };
130    ///
131    /// assert!(foo.field("a").is_some());
132    /// assert!(foo.field("b").is_none());
133    /// ```
134    #[inline]
135    fn field(&self, field: &str) -> Option<Field<'_>> {
136        self.field_as_any(field).map(Field::new)
137    }
138
139    /// Mutable field access.
140    ///
141    /// Returns `Some(_)` if the field is accessible, otherwise `None`.
142    ///
143    /// The returned [`FieldMut`] provides methods to mutably interact with the field. See its
144    /// documentation for more.
145    ///
146    /// # Example
147    ///
148    /// ```
149    /// use field_access::FieldAccess;
150    ///
151    /// #[derive(FieldAccess)]
152    /// struct Foo {
153    ///     a: u8
154    /// }
155    ///
156    /// let mut foo = Foo { a: 1 };
157    ///
158    /// assert!(foo.field_mut("a").is_some());
159    /// assert!(foo.field_mut("b").is_none());
160    /// ```
161    #[inline]
162    fn field_mut(&mut self, field: &str) -> Option<FieldMut<'_>> {
163        self.field_as_any_mut(field).map(FieldMut::new)
164    }
165
166    /// Returns an iterator over all struct fields.
167    ///
168    /// The order of the items yielded by the iterator is undefined and should not be relied upon.
169    ///
170    /// # Example
171    ///
172    /// ```
173    /// use field_access::FieldAccess;
174    ///
175    /// #[derive(FieldAccess)]
176    /// struct Foo {
177    ///     a: u8,
178    ///     b: u16,
179    ///     c: u32
180    /// }
181    ///
182    /// let foo = Foo { a: 1, b: 2, c: 3 };
183    /// let tuples: Vec<_> = foo.fields()
184    ///                         .map(|(name, field)| (name, field.as_u8()))
185    ///                         .collect();
186    /// assert_eq!(tuples, &[("a", Some(1)),
187    ///                      ("b", Some(2)),
188    ///                      ("c", Some(3))])
189    /// ```
190    #[inline]
191    fn fields(&self) -> Fields<'_>
192    where
193        Self: Sized,
194    {
195        Fields::new(self)
196    }
197}
198
199impl<T> FieldAccess for T where T: AnyFieldAccess {}
200
201/// An immutable struct field reference.
202///
203/// A `FieldRef` is a proxy for immutable operations on a struct's field.
204///
205/// Values of this type are created by [`FieldAccess::field`].
206#[derive(Debug, Clone)]
207pub struct Field<'a> {
208    value: &'a dyn Any,
209}
210
211impl<'a> Field<'a> {
212    fn new(value: &'a dyn Any) -> Self {
213        Field { value }
214    }
215
216    /// Returns `true` if the field is of type `T`.
217    ///
218    /// # Example
219    ///
220    /// ```
221    /// use field_access::FieldAccess;
222    ///
223    /// #[derive(FieldAccess)]
224    /// struct Foo {
225    ///     a: u8
226    /// }
227    ///
228    /// let foo = Foo { a: 1 };
229    /// let field = foo.field("a").unwrap();
230    ///
231    /// assert!(field.is::<u8>());
232    /// assert!(!field.is::<&str>());
233    /// ```
234    #[inline]
235    pub fn is<T: Any>(&self) -> bool {
236        self.value.is::<T>()
237    }
238
239    /// Gets the `TypeId` of the field's value.
240    ///
241    /// # Example
242    ///
243    /// ```
244    /// use core::any::TypeId;
245    /// use field_access::FieldAccess;
246    ///
247    /// #[derive(FieldAccess)]
248    /// struct Foo {
249    ///     a: u8
250    /// }
251    ///
252    /// let foo = Foo { a: 1 };
253    /// let field = foo.field("a").unwrap();
254    ///
255    /// assert_eq!(field.type_id(), TypeId::of::<u8>());
256    /// ```
257    #[inline]
258    pub fn type_id(&self) -> TypeId {
259        self.value.type_id()
260    }
261
262    /// Obtains an immutable reference to the value of type `T`.
263    ///
264    /// Returns `Some(_)` if field's value is of type `T`, `None` otherwise.
265    ///
266    /// # Example
267    ///
268    /// ```
269    /// use field_access::FieldAccess;
270    ///
271    /// #[derive(FieldAccess)]
272    /// struct Foo {
273    ///     a: u8
274    /// }
275    ///
276    /// let foo = Foo { a: 42 };
277    /// let field = foo.field("a").unwrap();
278    ///
279    /// assert_eq!(field.get::<u8>(), Some(&42u8));
280    /// assert_eq!(field.get::<&str>(), None);
281    /// ```
282    #[inline]
283    pub fn get<T: Any>(&self) -> Option<&T> {
284        self.value.downcast_ref::<T>()
285    }
286
287    /// Obtains an immutable reference to the value as `&dyn Any`.
288    ///
289    /// # Example
290    ///
291    /// ```
292    /// use field_access::FieldAccess;
293    ///
294    /// #[derive(FieldAccess)]
295    /// struct Foo {
296    ///     a: u8
297    /// }
298    ///
299    /// let foo = Foo { a: 42 };
300    /// let field = foo.field("a").unwrap();
301    /// let any = field.as_any();
302    ///
303    /// assert_eq!(any.downcast_ref::<u8>(), Some(&42u8));
304    /// ```
305    #[inline]
306    pub fn as_any(&self) -> &dyn Any {
307        self.value
308    }
309
310    /// Returns `true` if the field value is of type `&[T]`.
311    ///
312    /// # Example
313    ///
314    /// ```
315    /// use field_access::FieldAccess;
316    ///
317    /// #[derive(FieldAccess)]
318    /// struct Foo {
319    ///     a: &'static [u8]
320    /// }
321    ///
322    /// let foo = Foo { a: &[1, 2, 3] };
323    /// let field = foo.field("a").unwrap();
324    ///
325    /// assert!(field.is_slice::<u8>());
326    /// ```
327    #[inline]
328    pub fn is_slice<T: Any>(&self) -> bool {
329        self.is::<&[T]>()
330    }
331
332    /// Obtain an immutable reference to the value as `&[T]`.
333    ///
334    /// Returns `Some(_)` if [`.is_slice::<T>()`](Self::is_slice) or
335    /// [`.is_vec::<T>()`][Self::is_vec] would return `true`, `None` otherwise.
336    ///
337    /// # Example
338    ///
339    /// ```
340    /// use field_access::FieldAccess;
341    ///
342    /// #[derive(FieldAccess)]
343    /// struct Foo {
344    ///     a: Vec<u8>
345    /// }
346    ///
347    /// let foo = Foo { a: vec![1, 2, 3] };
348    /// let field = foo.field("a").unwrap();
349    ///
350    /// assert_eq!(field.as_slice(), Some(&[1u8, 2, 3][..]));
351    /// ```
352    #[cfg(feature = "alloc")]
353    pub fn as_slice<T: Any>(&self) -> Option<&[T]> {
354        get_downcast_ref!(
355            self.value,
356            &[T] => |&v| Some(v),
357            Vec<T> => |v| Some(v.as_slice())
358        )
359    }
360
361    /// Obtain an immutable reference to the value as `&[T]`.
362    ///
363    /// Returns `Some(_)` if field's value is of type `&[T]`, `None` otherwise.
364    ///
365    /// # Example
366    ///
367    /// ```
368    /// use field_access::FieldAccess;
369    ///
370    /// #[derive(FieldAccess)]
371    /// struct Foo {
372    ///     a: &'static [u8]
373    /// }
374    ///
375    /// let foo = Foo { a: &[1, 2, 3] };
376    /// let field = foo.field("a").unwrap();
377    ///
378    /// assert_eq!(field.as_slice(), Some(&[1u8, 2, 3][..]));
379    /// ```
380    #[cfg(not(feature = "alloc"))]
381    #[inline]
382    pub fn as_slice<T: Any>(&self) -> Option<&[T]> {
383        self.get().copied()
384    }
385
386    /// Returns `true` if the field value is of type `Vec<T>`.
387    ///
388    /// # Example
389    ///
390    /// ```
391    /// use field_access::FieldAccess;
392    ///
393    /// #[derive(FieldAccess)]
394    /// struct Foo {
395    ///     a: Vec<u8>
396    /// }
397    ///
398    /// let foo = Foo { a: vec![1, 2, 3] };
399    /// let field = foo.field("a").unwrap();
400    ///
401    /// assert!(field.is_vec::<u8>());
402    /// assert!(!field.is_vec::<u16>());
403    /// ```
404    #[cfg(feature = "alloc")]
405    #[inline]
406    pub fn is_vec<T: Any>(&self) -> bool {
407        self.is::<Vec<T>>()
408    }
409
410    /// Returns `true` if the field value is of type `String`.
411    ///
412    /// # Example
413    ///
414    /// ```
415    /// use field_access::FieldAccess;
416    ///
417    /// #[derive(FieldAccess)]
418    /// struct Foo {
419    ///     a: String,
420    /// }
421    ///
422    /// let foo = Foo { a: String::from("bar") };
423    /// let field = foo.field("a").unwrap();
424    ///
425    /// assert!(field.is_string());
426    /// assert!(!field.is_str());
427    /// ```
428    #[cfg(feature = "alloc")]
429    #[inline]
430    pub fn is_string(&self) -> bool {
431        self.is::<String>()
432    }
433
434    /// Returns `true` if the field value is of type `&str`.
435    ///
436    /// # Example
437    ///
438    /// ```
439    /// use field_access::FieldAccess;
440    ///
441    /// #[derive(FieldAccess)]
442    /// struct Foo {
443    ///     a: &'static str,
444    /// }
445    ///
446    /// let foo = Foo { a: "bar" };
447    /// let field = foo.field("a").unwrap();
448    ///
449    /// assert!(field.is_str());
450    /// ```
451    #[inline]
452    pub fn is_str(&self) -> bool {
453        self.is::<&str>()
454    }
455
456    /// Obtain an immutable reference to the value as `&str`.
457    ///
458    /// Returns `Some(_)` if [`.is_str()`](Self::is_str) or [`.is_string()`][Self::is_string] would
459    /// return `true`, `None` otherwise.
460    ///
461    /// # Example
462    ///
463    /// ```
464    /// use field_access::FieldAccess;
465    ///
466    /// #[derive(FieldAccess)]
467    /// struct Foo {
468    ///     a: String
469    /// }
470    ///
471    /// let foo = Foo { a: String::from("bar") };
472    /// let field = foo.field("a").unwrap();
473    ///
474    /// assert_eq!(field.as_str(), Some("bar"));
475    /// ```
476    #[cfg(feature = "alloc")]
477    pub fn as_str(&self) -> Option<&str> {
478        get_downcast_ref!(
479            self.value,
480            &str => |&v| Some(v),
481            String => |v| Some(v.as_str())
482        )
483    }
484
485    /// Obtain an immutable reference to the value as `&str`.
486    ///
487    /// Returns `Some(_)` if field's value is of type `&str`, `None` otherwise.
488    ///
489    /// # Example
490    ///
491    /// ```
492    /// use field_access::FieldAccess;
493    ///
494    /// #[derive(FieldAccess)]
495    /// struct Foo {
496    ///     a: &'static str
497    /// }
498    ///
499    /// let foo = Foo { a: "bar" };
500    /// let field = foo.field("a").unwrap();
501    ///
502    /// assert_eq!(field.as_str(), Some("bar"));
503    /// ```
504    #[cfg(not(feature = "alloc"))]
505    #[inline]
506    pub fn as_str(&self) -> Option<&str> {
507        self.get().copied()
508    }
509
510    is_type_method!(bool);
511    is_type_method!(u8, u16, u32, u64, u128, usize);
512    is_type_method!(i8, i16, i32, i64, i128, isize);
513    is_type_method!(f32, f64);
514
515    as_type_method!(bool);
516    as_type_method! {
517        u8 { u16 | u32 | u64 | u128 | usize => |&v| v.try_into().ok() },
518        u16 {
519            u8 => |&v| Some(v.into()),
520            u32 | u64 | u128 | usize => |&v| v.try_into().ok(),
521        },
522        u32 {
523            u16 | u8 => |&v| Some(v.into()),
524            u64 | u128 | usize => |&v| v.try_into().ok(),
525        },
526        u64 {
527            u32 | u16 | u8 => |&v| Some(v.into()),
528            u128 | usize => |&v| v.try_into().ok(),
529        },
530        u128 {
531            u8 | u16 | u32 | u64 => |&v| Some(v.into()),
532            usize => |&v| v.try_into().ok(),
533        },
534        usize {
535            u16 | u8 => |&v| Some(v.into()),
536            u32 | u64 | u128 => |&v| v.try_into().ok(),
537        },
538    }
539    as_type_method! {
540        i8 { i16 | i32 | i64 | i128 | isize => |&v| v.try_into().ok() },
541        i16 {
542            i8 => |&v| Some(v.into()),
543            i32 | i64 | i128 | isize => |&v| v.try_into().ok(),
544        },
545        i32 {
546            i16 | i8 => |&v| Some(v.into()),
547            i64 | i128 | isize => |&v| v.try_into().ok(),
548        },
549        i64 {
550            i32 | i16 | i8 => |&v| Some(v.into()),
551            i128 | isize => |&v| v.try_into().ok(),
552        },
553        i128 {
554            i8 | i16 | i32 | i64 => |&v| Some(v.into()),
555            isize => |&v| v.try_into().ok(),
556        },
557        isize {
558            i16 | i8 => |&v| Some(v.into()),
559            i32 | i64 | i128 => |&v| v.try_into().ok(),
560        },
561    }
562    as_type_method! {
563        f32,
564        f64 { f32 => |&v| Some(v.into()) }
565    }
566}
567
568/// A mutable struct field reference.
569///
570/// A `FieldMut` is a proxy for mutable operations on a struct's field.
571///
572/// Values of this type are created by [`FieldAccess::field_mut`].
573#[derive(Debug)]
574pub struct FieldMut<'a> {
575    value: &'a mut dyn Any,
576}
577
578impl<'a> FieldMut<'a> {
579    fn new(value: &'a mut dyn Any) -> Self {
580        FieldMut { value }
581    }
582
583    /// Obtains a mutable reference to the value of type `T`.
584    ///
585    /// Returns `Some(_)` if field's value is of type `T`, `None` otherwise.
586    ///
587    /// # Example
588    ///
589    /// ```
590    /// use field_access::FieldAccess;
591    ///
592    /// #[derive(FieldAccess)]
593    /// struct Foo {
594    ///     a: u8
595    /// }
596    ///
597    /// let mut foo = Foo { a: 1 };
598    /// let mut field = foo.field_mut("a").unwrap();
599    ///
600    /// if let Some(field) = field.get_mut::<u8>() {
601    ///     *field = 42;
602    /// }
603    ///
604    /// assert_eq!(field.as_u8(), Some(42u8));
605    /// assert_eq!(field.get_mut::<&str>(), None);
606    /// ```
607    #[inline]
608    pub fn get_mut<T: Any>(&mut self) -> Option<&mut T> {
609        self.value.downcast_mut::<T>()
610    }
611
612    /// Obtains a mutable reference to the value as `&mut dyn Any`.
613    ///
614    /// # Example
615    ///
616    /// ```
617    /// use field_access::FieldAccess;
618    ///
619    /// #[derive(FieldAccess)]
620    /// struct Foo {
621    ///     a: u8
622    /// }
623    ///
624    /// let mut foo = Foo { a: 42 };
625    ///
626    /// let mut field = foo.field_mut("a").unwrap();
627    /// let any = field.as_any_mut();
628    ///
629    /// if let Some(value) = any.downcast_mut::<u8>() {
630    ///     *value = 42;
631    /// }
632    ///
633    /// assert_eq!(foo.a, 42);
634    /// ```
635    #[inline]
636    pub fn as_any_mut(&mut self) -> &mut dyn Any {
637        self.value
638    }
639
640    /// Sets the value of the field.
641    ///
642    /// Returns `true` if it was possible to replace the field's value with a value of type `T`,
643    /// `false` otherwise.
644    ///
645    /// # Example
646    ///
647    /// ```
648    /// use field_access::FieldAccess;
649    ///
650    /// #[derive(FieldAccess)]
651    /// struct Foo {
652    ///     a: u8
653    /// }
654    ///
655    /// let mut foo = Foo { a: 1 };
656    /// let mut field = foo.field_mut("a").unwrap();
657    ///
658    /// assert!(field.set(42u8));
659    /// assert_eq!(foo.a, 42);
660    /// ```
661    #[inline]
662    pub fn set<T: Any>(&mut self, value: T) -> bool {
663        self.replace(value).is_some()
664    }
665
666    /// Replaces the value of the field, returning the previous value.
667    ///
668    /// Returns `Some(old_value)` if it was possible to replace the field's value with a value of
669    /// type `T`, `None` otherwise.
670    ///
671    /// # Example
672    ///
673    /// ```
674    /// use field_access::FieldAccess;
675    ///
676    /// #[derive(FieldAccess)]
677    /// struct Foo {
678    ///     a: u8
679    /// }
680    ///
681    /// let mut foo = Foo { a: 1 };
682    /// let mut field = foo.field_mut("a").unwrap();
683    ///
684    /// assert_eq!(field.replace(42u8), Some(1));
685    /// assert_eq!(foo.a, 42);
686    /// ```
687    #[inline]
688    pub fn replace<T: Any>(&mut self, value: T) -> Option<T> {
689        self.get_mut().map(|dest| mem::replace(dest, value))
690    }
691
692    /// Swaps the value of the field and another mutable location.
693    ///
694    /// Returns `true` if it was possible to replace the field's value with a value of type `T`,
695    /// `false` otherwise.
696    ///
697    /// # Example
698    ///
699    /// ```
700    /// use field_access::FieldAccess;
701    ///
702    /// #[derive(FieldAccess)]
703    /// struct Foo {
704    ///     a: u8
705    /// }
706    ///
707    /// let mut foo = Foo { a: 1 };
708    /// let mut value = 2u8;
709    /// let mut field = foo.field_mut("a").unwrap();
710    ///
711    /// assert!(field.swap(&mut value));
712    /// assert_eq!(foo.a, 2);
713    /// assert_eq!(value, 1);
714    /// ```
715    #[inline]
716    pub fn swap<T: Any>(&mut self, value: &mut T) -> bool {
717        self.get_mut().map(|dest| mem::swap(dest, value)).is_some()
718    }
719
720    /// Takes the value of the field, replacing it with its default value.
721    ///
722    /// Returns `Some(_)` if it was possible to replace the field's value with the default value of
723    /// type `T`, `None` otherwise.
724    ///
725    /// # Example
726    ///
727    /// ```
728    /// use field_access::FieldAccess;
729    ///
730    /// #[derive(FieldAccess)]
731    /// struct Foo {
732    ///     a: u8
733    /// }
734    ///
735    /// let mut foo = Foo { a: 42 };
736    /// let mut field = foo.field_mut("a").unwrap();
737    ///
738    /// assert_eq!(field.take(), Some(42u8));
739    /// assert_eq!(foo.a, 0);
740    /// ```
741    #[inline]
742    pub fn take<T: Any + Default>(&mut self) -> Option<T> {
743        self.replace(T::default())
744    }
745
746    /// Returns a mutable reference to the value as `&mut Vec<T>`.
747    ///
748    /// Returns `Some(_)` if the field's value is of type `Vec<T>`, `None` otherwise.
749    ///
750    /// # Example
751    ///
752    /// ```
753    /// use field_access::FieldAccess;
754    ///
755    /// #[derive(FieldAccess)]
756    /// struct Foo {
757    ///     a: Vec<u8>
758    /// }
759    ///
760    /// let mut foo = Foo { a: vec![1, 2, 3] };
761    /// let mut field = foo.field_mut("a").unwrap();
762    ///
763    /// if let Some(vec) = field.as_vec_mut::<u8>() {
764    ///     vec.push(4);
765    /// }
766    ///
767    /// assert_eq!(foo.a, vec![1, 2, 3, 4]);
768    /// ```
769    #[cfg(feature = "alloc")]
770    #[inline]
771    pub fn as_vec_mut<T: Any>(&mut self) -> Option<&mut Vec<T>> {
772        self.get_mut::<Vec<T>>()
773    }
774
775    #[cfg(feature = "alloc")]
776    as_type_mut_method!(String {
777        example_value: String::from("bar")
778    });
779
780    as_type_mut_method!(bool {
781        example_value: true
782    });
783    as_type_mut_method!(u8, u16, u32, u64, u128, usize);
784    as_type_mut_method!(i8, i16, i32, i64, i128, isize);
785    as_type_mut_method!(f32, f64);
786}
787
788impl<'a> AsRef<Field<'a>> for FieldMut<'a> {
789    fn as_ref(&self) -> &Field<'a> {
790        // SAFETY: `FieldMut` and `Field` share the same memory layout and we're holding an
791        // immutable reference.
792        unsafe { &*(self as *const FieldMut).cast::<Field>() }
793    }
794}
795
796impl<'a> ops::Deref for FieldMut<'a> {
797    type Target = Field<'a>;
798
799    fn deref(&self) -> &Self::Target {
800        self.as_ref()
801    }
802}
803
804/// An immutable iterator over all fields of a struct.
805///
806/// Values of this type are created by [`FieldAccess::fields`].
807#[derive(Clone)]
808pub struct Fields<'a> {
809    access: &'a dyn FieldAccess,
810    field_names: slice::Iter<'a, &'static str>,
811}
812
813impl<'a> Fields<'a> {
814    fn new(access: &'a dyn FieldAccess) -> Self {
815        Fields {
816            access,
817            field_names: access.field_names().iter(),
818        }
819    }
820}
821
822impl<'a> fmt::Debug for Fields<'a> {
823    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
824        f.debug_list().entries(self.access.field_names()).finish()
825    }
826}
827
828impl<'a> Iterator for Fields<'a> {
829    type Item = (&'static str, Field<'a>);
830
831    fn next(&mut self) -> Option<Self::Item> {
832        self.field_names
833            .next()
834            .and_then(|&name| self.access.field(name).map(|field| (name, field)))
835    }
836
837    fn size_hint(&self) -> (usize, Option<usize>) {
838        self.field_names.size_hint()
839    }
840}
841
842impl<'a> DoubleEndedIterator for Fields<'a> {
843    fn next_back(&mut self) -> Option<Self::Item> {
844        self.field_names
845            .next_back()
846            .and_then(|&name| self.access.field(name).map(|field| (name, field)))
847    }
848}
849
850impl<'a> ExactSizeIterator for Fields<'a> {}
851impl<'a> FusedIterator for Fields<'a> {}