├── .gitignore ├── .travis.yml ├── .travis └── maven-settings.xml ├── LICENSE ├── README.md ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src ├── main └── java │ └── io │ └── vavr │ └── gson │ ├── JsonArrayConverter.java │ ├── JsonObjectConverter.java │ ├── LazyConverter.java │ ├── MapConverter.java │ ├── MultimapConverter.java │ ├── OptionConverter.java │ ├── TraversableConverter.java │ ├── TupleConverter.java │ └── VavrGson.java └── test └── java └── io └── vavr └── gson ├── AbstractTest.java ├── LazyTest.java ├── OptionTest.java ├── VavrGsonTest.java ├── collection ├── ArrayTest.java ├── CollectionTest.java ├── HashSetTest.java ├── IndexedSeqTest.java ├── LinearSeqTest.java ├── LinkedHashSetTest.java ├── ListTest.java ├── PriorityQueueTest.java ├── QueueTest.java ├── SeqTest.java ├── SetTest.java ├── SortedSetTest.java ├── StreamTest.java ├── TreeSetTest.java └── VectorTest.java ├── map ├── HashMapTest.java ├── LinkedHashMapTest.java ├── MapLikeTest.java ├── MapTest.java ├── SortedMapTest.java └── TreeMapTest.java ├── multimap ├── HashMultimapTest.java ├── LinkedHashMultimapTest.java ├── MultimapLikeTest.java ├── MultimapTest.java ├── SortedMultimapTest.java └── TreeMultimapTest.java └── tuples ├── Tuple0Test.java ├── Tuple1Test.java ├── Tuple2Test.java ├── Tuple3Test.java ├── Tuple4Test.java ├── Tuple5Test.java ├── Tuple6Test.java ├── Tuple7Test.java ├── Tuple8Test.java └── TupleNTest.java /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | out 3 | .gradle 4 | .idea 5 | *.iml 6 | *.ipr 7 | *.iws 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | dist: trusty 3 | jdk: 4 | - oraclejdk8 5 | env: 6 | global: 7 | - secure: cID0zXRLjdJ0NEBWzkjTLLW5eJ/6YIbCoHEqXz+uvDBTrBGC+LBJjew7TNc4wamBEwMtOqRPSNii0FXkRyhVyC3vRxS5e2+tsDv6XKHC2yRFfjZg1pqgwHcp2lh3K7Tr24M+pnKH2CrpByL0mWzu8pt3Et5AJd275bw6BkFAEryRiALC5Rlb8D5K3pJ/30uRIuxM7P66cEvmpBDjLuen27FRyxwiR1M9gGHRrDfNicmh44JUTzB77C0iCL2LBeuyqnyDv6XT8w2FFoTocX5bvWpFYvxXjJRiLDq6P9AJrWLO4BHkPclZunyS/LQWkSK+ojUqQpzWicXvEhwcLFpNMEWWpmY+ioY65c+AZpHP29mpC2eVYQOPyZTAs26XFktE82gp2QdJ2wir+CjfiZnFNP61p6f9qUHb2GvprzgDAiLZmsdyrn2emZT8duazQkucPI4fpxMWLWVKDSSGilASGeOE4REmACIqnepE0AZP5sfreQDI2C2mhrDtR7OpFUHLF2+OvftiMj/efYwIwSAFs01s/+XZm9+Y28Vd4GPbU8125MPf30xN4ys6x75pyHkxcmGibkHMTe7UXcmYsmV6bbterynzyfECvIfXV7B6oWUleYqdzRLSoyHUJUrc5vJevj3rANET9vv+HrOA+eFpkJPXVJPWIntJO9SEgbWOsUY= 8 | - secure: pGywYMtrdEHEtUbbul2hHOCiEy//WAveX5mx9d2JLva5CLlyWqBL/7IFchsyy7cjEqAjvq4zwcPHLMFanSi/SA3T+Ur5jzhrWc/3n7kzaBVNhiph+Sjut1CE1LnjvlQ3IONvqInYjtZgv5Lvs0Yxtf8mdiPcx3YNhDcs5emvjyI1XLYGRJ20hsG3vC/qSeIdtBeXo5a7vuRRfBNJMOnlOCd5j2SGEI92K2Hh3JIAqNax9NU59vRzA/sWb3Dm13wny8HKYCGQp120mpSrK8y3VFLbmMBfEtWz5Nbqaz12As8r37MOkKeXvLRXCahX272KlwTtbyRqmB/5fS0vvKcYvQ7C59m1BtjCLV0PEFUp0Rk/KkHUoJRKuVMfh2aIJgcON6EdOB7C9z4FGI1YB2yv1pjEWdVLU6HA8WMNGb8+SXfNAUMjqlyyPkC9wSJsqOY45sONlA+VtRebU84K1p9GbSBKAcuxKb50rpR+kgF0rn/MMr7FBgp9MDZ9v/LucoCU0l/VrM6FGkYrsnQOdAh5Kz4BbLbHSRavLpcQ5su8QJzywmJAJ6Qc0oIpYqLYEDcQktwBLpCJALmhCekI+yCWych6E/T5fgelQksqGMtxp03asA7AV1pjFuvQEJWEAUof1szTx3co5XCvfbXQNfl7Lo/UvxamfbPmSOCTmatvdAU= 9 | script: 10 | - ./gradlew clean check --refresh-dependencies 11 | - ./gradlew codeCoverageReport 12 | after_success: 13 | - bash <(curl -s https://codecov.io/bash) 14 | - ./gradlew uploadArchives -PnexusUsername="${SONATYPE_USER}" -PnexusPassword="${SONATYPE_PASS}" 15 | -------------------------------------------------------------------------------- /.travis/maven-settings.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | sonatype-nexus-snapshots 13 | ${env.SONATYPE_USER} 14 | ${env.SONATYPE_PASS} 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.vavr/vavr-gson/badge.svg)](https://maven-badges.herokuapp.com/maven-central/io.vavr/vavr-gson) 2 | [![Build Status](https://travis-ci.org/vavr-io/vavr-gson.svg?branch=master)](https://travis-ci.org/vavr-io/vavr-gson) 3 | [![Coverage Status](https://codecov.io/github/vavr-io/vavr-gson/coverage.svg?branch=master)](https://codecov.io/github/vavr-io/vavr-gson?branch=master) 4 | [![Gitter Chat](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/vavr-io/vavr) 5 | 6 | # vavr-gson 7 | A set of GSON serialiser/deserialisers for [Vavr](http://vavr.io/) library 8 | 9 | ## Usage 10 | 11 | ### Maven 12 | 13 | ```xml 14 | 15 | io.vavr 16 | vavr-gson 17 | 0.10.2 18 | 19 | ``` 20 | 21 | ### Gradle 22 | 23 | ```groovy 24 | compile("io.vavr:vavr-gson:0.10.2") 25 | ``` 26 | 27 | ### Registering converters 28 | 29 | ```java 30 | GsonBuilder builder = new GsonBuilder(); 31 | VavrGson.registerAll(builder); 32 | gson = builder.create(); 33 | ``` 34 | 35 | ### Serialization/deserialization 36 | 37 | ```java 38 | String json = gson.toJson(List.of(List.of(1))); 39 | // = [[1]] 40 | Object restored1 = gson.fromJson(json, List.class); 41 | // = List([1]) 42 | Type type = new TypeToken>>(){}.getType(); 43 | Object restored2 = gson.fromJson(json, type); 44 | // = List(List(1)) 45 | ``` 46 | 47 | ## Using Developer Versions 48 | 49 | Developer versions can be found [here](https://oss.sonatype.org/content/repositories/snapshots/io/vavr/vavr-gson). 50 | 51 | ### Maven 52 | 53 | ```xml 54 | 55 | io.vavr 56 | vavr-gson 57 | 1.0.0-SNAPSHOT 58 | 59 | ``` 60 | 61 | Ensure that your `~/.m2/settings.xml` contains the following: 62 | 63 | ```xml 64 | 65 | 66 | allow-snapshots 67 | 68 | true 69 | 70 | 71 | 72 | snapshots-repo 73 | https://oss.sonatype.org/content/repositories/snapshots 74 | 75 | false 76 | 77 | 78 | true 79 | 80 | 81 | 82 | 83 | 84 | ``` 85 | 86 | ### Gradle 87 | 88 | ```groovy 89 | compile("io.vavr:vavr-gson:1.0.0-SNAPSHOT") 90 | ``` 91 | 92 | Ensure that your `build.gradle` contains the following: 93 | 94 | ```groovy 95 | repositories { 96 | mavenCentral() 97 | maven { 98 | url "https://oss.sonatype.org/content/repositories/snapshots" 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | id 'maven' 4 | id 'jacoco' 5 | id 'com.bmuschko.nexus' version '2.3.1' 6 | } 7 | 8 | sourceCompatibility = JavaVersion.VERSION_1_8 9 | targetCompatibility = JavaVersion.VERSION_1_8 10 | 11 | group = 'io.vavr' 12 | version = '1.0.0-SNAPSHOT' 13 | 14 | repositories { 15 | mavenCentral() 16 | maven { 17 | url "https://oss.sonatype.org/content/repositories/snapshots" 18 | } 19 | } 20 | 21 | dependencies { 22 | compile "io.vavr:vavr:${vavrVersion}" 23 | compile "com.google.code.gson:gson:${gsonVersion}" 24 | testCompile "junit:junit:${junitVersion}" 25 | } 26 | 27 | task codeCoverageReport(type: JacocoReport) { 28 | executionData fileTree(project.rootDir.absolutePath).include("**/build/jacoco/*.exec") 29 | 30 | sourceSets sourceSets.main 31 | 32 | reports { 33 | xml.enabled = true 34 | xml.destination file("${buildDir}/reports/jacoco/report.xml") 35 | html.enabled = true 36 | csv.enabled = false 37 | } 38 | } 39 | 40 | codeCoverageReport.dependsOn { 41 | project.test 42 | } 43 | 44 | jar { 45 | manifest { 46 | attributes( 47 | 'Automatic-Module-Name': 'io.vavr.gson' 48 | ) 49 | } 50 | } 51 | 52 | modifyPom { 53 | project { 54 | name 'Vavr-Gson' 55 | description 'A set of GSON serialiser/deserialisers for Vavr.io' 56 | url 'http://vavr.io' 57 | inceptionYear '2017' 58 | 59 | scm { 60 | connection 'scm:git:git@github.com:vavr-io/vavr-gson.git' 61 | developerConnection 'scm:git:git@github.com:vavr-io/vavr-gson.git' 62 | url 'git@github.com:vavr-io/vavr-gson.git' 63 | } 64 | 65 | licenses { 66 | license { 67 | name 'The Apache Software License, Version 2.0' 68 | url 'http://www.apache.org/licenses/LICENSE-2.0.txt' 69 | } 70 | } 71 | 72 | developers { 73 | developer { 74 | id 'ruslansennov' 75 | name 'Ruslan Sennov' 76 | email 'ruslan.sennov@gmail.com' 77 | } 78 | } 79 | } 80 | } 81 | 82 | nexus { 83 | sign = !version.endsWith("SNAPSHOT") 84 | } 85 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | junitVersion=4.12 2 | vavrVersion=1.0.0-SNAPSHOT 3 | gsonVersion=2.8.0 4 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vavr-io/vavr-gson/af6c02c322ee56e98ceae02e231be7e8c795b0dc/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | # Determine the Java command to use to start the JVM. 86 | if [ -n "$JAVA_HOME" ] ; then 87 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 88 | # IBM's JDK on AIX uses strange locations for the executables 89 | JAVACMD="$JAVA_HOME/jre/sh/java" 90 | else 91 | JAVACMD="$JAVA_HOME/bin/java" 92 | fi 93 | if [ ! -x "$JAVACMD" ] ; then 94 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 95 | 96 | Please set the JAVA_HOME variable in your environment to match the 97 | location of your Java installation." 98 | fi 99 | else 100 | JAVACMD="java" 101 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 102 | 103 | Please set the JAVA_HOME variable in your environment to match the 104 | location of your Java installation." 105 | fi 106 | 107 | # Increase the maximum file descriptors if we can. 108 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 109 | MAX_FD_LIMIT=`ulimit -H -n` 110 | if [ $? -eq 0 ] ; then 111 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 112 | MAX_FD="$MAX_FD_LIMIT" 113 | fi 114 | ulimit -n $MAX_FD 115 | if [ $? -ne 0 ] ; then 116 | warn "Could not set maximum file descriptor limit: $MAX_FD" 117 | fi 118 | else 119 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 120 | fi 121 | fi 122 | 123 | # For Darwin, add options to specify how the application appears in the dock 124 | if $darwin; then 125 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 126 | fi 127 | 128 | # For Cygwin or MSYS, switch paths to Windows format before running java 129 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 130 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 131 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 132 | JAVACMD=`cygpath --unix "$JAVACMD"` 133 | 134 | # We build the pattern for arguments to be converted via cygpath 135 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 136 | SEP="" 137 | for dir in $ROOTDIRSRAW ; do 138 | ROOTDIRS="$ROOTDIRS$SEP$dir" 139 | SEP="|" 140 | done 141 | OURCYGPATTERN="(^($ROOTDIRS))" 142 | # Add a user-defined pattern to the cygpath arguments 143 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 144 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 145 | fi 146 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 147 | i=0 148 | for arg in "$@" ; do 149 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 150 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 151 | 152 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 153 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 154 | else 155 | eval `echo args$i`="\"$arg\"" 156 | fi 157 | i=$((i+1)) 158 | done 159 | case $i in 160 | (0) set -- ;; 161 | (1) set -- "$args0" ;; 162 | (2) set -- "$args0" "$args1" ;; 163 | (3) set -- "$args0" "$args1" "$args2" ;; 164 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 165 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 166 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 167 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 168 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 169 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 170 | esac 171 | fi 172 | 173 | # Escape application args 174 | save () { 175 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 176 | echo " " 177 | } 178 | APP_ARGS=$(save "$@") 179 | 180 | # Collect all arguments for the java command, following the shell quoting and substitution rules 181 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 182 | 183 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 184 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 185 | cd "$(dirname "$0")" 186 | fi 187 | 188 | exec "$JAVACMD" "$@" 189 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 33 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 34 | 35 | @rem Find java.exe 36 | if defined JAVA_HOME goto findJavaFromJavaHome 37 | 38 | set JAVA_EXE=java.exe 39 | %JAVA_EXE% -version >NUL 2>&1 40 | if "%ERRORLEVEL%" == "0" goto init 41 | 42 | echo. 43 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 44 | echo. 45 | echo Please set the JAVA_HOME variable in your environment to match the 46 | echo location of your Java installation. 47 | 48 | goto fail 49 | 50 | :findJavaFromJavaHome 51 | set JAVA_HOME=%JAVA_HOME:"=% 52 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 53 | 54 | if exist "%JAVA_EXE%" goto init 55 | 56 | echo. 57 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 58 | echo. 59 | echo Please set the JAVA_HOME variable in your environment to match the 60 | echo location of your Java installation. 61 | 62 | goto fail 63 | 64 | :init 65 | @rem Get command-line arguments, handling Windows variants 66 | 67 | if not "%OS%" == "Windows_NT" goto win9xME_args 68 | 69 | :win9xME_args 70 | @rem Slurp the command line arguments. 71 | set CMD_LINE_ARGS= 72 | set _SKIP=2 73 | 74 | :win9xME_args_slurp 75 | if "x%~1" == "x" goto execute 76 | 77 | set CMD_LINE_ARGS=%* 78 | 79 | :execute 80 | @rem Setup the command line 81 | 82 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 83 | 84 | @rem Execute Gradle 85 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 86 | 87 | :end 88 | @rem End local scope for the variables with windows NT shell 89 | if "%ERRORLEVEL%"=="0" goto mainEnd 90 | 91 | :fail 92 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 93 | rem the _cmd.exe /c_ return code! 94 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 95 | exit /b 1 96 | 97 | :mainEnd 98 | if "%OS%"=="Windows_NT" endlocal 99 | 100 | :omega 101 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'vavr-gson' -------------------------------------------------------------------------------- /src/main/java/io/vavr/gson/JsonArrayConverter.java: -------------------------------------------------------------------------------- 1 | /* __ __ __ __ __ ___ 2 | * \ \ / / \ \ / / __/ 3 | * \ \/ / /\ \ \/ / / 4 | * \____/__/ \__\____/__/.ɪᴏ 5 | * ᶜᵒᵖʸʳᶦᵍʰᵗ ᵇʸ ᵛᵃᵛʳ ⁻ ˡᶦᶜᵉⁿˢᵉᵈ ᵘⁿᵈᵉʳ ᵗʰᵉ ᵃᵖᵃᶜʰᵉ ˡᶦᶜᵉⁿˢᵉ ᵛᵉʳˢᶦᵒⁿ ᵗʷᵒ ᵈᵒᵗ ᶻᵉʳᵒ 6 | */ 7 | package io.vavr.gson; 8 | 9 | import com.google.gson.*; 10 | import io.vavr.collection.Traversable; 11 | 12 | import java.lang.reflect.ParameterizedType; 13 | import java.lang.reflect.Type; 14 | 15 | abstract class JsonArrayConverter implements JsonSerializer, JsonDeserializer { 16 | 17 | private static final Type[] EMPTY_TYPES = new Type[0]; 18 | 19 | abstract T fromJsonArray(JsonArray arr, Type type, Type[] subTypes, JsonDeserializationContext ctx) throws JsonParseException; 20 | abstract Traversable toTraversable(T src); 21 | 22 | @Override 23 | public T deserialize(JsonElement json, Type type, JsonDeserializationContext ctx) throws JsonParseException { 24 | if (json.isJsonArray()) { 25 | if (type instanceof ParameterizedType) { 26 | ParameterizedType parameterizedType = (ParameterizedType) type; 27 | Type[] types = parameterizedType.getActualTypeArguments(); 28 | return fromJsonArray(json.getAsJsonArray(), type, types, ctx); 29 | } else { 30 | return fromJsonArray(json.getAsJsonArray(), type, EMPTY_TYPES, ctx); 31 | } 32 | } else { 33 | throw new JsonParseException("array expected"); 34 | } 35 | } 36 | 37 | @Override 38 | public JsonElement serialize(T src, Type type, JsonSerializationContext ctx) { 39 | return toTraversable(src).foldLeft(new JsonArray(), (a, e) -> { 40 | a.add(ctx.serialize(e)); 41 | return a; 42 | }); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/io/vavr/gson/JsonObjectConverter.java: -------------------------------------------------------------------------------- 1 | /* __ __ __ __ __ ___ 2 | * \ \ / / \ \ / / __/ 3 | * \ \/ / /\ \ \/ / / 4 | * \____/__/ \__\____/__/.ɪᴏ 5 | * ᶜᵒᵖʸʳᶦᵍʰᵗ ᵇʸ ᵛᵃᵛʳ ⁻ ˡᶦᶜᵉⁿˢᵉᵈ ᵘⁿᵈᵉʳ ᵗʰᵉ ᵃᵖᵃᶜʰᵉ ˡᶦᶜᵉⁿˢᵉ ᵛᵉʳˢᶦᵒⁿ ᵗʷᵒ ᵈᵒᵗ ᶻᵉʳᵒ 6 | */ 7 | package io.vavr.gson; 8 | 9 | import com.google.gson.*; 10 | import io.vavr.collection.Map; 11 | 12 | import java.lang.reflect.ParameterizedType; 13 | import java.lang.reflect.Type; 14 | 15 | abstract class JsonObjectConverter implements JsonSerializer, JsonDeserializer { 16 | 17 | private static final Type[] EMPTY_TYPES = new Type[0]; 18 | 19 | abstract T fromJsonObject(JsonObject arr, Type type, Type[] subTypes, JsonDeserializationContext ctx) throws JsonParseException; 20 | abstract Map toMap(T src); 21 | 22 | @Override 23 | public T deserialize(JsonElement json, Type type, JsonDeserializationContext ctx) throws JsonParseException { 24 | if (json.isJsonObject()) { 25 | if (type instanceof ParameterizedType) { 26 | ParameterizedType parameterizedType = (ParameterizedType) type; 27 | Type[] types = parameterizedType.getActualTypeArguments(); 28 | return fromJsonObject(json.getAsJsonObject(), type, types, ctx); 29 | } else { 30 | return fromJsonObject(json.getAsJsonObject(), type, EMPTY_TYPES, ctx); 31 | } 32 | } else { 33 | throw new JsonParseException("object expected"); 34 | } 35 | } 36 | 37 | @Override 38 | public JsonElement serialize(T src, Type type, JsonSerializationContext ctx) { 39 | return toMap(src).foldLeft(new JsonObject(), (a, e) -> { 40 | a.add(ctx.serialize(e._1).getAsString(), ctx.serialize(e._2)); 41 | return a; 42 | }); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/io/vavr/gson/LazyConverter.java: -------------------------------------------------------------------------------- 1 | /* __ __ __ __ __ ___ 2 | * \ \ / / \ \ / / __/ 3 | * \ \/ / /\ \ \/ / / 4 | * \____/__/ \__\____/__/.ɪᴏ 5 | * ᶜᵒᵖʸʳᶦᵍʰᵗ ᵇʸ ᵛᵃᵛʳ ⁻ ˡᶦᶜᵉⁿˢᵉᵈ ᵘⁿᵈᵉʳ ᵗʰᵉ ᵃᵖᵃᶜʰᵉ ˡᶦᶜᵉⁿˢᵉ ᵛᵉʳˢᶦᵒⁿ ᵗʷᵒ ᵈᵒᵗ ᶻᵉʳᵒ 6 | */ 7 | package io.vavr.gson; 8 | 9 | import com.google.gson.*; 10 | import io.vavr.Lazy; 11 | 12 | import java.lang.reflect.ParameterizedType; 13 | import java.lang.reflect.Type; 14 | 15 | class LazyConverter implements JsonSerializer>, JsonDeserializer> { 16 | 17 | @Override 18 | public Lazy deserialize(JsonElement json, Type type, JsonDeserializationContext ctx) throws JsonParseException { 19 | if (type instanceof ParameterizedType) { 20 | ParameterizedType parameterizedType = (ParameterizedType) type; 21 | Type subType = parameterizedType.getActualTypeArguments()[0]; 22 | return Lazy.of(() -> ctx.deserialize(json, subType)); 23 | } else { 24 | return Lazy.of(() -> json); 25 | } 26 | } 27 | 28 | @Override 29 | public JsonElement serialize(Lazy src, Type type, JsonSerializationContext ctx) { 30 | return ctx.serialize(src.get()); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/io/vavr/gson/MapConverter.java: -------------------------------------------------------------------------------- 1 | /* __ __ __ __ __ ___ 2 | * \ \ / / \ \ / / __/ 3 | * \ \/ / /\ \ \/ / / 4 | * \____/__/ \__\____/__/.ɪᴏ 5 | * ᶜᵒᵖʸʳᶦᵍʰᵗ ᵇʸ ᵛᵃᵛʳ ⁻ ˡᶦᶜᵉⁿˢᵉᵈ ᵘⁿᵈᵉʳ ᵗʰᵉ ᵃᵖᵃᶜʰᵉ ˡᶦᶜᵉⁿˢᵉ ᵛᵉʳˢᶦᵒⁿ ᵗʷᵒ ᵈᵒᵗ ᶻᵉʳᵒ 6 | */ 7 | package io.vavr.gson; 8 | 9 | import com.google.gson.*; 10 | import io.vavr.Tuple; 11 | import io.vavr.Tuple2; 12 | import io.vavr.collection.Map; 13 | 14 | import java.lang.reflect.Type; 15 | import java.util.function.Function; 16 | import java.util.stream.Collectors; 17 | 18 | class MapConverter> extends JsonObjectConverter { 19 | 20 | private final Function>, Map> factory; 21 | 22 | MapConverter(Function>, Map> factory) { 23 | this.factory = factory; 24 | } 25 | 26 | @Override 27 | @SuppressWarnings("unchecked") 28 | T fromJsonObject(JsonObject obj, Type type, Type[] subTypes, JsonDeserializationContext ctx) throws JsonParseException { 29 | Function, Tuple2> mapper; 30 | if (subTypes.length == 2) { 31 | mapper = e -> Tuple.of(ctx.deserialize(new JsonPrimitive(e.getKey()), subTypes[0]), ctx.deserialize(e.getValue(), subTypes[1])); 32 | } else { 33 | mapper = e -> Tuple.of(e.getKey(), e.getValue()); 34 | } 35 | return (T) factory.apply(obj.entrySet().stream().map(mapper).collect(Collectors.toList())); 36 | } 37 | 38 | @Override 39 | Map toMap(T src) { 40 | return src; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/io/vavr/gson/MultimapConverter.java: -------------------------------------------------------------------------------- 1 | /* __ __ __ __ __ ___ 2 | * \ \ / / \ \ / / __/ 3 | * \ \/ / /\ \ \/ / / 4 | * \____/__/ \__\____/__/.ɪᴏ 5 | * ᶜᵒᵖʸʳᶦᵍʰᵗ ᵇʸ ᵛᵃᵛʳ ⁻ ˡᶦᶜᵉⁿˢᵉᵈ ᵘⁿᵈᵉʳ ᵗʰᵉ ᵃᵖᵃᶜʰᵉ ˡᶦᶜᵉⁿˢᵉ ᵛᵉʳˢᶦᵒⁿ ᵗʷᵒ ᵈᵒᵗ ᶻᵉʳᵒ 6 | */ 7 | package io.vavr.gson; 8 | 9 | import com.google.gson.*; 10 | import io.vavr.Function1; 11 | import io.vavr.Tuple; 12 | import io.vavr.Tuple2; 13 | import io.vavr.collection.LinkedHashMap; 14 | import io.vavr.collection.List; 15 | import io.vavr.collection.Map; 16 | import io.vavr.collection.Multimap; 17 | 18 | import java.lang.reflect.Type; 19 | import java.util.function.Function; 20 | import java.util.stream.Collectors; 21 | import java.util.stream.Stream; 22 | import java.util.stream.StreamSupport; 23 | 24 | class MultimapConverter> extends JsonObjectConverter { 25 | 26 | private final Function>, Multimap> factory; 27 | 28 | MultimapConverter(Function>, Multimap> factory) { 29 | this.factory = factory; 30 | } 31 | 32 | @Override 33 | @SuppressWarnings("unchecked") 34 | T fromJsonObject(JsonObject obj, Type type, Type[] subTypes, JsonDeserializationContext ctx) throws JsonParseException { 35 | Function1, Stream>> mapper; 36 | if (subTypes.length == 2) { 37 | mapper = e -> StreamSupport.stream(e.getValue().getAsJsonArray().spliterator(), false).map(v -> Tuple.of(ctx.deserialize(new JsonPrimitive(e.getKey()), subTypes[0]), ctx.deserialize(v, subTypes[1]))); 38 | } else { 39 | mapper = e -> StreamSupport.stream(e.getValue().getAsJsonArray().spliterator(), false).map(v -> Tuple.of(e.getKey(), v)); 40 | } 41 | return (T) factory.apply(obj.entrySet().stream().flatMap(mapper).collect(Collectors.toList())); 42 | } 43 | 44 | @Override 45 | @SuppressWarnings("unchecked") 46 | Map> toMap(T src) { 47 | // TODO implement Multimap.asMap() 48 | return src.foldLeft(LinkedHashMap.empty(), (m, t) -> m.put(t._1, (m.get(t._1)).getOrElse(List::empty).append(t._2))); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/io/vavr/gson/OptionConverter.java: -------------------------------------------------------------------------------- 1 | /* __ __ __ __ __ ___ 2 | * \ \ / / \ \ / / __/ 3 | * \ \/ / /\ \ \/ / / 4 | * \____/__/ \__\____/__/.ɪᴏ 5 | * ᶜᵒᵖʸʳᶦᵍʰᵗ ᵇʸ ᵛᵃᵛʳ ⁻ ˡᶦᶜᵉⁿˢᵉᵈ ᵘⁿᵈᵉʳ ᵗʰᵉ ᵃᵖᵃᶜʰᵉ ˡᶦᶜᵉⁿˢᵉ ᵛᵉʳˢᶦᵒⁿ ᵗʷᵒ ᵈᵒᵗ ᶻᵉʳᵒ 6 | */ 7 | package io.vavr.gson; 8 | 9 | import com.google.gson.JsonArray; 10 | import com.google.gson.JsonDeserializationContext; 11 | import com.google.gson.JsonParseException; 12 | import io.vavr.collection.List; 13 | import io.vavr.collection.Traversable; 14 | import io.vavr.control.Option; 15 | 16 | import java.lang.reflect.Type; 17 | 18 | class OptionConverter extends JsonArrayConverter> { 19 | 20 | @Override 21 | Option fromJsonArray(JsonArray arr, Type type, Type[] subTypes, JsonDeserializationContext ctx) throws JsonParseException { 22 | if (arr.size() < 1 || arr.size() > 2) { 23 | throw new JsonParseException("bad json format"); 24 | } 25 | String status = arr.get(0).getAsString(); 26 | if ("defined".equals(status)) { 27 | if (arr.size() == 2) { 28 | Object el = subTypes.length > 0 ? ctx.deserialize(arr.get(1), subTypes[0]) : arr.get(1); 29 | return Option.some(el); 30 | } else { 31 | throw new JsonParseException("expected array size: 2"); 32 | } 33 | } else { 34 | return Option.none(); 35 | } 36 | } 37 | 38 | @Override 39 | Traversable toTraversable(Option src) { 40 | return src.isDefined() ? List.of("defined", src.get()) : List.of("undefined"); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/io/vavr/gson/TraversableConverter.java: -------------------------------------------------------------------------------- 1 | /* __ __ __ __ __ ___ 2 | * \ \ / / \ \ / / __/ 3 | * \ \/ / /\ \ \/ / / 4 | * \____/__/ \__\____/__/.ɪᴏ 5 | * ᶜᵒᵖʸʳᶦᵍʰᵗ ᵇʸ ᵛᵃᵛʳ ⁻ ˡᶦᶜᵉⁿˢᵉᵈ ᵘⁿᵈᵉʳ ᵗʰᵉ ᵃᵖᵃᶜʰᵉ ˡᶦᶜᵉⁿˢᵉ ᵛᵉʳˢᶦᵒⁿ ᵗʷᵒ ᵈᵒᵗ ᶻᵉʳᵒ 6 | */ 7 | package io.vavr.gson; 8 | 9 | import com.google.gson.JsonArray; 10 | import com.google.gson.JsonDeserializationContext; 11 | import com.google.gson.JsonParseException; 12 | import io.vavr.collection.Stream; 13 | import io.vavr.collection.Traversable; 14 | 15 | import java.lang.reflect.Type; 16 | import java.util.function.Function; 17 | 18 | class TraversableConverter> extends JsonArrayConverter { 19 | 20 | private final Function, Traversable> factory; 21 | 22 | TraversableConverter(Function, Traversable> factory) { 23 | this.factory = factory; 24 | } 25 | 26 | @Override 27 | @SuppressWarnings("unchecked") 28 | T fromJsonArray(JsonArray arr, Type type, Type[] subTypes, JsonDeserializationContext ctx) throws JsonParseException { 29 | Stream stream = Stream.ofAll(arr).map(e -> subTypes.length == 1 ? ctx.deserialize(e, subTypes[0]) : e); 30 | return (T) factory.apply(stream); 31 | } 32 | 33 | @Override 34 | Traversable toTraversable(T src) { 35 | return src; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/io/vavr/gson/TupleConverter.java: -------------------------------------------------------------------------------- 1 | /* __ __ __ __ __ ___ 2 | * \ \ / / \ \ / / __/ 3 | * \ \/ / /\ \ \/ / / 4 | * \____/__/ \__\____/__/.ɪᴏ 5 | * ᶜᵒᵖʸʳᶦᵍʰᵗ ᵇʸ ᵛᵃᵛʳ ⁻ ˡᶦᶜᵉⁿˢᵉᵈ ᵘⁿᵈᵉʳ ᵗʰᵉ ᵃᵖᵃᶜʰᵉ ˡᶦᶜᵉⁿˢᵉ ᵛᵉʳˢᶦᵒⁿ ᵗʷᵒ ᵈᵒᵗ ᶻᵉʳᵒ 6 | */ 7 | package io.vavr.gson; 8 | 9 | import com.google.gson.JsonArray; 10 | import com.google.gson.JsonDeserializationContext; 11 | import com.google.gson.JsonElement; 12 | import com.google.gson.JsonParseException; 13 | import io.vavr.*; 14 | import io.vavr.collection.List; 15 | import io.vavr.collection.Traversable; 16 | 17 | import java.lang.reflect.Type; 18 | 19 | abstract class TupleConverter extends JsonArrayConverter { 20 | 21 | static class N0 extends TupleConverter { 22 | 23 | @Override 24 | Tuple0 create(Object[] arr) { 25 | return Tuple.empty(); 26 | } 27 | 28 | @Override 29 | Traversable toTraversable(Tuple0 src) { 30 | return List.empty(); 31 | } 32 | } 33 | 34 | static class N1 extends TupleConverter> { 35 | 36 | @Override 37 | Tuple1 create(Object[] arr) { 38 | return Tuple.of(arr[0]); 39 | } 40 | 41 | @Override 42 | Traversable toTraversable(Tuple1 src) { 43 | return List.of(src._1); 44 | } 45 | } 46 | 47 | static class N2 extends TupleConverter> { 48 | 49 | @Override 50 | Tuple2 create(Object[] arr) { 51 | return Tuple.of(arr[0], arr[1]); 52 | } 53 | 54 | @Override 55 | Traversable toTraversable(Tuple2 src) { 56 | return List.of(src._1, src._2); 57 | } 58 | } 59 | 60 | static class N3 extends TupleConverter> { 61 | 62 | @Override 63 | Tuple3 create(Object[] arr) { 64 | return Tuple.of(arr[0], arr[1], arr[2]); 65 | } 66 | 67 | @Override 68 | Traversable toTraversable(Tuple3 src) { 69 | return List.of(src._1, src._2, src._3); 70 | } 71 | } 72 | 73 | static class N4 extends TupleConverter> { 74 | 75 | @Override 76 | Tuple4 create(Object[] arr) { 77 | return Tuple.of(arr[0], arr[1], arr[2], arr[3]); 78 | } 79 | 80 | @Override 81 | Traversable toTraversable(Tuple4 src) { 82 | return List.of(src._1, src._2, src._3, src._4); 83 | } 84 | } 85 | 86 | static class N5 extends TupleConverter> { 87 | 88 | @Override 89 | Tuple5 create(Object[] arr) { 90 | return Tuple.of(arr[0], arr[1], arr[2], arr[3], arr[4]); 91 | } 92 | 93 | @Override 94 | Traversable toTraversable(Tuple5 src) { 95 | return List.of(src._1, src._2, src._3, src._4, src._5); 96 | } 97 | } 98 | 99 | static class N6 extends TupleConverter> { 100 | 101 | @Override 102 | Tuple6 create(Object[] arr) { 103 | return Tuple.of(arr[0], arr[1], arr[2], arr[3], arr[4], arr[5]); 104 | } 105 | 106 | @Override 107 | Traversable toTraversable(Tuple6 src) { 108 | return List.of(src._1, src._2, src._3, src._4, src._5, src._6); 109 | } 110 | } 111 | 112 | static class N7 extends TupleConverter> { 113 | 114 | @Override 115 | Tuple7 create(Object[] arr) { 116 | return Tuple.of(arr[0], arr[1], arr[2], arr[3], arr[4], arr[5], arr[6]); 117 | } 118 | 119 | @Override 120 | Traversable toTraversable(Tuple7 src) { 121 | return List.of(src._1, src._2, src._3, src._4, src._5, src._6, src._7); 122 | } 123 | } 124 | 125 | static class N8 extends TupleConverter> { 126 | 127 | @Override 128 | Tuple8 create(Object[] arr) { 129 | return Tuple.of(arr[0], arr[1], arr[2], arr[3], arr[4], arr[5], arr[6], arr[7]); 130 | } 131 | 132 | @Override 133 | Traversable toTraversable(Tuple8 src) { 134 | return List.of(src._1, src._2, src._3, src._4, src._5, src._6, src._7, src._8); 135 | } 136 | } 137 | 138 | abstract T create(Object[] arr); 139 | 140 | @Override 141 | T fromJsonArray(JsonArray json, Type type, Type[] subTypes, JsonDeserializationContext ctx) { 142 | if (subTypes.length > 0 && json.size() != subTypes.length) { 143 | throw new JsonParseException("elements expected: " + subTypes.length); 144 | } 145 | if (json.size() > 8) { 146 | throw new JsonParseException("bad tuple arity"); 147 | } 148 | Object[] arr = new Object[json.size()]; 149 | for (int i = 0; i < json.size(); i++) { 150 | JsonElement el = json.get(i); 151 | arr[i] = subTypes.length > 0 ? ctx.deserialize(el, subTypes[i]) : el; 152 | } 153 | return create(arr); 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /src/main/java/io/vavr/gson/VavrGson.java: -------------------------------------------------------------------------------- 1 | /* __ __ __ __ __ ___ 2 | * \ \ / / \ \ / / __/ 3 | * \ \/ / /\ \ \/ / / 4 | * \____/__/ \__\____/__/.ɪᴏ 5 | * ᶜᵒᵖʸʳᶦᵍʰᵗ ᵇʸ ᵛᵃᵛʳ ⁻ ˡᶦᶜᵉⁿˢᵉᵈ ᵘⁿᵈᵉʳ ᵗʰᵉ ᵃᵖᵃᶜʰᵉ ˡᶦᶜᵉⁿˢᵉ ᵛᵉʳˢᶦᵒⁿ ᵗʷᵒ ᵈᵒᵗ ᶻᵉʳᵒ 6 | */ 7 | package io.vavr.gson; 8 | 9 | import java.lang.reflect.Type; 10 | import java.util.Arrays; 11 | import java.util.Objects; 12 | 13 | import com.google.gson.GsonBuilder; 14 | import io.vavr.*; 15 | import io.vavr.collection.*; 16 | import io.vavr.control.Option; 17 | 18 | /** 19 | * Contains static methods for registering Vavr converters. 20 | */ 21 | public class VavrGson { 22 | 23 | private VavrGson() {} 24 | 25 | /** 26 | * Registers all the Vavr converters. 27 | * @param builder The GSON builder to register the converters with. 28 | * @return A reference to {@code builder}. 29 | */ 30 | public static GsonBuilder registerAll(GsonBuilder builder) { 31 | registerAdapters(builder); 32 | registerTuples(builder); 33 | registerAllCollections(builder); 34 | registerAllMaps(builder); 35 | registerAllMultimaps(builder); 36 | registerLazy(builder); 37 | registerOption(builder); 38 | return builder; 39 | } 40 | 41 | /** 42 | * Registers the {@link Lazy} converter. 43 | * @param builder The GSON builder to register the converters with. 44 | * @return A reference to {@code builder}. 45 | */ 46 | public static GsonBuilder registerLazy(GsonBuilder builder) { 47 | return registerAdapters(builder, Lazy.class); 48 | } 49 | 50 | /** 51 | * Registers the {@link Option} converter. 52 | * @param builder The GSON builder to register the converters with. 53 | * @return A reference to {@code builder}. 54 | */ 55 | public static GsonBuilder registerOption(GsonBuilder builder) { 56 | return registerAdapters(builder).registerTypeHierarchyAdapter(Option.class, new OptionConverter()); 57 | } 58 | 59 | /** 60 | * Registers all the {@link Multimap} converters. 61 | * @param builder The GSON builder to register the converters with. 62 | * @return A reference to {@code builder}. 63 | */ 64 | public static GsonBuilder registerAllMultimaps(GsonBuilder builder) { 65 | registerAdapters(builder); 66 | registerMultimap(builder); 67 | registerSortedMultimap(builder); 68 | registerHashMultimap(builder); 69 | registerLinkedHashMultimap(builder); 70 | registerTreeMultimap(builder); 71 | return builder; 72 | } 73 | 74 | /** 75 | * Registers the {@link HashMultimap} converter. 76 | * @param builder The GSON builder to register the converters with. 77 | * @return A reference to {@code builder}. 78 | */ 79 | public static GsonBuilder registerHashMultimap(GsonBuilder builder) { 80 | return registerAdapters(builder, HashMultimap.class); 81 | } 82 | 83 | /** 84 | * Registers the {@link Multimap} converter. 85 | * @param builder The GSON builder to register the converters with. 86 | * @return A reference to {@code builder}. 87 | */ 88 | public static GsonBuilder registerMultimap(GsonBuilder builder) { 89 | return registerAdapters(builder, Multimap.class); 90 | } 91 | 92 | /** 93 | * Registers the {@link SortedMultimap} converter. 94 | * @param builder The GSON builder to register the converters with. 95 | * @return A reference to {@code builder}. 96 | */ 97 | public static GsonBuilder registerSortedMultimap(GsonBuilder builder) { 98 | return registerAdapters(builder, SortedMultimap.class); 99 | } 100 | 101 | /** 102 | * Registers the {@link LinkedHashMultimap} converter. 103 | * @param builder The GSON builder to register the converters with. 104 | * @return A reference to {@code builder}. 105 | */ 106 | public static GsonBuilder registerLinkedHashMultimap(GsonBuilder builder) { 107 | return registerAdapters(builder, LinkedHashMultimap.class); 108 | } 109 | 110 | /** 111 | * Registers the {@link TreeMultimap} converter. 112 | * @param builder The GSON builder to register the converters with. 113 | * @return A reference to {@code builder}. 114 | */ 115 | public static GsonBuilder registerTreeMultimap(GsonBuilder builder) { 116 | return registerAdapters(builder, TreeMultimap.class); 117 | } 118 | 119 | /** 120 | * Registers all the {@link Map} converters. 121 | * @param builder The GSON builder to register the converters with. 122 | * @return A reference to {@code builder}. 123 | */ 124 | public static GsonBuilder registerAllMaps(GsonBuilder builder) { 125 | registerAdapters(builder); 126 | registerMap(builder); 127 | registerSortedMap(builder); 128 | registerHashMap(builder); 129 | registerLinkedHashMap(builder); 130 | registerTreeMap(builder); 131 | return builder; 132 | } 133 | 134 | /** 135 | * Registers the {@link HashMap} converter. 136 | * @param builder The GSON builder to register the converters with. 137 | * @return A reference to {@code builder}. 138 | */ 139 | public static GsonBuilder registerHashMap(GsonBuilder builder) { 140 | return registerAdapters(builder, HashMap.class); 141 | } 142 | 143 | /** 144 | * Registers the {@link Map} converter. 145 | * @param builder The GSON builder to register the converters with. 146 | * @return A reference to {@code builder}. 147 | */ 148 | public static GsonBuilder registerMap(GsonBuilder builder) { 149 | return registerAdapters(builder, Map.class); 150 | } 151 | 152 | /** 153 | * Registers the {@link SortedMap} converter. 154 | * @param builder The GSON builder to register the converters with. 155 | * @return A reference to {@code builder}. 156 | */ 157 | public static GsonBuilder registerSortedMap(GsonBuilder builder) { 158 | return registerAdapters(builder, SortedMap.class); 159 | } 160 | 161 | /** 162 | * Registers the {@link LinkedHashMap} converter. 163 | * @param builder The GSON builder to register the converters with. 164 | * @return A reference to {@code builder}. 165 | */ 166 | public static GsonBuilder registerLinkedHashMap(GsonBuilder builder) { 167 | return registerAdapters(builder, LinkedHashMap.class); 168 | } 169 | 170 | /** 171 | * Registers the {@link TreeMap} converter. 172 | * @param builder The GSON builder to register the converters with. 173 | * @return A reference to {@code builder}. 174 | */ 175 | public static GsonBuilder registerTreeMap(GsonBuilder builder) { 176 | return registerAdapters(builder, TreeMap.class); 177 | } 178 | 179 | /** 180 | * Registers all the {@link Tuple}s converters. 181 | * @param builder The GSON builder to register the converters with. 182 | * @return A reference to {@code builder}. 183 | */ 184 | public static GsonBuilder registerTuples(GsonBuilder builder) { 185 | return registerAdapters(builder, 186 | Tuple0.class, 187 | Tuple1.class, 188 | Tuple2.class, 189 | Tuple3.class, 190 | Tuple4.class, 191 | Tuple5.class, 192 | Tuple6.class, 193 | Tuple7.class, 194 | Tuple8.class); 195 | } 196 | 197 | /** 198 | * Registers all the collection converters. 199 | * @param builder The GSON builder to register the converters with. 200 | * @return A reference to {@code builder}. 201 | */ 202 | public static GsonBuilder registerAllCollections(GsonBuilder builder) { 203 | registerArray(builder); 204 | registerSeq(builder); 205 | registerIndexedSeq(builder); 206 | registerLinearSeq(builder); 207 | registerList(builder); 208 | registerQueue(builder); 209 | registerStream(builder); 210 | registerVector(builder); 211 | registerSet(builder); 212 | registerSortedSet(builder); 213 | registerHashSet(builder); 214 | registerLinkedHashSet(builder); 215 | registerTreeSet(builder); 216 | registerPriorityQueue(builder); 217 | return builder; 218 | } 219 | 220 | /** 221 | * Registers the {@link PriorityQueue} converter. 222 | * @param builder The GSON builder to register the converters with. 223 | * @return A reference to {@code builder}. 224 | */ 225 | @SuppressWarnings("unchecked") 226 | public static GsonBuilder registerPriorityQueue(GsonBuilder builder) { 227 | return registerAdapters(builder, PriorityQueue.class); 228 | } 229 | 230 | /** 231 | * Registers the {@link HashSet} converter. 232 | * @param builder The GSON builder to register the converters with. 233 | * @return A reference to {@code builder}. 234 | */ 235 | public static GsonBuilder registerHashSet(GsonBuilder builder) { 236 | return registerAdapters(builder, HashSet.class); 237 | } 238 | 239 | /** 240 | * Registers the {@link Set} converter. 241 | * @param builder The GSON builder to register the converters with. 242 | * @return A reference to {@code builder}. 243 | */ 244 | public static GsonBuilder registerSet(GsonBuilder builder) { 245 | return registerAdapters(builder, Set.class); 246 | } 247 | 248 | /** 249 | * Registers the {@link SortedSet} converter. 250 | * @param builder The GSON builder to register the converters with. 251 | * @return A reference to {@code builder}. 252 | */ 253 | @SuppressWarnings("unchecked") 254 | public static GsonBuilder registerSortedSet(GsonBuilder builder) { 255 | return registerAdapters(builder, SortedSet.class); 256 | } 257 | 258 | /** 259 | * Registers the {@link LinkedHashSet} converter. 260 | * @param builder The GSON builder to register the converters with. 261 | * @return A reference to {@code builder}. 262 | */ 263 | public static GsonBuilder registerLinkedHashSet(GsonBuilder builder) { 264 | return registerAdapters(builder, LinkedHashSet.class); 265 | } 266 | 267 | /** 268 | * Registers the {@link TreeSet} converter. 269 | * @param builder The GSON builder to register the converters with. 270 | * @return A reference to {@code builder}. 271 | */ 272 | @SuppressWarnings("unchecked") 273 | public static GsonBuilder registerTreeSet(GsonBuilder builder) { 274 | return registerAdapters(builder, TreeSet.class); 275 | } 276 | 277 | /** 278 | * Registers the {@link Array} converter. 279 | * @param builder The GSON builder to register the converters with. 280 | * @return A reference to {@code builder}. 281 | */ 282 | public static GsonBuilder registerArray(GsonBuilder builder) { 283 | return registerAdapters(builder, Array.class); 284 | } 285 | 286 | /** 287 | * Registers the {@link Seq} converter. 288 | * @param builder The GSON builder to register the converters with. 289 | * @return A reference to {@code builder}. 290 | */ 291 | public static GsonBuilder registerSeq(GsonBuilder builder) { 292 | return registerAdapters(builder, Seq.class); 293 | } 294 | 295 | /** 296 | * Registers the {@link IndexedSeq} converter. 297 | * @param builder The GSON builder to register the converters with. 298 | * @return A reference to {@code builder}. 299 | */ 300 | public static GsonBuilder registerIndexedSeq(GsonBuilder builder) { 301 | return registerAdapters(builder, IndexedSeq.class); 302 | } 303 | 304 | /** 305 | * Registers the {@link LinearSeq} converter. 306 | * @param builder The GSON builder to register the converters with. 307 | * @return A reference to {@code builder}. 308 | */ 309 | public static GsonBuilder registerLinearSeq(GsonBuilder builder) { 310 | return registerAdapters(builder, LinearSeq.class); 311 | } 312 | 313 | /** 314 | * Registers the {@link List} converter. 315 | * @param builder The GSON builder to register the converters with. 316 | * @return A reference to {@code builder}. 317 | */ 318 | public static GsonBuilder registerList(GsonBuilder builder) { 319 | return registerAdapters(builder, List.class); 320 | } 321 | 322 | /** 323 | * Registers the {@link Queue} converter. 324 | * @param builder The GSON builder to register the converters with. 325 | * @return A reference to {@code builder}. 326 | */ 327 | public static GsonBuilder registerQueue(GsonBuilder builder) { 328 | return registerAdapters(builder, Queue.class); 329 | } 330 | 331 | /** 332 | * Registers the {@link Stream} converter. 333 | * @param builder The GSON builder to register the converters with. 334 | * @return A reference to {@code builder}. 335 | */ 336 | public static GsonBuilder registerStream(GsonBuilder builder) { 337 | return registerAdapters(builder, Stream.class); 338 | } 339 | 340 | /** 341 | * Registers the {@link Vector} converter. 342 | * @param builder The GSON builder to register the converters with. 343 | * @return A reference to {@code builder}. 344 | */ 345 | public static GsonBuilder registerVector(GsonBuilder builder) { 346 | return registerAdapters(builder, Vector.class); 347 | } 348 | 349 | public static Map typeAdapters() { 350 | return collectionTypeAdapters() 351 | .merge(tupleTypeAdapters()) 352 | .merge(mapTypeAdapters()) 353 | .merge(multiMapTypeAdapters()) 354 | .merge(lazyTypeAdapters()); 355 | } 356 | 357 | public static Map, Object> typeHierarchyAdapters() { 358 | return API., Object>Map() 359 | .put(List.class, new TraversableConverter<>(List::ofAll)) 360 | .put(Stream.class, new TraversableConverter<>(Stream::ofAll)) 361 | .put(Option.class, new OptionConverter()); 362 | } 363 | 364 | public static Map lazyTypeAdapters() { 365 | return API.Map() 366 | .put(Lazy.class, new LazyConverter()); 367 | } 368 | 369 | public static Map multiMapTypeAdapters() { 370 | return API.Map() 371 | .put(Multimap.class, new MultimapConverter<>(t -> HashMultimap.withSeq().ofEntries(t))) 372 | .put(SortedMultimap.class, new MultimapConverter<>(t -> TreeMultimap.withSeq().ofEntries(t))) 373 | .put(HashMultimap.class, new MultimapConverter<>(t -> HashMultimap.withSeq().ofEntries(t))) 374 | .put(LinkedHashMultimap.class, new MultimapConverter<>(t -> LinkedHashMultimap.withSeq().ofEntries(t))) 375 | .put(TreeMultimap.class, new MultimapConverter<>(t -> TreeMultimap.withSeq().ofEntries(t))); 376 | } 377 | 378 | public static Map mapTypeAdapters() { 379 | return API.Map() 380 | .put(Map.class, new MapConverter<>(HashMap::ofEntries)) 381 | .put(SortedMap.class, new MapConverter<>(TreeMap::ofEntries)) 382 | .put(HashMap.class, new MapConverter<>(HashMap::ofEntries)) 383 | .put(LinkedHashMap.class, new MapConverter<>(LinkedHashMap::ofEntries)) 384 | .put(TreeMap.class, new MapConverter<>(TreeMap::ofEntries)); 385 | } 386 | 387 | public static Map collectionTypeAdapters() { 388 | return API.Map() 389 | .put(Array.class, new TraversableConverter<>(Array::ofAll)) 390 | .put(Seq.class, new TraversableConverter<>(List::ofAll)) 391 | .put(IndexedSeq.class, new TraversableConverter<>(Vector::ofAll)) 392 | .put(LinearSeq.class, new TraversableConverter<>(List::ofAll)) 393 | .put(Queue.class, new TraversableConverter<>(Queue::ofAll)) 394 | .put(Vector.class, new TraversableConverter<>(Vector::ofAll)) 395 | .put(Set.class, new TraversableConverter<>(HashSet::ofAll)) 396 | .put(SortedSet.class, new TraversableConverter<>(it -> TreeSet.ofAll((o1, o2) -> ((Comparable) o1).compareTo(o2), it))) 397 | .put(HashSet.class, new TraversableConverter<>(HashSet::ofAll)) 398 | .put(LinkedHashSet.class, new TraversableConverter<>(LinkedHashSet::ofAll)) 399 | .put(TreeSet.class, new TraversableConverter<>(it -> TreeSet.ofAll((o1, o2) -> ((Comparable) o1).compareTo(o2), it))) 400 | .put(PriorityQueue.class, new TraversableConverter<>(it -> PriorityQueue.ofAll((o1, o2) -> ((Comparable) o1).compareTo(o2), it))); 401 | } 402 | 403 | public static Map tupleTypeAdapters() { 404 | return API.Map(Tuple0.class, new TupleConverter.N0(), 405 | Tuple1.class, new TupleConverter.N1(), 406 | Tuple2.class, new TupleConverter.N2(), 407 | Tuple3.class, new TupleConverter.N3(), 408 | Tuple4.class, new TupleConverter.N4(), 409 | Tuple5.class, new TupleConverter.N5(), 410 | Tuple6.class, new TupleConverter.N6(), 411 | Tuple7.class, new TupleConverter.N7(), 412 | Tuple8.class, new TupleConverter.N8()); 413 | } 414 | 415 | private static GsonBuilder registerAdapters(GsonBuilder builder, Class ...types) { 416 | Objects.requireNonNull(builder, "builder cannot be null"); 417 | List.ofAll(Arrays.asList(types)) 418 | .forEach(type -> { 419 | typeAdapters().get(type).map(adapter -> builder.registerTypeAdapter(type, adapter)); 420 | typeHierarchyAdapters().get(type).map(adapter -> builder.registerTypeHierarchyAdapter(type, adapter)); 421 | }); 422 | return builder; 423 | } 424 | } 425 | -------------------------------------------------------------------------------- /src/test/java/io/vavr/gson/AbstractTest.java: -------------------------------------------------------------------------------- 1 | package io.vavr.gson; 2 | 3 | import com.google.gson.Gson; 4 | import com.google.gson.GsonBuilder; 5 | import org.junit.BeforeClass; 6 | 7 | public class AbstractTest { 8 | 9 | protected static Gson gson; 10 | 11 | @BeforeClass 12 | public static void before() { 13 | GsonBuilder builder = new GsonBuilder(); 14 | VavrGson.registerAll(builder); 15 | gson = builder.create(); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/test/java/io/vavr/gson/LazyTest.java: -------------------------------------------------------------------------------- 1 | package io.vavr.gson; 2 | 3 | import com.google.gson.JsonPrimitive; 4 | import com.google.gson.reflect.TypeToken; 5 | import io.vavr.Lazy; 6 | import org.junit.Test; 7 | 8 | public class LazyTest extends AbstractTest { 9 | 10 | @Test 11 | public void serializeSome() { 12 | assert gson.toJson(Lazy.of(() -> 42)).equals("42"); 13 | } 14 | 15 | @Test 16 | public void deserializeSimpleType() { 17 | Lazy lazy = gson.fromJson("2", Lazy.class); 18 | assert lazy.get() instanceof JsonPrimitive; 19 | assert ((JsonPrimitive) lazy.get()).getAsInt() == 2; 20 | } 21 | 22 | @Test 23 | public void deserialize() { 24 | Lazy lazy = gson.fromJson("1", new TypeToken>(){}.getType()); 25 | assert lazy.get() == 1; 26 | } 27 | 28 | @Test 29 | public void deserializeNested() { 30 | Lazy> lazy = gson.fromJson("1", new TypeToken>>(){}.getType()); 31 | assert lazy.get().get() == 1; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/test/java/io/vavr/gson/OptionTest.java: -------------------------------------------------------------------------------- 1 | package io.vavr.gson; 2 | 3 | import com.google.gson.JsonParseException; 4 | import com.google.gson.JsonPrimitive; 5 | import com.google.gson.reflect.TypeToken; 6 | import io.vavr.control.Option; 7 | import org.junit.Test; 8 | 9 | import java.lang.reflect.Type; 10 | 11 | public class OptionTest extends AbstractTest { 12 | 13 | private static final Type OPT_TYPE = new TypeToken>(){}.getType(); 14 | 15 | @Test(expected = JsonParseException.class) 16 | public void badJson1() { 17 | gson.fromJson("1", OPT_TYPE); 18 | } 19 | 20 | @Test(expected = JsonParseException.class) 21 | public void badJson2() { 22 | gson.fromJson("[\"defined\"]", OPT_TYPE); 23 | } 24 | 25 | @Test(expected = JsonParseException.class) 26 | public void badJson3() { 27 | gson.fromJson("[\"defined\",4,2]", OPT_TYPE); 28 | } 29 | 30 | @Test(expected = JsonParseException.class) 31 | public void badJson4() { 32 | gson.fromJson("[]", OPT_TYPE); 33 | } 34 | 35 | @Test 36 | public void serializeNone() { 37 | assert gson.toJson(Option.none()).equals("[\"undefined\"]"); 38 | } 39 | 40 | @Test 41 | public void serializeSome() { 42 | assert gson.toJson(Option.some(42)).equals("[\"defined\",42]"); 43 | } 44 | 45 | @Test 46 | public void deserializeSimpleType() { 47 | Option opt = gson.fromJson("[\"defined\",2]", Option.class); 48 | assert opt.isDefined(); 49 | assert opt.get() instanceof JsonPrimitive; 50 | assert ((JsonPrimitive) opt.get()).getAsInt() == 2; 51 | } 52 | 53 | @Test 54 | public void deserializeNone() { 55 | Option opt = gson.fromJson("[\"undefined\"]", OPT_TYPE); 56 | assert !opt.isDefined(); 57 | } 58 | 59 | @Test 60 | public void deserializeSome() { 61 | Option opt = gson.fromJson("[\"defined\",2]", OPT_TYPE); 62 | assert opt.isDefined(); 63 | assert opt.get() == 2; 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /src/test/java/io/vavr/gson/VavrGsonTest.java: -------------------------------------------------------------------------------- 1 | package io.vavr.gson; 2 | 3 | import org.junit.Test; 4 | 5 | public class VavrGsonTest { 6 | 7 | @Test(expected = NullPointerException.class) 8 | public void emptyBuilder() { 9 | VavrGson.registerAll(null); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/test/java/io/vavr/gson/collection/ArrayTest.java: -------------------------------------------------------------------------------- 1 | package io.vavr.gson.collection; 2 | 3 | import com.google.gson.reflect.TypeToken; 4 | import io.vavr.collection.Array; 5 | 6 | import java.lang.reflect.Type; 7 | import java.util.Arrays; 8 | 9 | public class ArrayTest extends CollectionTest> { 10 | 11 | @Override 12 | Array of(Object... arr) { 13 | return Array.ofAll(Arrays.asList(arr)); 14 | } 15 | 16 | @Override 17 | Class clz() { 18 | return Array.class; 19 | } 20 | 21 | @Override 22 | Type type() { 23 | return new TypeToken>(){}.getType(); 24 | } 25 | 26 | @Override 27 | Type typeWithNestedType() { 28 | return new TypeToken>>(){}.getType(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/test/java/io/vavr/gson/collection/CollectionTest.java: -------------------------------------------------------------------------------- 1 | package io.vavr.gson.collection; 2 | 3 | import com.google.gson.JsonParseException; 4 | import com.google.gson.JsonPrimitive; 5 | import io.vavr.collection.Traversable; 6 | import io.vavr.gson.AbstractTest; 7 | import org.junit.Test; 8 | 9 | import java.lang.reflect.Type; 10 | 11 | public abstract class CollectionTest> extends AbstractTest { 12 | 13 | abstract T of(Object... arr); 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 | Traversable seq = (Traversable) obj; 33 | assert seq.head() instanceof JsonPrimitive; 34 | assert seq.map(e -> ((JsonPrimitive) e).getAsInt()).equals(of(1, 2)); 35 | } 36 | 37 | @Test 38 | public void deserialize() { 39 | Traversable seq = gson.fromJson("[1,2]", type()); 40 | assert clz().isAssignableFrom(seq.getClass()); 41 | assert seq.head().getClass() == Integer.class; 42 | assert seq.equals(of(1, 2)); 43 | } 44 | 45 | @Test 46 | public void deserializeWithCast() { 47 | Traversable seq = gson.fromJson("[\"1\",\"2\"]", type()); 48 | assert clz().isAssignableFrom(seq.getClass()); 49 | assert seq.head().getClass() == Integer.class; 50 | assert seq.equals(of(1, 2)); 51 | } 52 | 53 | @Test 54 | public void deserializeNested() { 55 | Traversable> seq = gson.fromJson("[[1],[2]]", typeWithNestedType()); 56 | assert clz().isAssignableFrom(seq.head().getClass()); 57 | assert seq.equals(of(of(1), of(2))); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/test/java/io/vavr/gson/collection/HashSetTest.java: -------------------------------------------------------------------------------- 1 | package io.vavr.gson.collection; 2 | 3 | import com.google.gson.reflect.TypeToken; 4 | import io.vavr.collection.HashSet; 5 | 6 | import java.lang.reflect.Type; 7 | import java.util.Arrays; 8 | 9 | public class HashSetTest extends CollectionTest> { 10 | 11 | @Override 12 | HashSet of(Object... arr) { 13 | return HashSet.ofAll(Arrays.asList(arr)); 14 | } 15 | 16 | @Override 17 | Class clz() { 18 | return HashSet.class; 19 | } 20 | 21 | @Override 22 | Type type() { 23 | return new TypeToken>(){}.getType(); 24 | } 25 | 26 | @Override 27 | Type typeWithNestedType() { 28 | return new TypeToken>>(){}.getType(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/test/java/io/vavr/gson/collection/IndexedSeqTest.java: -------------------------------------------------------------------------------- 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> { 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>(){}.getType(); 25 | } 26 | 27 | @Override 28 | Type typeWithNestedType() { 29 | return new TypeToken>>(){}.getType(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/io/vavr/gson/collection/LinearSeqTest.java: -------------------------------------------------------------------------------- 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> { 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>(){}.getType(); 25 | } 26 | 27 | @Override 28 | Type typeWithNestedType() { 29 | return new TypeToken>>(){}.getType(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/io/vavr/gson/collection/LinkedHashSetTest.java: -------------------------------------------------------------------------------- 1 | package io.vavr.gson.collection; 2 | 3 | import com.google.gson.reflect.TypeToken; 4 | import io.vavr.collection.LinkedHashSet; 5 | 6 | import java.lang.reflect.Type; 7 | import java.util.Arrays; 8 | 9 | public class LinkedHashSetTest extends CollectionTest> { 10 | 11 | @Override 12 | LinkedHashSet of(Object... arr) { 13 | return LinkedHashSet.ofAll(Arrays.asList(arr)); 14 | } 15 | 16 | @Override 17 | Class clz() { 18 | return LinkedHashSet.class; 19 | } 20 | 21 | @Override 22 | Type type() { 23 | return new TypeToken>(){}.getType(); 24 | } 25 | 26 | @Override 27 | Type typeWithNestedType() { 28 | return new TypeToken>>(){}.getType(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/test/java/io/vavr/gson/collection/ListTest.java: -------------------------------------------------------------------------------- 1 | package io.vavr.gson.collection; 2 | 3 | import com.google.gson.reflect.TypeToken; 4 | import io.vavr.collection.List; 5 | 6 | import java.lang.reflect.Type; 7 | import java.util.Arrays; 8 | 9 | public class ListTest extends CollectionTest> { 10 | 11 | @Override 12 | List of(Object... arr) { 13 | return List.ofAll(Arrays.asList(arr)); 14 | } 15 | 16 | @Override 17 | Class clz() { 18 | return List.class; 19 | } 20 | 21 | @Override 22 | Type type() { 23 | return new TypeToken>(){}.getType(); 24 | } 25 | 26 | @Override 27 | Type typeWithNestedType() { 28 | return new TypeToken>>(){}.getType(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/test/java/io/vavr/gson/collection/PriorityQueueTest.java: -------------------------------------------------------------------------------- 1 | package io.vavr.gson.collection; 2 | 3 | import com.google.gson.reflect.TypeToken; 4 | import io.vavr.collection.PriorityQueue; 5 | import org.junit.Test; 6 | 7 | import java.lang.reflect.Type; 8 | import java.util.Arrays; 9 | 10 | public class PriorityQueueTest extends CollectionTest> { 11 | 12 | @Override 13 | @SuppressWarnings("unchecked") 14 | PriorityQueue of(Object... arr) { 15 | return PriorityQueue.ofAll((o1, o2) -> ((Comparable) o1).compareTo(o2), Arrays.asList(arr)); 16 | } 17 | 18 | @Override 19 | Class clz() { 20 | return PriorityQueue.class; 21 | } 22 | 23 | @Override 24 | Type type() { 25 | return new TypeToken>(){}.getType(); 26 | } 27 | 28 | @Override 29 | Type typeWithNestedType() { 30 | return new TypeToken>>(){}.getType(); 31 | } 32 | 33 | @Test 34 | @Override 35 | public void deserializeSimpleType() { 36 | // ignore 37 | } 38 | 39 | @Test 40 | @Override 41 | public void deserializeNested() { 42 | // ignore 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/test/java/io/vavr/gson/collection/QueueTest.java: -------------------------------------------------------------------------------- 1 | package io.vavr.gson.collection; 2 | 3 | import com.google.gson.reflect.TypeToken; 4 | import io.vavr.collection.Queue; 5 | 6 | import java.lang.reflect.Type; 7 | import java.util.Arrays; 8 | 9 | public class QueueTest extends CollectionTest> { 10 | 11 | @Override 12 | Queue of(Object... arr) { 13 | return Queue.ofAll(Arrays.asList(arr)); 14 | } 15 | 16 | @Override 17 | Class clz() { 18 | return Queue.class; 19 | } 20 | 21 | @Override 22 | Type type() { 23 | return new TypeToken>(){}.getType(); 24 | } 25 | 26 | @Override 27 | Type typeWithNestedType() { 28 | return new TypeToken>>(){}.getType(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/test/java/io/vavr/gson/collection/SeqTest.java: -------------------------------------------------------------------------------- 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> { 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>(){}.getType(); 25 | } 26 | 27 | @Override 28 | Type typeWithNestedType() { 29 | return new TypeToken>>(){}.getType(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/io/vavr/gson/collection/SetTest.java: -------------------------------------------------------------------------------- 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> { 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>(){}.getType(); 25 | } 26 | 27 | @Override 28 | Type typeWithNestedType() { 29 | return new TypeToken>>(){}.getType(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/io/vavr/gson/collection/SortedSetTest.java: -------------------------------------------------------------------------------- 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> { 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>(){}.getType(); 27 | } 28 | 29 | @Override 30 | Type typeWithNestedType() { 31 | return new TypeToken>>(){}.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 | } 46 | -------------------------------------------------------------------------------- /src/test/java/io/vavr/gson/collection/StreamTest.java: -------------------------------------------------------------------------------- 1 | package io.vavr.gson.collection; 2 | 3 | import com.google.gson.reflect.TypeToken; 4 | import io.vavr.collection.Stream; 5 | 6 | import java.lang.reflect.Type; 7 | import java.util.Arrays; 8 | 9 | public class StreamTest extends CollectionTest> { 10 | 11 | @Override 12 | Stream of(Object... arr) { 13 | return Stream.ofAll(Arrays.asList(arr)); 14 | } 15 | 16 | @Override 17 | Class clz() { 18 | return Stream.class; 19 | } 20 | 21 | @Override 22 | Type type() { 23 | return new TypeToken>(){}.getType(); 24 | } 25 | 26 | @Override 27 | Type typeWithNestedType() { 28 | return new TypeToken>>(){}.getType(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/test/java/io/vavr/gson/collection/TreeSetTest.java: -------------------------------------------------------------------------------- 1 | package io.vavr.gson.collection; 2 | 3 | import com.google.gson.reflect.TypeToken; 4 | import io.vavr.collection.TreeSet; 5 | import org.junit.Test; 6 | 7 | import java.lang.reflect.Type; 8 | import java.util.Arrays; 9 | 10 | public class TreeSetTest extends CollectionTest> { 11 | 12 | @Override 13 | @SuppressWarnings("unchecked") 14 | TreeSet of(Object... arr) { 15 | return TreeSet.ofAll((o1, o2) -> ((Comparable) o1).compareTo(o2), Arrays.asList(arr)); 16 | } 17 | 18 | @Override 19 | Class clz() { 20 | return TreeSet.class; 21 | } 22 | 23 | @Override 24 | Type type() { 25 | return new TypeToken>(){}.getType(); 26 | } 27 | 28 | @Override 29 | Type typeWithNestedType() { 30 | return new TypeToken>>(){}.getType(); 31 | } 32 | 33 | @Test 34 | @Override 35 | public void deserializeSimpleType() { 36 | // ignore 37 | } 38 | 39 | @Test 40 | @Override 41 | public void deserializeNested() { 42 | // ignore 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/test/java/io/vavr/gson/collection/VectorTest.java: -------------------------------------------------------------------------------- 1 | package io.vavr.gson.collection; 2 | 3 | import com.google.gson.reflect.TypeToken; 4 | import io.vavr.collection.Vector; 5 | 6 | import java.lang.reflect.Type; 7 | import java.util.Arrays; 8 | 9 | public class VectorTest extends CollectionTest> { 10 | 11 | @Override 12 | Vector of(Object... arr) { 13 | return Vector.ofAll(Arrays.asList(arr)); 14 | } 15 | 16 | @Override 17 | Class clz() { 18 | return Vector.class; 19 | } 20 | 21 | @Override 22 | Type type() { 23 | return new TypeToken>(){}.getType(); 24 | } 25 | 26 | @Override 27 | Type typeWithNestedType() { 28 | return new TypeToken>>(){}.getType(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/test/java/io/vavr/gson/map/HashMapTest.java: -------------------------------------------------------------------------------- 1 | package io.vavr.gson.map; 2 | 3 | import com.google.gson.reflect.TypeToken; 4 | import io.vavr.collection.HashMap; 5 | 6 | import java.lang.reflect.Type; 7 | 8 | public class HashMapTest extends MapLikeTest> { 9 | @Override 10 | HashMap of(Object key, Object value) { 11 | return HashMap.of(key, value); 12 | } 13 | 14 | @Override 15 | Class clz() { 16 | return HashMap.class; 17 | } 18 | 19 | @Override 20 | Type type() { 21 | return new TypeToken>(){}.getType(); 22 | } 23 | 24 | @Override 25 | Type typeWithNestedType() { 26 | return new TypeToken>>(){}.getType(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/java/io/vavr/gson/map/LinkedHashMapTest.java: -------------------------------------------------------------------------------- 1 | package io.vavr.gson.map; 2 | 3 | import com.google.gson.reflect.TypeToken; 4 | import io.vavr.collection.LinkedHashMap; 5 | 6 | import java.lang.reflect.Type; 7 | 8 | public class LinkedHashMapTest extends MapLikeTest> { 9 | @Override 10 | LinkedHashMap of(Object key, Object value) { 11 | return LinkedHashMap.of(key, value); 12 | } 13 | 14 | @Override 15 | Class clz() { 16 | return LinkedHashMap.class; 17 | } 18 | 19 | @Override 20 | Type type() { 21 | return new TypeToken>(){}.getType(); 22 | } 23 | 24 | @Override 25 | Type typeWithNestedType() { 26 | return new TypeToken>>(){}.getType(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/java/io/vavr/gson/map/MapLikeTest.java: -------------------------------------------------------------------------------- 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> 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 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 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> 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 | } 58 | -------------------------------------------------------------------------------- /src/test/java/io/vavr/gson/map/MapTest.java: -------------------------------------------------------------------------------- 1 | package io.vavr.gson.map; 2 | 3 | import com.google.gson.reflect.TypeToken; 4 | import io.vavr.collection.HashMap; 5 | import io.vavr.collection.Map; 6 | 7 | import java.lang.reflect.Type; 8 | 9 | public class MapTest extends MapLikeTest> { 10 | @Override 11 | Map of(Object key, Object value) { 12 | return HashMap.of(key, value); 13 | } 14 | 15 | @Override 16 | Class clz() { 17 | return Map.class; 18 | } 19 | 20 | @Override 21 | Type type() { 22 | return new TypeToken>(){}.getType(); 23 | } 24 | 25 | @Override 26 | Type typeWithNestedType() { 27 | return new TypeToken>>(){}.getType(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/test/java/io/vavr/gson/map/SortedMapTest.java: -------------------------------------------------------------------------------- 1 | package io.vavr.gson.map; 2 | 3 | import com.google.gson.reflect.TypeToken; 4 | import io.vavr.collection.SortedMap; 5 | import io.vavr.collection.TreeMap; 6 | 7 | import java.lang.reflect.Type; 8 | 9 | public class SortedMapTest extends MapLikeTest> { 10 | @Override 11 | @SuppressWarnings("unchecked") 12 | SortedMap of(Object key, Object value) { 13 | return TreeMap.of((Comparable) key, value); 14 | } 15 | 16 | @Override 17 | Class clz() { 18 | return SortedMap.class; 19 | } 20 | 21 | @Override 22 | Type type() { 23 | return new TypeToken>(){}.getType(); 24 | } 25 | 26 | @Override 27 | Type typeWithNestedType() { 28 | return new TypeToken>>(){}.getType(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/test/java/io/vavr/gson/map/TreeMapTest.java: -------------------------------------------------------------------------------- 1 | package io.vavr.gson.map; 2 | 3 | import com.google.gson.reflect.TypeToken; 4 | import io.vavr.collection.TreeMap; 5 | 6 | import java.lang.reflect.Type; 7 | 8 | public class TreeMapTest extends MapLikeTest> { 9 | @Override 10 | @SuppressWarnings("unchecked") 11 | TreeMap of(Object key, Object value) { 12 | return TreeMap.of((Comparable) key, value); 13 | } 14 | 15 | @Override 16 | Class clz() { 17 | return TreeMap.class; 18 | } 19 | 20 | @Override 21 | Type type() { 22 | return new TypeToken>(){}.getType(); 23 | } 24 | 25 | @Override 26 | Type typeWithNestedType() { 27 | return new TypeToken>>(){}.getType(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/test/java/io/vavr/gson/multimap/HashMultimapTest.java: -------------------------------------------------------------------------------- 1 | package io.vavr.gson.multimap; 2 | 3 | import com.google.gson.reflect.TypeToken; 4 | import io.vavr.collection.HashMultimap; 5 | 6 | import java.lang.reflect.Type; 7 | 8 | public class HashMultimapTest extends MultimapLikeTest> { 9 | @Override 10 | HashMultimap of(Object key, Object value) { 11 | return HashMultimap.withSeq().of(key, value); 12 | } 13 | 14 | @Override 15 | Class clz() { 16 | return HashMultimap.class; 17 | } 18 | 19 | @Override 20 | Type type() { 21 | return new TypeToken>(){}.getType(); 22 | } 23 | 24 | @Override 25 | Type typeWithNestedType() { 26 | return new TypeToken>>(){}.getType(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/java/io/vavr/gson/multimap/LinkedHashMultimapTest.java: -------------------------------------------------------------------------------- 1 | package io.vavr.gson.multimap; 2 | 3 | import com.google.gson.reflect.TypeToken; 4 | import io.vavr.collection.LinkedHashMultimap; 5 | 6 | import java.lang.reflect.Type; 7 | 8 | public class LinkedHashMultimapTest extends MultimapLikeTest> { 9 | @Override 10 | LinkedHashMultimap of(Object key, Object value) { 11 | return LinkedHashMultimap.withSeq().of(key, value); 12 | } 13 | 14 | @Override 15 | Class clz() { 16 | return LinkedHashMultimap.class; 17 | } 18 | 19 | @Override 20 | Type type() { 21 | return new TypeToken>(){}.getType(); 22 | } 23 | 24 | @Override 25 | Type typeWithNestedType() { 26 | return new TypeToken>>(){}.getType(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/java/io/vavr/gson/multimap/MultimapLikeTest.java: -------------------------------------------------------------------------------- 1 | package io.vavr.gson.multimap; 2 | 3 | import com.google.gson.JsonParseException; 4 | import com.google.gson.JsonPrimitive; 5 | import io.vavr.collection.List; 6 | import io.vavr.collection.Multimap; 7 | import io.vavr.gson.AbstractTest; 8 | import org.junit.Test; 9 | 10 | import java.lang.reflect.Type; 11 | 12 | public abstract class MultimapLikeTest> extends AbstractTest { 13 | 14 | abstract T of(Object key, Object value); 15 | abstract Class clz(); 16 | abstract Type type(); 17 | abstract Type typeWithNestedType(); 18 | 19 | @Test(expected = JsonParseException.class) 20 | public void badJson() { 21 | gson.fromJson("1", type()); 22 | } 23 | 24 | @Test 25 | public void serialize() { 26 | assert gson.toJson(of(1, 2)).equals("{\"1\":[2]}"); 27 | } 28 | 29 | @Test 30 | public void deserializeSimpleType() { 31 | Object obj = gson.fromJson("{\"1\":[2]}", clz()); 32 | assert clz().isAssignableFrom(obj.getClass()); 33 | Multimap map = (Multimap) obj; 34 | assert map.head()._2 instanceof JsonPrimitive; 35 | assert ((JsonPrimitive) map.head()._2).getAsInt() == 2; 36 | } 37 | 38 | @Test 39 | public void deserialize() { 40 | Multimap map = gson.fromJson("{\"1\":[2]}", type()); 41 | assert clz().isAssignableFrom(map.getClass()); 42 | assert map.get("1").get().equals(List.of(2)); 43 | } 44 | 45 | @Test 46 | public void deserializeWithCast() { 47 | Multimap map = gson.fromJson("{\"1\":[\"2\"]}", type()); 48 | assert clz().isAssignableFrom(map.getClass()); 49 | assert map.get("1").get().equals(List.of(2)); 50 | } 51 | 52 | @Test 53 | public void deserializeNested() { 54 | Multimap> map = gson.fromJson("{\"1\":[{\"2\":[3]}]}", typeWithNestedType()); 55 | assert clz().isAssignableFrom(map.get("1").get().head().getClass()); 56 | assert map.get("1").get().head().get("2").get().equals(List.of(3)); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/test/java/io/vavr/gson/multimap/MultimapTest.java: -------------------------------------------------------------------------------- 1 | package io.vavr.gson.multimap; 2 | 3 | import com.google.gson.reflect.TypeToken; 4 | import io.vavr.collection.HashMultimap; 5 | import io.vavr.collection.Multimap; 6 | 7 | import java.lang.reflect.Type; 8 | 9 | public class MultimapTest extends MultimapLikeTest> { 10 | @Override 11 | Multimap of(Object key, Object value) { 12 | return HashMultimap.withSeq().of(key, value); 13 | } 14 | 15 | @Override 16 | Class clz() { 17 | return Multimap.class; 18 | } 19 | 20 | @Override 21 | Type type() { 22 | return new TypeToken>(){}.getType(); 23 | } 24 | 25 | @Override 26 | Type typeWithNestedType() { 27 | return new TypeToken>>(){}.getType(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/test/java/io/vavr/gson/multimap/SortedMultimapTest.java: -------------------------------------------------------------------------------- 1 | package io.vavr.gson.multimap; 2 | 3 | import com.google.gson.reflect.TypeToken; 4 | import io.vavr.collection.SortedMultimap; 5 | import io.vavr.collection.TreeMultimap; 6 | 7 | import java.lang.reflect.Type; 8 | 9 | public class SortedMultimapTest extends MultimapLikeTest> { 10 | @Override 11 | @SuppressWarnings("unchecked") 12 | SortedMultimap of(Object key, Object value) { 13 | return TreeMultimap.withSeq().of((Comparable) key, value); 14 | } 15 | 16 | @Override 17 | Class clz() { 18 | return SortedMultimap.class; 19 | } 20 | 21 | @Override 22 | Type type() { 23 | return new TypeToken>(){}.getType(); 24 | } 25 | 26 | @Override 27 | Type typeWithNestedType() { 28 | return new TypeToken>>(){}.getType(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/test/java/io/vavr/gson/multimap/TreeMultimapTest.java: -------------------------------------------------------------------------------- 1 | package io.vavr.gson.multimap; 2 | 3 | import com.google.gson.reflect.TypeToken; 4 | import io.vavr.collection.TreeMultimap; 5 | 6 | import java.lang.reflect.Type; 7 | 8 | public class TreeMultimapTest extends MultimapLikeTest> { 9 | @Override 10 | @SuppressWarnings("unchecked") 11 | TreeMultimap of(Object key, Object value) { 12 | return TreeMultimap.withSeq().of((Comparable) key, value); 13 | } 14 | 15 | @Override 16 | Class clz() { 17 | return TreeMultimap.class; 18 | } 19 | 20 | @Override 21 | Type type() { 22 | return new TypeToken>(){}.getType(); 23 | } 24 | 25 | @Override 26 | Type typeWithNestedType() { 27 | return new TypeToken>>(){}.getType(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/test/java/io/vavr/gson/tuples/Tuple0Test.java: -------------------------------------------------------------------------------- 1 | package io.vavr.gson.tuples; 2 | 3 | import com.google.gson.reflect.TypeToken; 4 | import io.vavr.Tuple; 5 | import io.vavr.Tuple0; 6 | import io.vavr.gson.AbstractTest; 7 | import org.junit.Test; 8 | 9 | public class Tuple0Test extends AbstractTest { 10 | 11 | @Test 12 | public void serialize() { 13 | Tuple0 t = Tuple.empty(); 14 | assert gson.toJson(t).equals("[]"); 15 | } 16 | 17 | @Test 18 | public void deserialize() { 19 | Tuple0 t = gson.fromJson("[]", new TypeToken(){}.getType()); 20 | assert t != null; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/test/java/io/vavr/gson/tuples/Tuple1Test.java: -------------------------------------------------------------------------------- 1 | package io.vavr.gson.tuples; 2 | 3 | import com.google.gson.reflect.TypeToken; 4 | import io.vavr.Tuple; 5 | import io.vavr.Tuple1; 6 | import io.vavr.gson.AbstractTest; 7 | import org.junit.Test; 8 | 9 | public class Tuple1Test extends AbstractTest { 10 | 11 | @Test 12 | public void serialize() { 13 | Tuple1 t = Tuple.of(1); 14 | assert gson.toJson(t).equals("[1]"); 15 | } 16 | 17 | @Test 18 | public void deserialize() { 19 | Tuple1 t = 20 | gson.fromJson("[1]", new TypeToken>(){}.getType()); 21 | assert t._1.equals(1); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/test/java/io/vavr/gson/tuples/Tuple2Test.java: -------------------------------------------------------------------------------- 1 | package io.vavr.gson.tuples; 2 | 3 | import com.google.gson.reflect.TypeToken; 4 | import io.vavr.Tuple; 5 | import io.vavr.Tuple2; 6 | import io.vavr.gson.AbstractTest; 7 | import org.junit.Test; 8 | 9 | public class Tuple2Test extends AbstractTest { 10 | 11 | @Test 12 | public void serialize() { 13 | Tuple2 t = Tuple.of(1, 2); 14 | assert gson.toJson(t).equals("[1,2]"); 15 | } 16 | 17 | @Test 18 | public void deserialize() { 19 | Tuple2 t = 20 | gson.fromJson("[1,2]", new TypeToken>(){}.getType()); 21 | assert t._1.equals(1); 22 | assert t._2.equals(2f); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/test/java/io/vavr/gson/tuples/Tuple3Test.java: -------------------------------------------------------------------------------- 1 | package io.vavr.gson.tuples; 2 | 3 | import com.google.gson.reflect.TypeToken; 4 | import io.vavr.Tuple; 5 | import io.vavr.Tuple3; 6 | import io.vavr.gson.AbstractTest; 7 | import org.junit.Test; 8 | 9 | public class Tuple3Test extends AbstractTest { 10 | 11 | @Test 12 | public void serialize() { 13 | Tuple3 t = Tuple.of(1, 2, 3); 14 | assert gson.toJson(t).equals("[1,2,3]"); 15 | } 16 | 17 | @Test 18 | public void deserialize() { 19 | Tuple3 t = 20 | gson.fromJson("[1,2,3]", new TypeToken>(){}.getType()); 21 | assert t._1.equals(1); 22 | assert t._2.equals(2f); 23 | assert t._3.equals(3.0); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/test/java/io/vavr/gson/tuples/Tuple4Test.java: -------------------------------------------------------------------------------- 1 | package io.vavr.gson.tuples; 2 | 3 | import com.google.gson.reflect.TypeToken; 4 | import io.vavr.Tuple; 5 | import io.vavr.Tuple4; 6 | import io.vavr.gson.AbstractTest; 7 | import org.junit.Test; 8 | 9 | public class Tuple4Test extends AbstractTest { 10 | 11 | @Test 12 | public void serialize() { 13 | Tuple4 t = Tuple.of(1, 2, 3, 4); 14 | assert gson.toJson(t).equals("[1,2,3,4]"); 15 | } 16 | 17 | @Test 18 | public void deserialize() { 19 | Tuple4 t = 20 | gson.fromJson("[1,2,3,4]", new TypeToken>(){}.getType()); 21 | assert t._1.equals(1); 22 | assert t._2.equals(2f); 23 | assert t._3.equals(3.0); 24 | assert t._4.equals("4"); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/test/java/io/vavr/gson/tuples/Tuple5Test.java: -------------------------------------------------------------------------------- 1 | package io.vavr.gson.tuples; 2 | 3 | import com.google.gson.reflect.TypeToken; 4 | import io.vavr.Tuple; 5 | import io.vavr.Tuple5; 6 | import io.vavr.gson.AbstractTest; 7 | import org.junit.Test; 8 | 9 | public class Tuple5Test extends AbstractTest { 10 | 11 | @Test 12 | public void serialize() { 13 | Tuple5 t = Tuple.of(1, 2, 3, 4, 5); 14 | assert gson.toJson(t).equals("[1,2,3,4,5]"); 15 | } 16 | 17 | @Test 18 | public void deserialize() { 19 | Tuple5 t = 20 | gson.fromJson("[1,2,3,4,5]", new TypeToken>(){}.getType()); 21 | assert t._1.equals(1); 22 | assert t._2.equals(2f); 23 | assert t._3.equals(3.0); 24 | assert t._4.equals("4"); 25 | assert t._5.equals(5); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/test/java/io/vavr/gson/tuples/Tuple6Test.java: -------------------------------------------------------------------------------- 1 | package io.vavr.gson.tuples; 2 | 3 | import com.google.gson.reflect.TypeToken; 4 | import io.vavr.Tuple; 5 | import io.vavr.Tuple6; 6 | import io.vavr.gson.AbstractTest; 7 | import org.junit.Test; 8 | 9 | public class Tuple6Test extends AbstractTest { 10 | 11 | @Test 12 | public void serialize() { 13 | Tuple6 t = Tuple.of(1, 2, 3, 4, 5, 6); 14 | assert gson.toJson(t).equals("[1,2,3,4,5,6]"); 15 | } 16 | 17 | @Test 18 | public void deserialize() { 19 | Tuple6 t = 20 | gson.fromJson("[1,2,3,4,5,6]", new TypeToken>(){}.getType()); 21 | assert t._1.equals(1); 22 | assert t._2.equals(2f); 23 | assert t._3.equals(3.0); 24 | assert t._4.equals("4"); 25 | assert t._5.equals(5); 26 | assert t._6.equals(6); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/java/io/vavr/gson/tuples/Tuple7Test.java: -------------------------------------------------------------------------------- 1 | package io.vavr.gson.tuples; 2 | 3 | import com.google.gson.reflect.TypeToken; 4 | import io.vavr.Tuple; 5 | import io.vavr.Tuple7; 6 | import io.vavr.gson.AbstractTest; 7 | import org.junit.Test; 8 | 9 | public class Tuple7Test extends AbstractTest { 10 | 11 | @Test 12 | public void serialize() { 13 | Tuple7 t = Tuple.of(1, 2, 3, 4, 5, 6, 7); 14 | assert gson.toJson(t).equals("[1,2,3,4,5,6,7]"); 15 | } 16 | 17 | @Test 18 | public void deserialize() { 19 | Tuple7 t = 20 | gson.fromJson("[1,2,3,4,5,6,7]", new TypeToken>(){}.getType()); 21 | assert t._1.equals(1); 22 | assert t._2.equals(2f); 23 | assert t._3.equals(3.0); 24 | assert t._4.equals("4"); 25 | assert t._5.equals(5); 26 | assert t._6.equals(6); 27 | assert t._7.equals(7); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/test/java/io/vavr/gson/tuples/Tuple8Test.java: -------------------------------------------------------------------------------- 1 | package io.vavr.gson.tuples; 2 | 3 | import com.google.gson.reflect.TypeToken; 4 | import io.vavr.Tuple; 5 | import io.vavr.Tuple8; 6 | import io.vavr.gson.AbstractTest; 7 | import org.junit.Test; 8 | 9 | public class Tuple8Test extends AbstractTest { 10 | 11 | @Test 12 | public void serialize() { 13 | Tuple8 t = Tuple.of(1, 2, 3, 4, 5, 6, 7, 8); 14 | assert gson.toJson(t).equals("[1,2,3,4,5,6,7,8]"); 15 | } 16 | 17 | @Test 18 | public void deserialize() { 19 | Tuple8 t = 20 | gson.fromJson("[1,2,3,4,5,6,7,8]", new TypeToken>(){}.getType()); 21 | assert t._1.equals(1); 22 | assert t._2.equals(2f); 23 | assert t._3.equals(3.0); 24 | assert t._4.equals("4"); 25 | assert t._5.equals(5); 26 | assert t._6.equals(6); 27 | assert t._7.equals(7); 28 | assert t._8.equals(8); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/test/java/io/vavr/gson/tuples/TupleNTest.java: -------------------------------------------------------------------------------- 1 | package io.vavr.gson.tuples; 2 | 3 | import com.google.gson.JsonParseException; 4 | import com.google.gson.JsonPrimitive; 5 | import com.google.gson.reflect.TypeToken; 6 | import io.vavr.Tuple2; 7 | import io.vavr.Tuple8; 8 | import io.vavr.gson.AbstractTest; 9 | import org.junit.Test; 10 | 11 | public class TupleNTest extends AbstractTest { 12 | 13 | @Test(expected = JsonParseException.class) 14 | public void badJson() { 15 | gson.fromJson("1", new TypeToken>(){}.getType()); 16 | } 17 | 18 | @Test(expected = JsonParseException.class) 19 | public void badArrayLength() { 20 | gson.fromJson("[1, 2, 3]", new TypeToken>(){}.getType()); 21 | } 22 | 23 | @Test(expected = JsonParseException.class) 24 | public void tooBigArray() { 25 | gson.fromJson("[1, 2, 3, 4, 5, 6, 7, 8, 9]", Tuple8.class); 26 | } 27 | 28 | @Test 29 | public void deserializeSimpleType() { 30 | Object obj = gson.fromJson("[1,2]", Tuple2.class); 31 | assert obj.getClass() == Tuple2.class; 32 | Tuple2 t = (Tuple2) obj; 33 | assert t._1 instanceof JsonPrimitive; 34 | assert ((JsonPrimitive) t._1).getAsInt() == 1; 35 | assert t._2 instanceof JsonPrimitive; 36 | assert ((JsonPrimitive) t._2).getAsInt() == 2; 37 | } 38 | } 39 | --------------------------------------------------------------------------------