qlty_analysis/code/
line_index.rs

1use std::{
2    collections::{HashMap, HashSet},
3    ops::RangeInclusive,
4    path::{Path, PathBuf},
5};
6
7type LineNumber = u32;
8
9#[derive(Debug, Default, Clone)]
10pub struct FileInfo {
11    pub new_file: bool,
12    pub line_numbers: HashSet<LineNumber>,
13}
14
15impl FileInfo {
16    pub fn insert(&mut self, line_number: LineNumber) {
17        self.line_numbers.insert(line_number);
18    }
19}
20
21#[derive(Debug, Default, Clone)]
22pub struct FileIndex {
23    inner: HashMap<PathBuf, FileInfo>,
24}
25
26impl FileIndex {
27    pub fn new() -> Self {
28        Self::default()
29    }
30
31    pub fn insert_line(&mut self, path: &Path, line_number: LineNumber) {
32        if !self.inner.contains_key(path) {
33            self.inner.insert(
34                path.to_path_buf(),
35                FileInfo {
36                    new_file: false,
37                    line_numbers: HashSet::new(),
38                },
39            );
40        }
41
42        self.inner.get_mut(path).unwrap().insert(line_number);
43    }
44
45    pub fn insert_file(&mut self, path: &Path) {
46        if !self.inner.contains_key(path) {
47            self.inner.insert(
48                path.to_path_buf(),
49                FileInfo {
50                    new_file: true,
51                    line_numbers: HashSet::new(),
52                },
53            );
54        }
55    }
56
57    pub fn matches_path(&self, path: &Path) -> bool {
58        self.inner.contains_key(path)
59    }
60
61    /// If any of the inputes overlap the index, return true. Otherwise, return false.
62    pub fn matches_line_range(
63        &self,
64        path: &Path,
65        line_numbers: RangeInclusive<LineNumber>,
66    ) -> bool {
67        if let Some(file_info) = self.inner.get(path) {
68            if file_info.new_file {
69                return true;
70            }
71
72            for line_number in line_numbers {
73                if file_info.line_numbers.get(&line_number).is_some() {
74                    return true;
75                }
76            }
77
78            false
79        } else {
80            false
81        }
82    }
83}