Skip to content

Commit 103cc03

Browse files
thcedclaude
andcommitted
feat(schema): SchemaParser handles combinators, const, top-level enum
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent a7cbfbf commit 103cc03

2 files changed

Lines changed: 57 additions & 0 deletions

File tree

src/main/java/com/retailsvc/http/spec/schema/SchemaParser.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.retailsvc.http.spec.schema;
22

3+
import java.util.ArrayList;
34
import java.util.EnumSet;
45
import java.util.LinkedHashMap;
56
import java.util.List;
@@ -15,6 +16,15 @@ public static Schema parse(Map<String, Object> raw) {
1516
return new RefSchema((String) raw.get("$ref"));
1617
}
1718

19+
if (raw.containsKey("oneOf")) return new OneOfSchema(parseList(raw, "oneOf"));
20+
if (raw.containsKey("anyOf")) return new AnyOfSchema(parseList(raw, "anyOf"));
21+
if (raw.containsKey("allOf")) return new AllOfSchema(parseList(raw, "allOf"));
22+
if (raw.containsKey("not")) return new NotSchema(parse((Map<String, Object>) raw.get("not")));
23+
if (raw.containsKey("const")) return new ConstSchema(raw.get("const"));
24+
if (raw.containsKey("enum") && !raw.containsKey("type")) {
25+
return new EnumSchema(List.copyOf((List<Object>) raw.get("enum")));
26+
}
27+
1828
Set<TypeName> types = parseTypes(raw);
1929

2030
// Pick primary (non-null) type for record dispatch.
@@ -122,6 +132,14 @@ private static ArraySchema parseArray(Map<String, Object> raw, Set<TypeName> typ
122132
Boolean.TRUE.equals(raw.get("uniqueItems")));
123133
}
124134

135+
@SuppressWarnings("unchecked")
136+
private static List<Schema> parseList(Map<String, Object> raw, String key) {
137+
List<Map<String, Object>> raws = (List<Map<String, Object>>) raw.get(key);
138+
List<Schema> out = new ArrayList<>(raws.size());
139+
for (Map<String, Object> r : raws) out.add(parse(r));
140+
return List.copyOf(out);
141+
}
142+
125143
private static Integer toIntOrNull(Object v) {
126144
return v == null ? null : ((Number) v).intValue();
127145
}

src/test/java/com/retailsvc/http/spec/schema/SchemaParserTest.java

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,4 +107,43 @@ void parsesArrayWithItems() {
107107
assertThat(a.minItems()).isEqualTo(1);
108108
assertThat(a.uniqueItems()).isTrue();
109109
}
110+
111+
@Test
112+
void parsesOneOf() {
113+
Map<String, Object> raw =
114+
Map.of("oneOf", List.of(Map.of("type", "string"), Map.of("type", "integer")));
115+
OneOfSchema o = (OneOfSchema) SchemaParser.parse(raw);
116+
assertThat(o.options()).hasSize(2);
117+
assertThat(o.options().get(0)).isInstanceOf(StringSchema.class);
118+
}
119+
120+
@Test
121+
void parsesAnyOfAllOfNot() {
122+
assertThat(SchemaParser.parse(Map.of("anyOf", List.of(Map.of("type", "string")))))
123+
.isInstanceOf(AnyOfSchema.class);
124+
assertThat(SchemaParser.parse(Map.of("allOf", List.of(Map.of("type", "string")))))
125+
.isInstanceOf(AllOfSchema.class);
126+
assertThat(SchemaParser.parse(Map.of("not", Map.of("type", "null"))))
127+
.isInstanceOf(NotSchema.class);
128+
}
129+
130+
@Test
131+
void parsesConst() {
132+
assertThat(SchemaParser.parse(Map.of("const", 42))).isInstanceOf(ConstSchema.class);
133+
assertThat(((ConstSchema) SchemaParser.parse(Map.of("const", "a"))).value()).isEqualTo("a");
134+
}
135+
136+
@Test
137+
void parsesTopLevelEnumWithoutType() {
138+
Schema s = SchemaParser.parse(Map.of("enum", List.of(1, 2, 3)));
139+
assertThat(s).isInstanceOf(EnumSchema.class);
140+
assertThat(((EnumSchema) s).values()).containsExactly(1, 2, 3);
141+
}
142+
143+
@Test
144+
void enumOnStringStaysAsStringSchema() {
145+
Schema s = SchemaParser.parse(Map.of("type", "string", "enum", List.of("a", "b")));
146+
assertThat(s).isInstanceOf(StringSchema.class);
147+
assertThat(((StringSchema) s).enumValues()).containsExactly("a", "b");
148+
}
110149
}

0 commit comments

Comments
 (0)