Skip to content

Commit 547e82f

Browse files
committed
docs: update nested generics examples and naming
1 parent 4426443 commit 547e82f

7 files changed

Lines changed: 152 additions & 0 deletions

File tree

README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ Use mutable classes with fields that can be set reflectively. Field visibility c
4242
- Fields should be non-primitive boxed/object types (`Integer`, not `int`).
4343
- Value objects can validate with a single-arg constructor.
4444
- `Optional<T>`, `List<T>`, `Set<T>`, and `Map<K,V>` are supported.
45+
- Nested generic combinations are supported (for example `GenericBox<List<GenericItem<String>>>`, `Map<StringConstructedGenericKey<Integer>, List<String>>`).
4546
- Enums are parsed from string names.
4647
- Expose values however you prefer (public fields or getters on private fields).
4748

@@ -119,6 +120,30 @@ AppConfig xmlCfg = new XmlDeserializer().deserialize(
119120
);
120121
```
121122

123+
## Nested generics example
124+
125+
```java
126+
import java.util.List;
127+
import java.util.Map;
128+
129+
class GenericBox<T> { public T value; }
130+
class GenericItem<T> { public T payload; }
131+
class StringConstructedGenericKey<T> {
132+
public final String value;
133+
public StringConstructedGenericKey(String value) { this.value = value; }
134+
}
135+
136+
class GenericConfig {
137+
public GenericBox<List<GenericItem<String>>> foo;
138+
public Map<StringConstructedGenericKey<Integer>, List<String>> values;
139+
}
140+
141+
GenericConfig cfg = new JsonDeserializer().deserialize(
142+
"{\"foo\":{\"value\":[{\"payload\":\"a\"}]},\"values\":{\"k1\":[\"x\",\"y\"]}}",
143+
GenericConfig.class
144+
);
145+
```
146+
122147
## Validation and errors
123148

124149
Object mapping and validation are done in one pass. Field errors are collected, then one `ConfigDeserializationException` is thrown with all errors.

modules/deserializer/README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,22 @@ implementation "org.msuo:deserializer:<version>"
2626
- Missing key and explicit nil are handled differently.
2727
- Missing required fields fail unless a default already exists.
2828
- `Optional<T>` maps missing/nil to `Optional.empty()`.
29+
- Nested generics are supported across object graphs and containers.
30+
31+
Example:
32+
33+
```java
34+
class GenericBox<T> { public T value; }
35+
class GenericItem<T> { public T payload; }
36+
class StringConstructedGenericKey<T> {
37+
public final String value;
38+
public StringConstructedGenericKey(String value) { this.value = value; }
39+
}
40+
class GenericConfig {
41+
public GenericBox<java.util.List<GenericItem<String>>> foo;
42+
public java.util.Map<StringConstructedGenericKey<Integer>, java.util.List<String>> values;
43+
}
44+
```
2945

3046
## For language implementers
3147

modules/groovy2java/README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,27 @@ assertEquals(List.of("a", "b"), cfg.tags);
9292
assertEquals(Integer.valueOf(10), cfg.limits.get("api"));
9393
```
9494

95+
## Nested generics
96+
97+
```java
98+
import java.util.List;
99+
import java.util.Map;
100+
101+
class GenericBox<T> { public T value; }
102+
class GenericItem<T> { public T payload; }
103+
class StringConstructedGenericKey<T> {
104+
public final String value;
105+
public StringConstructedGenericKey(String value) { this.value = value; }
106+
}
107+
class GenericConfig {
108+
public GenericBox<List<GenericItem<String>>> foo;
109+
public Map<StringConstructedGenericKey<Integer>, List<String>> values;
110+
}
111+
112+
String groovy = "return [foo: [value: [[payload: 'a']]], values: [k1: ['x', 'y']]]";
113+
GenericConfig cfg = new GroovyDeserializer().deserialize(groovy, GenericConfig.class);
114+
```
115+
95116
## Null semantics
96117

97118
```java

modules/json2java/README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,27 @@ assertEquals(List.of("a", "b"), cfg.tags);
8989
assertEquals(Integer.valueOf(10), cfg.limits.get("api"));
9090
```
9191

