Skip to main content

cfg_symbol/
intern.rs

1//! Interns symbols and implements symbol mappings.
2
3use crate::*;
4
5#[cfg(feature = "serde")]
6use serde::{Deserialize, Serialize};
7
8/// Contains maps for translation between internal and external symbols.
9#[derive(Clone, Default, Debug)]
10#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11#[derive(miniserde::Serialize, miniserde::Deserialize)]
12pub struct Mapping {
13    /// An array of internal symbols, indexed by external symbol ID.
14    pub to_internal: Vec<Option<Symbol>>,
15    /// An array of external symbols, indexed by internal symbol ID.
16    pub to_external: Vec<Symbol>,
17}
18
19impl Mapping {
20    /// Creates an empty `Mapping`. It has zero internal symbols,
21    /// and space for the given number of external symbols.
22    pub fn new(num_external: usize) -> Self {
23        Mapping {
24            to_internal: vec![None; num_external],
25            to_external: vec![],
26        }
27    }
28
29    /// Translates symbols in this map using another symbol map.
30    /// This map becomes a combination of both mappings.
31    pub fn translate(&mut self, other: &Self) {
32        // For mapping to internal.
33        for internal in &mut self.to_internal[..] {
34            *internal = if let Some(sym) = *internal {
35                other.to_internal.get(sym.usize()).and_then(|&x| x)
36            } else {
37                None
38            };
39        }
40        // For mapping to external.
41        let remapped = other
42            .to_external
43            .iter()
44            .map(|middle| self.to_external[middle.usize()])
45            .collect();
46        self.to_external = remapped;
47    }
48}