Skip to content

Commit

Permalink
refactor(go): simplify indenting logic
Browse files Browse the repository at this point in the history
Use a dedicated type that implements the `Display` trait, which allows
for a much simpler way of expressing and forwarding indents.
  • Loading branch information
dnaka91 committed Jan 31, 2024
1 parent 0bd1940 commit 7425a11
Show file tree
Hide file tree
Showing 5 changed files with 245 additions and 275 deletions.
124 changes: 47 additions & 77 deletions crates/mabo-go/src/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ use std::fmt::{self, Display};

use mabo_compiler::simplify::{FieldKind, Fields, Struct, Type, Variant};

use crate::definition::{self, RenderGenericNames};
use crate::{
definition::{self, RenderGenericNames},
Indent,
};

pub(super) struct RenderStruct<'a>(pub(super) &'a Struct<'a>);

Expand Down Expand Up @@ -142,8 +145,8 @@ impl Display for RenderFields<'_> {
"\t\t\t\tr2, value, err := {}",
RenderType {
ty: &field.ty,
indent: 4
}
indent: Indent(4),
},
)?;
writeln!(f, "\t\t\t\tif err != nil {{")?;
writeln!(f, "\t\t\t\t\treturn nil, err")?;
Expand All @@ -152,12 +155,12 @@ impl Display for RenderFields<'_> {
writeln!(
f,
"\t\t\t\tv.{} = value",
heck::AsUpperCamelCase(&field.name)
heck::AsUpperCamelCase(&field.name),
)?;
writeln!(
f,
"\t\t\t\tfound{} = true",
heck::AsUpperCamelCase(&field.name)
heck::AsUpperCamelCase(&field.name),
)?;
}

Expand All @@ -167,7 +170,7 @@ impl Display for RenderFields<'_> {

struct RenderType<'a> {
ty: &'a Type<'a>,
indent: usize,
indent: Indent,
}

impl Display for RenderType<'_> {
Expand Down Expand Up @@ -290,42 +293,21 @@ impl Display for RenderType<'_> {
for (idx, ty) in types.iter().enumerate() {
writeln!(
f,
"{:\t<indent$}r2, value{idx}, err := {}",
"",
"{}r2, value{idx}, err := {}",
self.indent + 1,
RenderType {
ty,
indent: self.indent + 1
indent: self.indent + 1,
},
indent = self.indent + 1,
)?;
writeln!(
f,
"{:\t<indent$}if err != nil {{",
"",
indent = self.indent + 1,
)?;
writeln!(
f,
"{:\t<indent$}return nil, value, err",
"",
indent = self.indent + 2,
)?;
writeln!(f, "{:\t<indent$}}}", "", indent = self.indent + 1)?;
writeln!(f, "{:\t<indent$}r = r2", "", indent = self.indent + 1)?;
writeln!(
f,
"{:\t<indent$}tuple.F{idx} = value{idx}",
"",
indent = self.indent + 1,
)?;
writeln!(f, "{}if err != nil {{", self.indent + 1)?;
writeln!(f, "{}return nil, value, err", self.indent + 2)?;
writeln!(f, "{}}}", self.indent + 1)?;
writeln!(f, "{}r = r2", self.indent + 1)?;
writeln!(f, "{}tuple.F{idx} = value{idx}", self.indent + 1)?;
}
writeln!(
f,
"{:\t<indent$}return r, tuple, nil",
"",
indent = self.indent + 1,
)?;
write!(f, "{:\t<indent$}}}(r)", "", indent = self.indent)
writeln!(f, "{}return r, tuple, nil", self.indent + 1)?;
write!(f, "{}}}(r)", self.indent)
}
n => todo!("compiler should catch invalid tuple with {n} elements"),
},
Expand All @@ -338,15 +320,14 @@ impl Display for RenderType<'_> {
)?;
writeln!(
f,
"{:\t<indent$}return {}",
"",
"{}return {}",
self.indent + 1,
RenderType {
ty,
indent: self.indent + 1
indent: self.indent + 1,
},
indent = self.indent + 1,
)?;
write!(f, "{:\t<indent$}}})", "", indent = self.indent)
write!(f, "{}}})", self.indent)
}
n => todo!("arrays with larger ({n}) sizes"),
},
Expand All @@ -358,18 +339,12 @@ impl Display for RenderType<'_> {
)?;
writeln!(
f,
"{:\t<indent$}var value {}",
"",
"{}var value {}",
self.indent + 1,
definition::RenderType(self.ty),
indent = self.indent + 1,
)?;
writeln!(
f,
"{:\t<indent$}return value.Decode(r)",
"",
indent = self.indent + 1,
)?;
writeln!(f, "{:\t<indent$}}}(r)", "", indent = self.indent)
writeln!(f, "{}return value.Decode(r)", self.indent + 1)?;
writeln!(f, "{}}}(r)", self.indent)
}
}
}
Expand All @@ -378,7 +353,7 @@ impl Display for RenderType<'_> {
struct DecodeGenericSingle<'a> {
name: &'static str,
ty: &'a Type<'a>,
indent: usize,
indent: Indent,
}

impl Display for DecodeGenericSingle<'_> {
Expand All @@ -391,22 +366,21 @@ impl Display for DecodeGenericSingle<'_> {
)?;
writeln!(
f,
"{:\t<indent$}return {}",
"",
"{}return {}",
self.indent + 1,
RenderType {
ty: self.ty,
indent: self.indent + 1
indent: self.indent + 1,
},
indent = self.indent + 1,
)?;
write!(f, "{:\t<indent$}}})", "", indent = self.indent)
write!(f, "{}}})", self.indent)
}
}

