Skip to main content

forge/brutalizer/
transform.rs

1use solar::ast::Span;
2
3pub(super) enum Transform {
4    Insert { offset: usize, replacement: String },
5    Replace { span: Span, replacement: String },
6}
7
8impl Transform {
9    fn start(&self) -> usize {
10        match self {
11            Self::Insert { offset, .. } => *offset,
12            Self::Replace { span, .. } => span.lo().0 as usize,
13        }
14    }
15
16    fn end(&self) -> usize {
17        match self {
18            Self::Insert { offset, .. } => *offset,
19            Self::Replace { span, .. } => span.hi().0 as usize,
20        }
21    }
22}
23
24pub(super) fn span_text(source: &str, span: Span) -> Option<&str> {
25    let lo = span.lo().0 as usize;
26    let hi = span.hi().0 as usize;
27    source.get(lo..hi)
28}
29
30pub(super) fn apply_transforms(source: &str, mut transforms: Vec<Transform>) -> String {
31    transforms.sort_by(|a, b| b.start().cmp(&a.start()).then_with(|| b.end().cmp(&a.end())));
32
33    let mut result = source.to_string();
34    for transform in transforms {
35        match transform {
36            Transform::Insert { offset, replacement } => result.insert_str(offset, &replacement),
37            Transform::Replace { span, replacement } => {
38                let lo = span.lo().0 as usize;
39                let hi = span.hi().0 as usize;
40                result.replace_range(lo..hi, &replacement);
41            }
42        }
43    }
44    result
45}