Skip to content

Commit

Permalink
fix(serializer): do not emit newline if block body is empty (#32)
Browse files Browse the repository at this point in the history
Previously, empty blocks were rendered as:

    empty {
    }

With this change they are rendered as:

    empty {}
  • Loading branch information
martinohmann committed Jun 4, 2022
1 parent 4ecb118 commit a36fa7d
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 16 deletions.
50 changes: 34 additions & 16 deletions src/ser/format.rs
Expand Up @@ -243,6 +243,7 @@ enum FormatState {
AttributeEnd,
BlockStart,
BlockEnd,
BlockBodyStart,
}

/// A pretty printing HCL formatter.
Expand Down Expand Up @@ -409,11 +410,7 @@ impl<'a> Format for PrettyFormatter<'a> {
where
W: ?Sized + io::Write,
{
if !self.dense && self.state == FormatState::BlockEnd {
writer.write_all(b"\n")?;
}

self.state = FormatState::AttributeStart;
self.maybe_write_newline(writer, FormatState::AttributeStart)?;
indent(writer, self.current_indent, self.indent)
}

Expand All @@ -429,16 +426,7 @@ impl<'a> Format for PrettyFormatter<'a> {
where
W: ?Sized + io::Write,
{
if !self.dense
&& matches!(
self.state,
FormatState::AttributeEnd | FormatState::BlockEnd
)
{
writer.write_all(b"\n")?;
}

self.state = FormatState::BlockStart;
self.maybe_write_newline(writer, FormatState::BlockStart)?;
indent(writer, self.current_indent, self.indent)
}

Expand All @@ -447,7 +435,8 @@ impl<'a> Format for PrettyFormatter<'a> {
W: ?Sized + io::Write,
{
self.current_indent += 1;
writer.write_all(b" {\n")
self.state = FormatState::BlockBodyStart;
writer.write_all(b" {")
}

fn end_block<W>(&mut self, writer: &mut W) -> io::Result<()>
Expand All @@ -461,6 +450,35 @@ impl<'a> Format for PrettyFormatter<'a> {
}
}

impl<'a> PrettyFormatter<'a> {
// Conditionally writes a newline character depending on the formatter configuration and the
// current and next state. Updates the state to `next_state`.
fn maybe_write_newline<W>(&mut self, writer: &mut W, next_state: FormatState) -> io::Result<()>
where
W: ?Sized + io::Write,
{
let newline = match &self.state {
FormatState::AttributeEnd if !self.dense => {
matches!(next_state, FormatState::BlockStart)
}
FormatState::BlockEnd if !self.dense => {
matches!(
next_state,
FormatState::BlockStart | FormatState::AttributeStart
)
}
other => matches!(other, FormatState::BlockBodyStart),
};

if newline {
writer.write_all(b"\n")?;
}

self.state = next_state;
Ok(())
}
}

fn indent<W>(writer: &mut W, n: usize, s: &[u8]) -> io::Result<()>
where
W: ?Sized + io::Write,
Expand Down
9 changes: 9 additions & 0 deletions src/ser/tests.rs
Expand Up @@ -181,6 +181,15 @@ qux = {
assert_eq!(to_string(&value).unwrap(), expected);
}

#[test]
fn serialize_empty_block() {
let body = Body::builder()
.add_block(Block::builder("empty").build())
.build();

assert_eq!(to_string(&body).unwrap(), "empty {}\n");
}

#[test]
fn serialize_errors() {
assert!(to_string(&true).is_err());
Expand Down

0 comments on commit a36fa7d

Please sign in to comment.