struct DecodeGenericPair<'a> {
name: &'static str,
pair: &'a (Type<'a>, Type<'a>),
indent: usize,
indent: Indent,
}

impl Display for DecodeGenericPair<'_> {
Expand All @@ -418,45 +392,41 @@ impl Display for DecodeGenericPair<'_> {
definition::RenderType(&self.pair.0),
definition::RenderType(&self.pair.1)
)?;
writeln!(f, "{:\t<indent$}r,", "", indent = self.indent + 1)?;
writeln!(f, "{}r,", self.indent + 1)?;

writeln!(
f,
"{:\t<indent$}func(r []byte) ([]byte, {}, error) {{",
"",
"{}func(r []byte) ([]byte, {}, error) {{",
self.indent + 1,
definition::RenderType(&self.pair.0),
indent = self.indent + 1
)?;
writeln!(
f,
"{:\t<indent$}return {}",
"",
"{}return {}",
self.indent + 2,
RenderType {
ty: &self.pair.0,
indent: self.indent + 2
indent: self.indent + 2,
},
indent = self.indent + 2,
)?;
writeln!(f, "{:\t<indent$}}},", "", indent = self.indent + 1)?;
writeln!(f, "{}}},", self.indent + 1)?;

writeln!(
f,
"{:\t<indent$}func(r []byte) ([]byte, {}, error) {{",
"",
"{}func(r []byte) ([]byte, {}, error) {{",
self.indent + 1,
definition::RenderType(&self.pair.1),
indent = self.indent + 1
)?;
writeln!(
f,
"{:\t<indent$}return {}",
"",
"{}return {}",
self.indent + 2,
RenderType {
ty: &self.pair.1,
indent: self.indent + 2
indent: self.indent + 2,
},
indent = self.indent + 2,
)?;
writeln!(f, "{:\t<indent$}}},", "", indent = self.indent + 1)?;
write!(f, "{:\t<indent$})", "", indent = self.indent)
writeln!(f, "{}}},", self.indent + 1)?;
write!(f, "{})", self.indent)
}
}
30 changes: 19 additions & 11 deletions crates/mabo-go/src/definition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use mabo_compiler::simplify::{
Variant,
};

use crate::{decode, encode, size, Opts, Output};
use crate::{decode, encode, size, Indent, Opts, Output};

/// Take a single schema and convert it into Go source code (which can result in multiple files).
#[must_use]
Expand Down Expand Up @@ -103,7 +103,14 @@ struct RenderPackage<'a>(&'a str, Option<&'a [&'a str]>);
impl Display for RenderPackage<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if let Some(comment) = self.1 {
write!(f, "{}", RenderComment { indent: 0, comment })?;
write!(
f,
"{}",
RenderComment {
indent: Indent(0),
comment
}
)?;
}

writeln!(f, "package {}\n", heck::AsSnakeCase(self.0))
Expand All @@ -129,7 +136,7 @@ impl Display for RenderStruct<'_> {
f,
"{}type {}{} {}",
RenderComment {
indent: 0,
indent: Indent(0),
comment: &self.0.comment
},
heck::AsUpperCamelCase(&self.0.name),
Expand Down Expand Up @@ -293,7 +300,7 @@ impl Display for RenderFields<'_> {
f,
"{}\t{} {}",
RenderComment {
indent: 1,
indent: Indent(1),
comment: &field.comment
},
heck::AsUpperCamelCase(&field.name),
Expand Down Expand Up @@ -358,7 +365,7 @@ impl Display for RenderAlias<'_> {
f,
"{}type {} {}",
RenderComment {
indent: 0,
indent: Indent(0),
comment: &self.0.comment,
},
heck::AsUpperCamelCase(&self.0.name),
Expand All @@ -368,14 +375,15 @@ impl Display for RenderAlias<'_> {
}

struct RenderComment<'a> {
indent: usize,
indent: Indent,
comment: &'a [&'a str],
}

impl Display for RenderComment<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for line in self.comment {
writeln!(f, "{:\t<width$}// {}", "", line, width = self.indent)?;
let Self { indent, comment } = *self;
for line in comment {
writeln!(f, "{indent}// {line}")?;
}

Ok(())
Expand Down Expand Up @@ -529,7 +537,7 @@ impl Display for RenderConst<'_> {
f,
"{}{kind} {} {} = {}",
RenderComment {
indent: 0,
indent: Indent(0),
comment: &self.0.comment
},
heck::AsUpperCamelCase(&self.0.name),
Expand Down Expand Up @@ -582,7 +590,7 @@ impl Display for RenderEnum<'_> {
f,
"\n{}type {} {1}Variant",
RenderComment {
indent: 0,
indent: Indent(0),
comment: &self.0.comment
},
heck::AsUpperCamelCase(&self.0.name),
Expand Down Expand Up @@ -616,7 +624,7 @@ impl Display for RenderEnumVariant<'_> {
f,
"{}type {}_{}{} {}",
RenderComment {
indent: 0,
indent: Indent(0),
comment: &self.variant.comment
},
heck::AsUpperCamelCase(self.enum_name),
Expand Down
Loading

0 comments on commit 7425a11

Please sign in to comment.