maudit_rolldown_sourcemap/
source.rs1use 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}