use serde::{Deserialize, Serialize};
use crate::resource::ResourceId;
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Material {
pub name: String,
pub shader: ShaderSource,
pub bindings: Vec<UniformBinding>,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(tag = "kind", rename_all = "snake_case")]
pub enum ShaderSource {
Inline { wgsl: String },
Path { path: String },
}
impl ShaderSource {
#[must_use]
pub fn inline(wgsl: impl Into<String>) -> Self {
Self::Inline { wgsl: wgsl.into() }
}
#[must_use]
pub fn path(path: impl Into<String>) -> Self {
Self::Path { path: path.into() }
}
#[must_use]
pub fn display_short(&self) -> String {
match self {
ShaderSource::Inline { wgsl } => {
let preview: String = wgsl.chars().take(40).collect();
format!("inline:{preview}")
}
ShaderSource::Path { path } => format!("path:{path}"),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct UniformBinding {
pub binding: u32,
pub kind: BindingKind,
pub resource: ResourceId,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum BindingKind {
Uniform,
StorageRead,
StorageReadWrite,
Texture,
Sampler,
}