#![no_std]
extern crate alloc;
use alloc::format;
use alloc::string::String;
use alloc::vec::Vec;
use core::fmt;
use naga::valid::Capabilities;
use crate::ra::PrintAst as _;
mod config;
mod conv;
mod ra;
mod util;
mod writer;
pub use config::Config;
pub use writer::Writer;
pub use naga;
pub const CAPABILITIES: Capabilities = Capabilities::FLOAT64;
#[derive(Debug)]
#[non_exhaustive]
pub enum Error {
FmtError(fmt::Error),
Unimplemented(String),
#[non_exhaustive]
GlobalVariablesNotEnabled {
example: String,
},
#[non_exhaustive]
ResourcesNotEnabled {
example: String,
},
}
impl From<fmt::Error> for Error {
fn from(value: fmt::Error) -> Self {
Self::FmtError(value)
}
}
impl core::error::Error for Error {}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Error::FmtError(fmt::Error) => write!(f, "formatting cancelled"),
Error::Unimplemented(msg) => write!(f, "not yet implemented for Rust: {msg}"),
Error::GlobalVariablesNotEnabled { example } => write!(
f,
"global variable `{example}` found in shader, but `global_struct` is not configured"
),
Error::ResourcesNotEnabled { example } => write!(
f,
"resource `{example}` found in shader, but `resource_struct` is not configured"
),
}
}
}
pub fn write_string(
module: &naga::Module,
info: &naga::valid::ModuleInfo,
config: Config,
) -> Result<String, Error> {
let mut w = Writer::new(config);
let mut output = String::new();
w.write(&mut output, module, info)?;
Ok(output)
}
#[doc(hidden)] #[mutants::skip] pub fn translate_function_body_only_for_testing(
module: &naga::Module,
info: &naga::valid::ModuleInfo,
config: &Config,
) -> Result<String, Error> {
let mut w = Writer::new(config.clone());
let items = w.translate_module(module, info)?;
let functions: Vec<ra::FunctionItem> = items
.into_iter()
.filter_map(|item| {
let ra::Item::Function(fn_item) = item else {
return None;
};
if !fn_item.name.starts_with("v_") {
return None;
}
Some(fn_item)
})
.collect();
if functions.len() != 1 {
return Err(Error::Unimplemented(format!(
"expected exactly one function; found {items:?}",
items = functions.into_iter().map(|f| f.name).collect::<Vec<_>>()
)));
}
let function = functions.into_iter().next().unwrap();
let mut output = String::new();
function.body.write(
&mut output,
ra::PrintCtx {
config,
indent: naga::back::Level(0),
},
)?;
Ok(output)
}