From d6662da7b9a56f71fcfc51bc80e925f884191903 Mon Sep 17 00:00:00 2001 From: hal8174 Date: Sun, 10 Aug 2025 22:07:44 +0200 Subject: [PATCH] Add macro for parsing dictionaries --- ray-tracing-pbrt-scene/src/lib.rs | 88 +++++++++++++++++++++---------- 1 file changed, 60 insertions(+), 28 deletions(-) diff --git a/ray-tracing-pbrt-scene/src/lib.rs b/ray-tracing-pbrt-scene/src/lib.rs index 8f4b7ce..42d8b57 100644 --- a/ray-tracing-pbrt-scene/src/lib.rs +++ b/ray-tracing-pbrt-scene/src/lib.rs @@ -47,42 +47,74 @@ fn parse_look_at(iter: &mut Tokenizer) -> Result { )) } +macro_rules! parse_dict { + ($tokenizer:expr => $($name_decl:ident, $type:ty, $default:expr);+ => $($name_parsing:ident, $expr:expr, $parsing:expr);+ + ) => { + { + $( + let mut $name_decl = None; + )+ + + while let Some(p) = $tokenizer.next_if(|p| p.starts_with('"')).transpose()? { + match p.as_str() { + $( + $expr => { + if $name_parsing.is_none() { + $name_parsing = Some($parsing); + } else { + return Err(miette!("dfs")) + } + } + )+ + _ => {todo!()} + } + } + + #[derive(Debug)] + struct Dict { + $( + $name_decl: $type, + )+ + } + + $( + let $name_decl = $name_decl.unwrap_or_else(|| $default); + )* + + Dict { + $($name_decl,)* + } + } + }; +} + fn parse_shape(iter: &mut Tokenizer) -> Result { let shape_type = iter.next().ok_or(miette!("unable to get shape type"))??; match shape_type.as_str() { "\"sphere\"" => { - let mut radius = 1.0; - let zmin = -radius; - let zmax = radius; - let phimax = 360.0; - let mut alpha = ShapeAlpha::None; - - while let Some(p) = iter.next_if(|p| p.starts_with('"')).transpose()? { - match p.as_str() { - "\"float radius\"" => { - radius = iter.parse_parameter()?; - } - "\"float alpha\"" => { - alpha = ShapeAlpha::Value(iter.parse_parameter()?); - } - "\"texture alpha\"" => { - alpha = ShapeAlpha::Texture(iter.parse_parameter()?); - } - _ => { - bail!("unknown argument {}", p) - } - } - } - + let t = parse_dict!(iter => + radius, Float, 1.0; + zmin, Float, {-radius}; + zmax, Float, {radius}; + phimax, Float, 360.0; + alpha, ShapeAlpha, ShapeAlpha::None + => + radius, "\"float radius\"", iter.parse_parameter()?; + zmin, "\"float zmin\"", iter.parse_parameter()?; + zmax, "\"float zmax\"", iter.parse_parameter()?; + phimax, "\"float phimax\"", iter.parse_parameter()?; + alpha, "\"float alpha\"", ShapeAlpha::Value(iter.parse_parameter()?); + alpha, "\"texture alpha\"", ShapeAlpha::Texture(iter.parse_parameter()?) + ); Ok(Statement::Shape( ShapeType::Sphere { - radius, - zmin, - zmax, - phimax, + radius: t.radius, + zmin: t.zmin, + zmax: t.zmax, + phimax: t.phimax, }, - alpha, + t.alpha, )) } "\"trianglemesh\"" => {