in codegen/smithy-ruby-codegen/src/main/java/software/amazon/smithy/ruby/codegen/generators/ParamsGenerator.java [214:259]
public Void unionShape(UnionShape shape) {
Symbol symbol = symbolProvider.toSymbol(shape);
String shapeName = symbol.getName();
writer
.write("")
.openBlock("module $L", shapeName)
.openBlock("def self.build(params, context: '')")
.write("return params if params.is_a?(Types::$L)", shapeName)
.write("Seahorse::Validator.validate!(params, ::Hash, Types::$L, context: context)", shapeName)
.openBlock("unless params.size == 1")
.write("raise ArgumentError,")
.indent(3)
.write("\"Expected #{context} to have exactly one member, got: #{params}\"")
.dedent(3)
.closeBlock("end")
.write("key, value = params.flatten")
.write("case key"); //start a case statement. This does NOT indent
for (MemberShape member : shape.members()) {
Shape target = model.expectShape(member.getTarget());
String memberClassName = symbolProvider.toMemberName(member);
String memberName = RubyFormatter.asSymbol(memberClassName);
writer.write("when $L", memberName)
.indent()
.openBlock("Types::$L::$L.new(", shapeName, memberClassName);
String input = "params[" + memberName + "]";
String context = "\"#{context}[" + memberName + "]\"";
target.accept(new MemberBuilder(writer, symbolProvider, "", input, context, member, false));
writer.closeBlock(")")
.dedent();
}
String expectedMembers =
shape.members().stream().map((member) -> RubyFormatter.asSymbol(member.getMemberName()))
.collect(Collectors.joining(", "));
writer.write("else")
.indent()
.write("raise ArgumentError,")
.indent(3)
.write("\"Expected #{context} to have one of $L set\"", expectedMembers)
.dedent(4);
writer.write("end") //end of case statement, NOT indented
.closeBlock("end")
.closeBlock("end");
return null;
}