Skip to main content

huff_neo_utils/file/
full_file_source.rs

1use crate::file::file_source::FileSource;
2use crate::prelude::Span;
3use serde::{Deserialize, Serialize};
4use std::sync::Arc;
5
6#[allow(clippy::to_string_in_format_args)]
7/// An aliased output location to derive from the cli arguments.
8#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Default)]
9pub struct OutputLocation(pub String);
10
11/// Full File Source
12#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Clone)]
13pub struct FullFileSource<'a> {
14    /// Flattened file source
15    pub source: &'a str,
16    /// The top level file source
17    pub file: Option<Arc<FileSource>>,
18    /// Files and their associated spans in the flattend file source
19    pub spans: Vec<(Arc<FileSource>, Span)>,
20}
21
22impl FullFileSource<'_> {
23    /// Get the relative span by position. Because the file source is flattened, we need to find the correct file source.
24    pub fn relative_span_by_pos(&self, start: usize, end: usize) -> Span {
25        // If spans are empty we have a single file source e.g. for tests
26        if self.spans.is_empty() {
27            return Span { start, end, file: self.file.clone() };
28        }
29        let span_opt = self
30            .spans
31            .iter()
32            .filter(|s| s.1.start <= start && s.1.end >= end)
33            .map(|s| Span { start: start - s.1.start, end: end - s.1.start, file: Some(s.0.clone()) })
34            .collect::<Vec<Span>>()
35            .into_iter()
36            .next();
37        if let Some(span) = span_opt { span } else { Span { start, end, file: self.file.clone() } }
38    }
39}