1use std::convert::TryFrom;
2
3use pest::iterators::Pair;
4
5use crate::{Error, ObjectDataParser, Rule, SubRuleFn};
6
7pub use self::{bdy_kind::BdyKind, bdy_kind_parse_error::BdyKindParseError};
8
9mod bdy_kind;
10mod bdy_kind_parse_error;
11
12#[derive(Clone, Copy, Debug, PartialEq, Eq)]
14pub struct Bdy {
15 pub kind: BdyKind,
20 pub x: i32,
22 pub y: i32,
24 pub w: u32,
26 pub h: u32,
28 pub z_width: u32,
33}
34
35impl Default for Bdy {
36 fn default() -> Bdy {
37 Bdy {
38 kind: Default::default(),
39 x: Default::default(),
40 y: Default::default(),
41 w: Default::default(),
42 h: Default::default(),
43 z_width: Self::Z_WIDTH_DEFAULT,
44 }
45 }
46}
47
48impl Bdy {
49 pub const Z_WIDTH_DEFAULT: u32 = 13;
51
52 fn parse_tags<'i>(bdy: Bdy, bdy_data_pair: Pair<'i, Rule>) -> Result<Bdy, Error<'i>> {
53 bdy_data_pair.into_inner().try_fold(bdy, Bdy::parse_tag)
54 }
55
56 fn parse_tag<'i>(bdy: Bdy, bdy_tag_pair: Pair<'i, Rule>) -> Result<Bdy, Error<'i>> {
57 ObjectDataParser::parse_as_type(
58 bdy,
59 bdy_tag_pair,
60 Rule::BdyTag,
61 &[Self::parse_tag_value as SubRuleFn<_>],
62 )
63 }
64
65 fn parse_tag_value<'i>(mut bdy: Bdy, bdy_tag_pair: Pair<'i, Rule>) -> Result<Bdy, Error<'i>> {
66 bdy = match bdy_tag_pair.as_rule() {
67 Rule::TagKind => {
68 ObjectDataParser::parse_value(bdy, bdy_tag_pair, Self::parse_kind_value)?
69 }
70 Rule::TagX => ObjectDataParser::parse_value(bdy, bdy_tag_pair, Self::parse_x_value)?,
71 Rule::TagY => ObjectDataParser::parse_value(bdy, bdy_tag_pair, Self::parse_y_value)?,
72 Rule::TagW => ObjectDataParser::parse_value(bdy, bdy_tag_pair, Self::parse_w_value)?,
73 Rule::TagH => ObjectDataParser::parse_value(bdy, bdy_tag_pair, Self::parse_h_value)?,
74 Rule::TagZWidth => {
75 ObjectDataParser::parse_value(bdy, bdy_tag_pair, Self::parse_z_width_value)?
76 }
77 _ => bdy,
78 };
79 Ok(bdy)
80 }
81
82 fn parse_kind_value<'i>(mut bdy: Bdy, value_pair: Pair<'i, Rule>) -> Result<Bdy, Error<'i>> {
83 let kind = value_pair
84 .as_str()
85 .parse()
86 .map_err(|error| Error::ParseBdyKind { value_pair, error })?;
87 bdy.kind = kind;
88 Ok(bdy)
89 }
90
91 fn parse_x_value<'i>(mut bdy: Bdy, value_pair: Pair<'i, Rule>) -> Result<Bdy, Error<'i>> {
92 let x = value_pair
93 .as_str()
94 .parse()
95 .map_err(|error| Error::ParseInt {
96 field: stringify!(x),
97 value_pair,
98 error,
99 })?;
100 bdy.x = x;
101 Ok(bdy)
102 }
103
104 fn parse_y_value<'i>(mut bdy: Bdy, value_pair: Pair<'i, Rule>) -> Result<Bdy, Error<'i>> {
105 let y = value_pair
106 .as_str()
107 .parse()
108 .map_err(|error| Error::ParseInt {
109 field: stringify!(y),
110 value_pair,
111 error,
112 })?;
113 bdy.y = y;
114 Ok(bdy)
115 }
116
117 fn parse_w_value<'i>(mut bdy: Bdy, value_pair: Pair<'i, Rule>) -> Result<Bdy, Error<'i>> {
118 let w = value_pair
119 .as_str()
120 .parse()
121 .map_err(|error| Error::ParseInt {
122 field: stringify!(w),
123 value_pair,
124 error,
125 })?;
126 bdy.w = w;
127 Ok(bdy)
128 }
129
130 fn parse_h_value<'i>(mut bdy: Bdy, value_pair: Pair<'i, Rule>) -> Result<Bdy, Error<'i>> {
131 let h = value_pair
132 .as_str()
133 .parse()
134 .map_err(|error| Error::ParseInt {
135 field: stringify!(h),
136 value_pair,
137 error,
138 })?;
139 bdy.h = h;
140 Ok(bdy)
141 }
142
143 fn parse_z_width_value<'i>(mut bdy: Bdy, value_pair: Pair<'i, Rule>) -> Result<Bdy, Error<'i>> {
144 let z_width = value_pair
145 .as_str()
146 .parse()
147 .map_err(|error| Error::ParseInt {
148 field: stringify!(zwidth),
149 value_pair,
150 error,
151 })?;
152 bdy.z_width = z_width;
153 Ok(bdy)
154 }
155}
156
157impl<'i> TryFrom<Pair<'i, Rule>> for Bdy {
158 type Error = Error<'i>;
159
160 fn try_from(pair: Pair<'i, Rule>) -> Result<Self, Self::Error> {
161 let sub_rule_fns: &[SubRuleFn<_>] = &[Bdy::parse_tags];
162 ObjectDataParser::parse_as_type(Bdy::default(), pair, Rule::Bdy, sub_rule_fns)
163 }
164}