rusty_source_map/
mapping_list.rs

1use crate::mapping::Mapping;
2use crate::source_map::Position;
3use crate::util;
4
5fn generated_position_after(a: &Mapping, b: &Mapping) -> bool {
6    let line_a = a.generated.line;
7    let line_b = b.generated.line;
8    let column_a = a.generated.column;
9    let column_b = b.generated.column;
10    line_b > line_a
11        || (line_b == line_a && column_b >= column_a)
12        || util::compare_by_generated_pos_inflated(a, b) <= 0
13}
14pub struct MappingList {
15    array: Vec<Mapping>,
16    sorted: bool,
17    last: Option<Mapping>,
18}
19
20impl Default for MappingList {
21    fn default() -> Self {
22        MappingList {
23            array: Vec::new(),
24            sorted: true,
25            last: None,
26        }
27    }
28}
29
30impl MappingList {
31    pub fn new() -> Self {
32        Default::default()
33    }
34
35    /// Iterate through internal items. This method takes the same arguments that
36    /// `Array.prototype.forEach` takes.
37
38    /// NOTE: The order of the mappings is NOT guaranteed.
39    pub fn unsorted_for_each(&self, callback: impl Fn(&Mapping, usize)) {
40        for (index, mapping) in self.array.iter().enumerate() {
41            callback(mapping, index);
42        }
43    }
44
45    pub fn add(&mut self, mapping: Mapping) {
46        if generated_position_after(
47            &self.last.clone().unwrap_or(Mapping {
48                name: None,
49                source: None,
50                generated: Position {
51                    column: -1,
52                    line: -1,
53                },
54                original: None,
55                last_generated_column: None,
56            }),
57            &mapping,
58        ) {
59            self.last = Some(mapping.clone());
60            self.array.push(mapping);
61        } else {
62            self.sorted = false;
63            self.array.push(mapping)
64        }
65    }
66
67    pub fn to_array(&mut self) -> Vec<Mapping> {
68        if !self.sorted {
69            self.array.sort_by(|a, b| {
70                let cmp = util::compare_by_generated_pos_inflated(a, b);
71                match cmp {
72                    d if d > 0 => std::cmp::Ordering::Greater,
73                    d if d == 0 => std::cmp::Ordering::Equal,
74                    _ => std::cmp::Ordering::Less,
75                }
76            });
77            self.sorted = true;
78        }
79
80        self.array.clone()
81    }
82}