Skip to content

Commit 8e4fb6f

Browse files
Merge pull request #465 from ijackson/nested-array
Fix nested arrays (by reworking array handling)
2 parents 3869610 + aa63d2d commit 8e4fb6f

File tree

1 file changed

+113
-74
lines changed

1 file changed

+113
-74
lines changed

src/ser.rs

Lines changed: 113 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::fmt::Display;
2+
use std::fmt::Write as _;
23

34
use serde::ser;
45

@@ -8,87 +9,83 @@ use crate::Config;
89

910
#[derive(Default, Debug)]
1011
pub struct ConfigSerializer {
11-
keys: Vec<(String, Option<usize>)>,
12+
keys: Vec<SerKey>,
1213
pub output: Config,
1314
}
1415

16+
#[derive(Debug)]
17+
enum SerKey {
18+
Named(String),
19+
Seq(usize),
20+
}
21+
22+
/// Serializer for numbered sequences
23+
///
24+
/// This wrapper is present when we are outputting a sequence (numbered indices).
25+
/// Making this a separate type centralises the handling of sequences
26+
/// and ensures we don't have any call sites for `ser::SerializeSeq::serialize_element`
27+
/// that don't do the necessary work of `SeqSerializer::new`.
28+
///
29+
/// Existence of this wrapper implies that `.0.keys.last()` is
30+
/// `Some(SerKey::Seq(next_index))`.
31+
pub struct SeqSerializer<'a>(&'a mut ConfigSerializer);
32+
1533
impl ConfigSerializer {
1634
fn serialize_primitive<T>(&mut self, value: T) -> Result<()>
1735
where
1836
T: Into<Value> + Display,
1937
{
20-
let key = match self.last_key_index_pair() {
21-
Some((key, Some(index))) => format!("{}[{}]", key, index),
22-
Some((key, None)) => key.to_string(),
23-
None => {
24-
return Err(ConfigError::Message(format!(
25-
"key is not found for value {}",
26-
value
27-
)))
28-
}
29-
};
38+
// At some future point we could perhaps retain a cursor into the output `Config`,
39+
// rather than reifying the whole thing into a single string with `make_full_key`
40+
// and passing that whole path to the `set` method.
41+
//
42+
// That would be marginally more performant, but more fiddly.
43+
let key = self.make_full_key()?;
3044

3145
#[allow(deprecated)]
3246
self.output.set(&key, value.into())?;
3347
Ok(())
3448
}
3549

36-
fn last_key_index_pair(&self) -> Option<(&str, Option<usize>)> {
37-
let len = self.keys.len();
38-
if len > 0 {
39-
self.keys
40-
.get(len - 1)
41-
.map(|&(ref key, opt)| (key.as_str(), opt))
42-
} else {
43-
None
44-
}
45-
}
50+
fn make_full_key(&self) -> Result<String> {
51+
let mut keys = self.keys.iter();
4652

47-
fn inc_last_key_index(&mut self) -> Result<()> {
48-
let len = self.keys.len();
49-
if len > 0 {
50-
self.keys
51-
.get_mut(len - 1)
52-
.map(|pair| pair.1 = pair.1.map(|i| i + 1).or(Some(0)))
53-
.ok_or_else(|| {
54-
ConfigError::Message(format!("last key is not found in {} keys", len))
55-
})
56-
} else {
57-
Err(ConfigError::Message("keys is empty".to_string()))
58-
}
59-
}
53+
let mut whole = match keys.next() {
54+
Some(SerKey::Named(s)) => s.clone(),
55+
_ => {
56+
return Err(ConfigError::Message(
57+
"top level is not a struct".to_string(),
58+
))
59+
}
60+
};
6061

61-
fn make_full_key(&self, key: &str) -> String {
62-
let len = self.keys.len();
63-
if len > 0 {
64-
if let Some(&(ref prev_key, index)) = self.keys.get(len - 1) {
65-
return if let Some(index) = index {
66-
format!("{}[{}].{}", prev_key, index, key)
67-
} else {
68-
format!("{}.{}", prev_key, key)
69-
};
62+
for k in keys {
63+
match k {
64+
SerKey::Named(s) => write!(whole, ".{}", s),
65+
SerKey::Seq(i) => write!(whole, "[{}]", i),
7066
}
67+
.expect("write! to a string failed");
7168
}
72-
key.to_string()
69+
70+
Ok(whole)
7371
}
7472

7573
fn push_key(&mut self, key: &str) {
76-
let full_key = self.make_full_key(key);
77-
self.keys.push((full_key, None));
74+
self.keys.push(SerKey::Named(key.to_string()));
7875
}
7976

80-
fn pop_key(&mut self) -> Option<(String, Option<usize>)> {
81-
self.keys.pop()
77+
fn pop_key(&mut self) {
78+
self.keys.pop();
8279
}
8380
}
8481

8582
impl<'a> ser::Serializer for &'a mut ConfigSerializer {
8683
type Ok = ();
8784
type Error = ConfigError;
88-
type SerializeSeq = Self;
89-
type SerializeTuple = Self;
90-
type SerializeTupleStruct = Self;
91-
type SerializeTupleVariant = Self;
85+
type SerializeSeq = SeqSerializer<'a>;
86+
type SerializeTuple = SeqSerializer<'a>;
87+
type SerializeTupleStruct = SeqSerializer<'a>;
88+
type SerializeTupleVariant = SeqSerializer<'a>;
9289
type SerializeMap = Self;
9390
type SerializeStruct = Self;
9491
type SerializeStructVariant = Self;
@@ -159,7 +156,8 @@ impl<'a> ser::Serializer for &'a mut ConfigSerializer {
159156
for byte in v {
160157
seq.serialize_element(byte)?;
161158
}
162-
seq.end()
159+
seq.end();
160+
Ok(())
163161
}
164162

165163
fn serialize_none(self) -> Result<Self::Ok> {
@@ -214,7 +212,7 @@ impl<'a> ser::Serializer for &'a mut ConfigSerializer {
214212
}
215213

216214
fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
217-
Ok(self)
215+
SeqSerializer::new(self)
218216
}
219217

220218
fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
@@ -234,10 +232,10 @@ impl<'a> ser::Serializer for &'a mut ConfigSerializer {
234232
_name: &'static str,
235233
_variant_index: u32,
236234
variant: &'static str,
237-
_len: usize,
235+
len: usize,
238236
) -> Result<Self::SerializeTupleVariant> {
239237
self.push_key(variant);
240-
Ok(self)
238+
self.serialize_seq(Some(len))
241239
}
242240

243241
fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
@@ -260,75 +258,92 @@ impl<'a> ser::Serializer for &'a mut ConfigSerializer {
260258
}
261259
}
262260

263-
impl<'a> ser::SerializeSeq for &'a mut ConfigSerializer {
261+
impl<'a> SeqSerializer<'a> {
262+
fn new(inner: &'a mut ConfigSerializer) -> Result<Self> {
263+
inner.keys.push(SerKey::Seq(0));
264+
265+
Ok(SeqSerializer(inner))
266+
}
267+
268+
fn end(self) -> &'a mut ConfigSerializer {
269+
// This ought to be Some(SerKey::Seq(..)) but we don't want to panic if we are buggy
270+
let _: Option<SerKey> = self.0.keys.pop();
271+
self.0
272+
}
273+
}
274+
275+
impl<'a> ser::SerializeSeq for SeqSerializer<'a> {
264276
type Ok = ();
265277
type Error = ConfigError;
266278

267279
fn serialize_element<T>(&mut self, value: &T) -> Result<()>
268280
where
269281
T: ?Sized + ser::Serialize,
270282
{
271-
self.inc_last_key_index()?;
272-
value.serialize(&mut **self)?;
283+
value.serialize(&mut *(self.0))?;
284+
match self.0.keys.last_mut() {
285+
Some(SerKey::Seq(i)) => *i += 1,
286+
_ => {
287+
return Err(ConfigError::Message(
288+
"config-rs internal error (ser._element but last not Seq!".to_string(),
289+
))
290+
}
291+
};
273292
Ok(())
274293
}
275294

276295
fn end(self) -> Result<Self::Ok> {
296+
self.end();
277297
Ok(())
278298
}
279299
}
280300

281-
impl<'a> ser::SerializeTuple for &'a mut ConfigSerializer {
301+
impl<'a> ser::SerializeTuple for SeqSerializer<'a> {
282302
type Ok = ();
283303
type Error = ConfigError;
284304

285305
fn serialize_element<T>(&mut self, value: &T) -> Result<()>
286306
where
287307
T: ?Sized + ser::Serialize,
288308
{
289-
self.inc_last_key_index()?;
290-
value.serialize(&mut **self)?;
291-
Ok(())
309+
ser::SerializeSeq::serialize_element(self, value)
292310
}
293311

294312
fn end(self) -> Result<Self::Ok> {
295-
Ok(())
313+
ser::SerializeSeq::end(self)
296314
}
297315
}
298316

299-
impl<'a> ser::SerializeTupleStruct for &'a mut ConfigSerializer {
317+
impl<'a> ser::SerializeTupleStruct for SeqSerializer<'a> {
300318
type Ok = ();
301319
type Error = ConfigError;
302320

303321
fn serialize_field<T>(&mut self, value: &T) -> Result<()>
304322
where
305323
T: ?Sized + ser::Serialize,
306324
{
307-
self.inc_last_key_index()?;
308-
value.serialize(&mut **self)?;
309-
Ok(())
325+
ser::SerializeSeq::serialize_element(self, value)
310326
}
311327

312328
fn end(self) -> Result<Self::Ok> {
313-
Ok(())
329+
ser::SerializeSeq::end(self)
314330
}
315331
}
316332

317-
impl<'a> ser::SerializeTupleVariant for &'a mut ConfigSerializer {
333+
impl<'a> ser::SerializeTupleVariant for SeqSerializer<'a> {
318334
type Ok = ();
319335
type Error = ConfigError;
320336

321337
fn serialize_field<T>(&mut self, value: &T) -> Result<()>
322338
where
323339
T: ?Sized + ser::Serialize,
324340
{
325-
self.inc_last_key_index()?;
326-
value.serialize(&mut **self)?;
327-
Ok(())
341+
ser::SerializeSeq::serialize_element(self, value)
328342
}
329343

330344
fn end(self) -> Result<Self::Ok> {
331-
self.pop_key();
345+
let inner = self.end();
346+
inner.pop_key();
332347
Ok(())
333348
}
334349
}
@@ -717,4 +732,28 @@ mod test {
717732
let actual: Test = config.try_deserialize().unwrap();
718733
assert_eq!(test, actual);
719734
}
735+
736+
#[test]
737+
fn test_nest() {
738+
let val = serde_json::json! { {
739+
"top": {
740+
"num": 1,
741+
"array": [2],
742+
"nested": [[3,4]],
743+
"deep": [{
744+
"yes": true,
745+
}],
746+
"mixed": [
747+
{ "boolish": false, },
748+
42,
749+
["hi"],
750+
{ "inner": 66 },
751+
23,
752+
],
753+
}
754+
} };
755+
let config = Config::try_from(&val).unwrap();
756+
let output: serde_json::Value = config.try_deserialize().unwrap();
757+
assert_eq!(val, output);
758+
}
720759
}

0 commit comments

Comments
 (0)