rascal 0.3.4

A parser and compiler for Flash ActionScript 2 files into SWFs
Documentation
use crate::SourceProvider;
use crate::internal::span::FileId;
use std::fmt::Debug;
use std::sync::Arc;

#[derive(Debug, Default)]
pub(crate) struct SourceSet {
    sources: Vec<Arc<SourceFile>>,
}

impl SourceSet {
    pub fn new() -> Self {
        Self::default()
    }

    pub fn get_or_load<P: SourceProvider + ?Sized>(
        &mut self,
        path: String,
        provider: &P,
    ) -> Result<Arc<SourceFile>, std::io::Error> {
        if let Some(id) = self.sources.iter().position(|source| source.path == path) {
            return Ok(self.sources[id].clone());
        }

        let source = provider.load(&path)?;
        let file_id = FileId::new(self.sources.len());
        let source_file = Arc::new(SourceFile {
            path,
            file_id,
            source,
        });
        self.sources.push(source_file.clone());
        Ok(source_file)
    }

    pub fn get_source(&self, file_id: FileId) -> Option<&Arc<SourceFile>> {
        self.sources.get(file_id.0)
    }
}

pub(crate) struct SourceFile {
    pub path: String,
    pub file_id: FileId,
    pub source: String,
}

impl Debug for SourceFile {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_struct("SourceFile")
            .field("path", &self.path)
            .finish()
    }
}