Add error check for WGSL

This commit is contained in:
Maximilian Ammann 2021-12-07 17:30:23 +01:00
parent 6b074f42e9
commit 430d6f368b
3 changed files with 88 additions and 0 deletions

2
Cargo.lock generated
View File

@ -1217,11 +1217,13 @@ dependencies = [
"log",
"lyon",
"lyon_path",
"naga",
"pollster",
"serde",
"serde_json",
"test-env-log",
"vector-tile",
"walkdir",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",

View File

@ -56,6 +56,10 @@ criterion = "0.3"
# Support logging in tests
test-env-log = "0.2"
[build-dependencies]
naga = { version = "0.7", features = ["wgsl-in"] }
walkdir = "2.3"
[[bin]]
name = "mapr"

82
build.rs Normal file
View File

@ -0,0 +1,82 @@
use std::env;
use std::path::Path;
use std::process::exit;
use naga::front::wgsl;
use naga::valid::{Capabilities, ValidationFlags, Validator};
use naga::{front::wgsl::ParseError, valid::ValidationError};
use walkdir::WalkDir;
#[derive(Debug)]
pub enum WgslError {
ValidationErr(ValidationError),
ParserErr {
error: String,
line: usize,
pos: usize,
},
IoErr(std::io::Error),
}
impl From<std::io::Error> for WgslError {
fn from(err: std::io::Error) -> Self {
Self::IoErr(err)
}
}
impl WgslError {
pub fn from_parse_err(err: ParseError, src: &str) -> Self {
let (line, pos) = err.location(src);
let error = err.emit_to_string(src);
Self::ParserErr { error, line, pos }
}
}
pub fn validate_wgsl(validator: &mut Validator, path: &Path) -> Result<(), WgslError> {
let shader = std::fs::read_to_string(&path).map_err(WgslError::from)?;
let module = wgsl::parse_str(&shader).map_err(|err| WgslError::from_parse_err(err, &shader))?;
if let Err(err) = validator.validate(&module) {
Err(WgslError::ValidationErr(err))
} else {
Ok(())
}
}
fn main() {
let mut validator = Validator::new(ValidationFlags::all(), Capabilities::all());
let root_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
let dir_walk = WalkDir::new(&root_dir);
let dir_walk = dir_walk.into_iter().filter_entry(|e| {
let path = e.path();
if !path.is_dir() {
path.extension().map(|ext| &*ext == "wgsl").unwrap_or(false)
} else {
true
}
});
for entry in dir_walk {
match entry {
Ok(entry) => {
let path = entry.path();
if !path.is_dir() {
match validate_wgsl(&mut validator, &path) {
Ok(_) => {}
Err(err) => {
let path = path.strip_prefix(&root_dir).unwrap_or(path);
println!("cargo:warning=Error ({:?}): {:?}", path, err);
exit(1);
}
};
}
}
Err(err) => {
println!("cargo:warning=Error: {:?}", err);
exit(1);
}
}
}
}