1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
use clap::{Parser, ValueEnum};
use serde::de::Deserializer;
use std::{
convert::TryFrom,
io::{Read, Write},
};
#[derive(Debug, Parser)]
#[clap(author, version, about, long_about = None)]
pub struct Opt {
/// Input type
#[clap(value_enum, ignore_case = true)]
pub input: Input,
/// Output type
#[clap(value_enum, ignore_case = true)]
pub output: Output,
#[clap(long, short = 'F', required_if_eq_any(&[("input", "d-bus"), ("input", "g-variant")]))]
pub format_in: Option<String>,
#[clap(long, short = 'f', required_if_eq_any(&[("output", "d-bus"), ("output", "g-variant")]))]
pub format_out: Option<String>,
/// For data format compatible, a default pretty format is output instead of a minified one
/// Output a pretty formated data instead of minified, only for format compatible
#[clap(long, short)]
pub pretty: bool,
/// Do not output a newline at the end of the stream
#[clap(long, short)]
pub no_newline: bool,
}
#[derive(Copy, Clone, Debug, ValueEnum)]
pub enum Input {
Bencode,
//Bson,
//Cbor,
DBus,
//DynamoDB,
//FlexBuffer,
GVariant,
Json,
Json5,
//SExpression,
Pickle,
//Qs, // NOTE: The crate is not noted "(serialization only)" on the [serde listing](https://serde.rs/#data-formats) but it does not expose a `Deserializer`
//Rmp, // NOTE: It appears that we are forced to deserialize into a concrete type
Ron,
//Toml
Yaml,
}
#[derive(Copy, Clone, Debug, ValueEnum)]
pub enum Output {
//Bencode,
//Bson,
//Cbor,
DBus,
//DynamoDB,
//FlexBuffer,
GVariant,
Json,
//Json5, // NOTE: The crate is not noted "(deserialization only)" on the [serde listing](https://serde.rs/#data-formats) but it does not expose a `Serializer`
//SExpression,
Pickle,
Qs,
Rmp,
Ron,
//Toml,
Yaml,
}
pub fn transcode(opt: Opt, input: &mut dyn Read, output: &mut dyn Write) {
de(&opt, input, output);
// TODO: I would love to be able to have `de` and `ser` return the correct
// (de)serializer and then call `serde_transcode::transcode(deserializer, serializer)`
// here once for all. This will be a clearer separation of function,
// but it may need `erased_serde` that I did not made it work with `serde_transcode`.
if !opt.no_newline {
output.write_all(b"\n").expect(
"We already wrote the whole serialized struct, a new line at the end should be OK",
);
}
}
fn de(opt: &Opt, input: &mut dyn Read, output: &mut dyn Write) {
match opt.input {
Input::Bencode => {
use bendy::serde::Deserializer;
let mut buf = vec![];
let _buf_size = input.read_to_end(&mut buf).unwrap();
let mut deserializer = Deserializer::from_bytes(&buf);
ser(opt, &mut deserializer, output);
}
/*
Input::Bson => {
use bson::Deserializer;
let deserializer = bson::from_reader(input).unwrap(); // FIXME: can we skip the type annotation?
ser(opt, deserializer, output);
}
*/
Input::DBus => {
use zvariant::dbus::Deserializer;
use zvariant::EncodingContext;
use zvariant::Signature;
use byteorder::LE;
let sig = opt.format_in.clone().unwrap();
let mut buf = String::new();
let _buf_size = input.read_to_string(&mut buf).unwrap();
let mut deserializer = Deserializer::new(
buf.as_bytes(),
None,
&Signature::try_from(sig).unwrap(),
EncodingContext::<LE>::new_dbus(0),
);
ser(opt, &mut deserializer, output);
}
/*
Input::DynamoDB => {
use serde_dynamo::Deserializer;
let deserializer = Deserializer::from(input); // from_reader(input);
ser(opt, deserializer, output);
}
*/
/*
Input::FlexBuffer => {
use serde_yaml::Deserializer;
let deserializer = Deserializer::from_reader(input);
ser(opt, deserializer, output);
}
*/
Input::GVariant => {
use zvariant::gvariant::Deserializer;
use zvariant::EncodingContext;
use zvariant::Signature;
use byteorder::LE;
let sig = opt.format_in.clone().unwrap();
let mut buf = String::new();
let _buf_size = input.read_to_string(&mut buf).unwrap();
let mut deserializer = Deserializer::new(
buf.as_bytes(),
None,
&Signature::try_from(sig).unwrap(),
EncodingContext::<LE>::new_dbus(0),
);
ser(opt, &mut deserializer, output);
}
Input::Json => {
use serde_json::Deserializer;
// NOTE: Apparently serde_json do not implement `Deserializer` on const?
let mut deserializer = Deserializer::from_reader(input);
ser(opt, &mut deserializer, output);
}
Input::Json5 => {
use json5::Deserializer;
// NOTE: Apparently Json5 do not implement `Deserializer` on const?
// NOTE: Apparently Json5 do not implement `Deserializer::from_reader` but it can serialise into a writter…
let mut buf = String::new();
let _buf_size = input.read_to_string(&mut buf).unwrap();
let mut deserializer = Deserializer::from_str(&buf).unwrap();
ser(opt, &mut deserializer, output);
}
/*
Input::SExpression => {
use serde_lexpr as Deserializer;
let deserializer = Deserializer::from_reader(input).unwrap(); // FIXME: can we skip the type annotation?
ser(opt, deserializer, output);
}
*/
Input::Pickle => {
use serde_pickle::Deserializer;
// NOTE: Apparently serde_pickle do not implement `Deserializer` on const?
let mut deserializer = Deserializer::new(input, serde_pickle::DeOptions::new());
ser(opt, &mut deserializer, output);
}
Input::Ron => {
use ron::Deserializer;
// NOTE: Apparently ron do not implement `Deserializer` on const?
// NOTE: Apparently ron do not implement `Deserializer::from_reader` but it can serialise into a writter…
let mut buf = vec![];
let _buf_size = input.read_to_end(&mut buf).unwrap();
let mut deserializer = Deserializer::from_bytes(&buf).unwrap();
ser(opt, &mut deserializer, output);
}
Input::Yaml => {
use serde_yaml::Deserializer;
let deserializer = Deserializer::from_reader(input);
ser(opt, deserializer, output);
}
};
}
fn ser<'de, D>(opt: &Opt, deserializer: D, output: &mut dyn Write)
where
D: Deserializer<'de>,
{
match opt.output {
/*
Output::Bencode => {
use bendy::serde::Serializer;
let serializer = &mut Serializer::new(/*output*/);
serde_transcode::transcode(deserializer, serializer).unwrap();
serializer.into_bytes();
}
*/
/*
Output::Bson => {
use bson::Serializer;
let options = bson::SerializerOptions::builder();
let options = if opt.pretty {
options.human_readable(true)
} else {
options.human_readable(false)
};
let serializer = Serializer::new_with_options(options.build()); // FIXME: why no way to tell the serializer were we want the output?
serde_transcode::transcode(deserializer, serializer).unwrap();
}
*/
Output::DBus => {
use zvariant::dbus::Serializer;
use zvariant::EncodingContext;
use zvariant::Signature;
use byteorder::LE;
let sig = opt.format_out.clone().unwrap();
let mut out = std::io::Cursor::new(vec![]);
let mut fs = vec![];
let serializer = &mut Serializer::new(
&Signature::try_from(sig).unwrap(),
&mut out,
&mut fs, //None,
EncodingContext::<LE>::new_dbus(0),
);
//let mut buf = String::new();
// let _buf_size = output.read_to_string(&mut buf).unwrap();
// let mut deserializer = Deserializer::new();
serde_transcode::transcode(deserializer, serializer).unwrap();
}
/*
Output::DynamoDB => {
use serde_dynamo::Serializer;
let serializer = &mut Serializer::new(output);
serde_transcode::transcode(deserializer, serializer).unwrap();
}
*/
/*
Output::FlexBuffer => {
use flexbuffers::FlexbufferSerializer as Serializer;
let serializer = &mut Serializer::new(/*output*/);
// serde_transcode::transcode(deserializer, serializer).unwrap();
let r = flexbuffers::Reader::get_root(serializer.view()).unwrap();
println!("{}", r);
}
*/
Output::GVariant => {
use zvariant::gvariant::Serializer;
use zvariant::EncodingContext;
use zvariant::Signature;
use byteorder::LE;
let sig = opt.format_out.clone().unwrap();
let mut out = std::io::Cursor::new(vec![]);
let mut fs = vec![];
let serializer = &mut Serializer::new(
&Signature::try_from(sig).unwrap(),
&mut out,
&mut fs, //None,
EncodingContext::<LE>::new_dbus(0),
);
//let mut buf = String::new();
// let _buf_size = output.read_to_string(&mut buf).unwrap();
// let mut deserializer = Deserializer::new();
serde_transcode::transcode(deserializer, serializer).unwrap();
}
Output::Json => {
use serde_json::Serializer;
if opt.pretty {
let formatter = serde_json::ser::PrettyFormatter::with_indent(b"\t");
let serializer = &mut Serializer::with_formatter(output, formatter);
serde_transcode::transcode(deserializer, serializer).unwrap();
} else {
let serializer = &mut Serializer::new(output);
serde_transcode::transcode(deserializer, serializer).unwrap();
};
// NOTE: serde_json’s PrettyFormatter and CompactFormatter are incompatibles…
// serde_transcode::transcode(deserializer, serializer).unwrap();
}
/*
Output::SExpression => {
use serde_lexpr::to_writer as Serializer;
let serializer = Serializer::new(output); // FIXME: There is a `to_writer` but the Serializer is not exposed directly.
serde_transcode::transcode(deserializer, serializer).unwrap();
}
*/
Output::Pickle => {
use serde_pickle::Serializer;
let serializer = &mut Serializer::new(output, serde_pickle::SerOptions::new());
serde_transcode::transcode(deserializer, serializer).unwrap();
}
Output::Qs => {
use serde_qs::Serializer;
let serializer = &mut Serializer::new(output);
serde_transcode::transcode(deserializer, serializer).unwrap();
}
Output::Rmp => {
use rmp_serde::Serializer;
let serializer = &mut Serializer::new(output);
serde_transcode::transcode(deserializer, serializer).unwrap();
}
Output::Ron => {
use ron::Serializer;
let mut pretty_config = None;
if opt.pretty {
let pretty = ron::ser::PrettyConfig::new().indentor("\t".to_owned());
pretty_config = Some(pretty);
}
let serializer = &mut Serializer::new(output, pretty_config).unwrap();
serde_transcode::transcode(deserializer, serializer).unwrap();
}
Output::Yaml => {
use serde_yaml::Serializer;
let serializer = &mut Serializer::new(output);
serde_transcode::transcode(deserializer, serializer).unwrap();
}
};
}