use std::{
ffi::OsStr,
fs::File,
os::unix::ffi::OsStrExt,
};
use crate::{
fmt::{self, Display},
symbol::{self, Symbol},
};
#[derive(Debug)]
pub struct Source {
pub path: Symbol,
pub contents: Box<[u8]>,
}
impl Source {
pub fn from_path(symbol: Symbol, interner: &mut symbol::Interner) -> std::io::Result<Self> {
let path = OsStr::from_bytes(
interner
.resolve(symbol)
.expect("failed to resolve path symbol")
);
let file = File::open(path)?;
Self::from_reader(symbol, file)
}
pub fn from_reader<R>(path: Symbol, mut reader: R) -> std::io::Result<Self>
where
R: std::io::Read,
{
let mut contents = Vec::with_capacity(512); reader.read_to_end(&mut contents)?;
Ok(Self { path, contents: contents.into() })
}
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
pub struct SourcePos {
pub line: u32,
pub column: u32,
pub path: Symbol,
}
impl<'a> Display<'a> for SourcePos {
type Context = &'a symbol::Interner;
fn fmt(&self, f: &mut std::fmt::Formatter, context: Self::Context) -> std::fmt::Result {
write!(
f,
"{} (line {}, column {})",
fmt::Show(self.path, context),
self.line,
self.column
)
}
}