concinnity_core/platform.rs
1//! The shader `Platform` vocabulary: which shader source language a rendering
2//! backend consumes. The enum is pure data with no ambient resolution of its
3//! own, so it sits in the runtime foundation and every caller states the
4//! platform it means -- the engine names the backend it was built for, and the
5//! build pipeline is told the backend it cooks for.
6
7/// Shader source language families supported by the engine. Each variant
8/// matches one render backend: Metal, HLSL (DirectX), or GLSL (Vulkan).
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub enum Platform {
11 /// Metal Shading Language, for the Metal backend.
12 Metal,
13 /// HLSL, for the DirectX backend.
14 Hlsl,
15 /// GLSL, for the Vulkan backend.
16 Glsl,
17}
18
19impl Platform {
20 /// String key used in the `sources` map of a `Shader` stage.
21 pub fn key(self) -> &'static str {
22 match self {
23 Platform::Metal => "metal",
24 Platform::Hlsl => "hlsl",
25 Platform::Glsl => "glsl",
26 }
27 }
28
29 /// Whether a shader source with the given file extension is usable on this
30 /// platform. The matching extension (`metal` / `hlsl` / `glsl`) is accepted;
31 /// a non-matching shader extension is rejected so a single-path source
32 /// authored for one backend doesn't get fed to another; an unknown
33 /// extension is accepted by default (the build step surfaces a real compile
34 /// error later if the file truly can't be built).
35 ///
36 /// Shared by the per-platform source selection of `Shader` stages and
37 /// `SdfVolume` so both apply identical fallback rules.
38 pub fn accepts_ext(self, ext: &str) -> bool {
39 !matches!(ext, "metal" | "hlsl" | "glsl") || ext == self.key()
40 }
41}
42
43#[cfg(test)]
44mod tests {
45 use super::*;
46
47 #[test]
48 fn platform_key_and_accepts_ext_cover_all_variants() {
49 assert_eq!(Platform::Metal.key(), "metal");
50 assert_eq!(Platform::Hlsl.key(), "hlsl");
51 assert_eq!(Platform::Glsl.key(), "glsl");
52
53 // The matching extension is accepted; another backend's shader
54 // extension is rejected; an unknown extension is accepted by default.
55 assert!(Platform::Metal.accepts_ext("metal"));
56 assert!(!Platform::Metal.accepts_ext("hlsl"));
57 assert!(!Platform::Metal.accepts_ext("glsl"));
58 assert!(Platform::Hlsl.accepts_ext("hlsl"));
59 assert!(!Platform::Hlsl.accepts_ext("metal"));
60 assert!(Platform::Glsl.accepts_ext("glsl"));
61 assert!(!Platform::Glsl.accepts_ext("hlsl"));
62 assert!(Platform::Metal.accepts_ext("txt"));
63 }
64}