wolfram_serialize/wxf/
writer.rs1use crate::constants::{ExpressionEnum, NumericArrayEnum, PackedArrayEnum};
9use crate::writer::Writer;
10use crate::Error;
11
12pub struct WxfWriter<W> {
14 inner: W,
15}
16
17impl<W: Writer> WxfWriter<W> {
18 pub fn new(inner: W) -> Self {
21 WxfWriter { inner }
22 }
23
24 pub fn into_inner(self) -> W {
26 self.inner
27 }
28
29 pub fn write_varint(&mut self, n: u64) -> Result<(), Error> {
33 let mut value = n;
34 loop {
35 let mut byte = (value & 0x7F) as u8;
36 value >>= 7;
37 if value != 0 {
38 byte |= 0x80;
39 self.inner.write_byte(byte)?;
40 } else {
41 self.inner.write_byte(byte)?;
42 return Ok(());
43 }
44 }
45 }
46
47 pub fn write_expr_token(&mut self, t: ExpressionEnum) -> Result<(), Error> {
49 self.inner.write_byte(t as u8)
50 }
51
52 pub fn write_integer(&mut self, n: i64) -> Result<(), Error> {
56 if let Ok(v) = i8::try_from(n) {
57 self.write_expr_token(ExpressionEnum::Integer8)?;
58 self.inner.write_bytes(&v.to_le_bytes())
59 } else if let Ok(v) = i16::try_from(n) {
60 self.write_expr_token(ExpressionEnum::Integer16)?;
61 self.inner.write_bytes(&v.to_le_bytes())
62 } else if let Ok(v) = i32::try_from(n) {
63 self.write_expr_token(ExpressionEnum::Integer32)?;
64 self.inner.write_bytes(&v.to_le_bytes())
65 } else {
66 self.write_expr_token(ExpressionEnum::Integer64)?;
67 self.inner.write_bytes(&n.to_le_bytes())
68 }
69 }
70
71 pub fn write_real(&mut self, f: f64) -> Result<(), Error> {
73 self.write_expr_token(ExpressionEnum::Real64)?;
74 self.inner.write_bytes(&f.to_le_bytes())
75 }
76
77 pub fn write_string(&mut self, s: &str) -> Result<(), Error> {
79 self.write_length_prefixed(ExpressionEnum::String, s.as_bytes())
80 }
81
82 pub fn write_symbol(&mut self, name: &str) -> Result<(), Error> {
84 self.write_length_prefixed(ExpressionEnum::Symbol, name.as_bytes())
85 }
86
87 pub fn write_byte_array(&mut self, bytes: &[u8]) -> Result<(), Error> {
89 self.write_length_prefixed(ExpressionEnum::ByteArray, bytes)
90 }
91
92 pub fn write_big_integer(&mut self, digits: &str) -> Result<(), Error> {
94 self.write_length_prefixed(ExpressionEnum::BigInteger, digits.as_bytes())
95 }
96
97 pub fn write_big_real(&mut self, digits: &str) -> Result<(), Error> {
99 self.write_length_prefixed(ExpressionEnum::BigReal, digits.as_bytes())
100 }
101
102 pub fn write_numeric_array(
104 &mut self,
105 dt: NumericArrayEnum,
106 dims: &[usize],
107 bytes: &[u8],
108 ) -> Result<(), Error> {
109 self.write_expr_token(ExpressionEnum::NumericArray)?;
110 self.inner.write_byte(dt as u8)?;
111 self.write_dims(dims)?;
112 self.inner.write_bytes(bytes)
113 }
114
115 pub fn write_packed_array(
117 &mut self,
118 dt: PackedArrayEnum,
119 dims: &[usize],
120 bytes: &[u8],
121 ) -> Result<(), Error> {
122 self.write_expr_token(ExpressionEnum::PackedArray)?;
123 self.inner.write_byte(NumericArrayEnum::from(dt) as u8)?;
124 self.write_dims(dims)?;
125 self.inner.write_bytes(bytes)
126 }
127
128 pub fn write_function(&mut self, arity: usize) -> Result<(), Error> {
133 self.write_expr_token(ExpressionEnum::Function)?;
134 self.write_varint(arity as u64)
135 }
136
137 pub fn write_association(&mut self, count: usize) -> Result<(), Error> {
140 self.write_expr_token(ExpressionEnum::Association)?;
141 self.write_varint(count as u64)
142 }
143
144 pub fn write_rule(&mut self, delayed: bool) -> Result<(), Error> {
146 self.write_expr_token(if delayed {
147 ExpressionEnum::RuleDelayed
148 } else {
149 ExpressionEnum::Rule
150 })
151 }
152
153 fn write_length_prefixed(
156 &mut self,
157 token: ExpressionEnum,
158 bytes: &[u8],
159 ) -> Result<(), Error> {
160 self.write_expr_token(token)?;
161 self.write_varint(bytes.len() as u64)?;
162 self.inner.write_bytes(bytes)
163 }
164
165 fn write_dims(&mut self, dims: &[usize]) -> Result<(), Error> {
166 self.write_varint(dims.len() as u64)?;
167 for d in dims {
168 self.write_varint(*d as u64)?;
169 }
170 Ok(())
171 }
172}