Skip to content

Commit 429f1bd

Browse files
authored
Merge pull request #5 from ruslansennov/iss4
interfaces binding -- fixes #4
2 parents d84c127 + 4bb12ae commit 429f1bd

19 files changed

+472
-93
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
build
2+
out
23
.gradle
34
.idea
45
*.iml

src/main/java/io/vavr/gson/VavrGson.java

+91
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ public static GsonBuilder registerOption(GsonBuilder builder) {
6060
*/
6161
public static GsonBuilder registerAllMultimaps(GsonBuilder builder) {
6262
checkBuilder(builder);
63+
registerMultimap(builder);
64+
registerSortedMultimap(builder);
6365
registerHashMultimap(builder);
6466
registerLinkedHashMultimap(builder);
6567
registerTreeMultimap(builder);
@@ -75,6 +77,24 @@ public static GsonBuilder registerHashMultimap(GsonBuilder builder) {
7577
return checkBuilder(builder).registerTypeAdapter(HashMultimap.class, new MultimapConverter<>(t -> HashMultimap.withSeq().ofEntries(t)));
7678
}
7779

80+
/**
81+
* Registers the {@link Multimap} converter.
82+
* @param builder The GSON builder to register the converters with.
83+
* @return A reference to {@code builder}.
84+
*/
85+
public static GsonBuilder registerMultimap(GsonBuilder builder) {
86+
return checkBuilder(builder).registerTypeAdapter(Multimap.class, new MultimapConverter<>(t -> HashMultimap.withSeq().ofEntries(t)));
87+
}
88+
89+
/**
90+
* Registers the {@link SortedMultimap} converter.
91+
* @param builder The GSON builder to register the converters with.
92+
* @return A reference to {@code builder}.
93+
*/
94+
public static GsonBuilder registerSortedMultimap(GsonBuilder builder) {
95+
return checkBuilder(builder).registerTypeAdapter(SortedMultimap.class, new MultimapConverter<>(t -> TreeMultimap.withSeq().ofEntries(t)));
96+
}
97+
7898
/**
7999
* Registers the {@link LinkedHashMultimap} converter.
80100
* @param builder The GSON builder to register the converters with.
@@ -100,6 +120,8 @@ public static GsonBuilder registerTreeMultimap(GsonBuilder builder) {
100120
*/
101121
public static GsonBuilder registerAllMaps(GsonBuilder builder) {
102122
checkBuilder(builder);
123+
registerMap(builder);
124+
registerSortedMap(builder);
103125
registerHashMap(builder);
104126
registerLinkedHashMap(builder);
105127
registerTreeMap(builder);
@@ -115,6 +137,24 @@ public static GsonBuilder registerHashMap(GsonBuilder builder) {
115137
return checkBuilder(builder).registerTypeAdapter(HashMap.class, new MapConverter<>(HashMap::ofEntries));
116138
}
117139

140+
/**
141+
* Registers the {@link Map} converter.
142+
* @param builder The GSON builder to register the converters with.
143+
* @return A reference to {@code builder}.
144+
*/
145+
public static GsonBuilder registerMap(GsonBuilder builder) {
146+
return checkBuilder(builder).registerTypeAdapter(Map.class, new MapConverter<>(HashMap::ofEntries));
147+
}
148+
149+
/**
150+
* Registers the {@link SortedMap} converter.
151+
* @param builder The GSON builder to register the converters with.
152+
* @return A reference to {@code builder}.
153+
*/
154+
public static GsonBuilder registerSortedMap(GsonBuilder builder) {
155+
return checkBuilder(builder).registerTypeAdapter(SortedMap.class, new MapConverter<>(TreeMap::ofEntries));
156+
}
157+
118158
/**
119159
* Registers the {@link LinkedHashMap} converter.
120160
* @param builder The GSON builder to register the converters with.
@@ -150,10 +190,15 @@ public static GsonBuilder registerTuples(GsonBuilder builder) {
150190
public static GsonBuilder registerAllCollections(GsonBuilder builder) {
151191
checkBuilder(builder);
152192
registerArray(builder);
193+
registerSeq(builder);
194+
registerIndexedSeq(builder);
195+
registerLinearSeq(builder);
153196
registerList(builder);
154197
registerQueue(builder);
155198
registerStream(builder);
156199
registerVector(builder);
200+
registerSet(builder);
201+
registerSortedSet(builder);
157202
registerHashSet(builder);
158203
registerLinkedHashSet(builder);
159204
registerTreeSet(builder);
@@ -180,6 +225,25 @@ public static GsonBuilder registerHashSet(GsonBuilder builder) {
180225
return checkBuilder(builder).registerTypeAdapter(HashSet.class, new TraversableConverter<>(HashSet::ofAll));
181226
}
182227

228+
/**
229+
* Registers the {@link Set} converter.
230+
* @param builder The GSON builder to register the converters with.
231+
* @return A reference to {@code builder}.
232+
*/
233+
public static GsonBuilder registerSet(GsonBuilder builder) {
234+
return checkBuilder(builder).registerTypeAdapter(Set.class, new TraversableConverter<>(HashSet::ofAll));
235+
}
236+
237+
/**
238+
* Registers the {@link SortedSet} converter.
239+
* @param builder The GSON builder to register the converters with.
240+
* @return A reference to {@code builder}.
241+
*/
242+
@SuppressWarnings("unchecked")
243+
public static GsonBuilder registerSortedSet(GsonBuilder builder) {
244+
return checkBuilder(builder).registerTypeAdapter(SortedSet.class, new TraversableConverter<>(it -> TreeSet.ofAll((o1, o2) -> ((Comparable) o1).compareTo(o2), it)));
245+
}
246+
183247
/**
184248
* Registers the {@link LinkedHashSet} converter.
185249
* @param builder The GSON builder to register the converters with.
@@ -208,6 +272,33 @@ public static GsonBuilder registerArray(GsonBuilder builder) {
208272
return checkBuilder(builder).registerTypeAdapter(Array.class, new TraversableConverter<>(Array::ofAll));
209273
}
210274

275+
/**
276+
* Registers the {@link Seq} converter.
277+
* @param builder The GSON builder to register the converters with.
278+
* @return A reference to {@code builder}.
279+
*/
280+
public static GsonBuilder registerSeq(GsonBuilder builder) {
281+
return checkBuilder(builder).registerTypeAdapter(Seq.class, new TraversableConverter<>(List::ofAll));
282+
}
283+
284+
/**
285+
* Registers the {@link IndexedSeq} converter.
286+
* @param builder The GSON builder to register the converters with.
287+
* @return A reference to {@code builder}.
288+
*/
289+
public static GsonBuilder registerIndexedSeq(GsonBuilder builder) {
290+
return checkBuilder(builder).registerTypeAdapter(IndexedSeq.class, new TraversableConverter<>(Vector::ofAll));
291+
}
292+
293+
/**
294+
* Registers the {@link LinearSeq} converter.
295+
* @param builder The GSON builder to register the converters with.
296+
* @return A reference to {@code builder}.
297+
*/
298+
public static GsonBuilder registerLinearSeq(GsonBuilder builder) {
299+
return checkBuilder(builder).registerTypeAdapter(LinearSeq.class, new TraversableConverter<>(List::ofAll));
300+
}
301+
211302
/**
212303
* Registers the {@link List} converter.
213304
* @param builder The GSON builder to register the converters with.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package io.vavr.gson.collection;
2+
3+
import com.google.gson.reflect.TypeToken;
4+
import io.vavr.collection.IndexedSeq;
5+
import io.vavr.collection.Vector;
6+
7+
import java.lang.reflect.Type;
8+
import java.util.Arrays;
9+
10+
public class IndexedSeqTest extends CollectionTest<IndexedSeq<?>> {
11+
12+
@Override
13+
IndexedSeq<?> of(Object... arr) {
14+
return Vector.ofAll(Arrays.asList(arr));
15+
}
16+
17+
@Override
18+
Class<?> clz() {
19+
return IndexedSeq.class;
20+
}
21+
22+
@Override
23+
Type type() {
24+
return new TypeToken<IndexedSeq<Integer>>(){}.getType();
25+
}
26+
27+
@Override
28+
Type typeWithNestedType() {
29+
return new TypeToken<IndexedSeq<IndexedSeq<Integer>>>(){}.getType();
30+
}
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package io.vavr.gson.collection;
2+
3+
import com.google.gson.reflect.TypeToken;
4+
import io.vavr.collection.LinearSeq;
5+
import io.vavr.collection.List;
6+
7+
import java.lang.reflect.Type;
8+
import java.util.Arrays;
9+
10+
public class LinearSeqTest extends CollectionTest<LinearSeq<?>> {
11+
12+
@Override
13+
LinearSeq<?> of(Object... arr) {
14+
return List.ofAll(Arrays.asList(arr));
15+
}
16+
17+
@Override
18+
Class<?> clz() {
19+
return LinearSeq.class;
20+
}
21+
22+
@Override
23+
Type type() {
24+
return new TypeToken<LinearSeq<Integer>>(){}.getType();
25+
}
26+
27+
@Override
28+
Type typeWithNestedType() {
29+
return new TypeToken<LinearSeq<LinearSeq<Integer>>>(){}.getType();
30+
}
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package io.vavr.gson.collection;
2+
3+
import com.google.gson.reflect.TypeToken;
4+
import io.vavr.collection.List;
5+
import io.vavr.collection.Seq;
6+
7+
import java.lang.reflect.Type;
8+
import java.util.Arrays;
9+
10+
public class SeqTest extends CollectionTest<Seq<?>> {
11+
12+
@Override
13+
Seq<?> of(Object... arr) {
14+
return List.ofAll(Arrays.asList(arr));
15+
}
16+
17+
@Override
18+
Class<?> clz() {
19+
return Seq.class;
20+
}
21+
22+
@Override
23+
Type type() {
24+
return new TypeToken<Seq<Integer>>(){}.getType();
25+
}
26+
27+
@Override
28+
Type typeWithNestedType() {
29+
return new TypeToken<Seq<Seq<Integer>>>(){}.getType();
30+
}
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package io.vavr.gson.collection;
2+
3+
import com.google.gson.reflect.TypeToken;
4+
import io.vavr.collection.HashSet;
5+
import io.vavr.collection.Set;
6+
7+
import java.lang.reflect.Type;
8+
import java.util.Arrays;
9+
10+
public class SetTest extends CollectionTest<Set<?>> {
11+
12+
@Override
13+
Set<?> of(Object... arr) {
14+
return HashSet.ofAll(Arrays.asList(arr));
15+
}
16+
17+
@Override
18+
Class<?> clz() {
19+
return Set.class;
20+
}
21+
22+
@Override
23+
Type type() {
24+
return new TypeToken<Set<Integer>>(){}.getType();
25+
}
26+
27+
@Override
28+
Type typeWithNestedType() {
29+
return new TypeToken<Set<Set<Integer>>>(){}.getType();
30+
}
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package io.vavr.gson.collection;
2+
3+
import com.google.gson.reflect.TypeToken;
4+
import io.vavr.collection.SortedSet;
5+
import io.vavr.collection.TreeSet;
6+
import org.junit.Test;
7+
8+
import java.lang.reflect.Type;
9+
import java.util.Arrays;
10+
11+
public class SortedSetTest extends CollectionTest<SortedSet<?>> {
12+
13+
@Override
14+
@SuppressWarnings("unchecked")
15+
SortedSet<?> of(Object... arr) {
16+
return TreeSet.ofAll((o1, o2) -> ((Comparable) o1).compareTo(o2), Arrays.asList(arr));
17+
}
18+
19+
@Override
20+
Class<?> clz() {
21+
return SortedSet.class;
22+
}
23+
24+
@Override
25+
Type type() {
26+
return new TypeToken<SortedSet<Integer>>(){}.getType();
27+
}
28+
29+
@Override
30+
Type typeWithNestedType() {
31+
return new TypeToken<SortedSet<SortedSet<Integer>>>(){}.getType();
32+
}
33+
34+
@Test
35+
@Override
36+
public void deserializeSimpleType() {
37+
// ignore
38+
}
39+
40+
@Test
41+
@Override
42+
public void deserializeNested() {
43+
// ignore
44+
}
45+
}

src/test/java/io/vavr/gson/map/HashMapTest.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import java.lang.reflect.Type;
77

8-
public class HashMapTest extends MapTest<HashMap<?,?>> {
8+
public class HashMapTest extends MapLikeTest<HashMap<?,?>> {
99
@Override
1010
HashMap<?, ?> of(Object key, Object value) {
1111
return HashMap.of(key, value);

src/test/java/io/vavr/gson/map/LinkedHashMapTest.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import java.lang.reflect.Type;
77

8-
public class LinkedHashMapTest extends MapTest<LinkedHashMap<?,?>> {
8+
public class LinkedHashMapTest extends MapLikeTest<LinkedHashMap<?,?>> {
99
@Override
1010
LinkedHashMap<?, ?> of(Object key, Object value) {
1111
return LinkedHashMap.of(key, value);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package io.vavr.gson.map;
2+
3+
import com.google.gson.JsonParseException;
4+
import com.google.gson.JsonPrimitive;
5+
import io.vavr.collection.Map;
6+
import io.vavr.gson.AbstractTest;
7+
import org.junit.Test;
8+
9+
import java.lang.reflect.Type;
10+
11+
public abstract class MapLikeTest<T extends Map<?,?>> extends AbstractTest {
12+
13+
abstract T of(Object key, Object value);
14+
abstract Class<?> clz();
15+
abstract Type type();
16+
abstract Type typeWithNestedType();
17+
18+
@Test(expected = JsonParseException.class)
19+
public void badJson() {
20+
gson.fromJson("1", type());
21+
}
22+
23+
@Test
24+
public void serialize() {
25+
assert gson.toJson(of(1, 2)).equals("{\"1\":2}");
26+
}
27+
28+
@Test
29+
public void deserializeSimpleType() {
30+
Object obj = gson.fromJson("{\"1\":2}", clz());
31+
assert clz().isAssignableFrom(obj.getClass());
32+
Map<?, ?> map = (Map<?, ?>) obj;
33+
assert map.head()._2 instanceof JsonPrimitive;
34+
assert ((JsonPrimitive) map.head()._2).getAsInt() == 2;
35+
}
36+
37+
@Test
38+
public void deserialize() {
39+
Map<String, Integer> map = gson.fromJson("{\"1\":2}", type());
40+
assert clz().isAssignableFrom(map.getClass());
41+
assert map.get("1").get() == 2;
42+
}
43+
44+
@Test
45+
public void deserializeWithCast() {
46+
Map<String, Integer> map = gson.fromJson("{\"1\":\"2\"}", type());
47+
assert clz().isAssignableFrom(map.getClass());
48+
assert map.get("1").get() == 2;
49+
}
50+
51+
@Test
52+
public void deserializeNested() {
53+
Map<String, Map<String, Integer>> map = gson.fromJson("{\"1\":{\"2\":3}}", typeWithNestedType());
54+
assert clz().isAssignableFrom(map.get("1").get().getClass());
55+
assert map.get("1").get().get("2").get() == 3;
56+
}
57+
}

0 commit comments

Comments
 (0)