maudit_rolldown_sourcemap/
source.rs

1use std::fmt::Debug;
2
3use oxc_sourcemap::SourceMap;
4
5pub trait Source {
6  fn sourcemap(&self) -> Option<&SourceMap>;
7  fn content(&self) -> &str;
8  fn lines_count(&self) -> u32 {
9    lines_count(self.content())
10  }
11}
12
13impl Source for &str {
14  fn sourcemap(&self) -> Option<&SourceMap> {
15    None
16  }
17
18  fn content(&self) -> &str {
19    self
20  }
21}
22
23impl Source for String {
24  fn sourcemap(&self) -> Option<&SourceMap> {
25    None
26  }
27
28  fn content(&self) -> &str {
29    self
30  }
31}
32
33#[derive(Debug)]
34pub struct SourceMapSource {
35  content: String,
36  sourcemap: SourceMap,
37  pre_computed_lines_count: Option<u32>,
38}
39
40impl SourceMapSource {
41  pub fn new(content: String, sourcemap: SourceMap) -> Self {
42    Self { content, sourcemap, pre_computed_lines_count: None }
43  }
44
45  #[must_use]
46  pub fn with_pre_compute_sourcemap_data(mut self, pre_compute: bool) -> Self {
47    if pre_compute {
48      self.pre_computed_lines_count = Some(lines_count(&self.content));
49    }
50    self
51  }
52}
53
54impl Source for SourceMapSource {
55  fn sourcemap(&self) -> Option<&SourceMap> {
56    Some(&self.sourcemap)
57  }
58
59  fn content(&self) -> &str {
60    &self.content
61  }
62
63  fn lines_count(&self) -> u32 {
64    self.pre_computed_lines_count.unwrap_or_else(|| lines_count(&self.content))
65  }
66}
67
68impl Source for &Box<dyn Source + Send + Sync> {
69  fn sourcemap(&self) -> Option<&SourceMap> {
70    self.as_ref().sourcemap()
71  }
72
73  fn content(&self) -> &str {
74    self.as_ref().content()
75  }
76
77  fn lines_count(&self) -> u32 {
78    self.as_ref().lines_count()
79  }
80}
81
82#[allow(clippy::cast_possible_truncation)]
83#[inline]
84fn lines_count(str: &str) -> u32 {
85  memchr::memmem::find_iter(str.as_bytes(), "\n").count() as u32
86}
87
88#[test]
89fn test() {
90  assert_eq!(lines_count("a\nb\nc"), 2);
91  assert_eq!(lines_count("a\nb\nc\n"), 3);
92  assert_eq!(lines_count("a"), 0);
93}