1use crate::constants::NumericArrayEnum;
6use crate::writer::Writer;
7use crate::wxf::writer::WxfWriter;
8use crate::Error;
9
10pub trait ToWXF {
12 fn to_wxf<W: Writer>(&self, w: &mut WxfWriter<W>) -> Result<(), Error>;
14}
15
16pub trait WxfStruct {}
20
21macro_rules! impl_to_wxf_int {
26 ($($t:ty),+) => {
27 $(
28 impl ToWXF for $t {
29 fn to_wxf<W: Writer>(&self, w: &mut WxfWriter<W>) -> Result<(), Error> {
30 w.write_integer(i64::from(*self))
31 }
32 }
33 )+
34 };
35}
36impl_to_wxf_int!(i8, i16, i32, i64, u8, u16, u32);
37
38impl ToWXF for u64 {
39 fn to_wxf<W: Writer>(&self, w: &mut WxfWriter<W>) -> Result<(), Error> {
40 w.write_integer(i64::try_from(*self).unwrap_or(i64::MAX))
42 }
43}
44
45impl ToWXF for f32 {
46 fn to_wxf<W: Writer>(&self, w: &mut WxfWriter<W>) -> Result<(), Error> {
47 w.write_real(f64::from(*self))
48 }
49}
50
51impl ToWXF for f64 {
52 fn to_wxf<W: Writer>(&self, w: &mut WxfWriter<W>) -> Result<(), Error> {
53 w.write_real(*self)
54 }
55}
56
57impl ToWXF for bool {
58 fn to_wxf<W: Writer>(&self, w: &mut WxfWriter<W>) -> Result<(), Error> {
59 w.write_symbol(if *self { "System`True" } else { "System`False" })
60 }
61}
62
63impl ToWXF for str {
64 fn to_wxf<W: Writer>(&self, w: &mut WxfWriter<W>) -> Result<(), Error> {
65 w.write_string(self)
66 }
67}
68
69impl ToWXF for String {
70 fn to_wxf<W: Writer>(&self, w: &mut WxfWriter<W>) -> Result<(), Error> {
71 w.write_string(self.as_str())
72 }
73}
74
75impl<T: ToWXF + ?Sized> ToWXF for &T {
76 fn to_wxf<W: Writer>(&self, w: &mut WxfWriter<W>) -> Result<(), Error> {
77 (*self).to_wxf(w)
78 }
79}
80
81impl<T: ToWXF + ?Sized> ToWXF for Box<T> {
82 fn to_wxf<W: Writer>(&self, w: &mut WxfWriter<W>) -> Result<(), Error> {
83 (**self).to_wxf(w)
84 }
85}
86
87impl ToWXF for [u8] {
93 fn to_wxf<W: Writer>(&self, w: &mut WxfWriter<W>) -> Result<(), Error> {
94 w.write_byte_array(self)
95 }
96}
97impl ToWXF for Vec<u8> {
98 fn to_wxf<W: Writer>(&self, w: &mut WxfWriter<W>) -> Result<(), Error> {
99 w.write_byte_array(self)
100 }
101}
102
103macro_rules! impl_slice_numeric {
106 ($($t:ty => $variant:ident),+ $(,)?) => {
107 $(
108 impl ToWXF for [$t] {
109 fn to_wxf<W: Writer>(&self, w: &mut WxfWriter<W>) -> Result<(), Error> {
110 let bytes: &[u8] = unsafe {
113 ::core::slice::from_raw_parts(
114 self.as_ptr() as *const u8,
115 ::core::mem::size_of::<$t>() * self.len(),
116 )
117 };
118 w.write_numeric_array(NumericArrayEnum::$variant, &[self.len()], bytes)
119 }
120 }
121
122 impl ToWXF for Vec<$t> {
123 fn to_wxf<W: Writer>(&self, w: &mut WxfWriter<W>) -> Result<(), Error> {
124 self.as_slice().to_wxf(w)
125 }
126 }
127 )+
128 };
129}
130impl_slice_numeric!(
131 i8 => Integer8,
132 i16 => Integer16,
133 i32 => Integer32,
134 i64 => Integer64,
135 u16 => UnsignedInteger16,
136 u32 => UnsignedInteger32,
137 u64 => UnsignedInteger64,
138 f32 => Real32,
139 f64 => Real64,
140);
141
142impl<T: ToWXF + WxfStruct> ToWXF for Vec<T> {
144 fn to_wxf<W: Writer>(&self, w: &mut WxfWriter<W>) -> Result<(), Error> {
145 w.write_function(self.len())?;
146 w.write_symbol("System`List")?;
147 for e in self {
148 e.to_wxf(w)?;
149 }
150 Ok(())
151 }
152}
153
154impl ToWXF for () {
159 fn to_wxf<W: Writer>(&self, w: &mut WxfWriter<W>) -> Result<(), Error> {
160 w.write_symbol("System`Null")
161 }
162}
163
164impl<T: ToWXF> ToWXF for Option<T> {
171 fn to_wxf<W: Writer>(&self, w: &mut WxfWriter<W>) -> Result<(), Error> {
172 match self {
173 None => crate::strategy::write_unit_variant(
174 w,
175 crate::strategy::DEFAULT_ENUM_HEAD,
176 "None",
177 ),
178 Some(v) => {
179 crate::strategy::begin_data_variant(
180 w,
181 crate::strategy::DEFAULT_ENUM_HEAD,
182 "Some",
183 1,
184 )?;
185 v.to_wxf(w)
186 },
187 }
188 }
189}
190
191impl<T: ToWXF, E: ToWXF> ToWXF for Result<T, E> {
192 fn to_wxf<W: Writer>(&self, w: &mut WxfWriter<W>) -> Result<(), Error> {
193 match self {
194 Ok(v) => {
195 crate::strategy::begin_data_variant(
196 w,
197 crate::strategy::DEFAULT_ENUM_HEAD,
198 "Ok",
199 1,
200 )?;
201 v.to_wxf(w)
202 },
203 Err(e) => {
204 crate::strategy::begin_data_variant(
205 w,
206 crate::strategy::DEFAULT_ENUM_HEAD,
207 "Err",
208 1,
209 )?;
210 e.to_wxf(w)
211 },
212 }
213 }
214}
215
216impl<K: ToWXF, V: ToWXF, S> ToWXF for std::collections::HashMap<K, V, S> {
217 fn to_wxf<W: Writer>(&self, w: &mut WxfWriter<W>) -> Result<(), Error> {
218 w.write_association(self.len())?;
219 for (k, v) in self {
220 w.write_rule(false)?;
221 k.to_wxf(w)?;
222 v.to_wxf(w)?;
223 }
224 Ok(())
225 }
226}
227
228impl<K: ToWXF, V: ToWXF> ToWXF for std::collections::BTreeMap<K, V> {
229 fn to_wxf<W: Writer>(&self, w: &mut WxfWriter<W>) -> Result<(), Error> {
230 w.write_association(self.len())?;
231 for (k, v) in self {
232 w.write_rule(false)?;
233 k.to_wxf(w)?;
234 v.to_wxf(w)?;
235 }
236 Ok(())
237 }
238}
239
240