|
25 | 25 | ) |
26 | 26 | ) |
27 | 27 |
|
28 | | -@sect("uPickle 3.3.1") |
| 28 | +@sect("uPickle 4.0.0-RC1") |
29 | 29 | @div(display.flex, alignItems.center, flexDirection.column) |
30 | 30 | @div |
31 | 31 | @a(href := "https://gitter.im/lihaoyi/upickle")( |
|
74 | 74 |
|
75 | 75 | @sect{Getting Started} |
76 | 76 | @hl.scala |
77 | | - "com.lihaoyi" %% "upickle" % "3.3.1" // SBT |
78 | | - ivy"com.lihaoyi::upickle:3.3.1" // Mill |
| 77 | + "com.lihaoyi" %% "upickle" % "4.0.0-RC1" // SBT |
| 78 | + ivy"com.lihaoyi::upickle:4.0.0-RC1" // Mill |
79 | 79 |
|
80 | 80 | @p |
81 | 81 | And then you can immediately start writing and reading common Scala |
|
93 | 93 | @p |
94 | 94 | For ScalaJS applications, use this dependencies instead: |
95 | 95 | @hl.scala |
96 | | - "com.lihaoyi" %%% "upickle" % "3.3.1" // SBT |
97 | | - ivy"com.lihaoyi::upickle::3.3.1" // Mill |
| 96 | + "com.lihaoyi" %%% "upickle" % "4.0.0-RC1" // SBT |
| 97 | + ivy"com.lihaoyi::upickle::4.0.0-RC1" // Mill |
98 | 98 |
|
99 | 99 | @sect{Scala Versions} |
100 | 100 | @p |
|
148 | 148 | @hl.ref(exampleTests, Seq("\"more\"", "\"seqs\"", "")) |
149 | 149 |
|
150 | 150 | @p |
151 | | - @code{Option}s are serialized as JSON lists with 0 or 1 element |
| 151 | + @code{Option}s are serialized as nullable values |
152 | 152 |
|
153 | 153 | @hl.ref(exampleTests, Seq("\"more\"", "\"options\"", "")) |
154 | 154 |
|
|
185 | 185 | After that, you can begin serializing that case class. |
186 | 186 |
|
187 | 187 | @hl.ref(exampleTests, Seq("object Simple", "")) |
188 | | - @hl.ref(exampleTests, Seq("\"more\"", "\"caseClass\"", ""), " }") |
| 188 | + @hl.ref(exampleTests, Seq("\"more\"", "\"caseClass\"", "")) |
189 | 189 |
|
190 | 190 | @p |
191 | 191 | Sealed hierarchies are serialized as tagged values, the serialized |
|
253 | 253 |
|
254 | 254 | Nulls serialize into JSON nulls, as you would expect |
255 | 255 |
|
256 | | - @hl.ref(exampleTests, Seq("\"more\"", "\"null\"", ""), " }") |
| 256 | + @hl.ref(exampleTests, Seq("test(\"null\")", "")) |
257 | 257 |
|
258 | 258 | @p |
259 | 259 | uPickle only throws exceptions on unpickling; if a pickler is |
|
291 | 291 | make the default @hl.scala{None}) and uPickle will happily read the |
292 | 292 | old data, filling in the missing field using the default value. |
293 | 293 |
|
| 294 | + @p |
| 295 | + You can enable serialization of default values a per-field or per-case-class basis |
| 296 | + using the @hl.scala{@@upickle.implicits.serializeDefaults(true)} |
| 297 | + annotation on that field or @hl.scala{case class}, or globally on a |
| 298 | + @sect.ref{Custom Configuration} via @hl.scala{override def serializeDefaults = true} |
| 299 | + |
294 | 300 | @sect{Supported Types} |
295 | 301 | @p |
296 | 302 | Out of the box, uPickle supports writing and reading the following types: |
|
328 | 334 | serializable up to 64 fields. |
329 | 335 |
|
330 | 336 | @p |
331 | | - Case classes are serialized using the @hl.scala{apply} and |
332 | | - @hl.scala{unapply} methods on their companion objects. This means that |
333 | | - you can make your own classes serializable by giving them companions |
334 | | - @hl.scala{apply} and @hl.scala{unapply}. @hl.scala{sealed} hierarchies |
335 | | - are serialized as tagged unions: whatever the serialization of the |
336 | | - actual object, together with the fully-qualified name of its class, so |
337 | | - the correct class in the sealed hierarchy can be reconstituted later. |
| 337 | + Case classes are de-serialized using the @hl.scala{apply} method on their |
| 338 | + companion objects. @hl.scala{sealed} hierarchies |
| 339 | + are serialized as tagged unions: whatever the serialization of the |
| 340 | + actual object, together with the partially-qualified name of its class |
| 341 | + in a @hl.scala{"$type": "..."} field, so |
| 342 | + the correct class in the sealed hierarchy can be reconstituted later. |
338 | 343 |
|
339 | 344 | @p |
340 | 345 | That concludes the list of supported types. Anything else is not supported |
|
378 | 383 |
|
379 | 384 | @sect{Custom Keys} |
380 | 385 | @p |
381 | | - |
382 | 386 | uPickle allows you to specify the key that a field is serialized with |
383 | 387 | via a @hl.scala{@@key} annotation |
384 | 388 |
|
385 | | - |
386 | 389 | @hl.ref(exampleTests, Seq("object Keyed", "")) |
387 | 390 | @hl.ref(exampleTests, Seq("\"keyed\"", "\"attrs\"", "")) |
388 | 391 |
|
|
428 | 431 | This is useful in cases where you need to override uPickle's default |
429 | 432 | behavior, for example to preserve compatibility with another JSON library. |
430 | 433 |
|
| 434 | + |
| 435 | + |
431 | 436 | @sect{JSON Dictionary Formats} |
432 | 437 | @p |
433 | 438 | By default, serializing a @hl.scala{Map[K, V]} generates a nested |
|
464 | 469 | the restriction that dictionary keys can only be strings: |
465 | 470 |
|
466 | 471 | @hl.ref(exampleTests, Seq("msgPackMapKeys", "")) |
| 472 | + @sect{Other Per-Case-Class Annotations} |
| 473 | + @p |
| 474 | + The full list of annotations that can be applied to @hl.scala{case class}es |
| 475 | + and @hl.scala{sealed trait}s is below: |
| 476 | + |
| 477 | + @hl.ref(wd / "upickle" / "implicits" / "src" / "upickle" / "implicits" / "key.scala", Nil) |
467 | 478 |
|
468 | 479 | @sect{Custom Configuration} |
469 | 480 | @p |
|
586 | 597 | @p |
587 | 598 | uJson comes with some convenient utilities on the `ujson` package: |
588 | 599 |
|
589 | | - @hl.ref(wd/'ujson/'src/'ujson/"package.scala", Seq("package object ujson", ""), "// End ujson") |
| 600 | + @hl.ref(wd/'ujson/'src/'ujson/"package.scala", Seq("package object ujson")) |
590 | 601 |
|
591 | 602 | @sect{Transformations} |
592 | 603 | @p |
|
904 | 915 | JSON library, and inherits a lot of it's performance from Erik's work. |
905 | 916 |
|
906 | 917 | @sect{Version History} |
| 918 | + @sect{4.0.0-RC1} |
| 919 | + @ul |
| 920 | + @li |
| 921 | + @b{4.0.0 is a major breaking change in uPickle, including in the serialization |
| 922 | + format for many common data types (@hl.scala{Option}s, @hl.scala{sealed trait}s, |
| 923 | + etc.), as well as breaking binary compatibility. Please be |
| 924 | + careful upgrading and follow the instructions below.} |
| 925 | + @li |
| 926 | + uPickle 4.0.0-RC1 is a release candidate. It breaks backwards compatibility with |
| 927 | + uPickle 3.x (binary and serialization), but makes no promises for compatibility |
| 928 | + with uPickle 4.0.0 final. Hopefully nothing will need to change between 4.0.0-RC1 |
| 929 | + and 4.0.0 final, but it cannot be guaranteed. |
| 930 | + @li |
| 931 | + Shorten @code{$type} tag used for discriminating @hl.scala{sealed trait} cases |
| 932 | + @lnk("#594", "https://github.com/com-lihaoyi/upickle/pull/596") |
| 933 | + @li |
| 934 | + Unbox first level of @code{Options} when serializing JSON |
| 935 | + @lnk("#598", "https://github.com/com-lihaoyi/upickle/pull/598") |
| 936 | + @li |
| 937 | + Make uPickle derivation in Scala 3 call @code{apply} method instead of @code{new} |
| 938 | + @lnk("#607", "https://github.com/com-lihaoyi/upickle/pull/607") |
| 939 | + @li |
| 940 | + Allow field-level and class-level application of @code{serializeDefaults} as an annotation |
| 941 | + @lnk("#608", "https://github.com/com-lihaoyi/upickle/pull/608"). |
| 942 | + @li |
| 943 | + To upgrade to uPickle 4.0.0 from uPickle 3.x while preserving the existing serialization |
| 944 | + format, please add @hl.scala{override def objectTypeKeyWriteFullyQualified = true} and |
| 945 | + @hl.scala{override def optionsAsNulls = false} to your upickle |
| 946 | + @sect.ref{Custom Configuration}. If you are currently using @code{upickle.default}, please define |
| 947 | + a @sect.ref{Custom Configuration} and replace all usage of @code{upickle.default} |
| 948 | + with it. This will preserve the prior serialization format, allowing a smooth upgrade |
| 949 | + @li |
| 950 | + @hl.scala{override def objectTypeKeyWriteFullyQualified = true} is both forwards and |
| 951 | + backwards compatible. Once your entire system is on uPickle 4.0.0, you can incrementally |
| 952 | + disable @code{objectTypeKeyWriteFullyQualified}, and uPickle 4.0.0 will be able to read |
| 953 | + the generate JSON whether @code{objectTypeKeyWriteFullyQualified} is @hl.scala{true} |
| 954 | + or @hl.scala{false}. |
| 955 | + @li |
| 956 | + @hl.scala{override def optionsAsNulls = false} is @b{not} forwards or backwards |
| 957 | + compatible, and cannot be due to the nature of the change in the serialization |
| 958 | + format. If you are unable to do a "big bang" upgrade of your entire system (both |
| 959 | + code and serialized data) to uPickle 4.0.0, it may be best to continue using |
| 960 | + @hl.scala{override def optionsAsNulls = false} for the foreseeable future. |
| 961 | + |
907 | 962 | @sect{3.3.1} |
908 | 963 | @ul |
909 | 964 | @li |
|
0 commit comments