1use crate::constants::NumericArrayEnum;
6use crate::writer::Writer;
7use crate::wxf::writer::WxfWriter;
8use crate::Error;
9
10pub trait ToWXF {
43 fn to_wxf<W: Writer>(&self, w: &mut WxfWriter<W>) -> Result<(), Error>;
45}
46
47pub trait WxfStruct {}
51
52macro_rules! impl_to_wxf_int {
57 ($($t:ty),+) => {
58 $(
59 impl ToWXF for $t {
60 fn to_wxf<W: Writer>(&self, w: &mut WxfWriter<W>) -> Result<(), Error> {
61 w.write_integer(i64::from(*self))
62 }
63 }
64 )+
65 };
66}
67impl_to_wxf_int!(i8, i16, i32, i64, u8, u16, u32);
68
69impl ToWXF for u64 {
70 fn to_wxf<W: Writer>(&self, w: &mut WxfWriter<W>) -> Result<(), Error> {
71 w.write_integer(i64::try_from(*self).unwrap_or(i64::MAX))
73 }
74}
75
76impl ToWXF for f32 {
77 fn to_wxf<W: Writer>(&self, w: &mut WxfWriter<W>) -> Result<(), Error> {
78 w.write_real(f64::from(*self))
79 }
80}
81
82impl ToWXF for f64 {
83 fn to_wxf<W: Writer>(&self, w: &mut WxfWriter<W>) -> Result<(), Error> {
84 w.write_real(*self)
85 }
86}
87
88impl ToWXF for bool {
89 fn to_wxf<W: Writer>(&self, w: &mut WxfWriter<W>) -> Result<(), Error> {
90 w.write_symbol(if *self { "System`True" } else { "System`False" })
91 }
92}
93
94impl ToWXF for str {
95 fn to_wxf<W: Writer>(&self, w: &mut WxfWriter<W>) -> Result<(), Error> {
96 w.write_string(self)
97 }
98}
99
100impl ToWXF for String {
101 fn to_wxf<W: Writer>(&self, w: &mut WxfWriter<W>) -> Result<(), Error> {
102 w.write_string(self.as_str())
103 }
104}
105
106impl<T: ToWXF + ?Sized> ToWXF for &T {
107 fn to_wxf<W: Writer>(&self, w: &mut WxfWriter<W>) -> Result<(), Error> {
108 (*self).to_wxf(w)
109 }
110}
111
112impl<T: ToWXF + ?Sized> ToWXF for Box<T> {
113 fn to_wxf<W: Writer>(&self, w: &mut WxfWriter<W>) -> Result<(), Error> {
114 (**self).to_wxf(w)
115 }
116}
117
118impl ToWXF for [u8] {
124 fn to_wxf<W: Writer>(&self, w: &mut WxfWriter<W>) -> Result<(), Error> {
125 w.write_byte_array(self)
126 }
127}
128impl ToWXF for Vec<u8> {
129 fn to_wxf<W: Writer>(&self, w: &mut WxfWriter<W>) -> Result<(), Error> {
130 w.write_byte_array(self)
131 }
132}
133
134macro_rules! impl_slice_numeric {
137 ($($t:ty => $variant:ident),+ $(,)?) => {
138 $(
139 impl ToWXF for [$t] {
140 fn to_wxf<W: Writer>(&self, w: &mut WxfWriter<W>) -> Result<(), Error> {
141 let bytes: &[u8] = unsafe {
144 ::core::slice::from_raw_parts(
145 self.as_ptr() as *const u8,
146 ::core::mem::size_of::<$t>() * self.len(),
147 )
148 };
149 w.write_numeric_array(NumericArrayEnum::$variant, &[self.len()], bytes)
150 }
151 }
152
153 impl ToWXF for Vec<$t> {
154 fn to_wxf<W: Writer>(&self, w: &mut WxfWriter<W>) -> Result<(), Error> {
155 self.as_slice().to_wxf(w)
156 }
157 }
158 )+
159 };
160}
161impl_slice_numeric!(
162 i8 => Integer8,
163 i16 => Integer16,
164 i32 => Integer32,
165 i64 => Integer64,
166 u16 => UnsignedInteger16,
167 u32 => UnsignedInteger32,
168 u64 => UnsignedInteger64,
169 f32 => Real32,
170 f64 => Real64,
171);
172
173impl<T: ToWXF + WxfStruct> ToWXF for Vec<T> {
175 fn to_wxf<W: Writer>(&self, w: &mut WxfWriter<W>) -> Result<(), Error> {
176 w.write_function(self.len())?;
177 w.write_symbol("System`List")?;
178 for e in self {
179 e.to_wxf(w)?;
180 }
181 Ok(())
182 }
183}
184
185impl ToWXF for () {
190 fn to_wxf<W: Writer>(&self, w: &mut WxfWriter<W>) -> Result<(), Error> {
191 w.write_symbol("System`Null")
192 }
193}
194
195impl<T: ToWXF> ToWXF for Option<T> {
202 fn to_wxf<W: Writer>(&self, w: &mut WxfWriter<W>) -> Result<(), Error> {
203 match self {
204 None => crate::strategy::write_unit_variant(
205 w,
206 crate::strategy::DEFAULT_ENUM_HEAD,
207 "None",
208 ),
209 Some(v) => {
210 crate::strategy::begin_data_variant(
211 w,
212 crate::strategy::DEFAULT_ENUM_HEAD,
213 "Some",
214 1,
215 )?;
216 v.to_wxf(w)
217 },
218 }
219 }
220}
221
222impl<T: ToWXF, E: ToWXF> ToWXF for Result<T, E> {
223 fn to_wxf<W: Writer>(&self, w: &mut WxfWriter<W>) -> Result<(), Error> {
224 match self {
225 Ok(v) => {
226 crate::strategy::begin_data_variant(
227 w,
228 crate::strategy::DEFAULT_ENUM_HEAD,
229 "Ok",
230 1,
231 )?;
232 v.to_wxf(w)
233 },
234 Err(e) => {
235 crate::strategy::begin_data_variant(
236 w,
237 crate::strategy::DEFAULT_ENUM_HEAD,
238 "Err",
239 1,
240 )?;
241 e.to_wxf(w)
242 },
243 }
244 }
245}
246
247impl<K: ToWXF, V: ToWXF, S> ToWXF for std::collections::HashMap<K, V, S> {
248 fn to_wxf<W: Writer>(&self, w: &mut WxfWriter<W>) -> Result<(), Error> {
249 w.write_association(self.len())?;
250 for (k, v) in self {
251 w.write_rule(false)?;
252 k.to_wxf(w)?;
253 v.to_wxf(w)?;
254 }
255 Ok(())
256 }
257}
258
259impl<K: ToWXF, V: ToWXF> ToWXF for std::collections::BTreeMap<K, V> {
260 fn to_wxf<W: Writer>(&self, w: &mut WxfWriter<W>) -> Result<(), Error> {
261 w.write_association(self.len())?;
262 for (k, v) in self {
263 w.write_rule(false)?;
264 k.to_wxf(w)?;
265 v.to_wxf(w)?;
266 }
267 Ok(())
268 }
269}
270
271