Skip to content

Commit 997ca3d

Browse files
authored
Merge pull request #39 from bowbahdoe/cleanup-feb-20
Add more examples
2 parents afd74ca + acc608f commit 997ca3d

File tree

1 file changed

+282
-1
lines changed

1 file changed

+282
-1
lines changed

README.md

Lines changed: 282 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,7 @@ public class Main {
525525
</details>
526526

527527
### Decode an object with optional fields.
528+
528529
<details>
529530
<summary>Show</summary>
530531

@@ -676,6 +677,53 @@ public class Main {
676677

677678
</details>
678679

680+
### Decode json with a fixed set of keys
681+
682+
<details>
683+
<summary>Show</summary>
684+
685+
```java
686+
import dev.mccue.json.Json;
687+
import dev.mccue.json.JsonDecodeException;
688+
import dev.mccue.json.JsonDecoder;
689+
690+
import java.util.HashSet;
691+
import java.util.Set;
692+
693+
record Prison(String location) {
694+
public static Prison fromJson(Json json) {
695+
var object = JsonDecoder.object(json);
696+
var expected = Set.of("location");
697+
if (!expected.equals(object.keySet())) {
698+
var extra = new HashSet<>(object.keySet());
699+
extra.removeAll(expected);
700+
throw JsonDecodeException.of("Extra Keys: " + extra, json);
701+
}
702+
703+
return new Prison(
704+
JsonDecoder.field(json, "location", JsonDecoder::string)
705+
);
706+
}
707+
}
708+
public class Main {
709+
public static void main(String[] args) {
710+
Json withExtraKeys = Json.readString(
711+
"""
712+
{
713+
"location": "Siberia",
714+
"escapeMethod": "tunnelling"
715+
}
716+
"""
717+
);
718+
719+
var prison = Prison.fromJson(withExtraKeys);
720+
}
721+
}
722+
```
723+
724+
</details>
725+
726+
679727
### Decode json into bean
680728

681729
<details>
@@ -736,7 +784,11 @@ public class Main {
736784
var fozzie = new Fozzie();
737785
fozzie.setJoke(JsonDecoder.field(json, "joke", JsonDecoder::string));
738786
fozzie.setPunchline(JsonDecoder.field(json, "punchline", JsonDecoder::string));
739-
fozzie.setHecklers(JsonDecoder.field(json, "hecklers", JsonDecoder.array(JsonDecoder::string)));
787+
fozzie.setHecklers(JsonDecoder.field(
788+
json,
789+
"hecklers",
790+
JsonDecoder.array(JsonDecoder::string)
791+
));
740792
return fozzie;
741793
}
742794

@@ -817,4 +869,233 @@ public class Main {
817869
[Person[firstName=Great, lastName=Gonzo], Person[firstName=Jim, lastName=Henson]]
818870
```
819871

872+
</details>
873+
874+
### Encode and Decode with Kotlin
875+
876+
<details>
877+
<summary>Show</summary>
878+
879+
```kotlin
880+
import dev.mccue.json.Json
881+
import dev.mccue.json.JsonDecoder
882+
import dev.mccue.json.JsonEncodable
883+
import dev.mccue.json.JsonWriteOptions
884+
885+
data class Muppet(
886+
val name: String,
887+
val scientist: Boolean,
888+
val lines: String?
889+
) : JsonEncodable {
890+
override fun toJson(): Json =
891+
Json.objectBuilder()
892+
.put("name", name)
893+
.put("scientist", scientist)
894+
.put("lines", lines)
895+
.build()
896+
897+
companion object {
898+
fun fromJson(json: Json): Muppet =
899+
Muppet(
900+
JsonDecoder.field(json, "name") { JsonDecoder.string(it) },
901+
JsonDecoder.field(json, "scientist") { JsonDecoder.boolean_(it) },
902+
JsonDecoder.nullableField(json,
903+
"lines",
904+
{ JsonDecoder.string(it) },
905+
null
906+
)
907+
)
908+
}
909+
}
910+
911+
912+
913+
data class Movie(
914+
val title: String,
915+
val muppets: List<Muppet>
916+
) : JsonEncodable {
917+
override fun toJson(): Json {
918+
return Json.objectBuilder()
919+
.put("title", title)
920+
.put("muppets", muppets)
921+
.build()
922+
}
923+
924+
companion object {
925+
fun fromJson(json: Json): Movie =
926+
Movie(
927+
JsonDecoder.field(json, "title") { JsonDecoder.string(it) },
928+
JsonDecoder.field(json, "muppets", JsonDecoder.array { Muppet.fromJson(it) })
929+
)
930+
}
931+
}
932+
933+
934+
fun main(args: Array<String>) {
935+
val movie = Movie(
936+
"Most wanted",
937+
listOf(
938+
Muppet(
939+
"kermit",
940+
false,
941+
"I'm not Constantine!"
942+
),
943+
Muppet(
944+
"beaker",
945+
true,
946+
null
947+
),
948+
Muppet(
949+
"bunsen",
950+
true,
951+
"I don't mean to be a stickler"
952+
)
953+
)
954+
)
955+
956+
println(Json.writeString(movie, JsonWriteOptions().withIndentation(4)))
957+
958+
val movieRoundTripped = Movie.fromJson(Json.readString(Json.writeString(movie)))
959+
960+
println(movieRoundTripped)
961+
println(movie)
962+
println(movie == movieRoundTripped)
963+
}
964+
```
965+
966+
```
967+
{
968+
"title": "Most wanted",
969+
"muppets": [
970+
{
971+
"name": "kermit",
972+
"scientist": false,
973+
"lines": "I'm not Constantine!"
974+
},
975+
{
976+
"name": "beaker",
977+
"scientist": true,
978+
"lines": null
979+
},
980+
{
981+
"name": "bunsen",
982+
"scientist": true,
983+
"lines": "I don't mean to be a stickler"
984+
}
985+
]
986+
}
987+
Movie(title=Most wanted, muppets=[Muppet(name=kermit, scientist=false, lines=I'm not Constantine!), Muppet(name=beaker, scientist=true, lines=null), Muppet(name=bunsen, scientist=true, lines=I don't mean to be a stickler)])
988+
Movie(title=Most wanted, muppets=[Muppet(name=kermit, scientist=false, lines=I'm not Constantine!), Muppet(name=beaker, scientist=true, lines=null), Muppet(name=bunsen, scientist=true, lines=I don't mean to be a stickler)])
989+
true
990+
```
991+
992+
</details>
993+
994+
### Encode and Decode with Scala 3
995+
996+
<details>
997+
<summary>Show</summary>
998+
999+
```scala
1000+
import dev.mccue.json.{Json, JsonDecoder, JsonEncodable, JsonWriteOptions}
1001+
1002+
import scala.jdk.CollectionConverters._
1003+
1004+
case class Muppet(name: String, scientist: Boolean, lines: Option[String]) extends JsonEncodable {
1005+
override def toJson: Json =
1006+
Json.objectBuilder()
1007+
.put("name", name)
1008+
.put("scientist", scientist)
1009+
.put("lines", lines.orNull)
1010+
.build
1011+
}
1012+
1013+
object Muppet {
1014+
def fromJson(json: Json): Muppet =
1015+
Muppet(
1016+
JsonDecoder.field(json, "name", JsonDecoder.string _),
1017+
JsonDecoder.field(json, "scientist", JsonDecoder.boolean_ _),
1018+
JsonDecoder.nullableField(json, "name", JsonDecoder.string _)
1019+
.map(Option(_))
1020+
.orElse(None)
1021+
)
1022+
}
1023+
1024+
case class Movie(title: String, muppets: Seq[Muppet]) extends JsonEncodable {
1025+
override def toJson: Json =
1026+
Json.objectBuilder()
1027+
.put("title", title)
1028+
.put("muppets", muppets.asJava)
1029+
.build()
1030+
}
1031+
1032+
object Movie {
1033+
def fromJson(json: Json): Movie =
1034+
Movie(
1035+
JsonDecoder.field(json, "title", JsonDecoder.string _),
1036+
JsonDecoder.field(json, "muppets", JsonDecoder.array(Muppet.fromJson _))
1037+
.asScala
1038+
.toSeq
1039+
)
1040+
}
1041+
1042+
1043+
@main
1044+
def main(): Unit = {
1045+
val movie = Movie(
1046+
"Most wanted",
1047+
Seq(
1048+
Muppet(
1049+
"kermit",
1050+
false,
1051+
Some("I'm not Constantine!")
1052+
),
1053+
Muppet(
1054+
"beaker",
1055+
true,
1056+
None
1057+
),
1058+
Muppet(
1059+
"bunsen",
1060+
true,
1061+
Some("I don't mean to be a stickler")
1062+
)
1063+
)
1064+
)
1065+
1066+
println(Json.writeString(movie, JsonWriteOptions().withIndentation(4)))
1067+
1068+
val movieRoundTripped = Movie.fromJson(Json.readString(Json.writeString(movie)))
1069+
1070+
println(movieRoundTripped)
1071+
println(movie)
1072+
println(movie == movieRoundTripped)
1073+
}
1074+
```
1075+
1076+
```
1077+
{
1078+
"title": "Most wanted",
1079+
"muppets": [
1080+
{
1081+
"name": "kermit",
1082+
"scientist": false,
1083+
"lines": "I'm not Constantine!"
1084+
},
1085+
{
1086+
"name": "beaker",
1087+
"scientist": true,
1088+
"lines": null
1089+
},
1090+
{
1091+
"name": "bunsen",
1092+
"scientist": true,
1093+
"lines": "I don't mean to be a stickler"
1094+
}
1095+
]
1096+
}
1097+
Movie(Most wanted,List(Muppet(kermit,false,Some(kermit)), Muppet(beaker,true,Some(beaker)), Muppet(bunsen,true,Some(bunsen))))
1098+
Movie(Most wanted,List(Muppet(kermit,false,Some(I'm not Constantine!)), Muppet(beaker,true,None), Muppet(bunsen,true,Some(I don't mean to be a stickler))))
1099+
false
1100+
```
8201101
</details>

0 commit comments

Comments
 (0)