pbrt_r3/core/parser/
common.rs1use crate::core::base::Float;
2use crate::core::param_set::wellknown_params;
3use crate::core::param_set::ParamSet;
4use nom::bytes;
5use nom::character;
6use nom::multi;
7use nom::number;
8use nom::sequence;
9use nom::IResult;
10
11pub fn space0(s: &str) -> IResult<&str, &str> {
12 return character::complete::multispace0(s);
13}
14
15pub fn space1(s: &str) -> IResult<&str, &str> {
16 return character::complete::multispace1(s);
17}
18
19pub fn bool_literal(s: &str) -> IResult<&str, &str> {
20 return nom::branch::alt((
21 nom::bytes::complete::tag_no_case("true"),
22 nom::bytes::complete::tag_no_case("false"),
23 ))(s);
24}
25
26pub fn float_literal(s: &str) -> IResult<&str, &str> {
27 return number::complete::recognize_float(s);
28}
29
30pub fn string_literal(s: &str) -> IResult<&str, &str> {
31 return sequence::delimited(
32 character::complete::char('"'),
33 bytes::complete::take_until("\""),
34 character::complete::char('"'),
35 )(s);
36}
37
38pub fn parse_literal(s: &str) -> IResult<&str, &str> {
39 return nom::branch::alt((float_literal, bool_literal, string_literal))(s);
40}
41
42pub fn parse_listed_literal(s: &str) -> IResult<&str, Vec<&str>> {
43 let (s, r) = parse_literal(s)?;
44 return Ok((s, vec![r]));
45}
46
47pub fn parse_list(s: &str) -> IResult<&str, Vec<&str>> {
48 return sequence::delimited(
49 character::complete::char('['),
50 sequence::delimited(
51 space0,
52 multi::separated_list1(space1, parse_literal), space0,
54 ),
55 character::complete::char(']'),
56 )(s);
57}
58
59pub fn get_param_type(s: &str) -> (&str, &str) {
60 let ss: Vec<&str> = s.split_ascii_whitespace().collect();
61 if ss.len() == 2 {
62 return (ss[0], ss[1]);
63 } else if ss.len() == 1 {
64 if let Some(t) = wellknown_params::find_type_from_key(ss[0]) {
65 return (t, ss[0]);
66 } else {
67 return ("", ss[0]);
68 }
69 } else {
70 return ("", s);
71 }
72}
73
74pub fn convert_bool(s: &str) -> Result<bool, std::str::ParseBoolError> {
75 let s = String::from(s).to_lowercase();
76 let s2: &str = &s;
77 match s2 {
78 "true" => return Ok(true),
79 "false" => return Ok(false),
80 "\"true\"" => return Ok(true),
81 "\"false\"" => return Ok(false),
82 _ => return s2.parse::<bool>(),
83 }
84}
85
86pub fn parse_params(s: &str) -> IResult<&str, ParamSet> {
87 let (s, v) = multi::separated_list0(
88 space1,
89 nom::branch::permutation((
90 sequence::terminated(string_literal, space1),
91 nom::branch::alt((parse_list, parse_listed_literal)),
92 )),
93 )(s)?;
94 let mut params = ParamSet::new();
95 for vv in v {
96 let org_key = vv.0;
97 let (t, key) = get_param_type(org_key);
98 let new_key = format!("{t} {key}");
99 match t {
100 "string" => {
101 let s_values = vv.1;
102 params.add_strings(&new_key, &s_values);
103 }
104 "texture" => {
105 let s_values = vv.1;
106 params.add_strings(&new_key, &s_values);
107 }
108 "spectrum" => {
109 let s_values = vv.1;
110 params.add_strings(&new_key, &s_values);
111 }
112 "bool" => {
113 let s_values = vv.1;
114 let values: Vec<bool> = s_values.iter().map(|s| convert_bool(s).unwrap()).collect();
115 params.add_bools(&new_key, &values);
116 }
117 "integer" => {
118 let s_values = vv.1;
119 let values: Vec<i32> = s_values.iter().map(|s| s.parse::<i32>().unwrap()).collect();
120 params.add_ints(&new_key, &values);
121 }
122 "color" => {
123 let s_values = vv.1;
124 let values: Vec<Float> = s_values
125 .iter()
126 .map(|s| s.parse::<Float>().unwrap())
127 .collect();
128 params.add_color(&new_key, &values);
129 }
130 "rgb" => {
131 let s_values = vv.1;
132 let values: Vec<Float> = s_values
133 .iter()
134 .map(|s| s.parse::<Float>().unwrap())
135 .collect();
136 params.add_rgb(&new_key, &values);
137 }
138 "xyz" => {
139 let s_values = vv.1;
140 let values: Vec<Float> = s_values
141 .iter()
142 .map(|s| s.parse::<Float>().unwrap())
143 .collect();
144 params.add_xyz(&new_key, &values);
145 }
146 "blackbody" => {
147 let s_values = vv.1;
148 let values: Vec<Float> = s_values
149 .iter()
150 .map(|s| s.parse::<Float>().unwrap())
151 .collect();
152 params.add_blackbody(&new_key, &values);
153 }
154 "point" | "point2" | "point3" | "point4" => {
155 let s_values = vv.1;
156 let values: Vec<Float> = s_values
157 .iter()
158 .map(|s| s.parse::<Float>().unwrap())
159 .collect();
160 params.add_point(&new_key, &values);
161 }
162 "vector" | "vector2" | "vector3" | "vector4" => {
163 let s_values = vv.1;
164 let values: Vec<Float> = s_values
165 .iter()
166 .map(|s| s.parse::<Float>().unwrap())
167 .collect();
168 params.add_point(&new_key, &values);
169 }
170 "normal" => {
171 let s_values = vv.1;
172 let values: Vec<Float> = s_values
173 .iter()
174 .map(|s| s.parse::<Float>().unwrap())
175 .collect();
176 params.add_point(&new_key, &values);
177 }
178 "float" => {
179 let s_values = vv.1;
180 let values: Vec<Float> = s_values
181 .iter()
182 .map(|s| s.parse::<Float>().unwrap())
183 .collect();
184 params.add_floats(&new_key, &values);
185 }
186 _ => {
187 let s_values = vv.1;
188 let values: Vec<Float> = s_values
190 .iter()
191 .map(|s| s.parse::<Float>().unwrap())
192 .collect();
193 params.add_floats(&new_key, &values);
194 }
195 }
196 }
197 return Ok((s, params));
198}