diff --git a/src/lib.rs b/src/lib.rs index 94b0cc2..6f013dd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,42 +8,39 @@ use { syn::{parse, LitStr}, }; +mod source_reader; + struct ShaderModule { - source_file: std::path::PathBuf, source_text: String, naga_module: naga::Module, } impl ShaderModule { fn try_new(source_file: impl Into) -> Result { - let source_file = source_file.into(); - let source_text = fs::read_to_string(&source_file).map_err(|err| { - Error::from_message(format!( - "Could not open \"{}\": {}", - &source_file.as_os_str().to_string_lossy(), - err - )) - })?; + let source_filename = source_file.into(); + let source_file = source_reader::read_source_file(source_filename)?; + let source_text = source_file.full_text().to_string(); let naga_module = wgsl::parse_str(&source_text).map_err(|err| { if let Some(location) = err.location(&source_text) { + let (inner_source_filename, inner_line_num) = + source_file.map_source_line_num(location.line_number as usize); Error::Message(format!( "Error in {} at line {}, column {}:\n{}", - &source_file.as_os_str().to_string_lossy(), - location.line_number, + &inner_source_filename.as_os_str().to_string_lossy(), + inner_line_num, location.line_position, err.message() )) } else { Error::Message(format!( "Error in {}:\n{}", - &source_file.as_os_str().to_string_lossy(), + &source_file.root_filename().as_os_str().to_string_lossy(), err.message() )) } })?; Ok(Self { - source_file, source_text, naga_module, }) diff --git a/src/source_reader.rs b/src/source_reader.rs new file mode 100644 index 0000000..e6deccf --- /dev/null +++ b/src/source_reader.rs @@ -0,0 +1,51 @@ +use { + crate::Error, + std::{ + fs, + path::{Path, PathBuf}, + }, +}; + +struct SourceMap { + filename: PathBuf, + offset: usize, + total_lines: usize, + insertions: Vec, +} + +pub struct SourceFile { + source_text: String, + source_map: SourceMap, +} + +impl SourceFile { + pub fn root_filename(&self) -> &Path { + &self.source_map.filename + } + pub fn full_text(&self) -> &str { + &self.source_text + } + + pub fn map_source_line_num(&self, line_num: usize) -> (&Path, usize) { + (&self.source_map.filename, line_num) + } +} + +pub fn read_source_file(filename: PathBuf) -> Result { + let source_text = fs::read_to_string(&filename).map_err(|err| { + Error::from_message(format!( + "Could not open \"{}\": {}", + &filename.as_os_str().to_string_lossy(), + err + )) + })?; + Ok(SourceFile { + source_text, + source_map: SourceMap { + filename, + offset: 0, + total_lines: 0, + insertions: vec![], + }, + }) +}