const_format_proc_macros/datastructure/
field_map.rs

1use super::*;
2
3use std::ops::{Index, IndexMut};
4
5/**
6This is a map from fields to some value.
7
8If you put this in a type,and use Default to initialize it,
9you must remember to replace the `FieldMap` using either `FieldMap::defaulted` or `FieldMap::with`
10
11*/
12#[derive(Debug)]
13pub struct FieldMap<T> {
14    // The outer vec is the enum variant (if it's a struct/union it's a single element Vec),
15    // the inner one is the field within a variant/struct/union.
16    fields: Vec<Vec<T>>,
17}
18
19impl<T> FieldMap<T> {
20    /// Constructs an FieldMap which maps each field in the DataStructure to a value
21    /// (obtained by mapping each individual field to `T` using a closure).
22    pub fn with<'a, F>(ds: &'a DataStructure<'a>, mut f: F) -> Self
23    where
24        F: FnMut(&'a Field<'a>) -> T,
25    {
26        Self {
27            fields: ds
28                .variants
29                .iter()
30                .map(|vari| vari.fields.iter().map(&mut f).collect::<Vec<_>>())
31                .collect::<Vec<_>>(),
32        }
33    }
34
35    #[allow(dead_code)]
36    pub fn iter(&self) -> impl Iterator<Item = (FieldIndex, &'_ T)> + Clone + '_ {
37        self.fields.iter().enumerate().flat_map(|(v_i, v)| {
38            v.iter().enumerate().map(move |(f_i, f)| {
39                let index = FieldIndex {
40                    variant: v_i as _,
41                    pos: f_i as _,
42                };
43                (index, f)
44            })
45        })
46    }
47
48    #[allow(dead_code)]
49    pub fn iter_mut(&mut self) -> impl Iterator<Item = (FieldIndex, &'_ mut T)> + '_ {
50        self.fields.iter_mut().enumerate().flat_map(|(v_i, v)| {
51            v.iter_mut().enumerate().map(move |(f_i, f)| {
52                let index = FieldIndex {
53                    variant: v_i as _,
54                    pos: f_i as _,
55                };
56                (index, f)
57            })
58        })
59    }
60}
61
62impl<'a, T> Index<FieldIndex> for FieldMap<T> {
63    type Output = T;
64
65    fn index(&self, index: FieldIndex) -> &T {
66        &self.fields[index.variant][index.pos]
67    }
68}
69
70impl<'a, T> IndexMut<FieldIndex> for FieldMap<T> {
71    fn index_mut(&mut self, index: FieldIndex) -> &mut T {
72        &mut self.fields[index.variant][index.pos]
73    }
74}
75
76impl<'a, T> Index<&'a Field<'a>> for FieldMap<T> {
77    type Output = T;
78
79    fn index(&self, field: &'a Field<'a>) -> &T {
80        let index = field.index;
81        &self.fields[index.variant][index.pos]
82    }
83}
84
85impl<'a, T> IndexMut<&'a Field<'a>> for FieldMap<T> {
86    fn index_mut(&mut self, field: &'a Field<'a>) -> &mut T {
87        let index = field.index;
88        &mut self.fields[index.variant][index.pos]
89    }
90}