fbxcel/writer/v7400/binary/
macros.rs1#[cfg_attr(docsrs, doc(cfg(feature = "writer")))]
39#[macro_export]
40macro_rules! write_v7400_binary {
41 (
42 writer=$writer:expr,
43 tree={$($tree:tt)*},
44 ) => {{
45 let mut f = || -> $crate::writer::v7400::binary::Result<()> {
46 let _writer = &mut $writer;
47 write_v7400_binary! { @__node, _writer, $($tree)* };
48 Ok(())
49 };
50 f()
51 }};
52
53
54 (@__node, $writer:ident,) => {};
55 (@__node, $writer:ident, , $($tree:tt)*) => {
56 write_v7400_binary! { @__node, $writer, $($tree)* }
57 };
58
59 (@__node, $writer:ident,
60 $name:ident: {
61 $($subtree:tt)*
62 }
63 $($rest:tt)*
64 ) => {{
65 $writer.new_node(stringify!($name))?;
66 write_v7400_binary! { @__node, $writer, $($subtree)* }
67 $writer.close_node()?;
68 write_v7400_binary! { @__node, $writer, $($rest)* }
69 }};
70 (@__node, $writer:ident,
71 $name:ident: [$($attr:expr),* $(,)?] {
72 $($subtree:tt)*
73 }
74 $($rest:tt)*
75 ) => {{
76 let mut _attrs = $writer.new_node(stringify!($name))?;
77 $({
78 let attr = $attr;
79 write_v7400_binary!(@__attr, _attrs, attr.into())?;
80 })*
81 write_v7400_binary! { @__node, $writer, $($subtree)* }
82 $writer.close_node()?;
83 write_v7400_binary! { @__node, $writer, $($rest)* }
84 }};
85 (@__node, $writer:ident,
86 $name:ident: ($attrs:expr) {
87 $($subtree:tt)*
88 }
89 $($rest:tt)*
90 ) => {{
91 let mut _attrs = $writer.new_node(stringify!($name))?;
92 $attrs.into_iter().try_for_each(|attr: $crate::low::v7400::AttributeValue| {
93 write_v7400_binary!(@__attr, _attrs, attr.into())
94 })?;
95 write_v7400_binary! { @__node, $writer, $($subtree)* }
96 $writer.close_node()?;
97 write_v7400_binary! { @__node, $writer, $($rest)* }
98 }};
99
100 (@__attr, $attrs:ident, $attr:expr) => {{
101 use $crate::low::v7400::AttributeValue::*;
102 match $attr {
103 Bool(v) => $attrs.append_bool(v),
104 I16(v) => $attrs.append_i16(v),
105 I32(v) => $attrs.append_i32(v),
106 I64(v) => $attrs.append_i64(v),
107 F32(v) => $attrs.append_f32(v),
108 F64(v) => $attrs.append_f64(v),
109 ArrBool(v) => $attrs.append_arr_bool_from_iter(None, v),
110 ArrI32(v) => $attrs.append_arr_i32_from_iter(None, v),
111 ArrI64(v) => $attrs.append_arr_i64_from_iter(None, v),
112 ArrF32(v) => $attrs.append_arr_f32_from_iter(None, v),
113 ArrF64(v) => $attrs.append_arr_f64_from_iter(None, v),
114 Binary(v) => $attrs.append_binary_direct(&v),
115 String(v) => $attrs.append_string_direct(&v),
116 }
117 }};
118}
119
120#[cfg(test)]
121mod tests {
122 use std::io::Cursor;
123
124 use crate::{
125 low::FbxVersion,
126 writer::v7400::binary::{Result, Writer},
127 };
128
129 #[test]
130 fn empty_writer() -> Result<()> {
131 let mut writer = Writer::new(Cursor::new(Vec::new()), FbxVersion::V7_4)?;
132 write_v7400_binary!(writer = writer, tree = {},)?;
133 let _buf = writer.finalize_and_flush(&Default::default())?;
134
135 Ok(())
136 }
137
138 #[test]
139 fn empty_node() -> Result<()> {
140 let mut writer = Writer::new(Cursor::new(Vec::new()), FbxVersion::V7_4)?;
141 write_v7400_binary!(
142 writer=writer,
143 tree={
144 Hello: {}
145 World: {},
146 },
147 )?;
148 let _buf = writer.finalize_and_flush(&Default::default())?;
149
150 Ok(())
151 }
152
153 #[test]
154 fn nested_node() -> Result<()> {
155 let mut writer = Writer::new(Cursor::new(Vec::new()), FbxVersion::V7_4)?;
156 write_v7400_binary!(
157 writer=writer,
158 tree={
159 Hello: {
160 Hello1: {},
161 Hello2: {}
162 }
163 World: {
164 World1: {
165 World1_1: {}
166 World1_2: {}
167 }
168 World2: {},
169 },
170 },
171 )?;
172 let _buf = writer.finalize_and_flush(&Default::default())?;
173
174 Ok(())
175 }
176
177 #[test]
178 fn nested_node_with_attrs() -> Result<()> {
179 let mut writer = Writer::new(Cursor::new(Vec::new()), FbxVersion::V7_4)?;
180 write_v7400_binary!(
181 writer=writer,
182 tree={
183 Hello: {
184 Hello1: (vec!["string".into()]) {},
185 Hello2: [1.234f32, 42i64] {}
186 }
187 World: {
188 World1: {
189 World1_1: (vec!["Hello".into(), 42i32.into()]) {}
190 World1_2: [] {}
191 }
192 World2: {},
193 },
194 },
195 )?;
196 let _buf = writer.finalize_and_flush(&Default::default())?;
197
198 Ok(())
199 }
200}