Skip to content

Commit 25eb456

Browse files
committed
Generate Go interfaces for discriminators
This commit implements jsontypedef/issues/67.
1 parent a42555d commit 25eb456

File tree

1 file changed

+32
-18
lines changed

1 file changed

+32
-18
lines changed

crates/target_go/src/lib.rs

+32-18
Original file line numberDiff line numberDiff line change
@@ -259,27 +259,31 @@ impl jtd_codegen::target::Target for Target {
259259
writeln!(out)?;
260260
write!(out, "{}", description(&metadata, 0))?;
261261
writeln!(out, "type {} struct {{", name)?;
262-
writeln!(out, "\t{} string", tag_field_name)?;
262+
writeln!(out, "\t// Value can be the following types:")?;
263263
for variant in &variants {
264-
writeln!(out)?;
265-
writeln!(out, "\t{} {}", &variant.field_name, &variant.type_name)?;
264+
writeln!(out, "\t// - [{}] ({})", &variant.type_name, &variant.tag_value)?;
266265
}
266+
writeln!(out, "\tValue value{}", name)?;
267+
writeln!(out)?;
268+
writeln!(out, "\tt string")?;
269+
writeln!(out, "}}")?;
270+
271+
writeln!(out)?;
272+
writeln!(out, "// {} returns the value of {}.", tag_field_name, tag_field_name)?;
273+
writeln!(out, "func (v {}) {}() string {{", name, tag_field_name)?;
274+
writeln!(out, "\treturn v.t")?;
267275
writeln!(out, "}}")?;
268276

269277
writeln!(out)?;
270278
writeln!(out, "func (v {}) MarshalJSON() ([]byte, error) {{", name)?;
271-
writeln!(out, "\tswitch v.{} {{", tag_field_name)?;
279+
writeln!(out, "\tswitch value := v.Value.(type) {{")?;
272280
for variant in &variants {
273-
writeln!(out, "\tcase {:?}:", variant.tag_value)?;
274-
writeln!(out, "\t\treturn json.Marshal(struct {{ T string `json:\"{}\"`; {} }}{{ v.{}, v.{} }})", tag_json_name, variant.type_name, tag_field_name, variant.field_name)?;
281+
writeln!(out, "\tcase {}:", variant.type_name)?;
282+
writeln!(out, "\t\treturn json.Marshal(struct {{ T string `json:\"{}\"`; {} }}{{ v.t, value }})", tag_json_name, variant.type_name)?;
275283
}
284+
writeln!(out, "\tdefault:")?;
285+
writeln!(out, "\t\tpanic(\"unreachable\")")?;
276286
writeln!(out, "\t}}")?;
277-
writeln!(out)?;
278-
writeln!(
279-
out,
280-
"\treturn nil, fmt.Errorf(\"bad {0} value: %s\", v.{0})",
281-
tag_field_name
282-
)?;
283287
writeln!(out, "}}")?;
284288

285289
writeln!(out)?;
@@ -293,15 +297,15 @@ impl jtd_codegen::target::Target for Target {
293297
writeln!(out, "\t\treturn err")?;
294298
writeln!(out, "\t}}")?;
295299
writeln!(out)?;
300+
writeln!(out, "\tvar value value{}", name)?;
296301
writeln!(out, "\tvar err error")?;
302+
writeln!(out)?;
297303
writeln!(out, "\tswitch t.T {{")?;
298304
for variant in &variants {
299305
writeln!(out, "\tcase {:?}:", variant.tag_value)?;
300-
writeln!(
301-
out,
302-
"\t\terr = json.Unmarshal(b, &v.{})",
303-
variant.field_name
304-
)?;
306+
writeln!(out, "\t\tvar v {}", variant.type_name)?;
307+
writeln!(out, "\t\terr = json.Unmarshal(b, &v)")?;
308+
writeln!(out, "\t\tvalue = v")?;
305309
}
306310
writeln!(out, "\tdefault:")?;
307311
writeln!(
@@ -315,10 +319,20 @@ impl jtd_codegen::target::Target for Target {
315319
writeln!(out, "\t\treturn err")?;
316320
writeln!(out, "\t}}")?;
317321
writeln!(out)?;
318-
writeln!(out, "\tv.{} = t.T", tag_field_name)?;
322+
writeln!(out, "\tv.t = t.T")?;
323+
writeln!(out, "\tv.Value = value")?;
319324
writeln!(out, "\treturn nil")?;
320325
writeln!(out, "}}")?;
321326

327+
writeln!(out)?;
328+
writeln!(out, "type value{} interface {{", name)?;
329+
writeln!(out, "\tis{}()", name)?;
330+
writeln!(out, "}}")?;
331+
writeln!(out)?;
332+
for variant in &variants {
333+
writeln!(out, "func ({}) is{}() {{}}", variant.type_name, name)?;
334+
}
335+
322336
None
323337
}
324338

0 commit comments

Comments
 (0)