Compare commits
2 Commits
9448ee9f58
...
395e641250
| Author | SHA1 | Date |
|---|---|---|
|
|
395e641250 | |
|
|
b9f236c5bc |
|
|
@ -14,3 +14,4 @@ Cargo.lock
|
||||||
# MSVC Windows builds of rustc generate these, which store debugging information
|
# MSVC Windows builds of rustc generate these, which store debugging information
|
||||||
*.pdb
|
*.pdb
|
||||||
|
|
||||||
|
*~
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
[package]
|
||||||
|
name = "wgsl-shader-assembler"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
proc-macro = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
quote = "1.0"
|
||||||
|
syn = "2.0.90"
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
[toolchain]
|
||||||
|
channel = "nightly"
|
||||||
|
|
@ -0,0 +1,77 @@
|
||||||
|
#![feature(proc_macro_span)]
|
||||||
|
|
||||||
|
use {
|
||||||
|
proc_macro::TokenStream,
|
||||||
|
quote::quote,
|
||||||
|
std::{fs, path::PathBuf},
|
||||||
|
syn::{parse, LitStr},
|
||||||
|
};
|
||||||
|
|
||||||
|
fn emit_create_shader_module(file_contents: &str) -> TokenStream {
|
||||||
|
quote! {
|
||||||
|
wgpu::ShaderModuleDescriptor {
|
||||||
|
label: None,
|
||||||
|
source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(#file_contents)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
struct WgslModuleMacroInput {
|
||||||
|
source_dir: PathBuf,
|
||||||
|
filename: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Error {
|
||||||
|
Message(String),
|
||||||
|
SynError(syn::Error),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Error {
|
||||||
|
fn from_message(message: impl Into<String>) -> Self {
|
||||||
|
Self::Message(message.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<syn::Error> for Error {
|
||||||
|
fn from(value: syn::Error) -> Self {
|
||||||
|
Self::SynError(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_input(token_stream: TokenStream) -> Result<WgslModuleMacroInput, Error> {
|
||||||
|
let token = token_stream
|
||||||
|
.clone()
|
||||||
|
.into_iter()
|
||||||
|
.next()
|
||||||
|
.ok_or(Error::from_message("Expected single string literal."))?;
|
||||||
|
|
||||||
|
let source_dir = token.span().source_file().path().parent().unwrap().into();
|
||||||
|
let literal: LitStr = parse(token_stream)?;
|
||||||
|
let filename = literal.value();
|
||||||
|
Ok(WgslModuleMacroInput {
|
||||||
|
source_dir,
|
||||||
|
filename,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn wgsl_module_inner(input_token_stream: TokenStream) -> Result<TokenStream, Error> {
|
||||||
|
let input = parse_input(input_token_stream)?;
|
||||||
|
let full_filename = input.source_dir.join(&input.filename);
|
||||||
|
let contents = fs::read_to_string(&full_filename).map_err(|err| {
|
||||||
|
Error::from_message(format!(
|
||||||
|
"Could not open \"{}\": {}",
|
||||||
|
&full_filename.as_os_str().to_string_lossy(),
|
||||||
|
err.to_string()
|
||||||
|
))
|
||||||
|
})?;
|
||||||
|
Ok(emit_create_shader_module(&contents))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn wgsl_module(input: TokenStream) -> TokenStream {
|
||||||
|
wgsl_module_inner(input).unwrap_or_else(|err| match err {
|
||||||
|
Error::Message(message) => quote! { compile_error!(#message) },
|
||||||
|
Error::SynError(syn_err) => syn_err.into_compile_error(),
|
||||||
|
}.into())
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue