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> {}