92+
## Nested generics
93+
94+
```java
95+
import java.util.List;
96+
import java.util.Map;
97+
98+
class GenericBox<T> { public T value; }
99+
class GenericItem<T> { public T payload; }
100+
class StringConstructedGenericKey<T> {
101+
public final String value;
102+
public StringConstructedGenericKey(String value) { this.value = value; }
103+
}
104+
class GenericConfig {
105+
public GenericBox<List<GenericItem<String>>> foo;
106+
public Map<StringConstructedGenericKey<Integer>, List<String>> values;
107+
}
108+
109+
String json = "{\"foo\":{\"value\":[{\"payload\":\"a\"}]},\"values\":{\"k1\":[\"x\",\"y\"]}}";
110+
GenericConfig cfg = new JsonDeserializer().deserialize(json, GenericConfig.class);
111+
```
112+
92113
## Null semantics
93114

94115
```java

modules/lua2java/README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,27 @@ assertEquals(List.of("a", "b"), cfg.tags);
9292
assertEquals(Integer.valueOf(10), cfg.limits.get("api"));
9393
```
9494

95+
## Nested generics
96+
97+
```java
98+
import java.util.List;
99+
import java.util.Map;
100+
101+
class GenericBox<T> { public T value; }
102+
class GenericItem<T> { public T payload; }
103+
class StringConstructedGenericKey<T> {
104+
public final String value;
105+
public StringConstructedGenericKey(String value) { this.value = value; }
106+
}
107+
class GenericConfig {
108+
public GenericBox<List<GenericItem<String>>> foo;
109+
public Map<StringConstructedGenericKey<Integer>, List<String>> values;
110+
}
111+
112+
String lua = "return { foo = { value = { { payload = 'a' } } }, values = { k1 = { 'x', 'y' } } }";
113+
GenericConfig cfg = new LuaDeserializer().deserialize(lua, GenericConfig.class);
114+
```
115+
95116
## Nil semantics
96117

97118
```java

modules/toml2java/README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,33 @@ assertEquals(List.of("a", "b"), cfg.tags);
101101
assertEquals(Integer.valueOf(10), cfg.limits.get("api"));
102102
```
103103

104+
## Nested generics
105+
106+
```java
107+
import java.util.List;
108+
import java.util.Map;
109+
110+
class GenericBox<T> { public T value; }
111+
class GenericItem<T> { public T payload; }
112+
class StringConstructedGenericKey<T> {
113+
public final String value;
114+
public StringConstructedGenericKey(String value) { this.value = value; }
115+
}
116+
class GenericConfig {
117+
public GenericBox<List<GenericItem<String>>> foo;
118+
public Map<StringConstructedGenericKey<Integer>, List<String>> values;
119+
}
120+
121+
String toml = """
122+
[[foo.value]]
123+
payload = "a"
124+
125+
[values]
126+
k1 = ["x", "y"]
127+
""";
128+
GenericConfig cfg = new TomlDeserializer().deserialize(toml, GenericConfig.class);
129+
```
130+
104131
## Optional semantics
105132

106133
```java

modules/xml2java/README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,27 @@ assertEquals(List.of("a", "b"), cfg.tags);
8989
assertEquals(Integer.valueOf(10), cfg.limits.get("api"));
9090
```
9191

92+
## Nested generics
93+
94+
```java
95+
import java.util.List;
96+
import java.util.Map;
97+
98+
class GenericBox<T> { public T value; }
99+
class GenericItem<T> { public T payload; }
100+
class StringConstructedGenericKey<T> {
101+
public final String value;
102+
public StringConstructedGenericKey(String value) { this.value = value; }
103+
}
104+
class GenericConfig {
105+
public GenericBox<List<GenericItem<String>>> foo;
106+
public Map<StringConstructedGenericKey<Integer>, List<String>> values;
107+
}
108+
109+
String xml = "<config><foo><value><payload>a</payload></value></foo><values><k1>x</k1><k1>y</k1></values></config>";
110+
GenericConfig cfg = new XmlDeserializer().deserialize(xml, GenericConfig.class);
111+
```
112+
92113
## Optional semantics
93114

94115
```java

0 commit comments

Comments
 (0)