encoding/openapi: dedup conjuncts and disjuncts

Change-Id: I8cb02a2341495c2063bf6796fb61486dd539a881
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/9263
Reviewed-by: CUE cueckoo <cueckoo@gmail.com>
Reviewed-by: Paul Jolly <paul@myitcv.org.uk>
diff --git a/encoding/openapi/build.go b/encoding/openapi/build.go
index a5330f2..d43490c 100644
--- a/encoding/openapi/build.go
+++ b/encoding/openapi/build.go
@@ -440,6 +440,21 @@
 
 func appendSplit(a []cue.Value, splitBy cue.Op, v cue.Value) []cue.Value {
 	op, args := v.Expr()
+	// dedup elements.
+	k := 1
+outer:
+	for i := 1; i < len(args); i++ {
+		for j := 0; j < k; j++ {
+			if args[i].Subsume(args[j], cue.Raw()) == nil &&
+				args[j].Subsume(args[i], cue.Raw()) == nil {
+				continue outer
+			}
+		}
+		args[k] = args[i]
+		k++
+	}
+	args = args[:k]
+
 	if op == cue.NoOp && len(args) == 1 {
 		// TODO: this is to deal with default value removal. This may change
 		// whe we completely separate default values from values.
diff --git a/encoding/openapi/testdata/oneof-resolve.json b/encoding/openapi/testdata/oneof-resolve.json
index 2d6183e..643029d 100644
--- a/encoding/openapi/testdata/oneof-resolve.json
+++ b/encoding/openapi/testdata/oneof-resolve.json
@@ -364,6 +364,7 @@
             "type": "integer"
          },
          "T": {
+            "description": "This should be dedupped.",
             "type": "object",
             "properties": {
                "shared": {
diff --git a/encoding/openapi/testdata/oneof.cue b/encoding/openapi/testdata/oneof.cue
index 55431f0..1561f6b 100644
--- a/encoding/openapi/testdata/oneof.cue
+++ b/encoding/openapi/testdata/oneof.cue
@@ -19,6 +19,13 @@
 	shared2: int
 }
 
+// This should be dedupped.
+#T: {} | {
+	count: int
+} | {
+	amount: int
+}
+
 #MyInt: int
 
 #Foo: {
diff --git a/encoding/openapi/testdata/oneof.json b/encoding/openapi/testdata/oneof.json
index e58cb6d..2c84297 100644
--- a/encoding/openapi/testdata/oneof.json
+++ b/encoding/openapi/testdata/oneof.json
@@ -232,6 +232,7 @@
             "type": "integer"
          },
          "T": {
+            "description": "This should be dedupped.",
             "type": "object",
             "properties": {
                "shared": {