use super::{Config, ESTree, ESTreeSerializer, Formatter, Serializer, TracePathPart};
pub trait SequenceSerializer {
fn serialize_element<T: ESTree + ?Sized>(&mut self, value: &T);
fn end(self);
}
pub struct ESTreeSequenceSerializer<'s, C: Config, F: Formatter> {
serializer: &'s mut ESTreeSerializer<C, F>,
len: usize,
}
impl<'s, C: Config, F: Formatter> ESTreeSequenceSerializer<'s, C, F> {
pub(super) fn new(mut serializer: &'s mut ESTreeSerializer<C, F>) -> Self {
if serializer.config.fixes() {
serializer.trace_path.push(TracePathPart::DUMMY);
}
serializer.buffer_mut().print_ascii_byte(b'[');
Self { serializer, len: 0 }
}
}
impl<C: Config, F: Formatter> SequenceSerializer for ESTreeSequenceSerializer<'_, C, F> {
fn serialize_element<T: ESTree + ?Sized>(&mut self, value: &T) {
if self.serializer.config.fixes() {
*self.serializer.trace_path.last_mut() = TracePathPart::Index(self.len);
}
let (buffer, formatter) = self.serializer.buffer_and_formatter_mut();
if self.len == 0 {
formatter.before_first_element(buffer);
} else {
buffer.print_ascii_byte(b',');
formatter.before_later_element(buffer);
}
value.serialize(&mut *self.serializer);
self.len += 1;
}
fn end(mut self) {
if self.serializer.config.fixes() {
unsafe { self.serializer.trace_path.pop_unchecked() };
}
let (buffer, formatter) = self.serializer.buffer_and_formatter_mut();
if self.len > 0 {
formatter.after_last_element(buffer);
}
buffer.print_ascii_byte(b']');
}
}
impl<T: ESTree> ESTree for &[T] {
fn serialize<S: Serializer>(&self, serializer: S) {
let mut seq = serializer.serialize_sequence();
for element in *self {
seq.serialize_element(element);
}
seq.end();
}
}
impl<T: ESTree, const N: usize> ESTree for [T; N] {
fn serialize<S: Serializer>(&self, serializer: S) {
let mut seq = serializer.serialize_sequence();
for element in self {
seq.serialize_element(element);
}
seq.end();
}
}
#[cfg(test)]
mod tests {
use super::super::{CompactSerializer, PrettySerializer, StructSerializer};
use super::*;
#[test]
fn serialize_sequence() {
struct Foo<'a> {
none: &'a [&'a str],
one: &'a [&'a str],
two: [&'a str; 2],
}
impl ESTree for Foo<'_> {
fn serialize<S: Serializer>(&self, serializer: S) {
let mut state = serializer.serialize_struct();
state.serialize_field("none", &self.none);
state.serialize_field("one", &self.one);
state.serialize_field("two", &self.two);
state.end();
}
}
let foo = Foo { none: &[], one: &["one"], two: ["two one", "two two"] };
let mut serializer = CompactSerializer::default();
foo.serialize(&mut serializer);
let s = serializer.into_string();
assert_eq!(&s, r#"{"none":[],"one":["one"],"two":["two one","two two"]}"#);
let mut serializer = PrettySerializer::default();
foo.serialize(&mut serializer);
let s = serializer.into_string();
assert_eq!(
&s,
r#"{
"none": [],
"one": [
"one"
],
"two": [
"two one",
"two two"
]
}"#
);
}
}