1use std::marker::PhantomData;
6
7use crate::{
8 builder::{CacheStoreBuilder, NodeStoreBuilder, ValueStoreBuilder},
9 elem_type::{
10 AccessMode, AddressKind, BitMask, CachingMode, DisplayNotation, Endianness,
11 FloatRepresentation, ImmOrPNode, IntegerRepresentation, MergePriority, NameSpace,
12 NamedValue, PIndex, PValue, RegPIndex, Sign, Slope, StandardNameSpace, ValueIndexed,
13 ValueKind, Visibility,
14 },
15 interface::INode,
16 store::{FloatId, IntegerId, NodeData, NodeId},
17 IntSwissKnifeNode,
18};
19
20use super::{
21 elem_name::{
22 ADDRESS, BIT, INDEX, INT_SWISS_KNIFE, NAME, OFFSET, P_ADDRESS, P_INDEX, P_OFFSET, P_VALUE,
23 P_VALUE_COPY, P_VALUE_INDEXED, VALUE, VALUE_INDEXED,
24 },
25 xml, Parse,
26};
27
28macro_rules! match_text_view{
29 ($text:expr,
30 $s1:expr => $var1:expr,
31 $($s:expr => $var:expr,)*
32 ) => {
33 if $text == $s1 {
34 $var1
35 } $(else if $text == $s {
36 $var
37 })* else {
38 unreachable!()
39 }
40 }
41}
42
43impl Default for NameSpace {
44 fn default() -> Self {
45 Self::Custom
46 }
47}
48
49impl From<&str> for NameSpace {
50 fn from(value: &str) -> Self {
51 match value {
52 "Standard" => Self::Standard,
53 "Custom" => Self::Custom,
54 _ => unreachable!(),
55 }
56 }
57}
58
59impl Parse for NameSpace {
60 fn parse(
61 node: &mut xml::Node,
62 _: &mut impl NodeStoreBuilder,
63 _: &mut impl ValueStoreBuilder,
64 _: &mut impl CacheStoreBuilder,
65 ) -> Self {
66 let text = node.next_text().unwrap();
67 match_text_view!(text,
68 "Standard" => Self::Standard,
69 "Custom" => Self::Custom,
70 )
71 }
72}
73
74impl Default for Visibility {
75 fn default() -> Self {
76 Self::Beginner
77 }
78}
79
80impl Parse for Visibility {
81 fn parse(
82 node: &mut xml::Node,
83 _: &mut impl NodeStoreBuilder,
84 _: &mut impl ValueStoreBuilder,
85 _: &mut impl CacheStoreBuilder,
86 ) -> Self {
87 let text = node.next_text().unwrap();
88 match_text_view!(text,
89 "Beginner" => Self::Beginner,
90 "Expert" => Self::Expert,
91 "Guru" => Self::Guru,
92 "Invisible" => Self::Invisible,
93 )
94 }
95}
96
97impl From<&str> for MergePriority {
98 fn from(value: &str) -> Self {
99 match value {
100 "1" => Self::High,
101 "0" => Self::Mid,
102 "-1" => Self::Low,
103 _ => unreachable!(),
104 }
105 }
106}
107
108impl Default for MergePriority {
109 fn default() -> Self {
110 Self::Mid
111 }
112}
113
114impl Parse for MergePriority {
115 fn parse(
116 node: &mut xml::Node,
117 _: &mut impl NodeStoreBuilder,
118 _: &mut impl ValueStoreBuilder,
119 _: &mut impl CacheStoreBuilder,
120 ) -> Self {
121 let text = node.next_text().unwrap();
122 match_text_view!(text,
123 "1" => Self::High,
124 "0" => Self::Mid,
125 "-1" => Self::Low,
126 )
127 }
128}
129
130impl Parse for AccessMode {
131 fn parse(
132 node: &mut xml::Node,
133 _: &mut impl NodeStoreBuilder,
134 _: &mut impl ValueStoreBuilder,
135 _: &mut impl CacheStoreBuilder,
136 ) -> Self {
137 let text = node.next_text().unwrap();
138 match_text_view!(text,
139 "RO" => Self::RO,
140 "WO" => Self::WO,
141 "RW" => Self::RW,
142 )
143 }
144}
145
146impl Parse for ImmOrPNode<i64> {
147 fn parse(
148 node: &mut xml::Node,
149 node_builder: &mut impl NodeStoreBuilder,
150 value_builder: &mut impl ValueStoreBuilder,
151 cache_builder: &mut impl CacheStoreBuilder,
152 ) -> Self {
153 let peeked_text = node.peek().unwrap().text();
154 if peeked_text.view().chars().next().unwrap().is_alphabetic() {
155 Self::PNode(node.parse(node_builder, value_builder, cache_builder))
156 } else {
157 Self::Imm(node.parse(node_builder, value_builder, cache_builder))
158 }
159 }
160}
161
162impl Parse for ImmOrPNode<f64> {
163 fn parse(
164 node: &mut xml::Node,
165 node_builder: &mut impl NodeStoreBuilder,
166 value_builder: &mut impl ValueStoreBuilder,
167 cache_builder: &mut impl CacheStoreBuilder,
168 ) -> Self {
169 let peeked_text = node.peek().unwrap().text();
170
171 if peeked_text == "INF"
172 || peeked_text == "-INF"
173 || peeked_text == "NaN"
174 || !peeked_text.view().chars().next().unwrap().is_alphabetic()
175 {
176 Self::Imm(node.parse(node_builder, value_builder, cache_builder))
177 } else {
178 Self::PNode(node.parse(node_builder, value_builder, cache_builder))
179 }
180 }
181}
182
183impl Parse for ImmOrPNode<bool> {
184 fn parse(
185 node: &mut xml::Node,
186 node_builder: &mut impl NodeStoreBuilder,
187 value_builder: &mut impl ValueStoreBuilder,
188 cache_builder: &mut impl CacheStoreBuilder,
189 ) -> Self {
190 if convert_to_bool_opt(&node.peek().unwrap().text().view()).is_some() {
191 Self::Imm(node.parse(node_builder, value_builder, cache_builder))
192 } else {
193 Self::PNode(node.parse(node_builder, value_builder, cache_builder))
194 }
195 }
196}
197
198macro_rules! impl_parse_for_imm_or_pnode_id {
199 ($id:ty, $value_ty:ty) => {
200 impl Parse for ImmOrPNode<$id> {
201 fn parse(
202 node: &mut xml::Node,
203 node_builder: &mut impl NodeStoreBuilder,
204 value_builder: &mut impl ValueStoreBuilder,
205 cache_builder: &mut impl CacheStoreBuilder,
206 ) -> Self {
207 let node: ImmOrPNode<$value_ty> =
208 node.parse(node_builder, value_builder, cache_builder);
209 match node {
210 ImmOrPNode::Imm(i) => {
211 let id = value_builder.store(i);
212 ImmOrPNode::Imm(id)
213 }
214 ImmOrPNode::PNode(id) => ImmOrPNode::PNode(id),
215 }
216 }
217 }
218 };
219}
220
221impl_parse_for_imm_or_pnode_id!(IntegerId, i64);
222impl_parse_for_imm_or_pnode_id!(FloatId, f64);
223
224impl Default for IntegerRepresentation {
225 fn default() -> Self {
226 Self::PureNumber
227 }
228}
229
230impl Parse for IntegerRepresentation {
231 fn parse(
232 node: &mut xml::Node,
233 _: &mut impl NodeStoreBuilder,
234 _: &mut impl ValueStoreBuilder,
235 _: &mut impl CacheStoreBuilder,
236 ) -> Self {
237 use IntegerRepresentation::{
238 Boolean, HexNumber, IpV4Address, Linear, Logarithmic, MacAddress, PureNumber,
239 };
240
241 let value = node.next_text().unwrap();
242 match_text_view!(value,
243 "Linear" => Linear,
244 "Logarithmic" => Logarithmic,
245 "Boolean" => Boolean,
246 "PureNumber" => PureNumber,
247 "HexNumber" => HexNumber,
248 "IPV4Address" => IpV4Address,
249 "MACAddress" => MacAddress,
250 )
251 }
252}
253
254impl Parse for FloatRepresentation {
255 fn parse(
256 node: &mut xml::Node,
257 _: &mut impl NodeStoreBuilder,
258 _: &mut impl ValueStoreBuilder,
259 _: &mut impl CacheStoreBuilder,
260 ) -> Self {
261 let text = node.next_text().unwrap();
262 match_text_view! {text,
263 "Linear" => Self::Linear,
264 "Logarithmic" => Self::Logarithmic,
265 "PureNumber" => Self::PureNumber,
266 }
267 }
268}
269
270impl Default for FloatRepresentation {
271 fn default() -> Self {
272 Self::PureNumber
273 }
274}
275
276impl Parse for Slope {
277 fn parse(
278 node: &mut xml::Node,
279 _: &mut impl NodeStoreBuilder,
280 _: &mut impl ValueStoreBuilder,
281 _: &mut impl CacheStoreBuilder,
282 ) -> Self {
283 let text = node.next_text().unwrap();
284 match_text_view! {text,
285 "Increasing" => Self::Increasing,
286 "Decreasing" => Self::Decreasing,
287 "Varying" => Self::Varying,
288 "Automatic" => Self::Automatic,
289 }
290 }
291}
292
293impl Default for Slope {
294 fn default() -> Self {
295 Self::Automatic
296 }
297}
298
299impl Default for DisplayNotation {
300 fn default() -> Self {
301 Self::Automatic
302 }
303}
304
305impl Parse for DisplayNotation {
306 fn parse(
307 node: &mut xml::Node,
308 _: &mut impl NodeStoreBuilder,
309 _: &mut impl ValueStoreBuilder,
310 _: &mut impl CacheStoreBuilder,
311 ) -> Self {
312 let text = node.next_text().unwrap();
313 match_text_view! {text,
314 "Automatic" => Self::Automatic,
315 "Fixed" => Self::Fixed,
316 "Scientific" => Self::Scientific,
317 }
318 }
319}
320
321impl From<&str> for StandardNameSpace {
322 fn from(value: &str) -> Self {
323 match value {
324 "None" => Self::None,
325 "IIDC" => Self::IIDC,
326 "GEV" => Self::GEV,
327 "CL" => Self::CL,
328 "USB" => Self::USB,
329 _ => unreachable!(),
330 }
331 }
332}
333
334impl Default for CachingMode {
335 fn default() -> Self {
336 Self::WriteThrough
337 }
338}
339
340impl Parse for CachingMode {
341 fn parse(
342 node: &mut xml::Node,
343 _: &mut impl NodeStoreBuilder,
344 _: &mut impl ValueStoreBuilder,
345 _: &mut impl CacheStoreBuilder,
346 ) -> Self {
347 let text = node.next_text().unwrap();
348 match_text_view! {text,
349 "WriteThrough" => Self::WriteThrough,
350 "WriteAround" => Self::WriteAround,
351 "NoCache" => Self::NoCache,
352 }
353 }
354}
355
356impl<T> Parse for NamedValue<T>
357where
358 T: Clone + PartialEq + Parse,
359{
360 fn parse(
361 node: &mut xml::Node,
362 node_builder: &mut impl NodeStoreBuilder,
363 value_builder: &mut impl ValueStoreBuilder,
364 cache_builder: &mut impl CacheStoreBuilder,
365 ) -> Self {
366 let name = node.peek().unwrap().attribute_of(NAME).unwrap().into();
367 let value = node.parse(node_builder, value_builder, cache_builder);
368 Self { name, value }
369 }
370}
371
372pub(super) fn convert_to_bool(value: &str) -> bool {
373 match convert_to_bool_opt(value) {
374 Some(b) => b,
375 _ => unreachable!(),
376 }
377}
378
379pub(super) fn convert_to_bool_opt(value: &str) -> Option<bool> {
380 match value {
381 "Yes" | "true" => Some(true),
382 "No" | "false" => Some(false),
383 _ => None,
384 }
385}
386
387impl Parse for bool {
388 fn parse(
389 node: &mut xml::Node,
390 _: &mut impl NodeStoreBuilder,
391 _: &mut impl ValueStoreBuilder,
392 _: &mut impl CacheStoreBuilder,
393 ) -> Self {
394 let text = node.next_text().unwrap();
395 convert_to_bool(&text.view())
396 }
397}
398
399pub(super) fn convert_to_int(value: &str) -> i64 {
400 if value.starts_with("0x") || value.starts_with("0X") {
401 i64::from_str_radix(&value[2..], 16).unwrap()
402 } else {
403 value.parse().unwrap()
404 }
405}
406
407pub(super) fn convert_to_uint(value: &str) -> u64 {
408 if value.starts_with("0x") || value.starts_with("0X") {
409 u64::from_str_radix(&value[2..], 16).unwrap()
410 } else {
411 value.parse().unwrap()
412 }
413}
414
415impl Parse for i64 {
416 fn parse(
417 node: &mut xml::Node,
418 _: &mut impl NodeStoreBuilder,
419 _: &mut impl ValueStoreBuilder,
420 _: &mut impl CacheStoreBuilder,
421 ) -> Self {
422 let value = node.next_text().unwrap();
423 convert_to_int(&value.view())
424 }
425}
426
427impl Parse for u64 {
428 fn parse(
429 node: &mut xml::Node,
430 _: &mut impl NodeStoreBuilder,
431 _: &mut impl ValueStoreBuilder,
432 _: &mut impl CacheStoreBuilder,
433 ) -> Self {
434 let value = node.next_text().unwrap();
435 convert_to_uint(&value.view())
436 }
437}
438
439impl Parse for f64 {
440 fn parse(
441 node: &mut xml::Node,
442 _: &mut impl NodeStoreBuilder,
443 _: &mut impl ValueStoreBuilder,
444 _: &mut impl CacheStoreBuilder,
445 ) -> Self {
446 let value = node.next_text().unwrap().view();
447 if value == "INF" {
448 f64::INFINITY
449 } else if value == "-INF" {
450 f64::NEG_INFINITY
451 } else {
452 value.parse().unwrap()
453 }
454 }
455}
456
457impl Parse for String {
458 fn parse(
459 node: &mut xml::Node,
460 _: &mut impl NodeStoreBuilder,
461 _: &mut impl ValueStoreBuilder,
462 _: &mut impl CacheStoreBuilder,
463 ) -> Self {
464 node.next_text().unwrap().view().into()
465 }
466}
467
468impl Parse for NodeId {
469 fn parse(
470 node: &mut xml::Node,
471 node_builder: &mut impl NodeStoreBuilder,
472 _: &mut impl ValueStoreBuilder,
473 _: &mut impl CacheStoreBuilder,
474 ) -> Self {
475 let text = node.next_text().unwrap();
476 node_builder.get_or_intern(text.view())
477 }
478}
479
480macro_rules! impl_parse_for_value_id {
481 ($id:ty, $value_ty:ty) => {
482 impl Parse for $id {
483 fn parse(
484 node: &mut xml::Node,
485 node_builder: &mut impl NodeStoreBuilder,
486 value_builder: &mut impl ValueStoreBuilder,
487 cache_builder: &mut impl CacheStoreBuilder,
488 ) -> Self {
489 let value: $value_ty = node.parse(node_builder, value_builder, cache_builder);
490 let id = value_builder.store(value);
491 id
492 }
493 }
494 };
495}
496
497impl_parse_for_value_id!(IntegerId, i64);
498impl_parse_for_value_id!(FloatId, f64);
499
500impl<T> Parse for ValueKind<T>
501where
502 T: Clone + Parse + PartialEq,
503 ImmOrPNode<T>: Parse,
504{
505 fn parse(
506 node: &mut xml::Node,
507 node_builder: &mut impl NodeStoreBuilder,
508 value_builder: &mut impl ValueStoreBuilder,
509 cache_builder: &mut impl CacheStoreBuilder,
510 ) -> Self {
511 let peek = node.peek().unwrap();
512 match peek.tag_name() {
513 VALUE => ValueKind::Value(node.parse(node_builder, value_builder, cache_builder)),
514 P_VALUE_COPY | P_VALUE => {
515 let p_value = node.parse(node_builder, value_builder, cache_builder);
516 ValueKind::PValue(p_value)
517 }
518 P_INDEX => {
519 let p_index = node.parse(node_builder, value_builder, cache_builder);
520 ValueKind::PIndex(p_index)
521 }
522 _ => unreachable!(),
523 }
524 }
525}
526
527impl<T> Parse for PValue<T> {
528 fn parse(
529 node: &mut xml::Node,
530 node_builder: &mut impl NodeStoreBuilder,
531 value_builder: &mut impl ValueStoreBuilder,
532 cache_builder: &mut impl CacheStoreBuilder,
533 ) -> Self {
534 let mut p_value_copies =
536 node.parse_while(P_VALUE_COPY, node_builder, value_builder, cache_builder);
537
538 let p_value = node.parse(node_builder, value_builder, cache_builder);
539
540 let node_ids: Vec<NodeId> =
541 node.parse_while(P_VALUE_COPY, node_builder, value_builder, cache_builder);
542 p_value_copies.extend(node_ids);
543
544 Self {
545 p_value,
546 p_value_copies,
547 phantom: PhantomData,
548 }
549 }
550}
551
552impl<T> Parse for PIndex<T>
553where
554 T: Clone + PartialEq + Parse,
555 ImmOrPNode<T>: Parse,
556{
557 fn parse(
558 node: &mut xml::Node,
559 node_builder: &mut impl NodeStoreBuilder,
560 value_builder: &mut impl ValueStoreBuilder,
561 cache_builder: &mut impl CacheStoreBuilder,
562 ) -> Self {
563 let p_index = node.parse(node_builder, value_builder, cache_builder);
564
565 let mut value_indexed = vec![];
566 while let Some(indexed) = node
567 .parse_if(VALUE_INDEXED, node_builder, value_builder, cache_builder)
568 .or_else(|| node.parse_if(P_VALUE_INDEXED, node_builder, value_builder, cache_builder))
569 {
570 value_indexed.push(indexed);
571 }
572
573 let value_default = node.parse(node_builder, value_builder, cache_builder);
574
575 Self {
576 p_index,
577 value_indexed,
578 value_default,
579 }
580 }
581}
582
583impl<T> Parse for ValueIndexed<T>
584where
585 T: Clone + PartialEq + Parse,
586 ImmOrPNode<T>: Parse,
587{
588 fn parse(
589 node: &mut xml::Node,
590 node_builder: &mut impl NodeStoreBuilder,
591 value_builder: &mut impl ValueStoreBuilder,
592 cache_builder: &mut impl CacheStoreBuilder,
593 ) -> Self {
594 let index = convert_to_int(node.peek().unwrap().attribute_of(INDEX).unwrap());
595 let indexed = node.parse(node_builder, value_builder, cache_builder);
596 Self { index, indexed }
597 }
598}
599
600impl Parse for AddressKind {
601 fn parse(
602 node: &mut xml::Node,
603 node_builder: &mut impl NodeStoreBuilder,
604 value_builder: &mut impl ValueStoreBuilder,
605 cache_builder: &mut impl CacheStoreBuilder,
606 ) -> Self {
607 let peeked_node = node.peek().unwrap();
608 match peeked_node.tag_name() {
609 ADDRESS | P_ADDRESS => {
610 Self::Address(node.parse(node_builder, value_builder, cache_builder))
611 }
612 INT_SWISS_KNIFE => {
613 let swiss_knife: IntSwissKnifeNode =
614 node.next()
615 .unwrap()
616 .parse(node_builder, value_builder, cache_builder);
617 let id = swiss_knife.node_base().id();
618 node_builder.store_node(id, NodeData::IntSwissKnife(swiss_knife.into()));
619 Self::IntSwissKnife(id)
620 }
621 P_INDEX => Self::PIndex(node.parse(node_builder, value_builder, cache_builder)),
622 _ => unreachable!(),
623 }
624 }
625}
626
627impl Parse for RegPIndex {
628 fn parse(
629 node: &mut xml::Node,
630 node_builder: &mut impl NodeStoreBuilder,
631 value_builder: &mut impl ValueStoreBuilder,
632 cache_builder: &mut impl CacheStoreBuilder,
633 ) -> Self {
634 let next_node = node.peek().unwrap();
635
636 let imm_offset = next_node
637 .attribute_of(OFFSET)
638 .map(|s| ImmOrPNode::Imm(convert_to_int(s)));
639 let pnode_offset = next_node
640 .attribute_of(P_OFFSET)
641 .map(|s| ImmOrPNode::PNode(node_builder.get_or_intern(s)));
642 let offset = imm_offset.xor(pnode_offset);
643
644 let p_index = node.parse(node_builder, value_builder, cache_builder);
645
646 Self { offset, p_index }
647 }
648}
649
650impl Default for Endianness {
651 fn default() -> Self {
652 Self::LE
653 }
654}
655
656impl Parse for Endianness {
657 fn parse(
658 node: &mut xml::Node,
659 _: &mut impl NodeStoreBuilder,
660 _: &mut impl ValueStoreBuilder,
661 _: &mut impl CacheStoreBuilder,
662 ) -> Self {
663 let text = node.next_text().unwrap();
664 match_text_view! {text,
665 "LittleEndian" => Self::LE,
666 "BigEndian" => Self::BE,
667 }
668 }
669}
670
671impl Default for Sign {
672 fn default() -> Self {
673 Self::Unsigned
674 }
675}
676
677impl Parse for Sign {
678 fn parse(
679 node: &mut xml::Node,
680 _: &mut impl NodeStoreBuilder,
681 _: &mut impl ValueStoreBuilder,
682 _: &mut impl CacheStoreBuilder,
683 ) -> Self {
684 let text = node.next_text().unwrap();
685 match_text_view! {text,
686 "Signed" => Self::Signed,
687 "Unsigned" => Self::Unsigned,
688 }
689 }
690}
691
692impl Parse for BitMask {
693 fn parse(
694 node: &mut xml::Node,
695 node_builder: &mut impl NodeStoreBuilder,
696 value_builder: &mut impl ValueStoreBuilder,
697 cache_builder: &mut impl CacheStoreBuilder,
698 ) -> Self {
699 node.parse_if(BIT, node_builder, value_builder, cache_builder)
700 .map_or_else(
701 || {
702 let lsb = node.parse(node_builder, value_builder, cache_builder);
703 let msb = node.parse(node_builder, value_builder, cache_builder);
704 Self::Range { lsb, msb }
705 },
706 Self::SingleBit,
707 )
708 }
709}