in serde-generate/src/java.rs [600:767]
fn output_struct_or_variant_container(
&mut self,
variant_base: Option<&str>,
variant_index: Option<u32>,
name: &str,
fields: &[Named<Format>],
) -> Result<()> {
// Beginning of class
writeln!(self.out)?;
if let Some(base) = variant_base {
self.output_comment(name)?;
writeln!(
self.out,
"public static final class {} extends {} {{",
name, base
)?;
} else {
self.output_comment(name)?;
writeln!(self.out, "public final class {} {{", name)?;
}
let reserved_names = &["Builder"];
self.enter_class(name, reserved_names);
// Fields
for field in fields {
self.output_comment(&field.name)?;
writeln!(
self.out,
"public final {} {};",
self.quote_type(&field.value),
field.name
)?;
}
if !fields.is_empty() {
writeln!(self.out)?;
}
// Constructor.
writeln!(
self.out,
"public {}({}) {{",
name,
fields
.iter()
.map(|f| format!("{} {}", self.quote_type(&f.value), &f.name))
.collect::<Vec<_>>()
.join(", ")
)?;
self.out.indent();
for field in fields {
writeln!(
self.out,
"java.util.Objects.requireNonNull({0}, \"{0} must not be null\");",
&field.name
)?;
}
for field in fields {
writeln!(self.out, "this.{} = {};", &field.name, &field.name)?;
}
self.out.unindent();
writeln!(self.out, "}}")?;
// Serialize
if self.generator.config.serialization {
writeln!(
self.out,
"\npublic void serialize(com.novi.serde.Serializer serializer) throws com.novi.serde.SerializationError {{",
)?;
self.out.indent();
writeln!(self.out, "serializer.increase_container_depth();")?;
if let Some(index) = variant_index {
writeln!(self.out, "serializer.serialize_variant_index({});", index)?;
}
for field in fields {
writeln!(
self.out,
"{}",
self.quote_serialize_value(&field.name, &field.value)
)?;
}
writeln!(self.out, "serializer.decrease_container_depth();")?;
self.out.unindent();
writeln!(self.out, "}}")?;
if variant_index.is_none() {
for encoding in &self.generator.config.encodings {
self.output_class_serialize_for_encoding(*encoding)?;
}
}
}
// Deserialize (struct) or Load (variant)
if self.generator.config.serialization {
if variant_index.is_none() {
writeln!(
self.out,
"\npublic static {} deserialize(com.novi.serde.Deserializer deserializer) throws com.novi.serde.DeserializationError {{",
name,
)?;
} else {
writeln!(
self.out,
"\nstatic {} load(com.novi.serde.Deserializer deserializer) throws com.novi.serde.DeserializationError {{",
name,
)?;
}
self.out.indent();
writeln!(self.out, "deserializer.increase_container_depth();")?;
writeln!(self.out, "Builder builder = new Builder();")?;
for field in fields {
writeln!(
self.out,
"builder.{} = {};",
field.name,
self.quote_deserialize(&field.value)
)?;
}
writeln!(self.out, "deserializer.decrease_container_depth();")?;
writeln!(self.out, "return builder.build();")?;
self.out.unindent();
writeln!(self.out, "}}")?;
if variant_index.is_none() {
for encoding in &self.generator.config.encodings {
self.output_class_deserialize_for_encoding(name, *encoding)?;
}
}
}
// Equality
write!(self.out, "\npublic boolean equals(Object obj) {{")?;
self.out.indent();
writeln!(
self.out,
r#"
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
{0} other = ({0}) obj;"#,
name,
)?;
for field in fields {
writeln!(
self.out,
"if (!java.util.Objects.equals(this.{0}, other.{0})) {{ return false; }}",
&field.name,
)?;
}
writeln!(self.out, "return true;")?;
self.out.unindent();
writeln!(self.out, "}}")?;
// Hashing
writeln!(self.out, "\npublic int hashCode() {{")?;
self.out.indent();
writeln!(self.out, "int value = 7;",)?;
for field in fields {
writeln!(
self.out,
"value = 31 * value + (this.{0} != null ? this.{0}.hashCode() : 0);",
&field.name
)?;
}
writeln!(self.out, "return value;")?;
self.out.unindent();
writeln!(self.out, "}}")?;
// Builder
self.output_struct_or_variant_container_builder(name, fields)?;
// Custom code
self.output_custom_code()?;
// End of class
self.leave_class(reserved_names);
writeln!(self.out, "}}")
}