use std::collections::BTreeMap; use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Deserialize)] #[serde(deny_unknown_fields, rename_all = "camelCase")] pub struct Graph { pub schema_version: u32, pub graph_id: String, pub revision: u32, pub nodes: Vec, } #[derive(Debug, Clone, Deserialize)] #[serde(deny_unknown_fields)] pub struct Node { pub id: String, pub state: NodeState, pub executor: ExecutorRef, pub parameters: serde_json::Value, pub inputs: BTreeMap, } #[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq)] #[serde(rename_all = "snake_case")] pub enum NodeState { Enabled, Muted, } #[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)] #[serde(deny_unknown_fields)] pub struct ExecutorRef { pub key: String, pub version: u32, } #[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord)] #[serde(deny_unknown_fields)] pub struct NodeOutputRef { pub node: String, pub socket: String, } #[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq, Hash, PartialOrd, Ord)] #[serde(rename_all = "snake_case")] pub enum TextureDimension { D1, D2, D3, } #[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq, Hash, PartialOrd, Ord)] #[serde(rename_all = "snake_case")] pub enum TextureFormat { Rgba8Unorm, Rgba8UnormSrgb, Bgra8Unorm, Bgra8UnormSrgb, Rgba16Float, R32Float, Depth32Float, } #[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, Hash, PartialOrd, Ord)] #[serde(tag = "kind", rename_all = "snake_case", deny_unknown_fields)] pub enum TextureExtent { Absolute { width: u32, height: u32, #[serde(rename = "depthOrArrayLayers")] depth_or_array_layers: u32, }, SurfaceRelative { width: Ratio, height: Ratio, #[serde(rename = "depthOrArrayLayers")] depth_or_array_layers: u32, }, } #[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq, Hash, PartialOrd, Ord)] #[serde(deny_unknown_fields)] pub struct Ratio { pub numerator: u32, pub denominator: u32, } #[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq, Hash, PartialOrd, Ord)] #[serde(rename_all = "snake_case")] pub enum TextureResidency { Transient, Persistent, History, Readback, } #[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, Hash, PartialOrd, Ord)] #[serde(deny_unknown_fields, rename_all = "camelCase")] pub struct TextureDescriptor { pub dimension: TextureDimension, pub format: TextureFormat, pub extent: TextureExtent, pub mip_level_count: u32, pub sample_count: u32, #[serde(default)] pub view_formats: Vec, } #[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord)] #[serde(rename_all = "snake_case")] pub enum TriStatePredicate { Any, RequiredTrue, RequiredFalse, } #[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord)] #[serde(deny_unknown_fields)] pub struct MeshFilter { pub flag: MeshFlag, pub predicate: TriStatePredicate, } #[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord)] #[serde(rename_all = "camelCase")] pub enum MeshFlag { IsVisible, IsFrustumCulled, } impl MeshFlag { pub const ORDERED: [Self; 2] = [Self::IsVisible, Self::IsFrustumCulled]; pub const fn input_socket(self) -> &'static str { match self { Self::IsVisible => "isVisible", Self::IsFrustumCulled => "isFrustumCulled", } } } #[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq)] #[serde(rename_all = "snake_case")] pub enum CompareFunction { Never, Less, Equal, LessEqual, Greater, NotEqual, GreaterEqual, Always, } pub(crate) fn identifier(value: &str) -> bool { let mut chars = value.chars(); chars.next().is_some_and(|c| c.is_ascii_alphabetic()) && chars.all(|c| c.is_ascii_alphanumeric() || matches!(c, '_' | '.' | '-')) }