cratestack_parser/load/
sources.rs1use std::collections::HashMap;
5use std::io;
6use std::path::{Path, PathBuf};
7
8use super::paths::fold;
9
10pub trait SchemaSources {
12 fn read(&self, path: &Path) -> io::Result<String>;
13}
14
15#[derive(Debug, Clone, Copy, Default)]
17pub struct FsSources;
18
19impl SchemaSources for FsSources {
20 fn read(&self, path: &Path) -> io::Result<String> {
21 std::fs::read_to_string(path)
22 }
23}
24
25#[derive(Debug, Clone)]
28pub struct OverlaySources {
29 files: HashMap<PathBuf, String>,
30 fallback_to_disk: bool,
31}
32
33impl OverlaySources {
34 pub fn new(fallback_to_disk: bool) -> Self {
35 Self {
36 files: HashMap::new(),
37 fallback_to_disk,
38 }
39 }
40
41 pub fn insert(&mut self, path: impl AsRef<Path>, text: impl Into<String>) {
42 self.files
43 .insert(canonical_schema_path(path.as_ref()), text.into());
44 }
45}
46
47impl SchemaSources for OverlaySources {
48 fn read(&self, path: &Path) -> io::Result<String> {
49 match self.files.get(&canonical_schema_path(path)) {
50 Some(text) => Ok(text.clone()),
51 None if self.fallback_to_disk => std::fs::read_to_string(path),
52 None => Err(io::Error::from(io::ErrorKind::NotFound)),
53 }
54 }
55}
56
57pub fn canonical_schema_path(path: &Path) -> PathBuf {
62 if let Ok(canonical) = std::fs::canonicalize(path) {
63 return canonical;
64 }
65 let absolute = std::path::absolute(path).unwrap_or_else(|_| path.to_path_buf());
66 fold(&absolute)
67}