preserves 4.995.2

Implementation of the Preserves serialization format via serde.
Documentation
@<EmacsMode "-*- preserves -*-">
@<Documentation [
  "Individual test cases may be any of the following record types:"
  <TestCaseTypes {
    Test:                 {fields: [binary annotatedValue] expectations: #{1 2 3 4 5 6 7 8}}
    NondeterministicTest: {fields: [binary annotatedValue] expectations: #{1 2 3 4 5 6 7}}
    ParseError:           {fields: [text]                  expectations: #{20}}
    ParseShort:           {fields: [text]                  expectations: #{21}}
    ParseEOF:             {fields: [text]                  expectations: #{22}}
    DecodeError:          {fields: [bytes]                 expectations: #{30}}
    DecodeShort:          {fields: [bytes]                 expectations: #{31}}
    DecodeEOF:            {fields: [bytes]                 expectations: #{32}}
  }>
  "In each test, let stripped = strip(annotatedValue),"
  "                  encodeBinary(·) produce canonical ordering and no annotations,"
  "                  looseEncodeBinary(·) produce any ordering, but with annotations,"
  "                  annotatedBinary(·) produce canonical ordering, but with annotations,"
  "                  decodeBinary(·) include annotations,"
  "                  encodeText(·) include annotations,"
  "                  decodeText(·) include annotations,"
  "and check the following numbered expectations according to the table above:"
  <TestCaseExpectations {
     1: "decodeBinary(encodeBinary(annotatedValue))) = stripped"
     2: "strip(decodeBinary(binary)) = stripped"
     3: "decodeBinary(binary) = annotatedValue"
     4: "decodeBinary(annotatedBinary(annotatedValue)) = annotatedValue"
     5: "decodeText(encodeText(stripped)) = stripped"
     6: "decodeText(encodeText(annotatedValue)) = annotatedValue"
     7: "annotatedBinary(annotatedValue) = binary"
     8: "looseEncodeBinary(annotatedValue) = binary"

    20: "decodeText(text) fails with a syntax error (NB. never with EOF)"
    21: "decodeText(text) fails signalling premature EOF after partial parse (NB. never with a syntax error)"
    22: "decodeText(text) fails signalling immediate EOF (NB. never with a syntax error)"

    30: "decodeBinary(bytes) fails with a syntax error (NB. never with EOF)"
    31: "decodeBinary(bytes) fails signalling premature EOF after partial parse (NB. never with a syntax error)"
    32: "decodeBinary(bytes) fails signalling immediate EOF (NB. never with a syntax error)"
  }>
  "Implementations may vary in their treatment of the difference between expectations"
  "21/22 and 31/32, depending on how they wish to treat end-of-stream conditions."
]>
<TestCases {
  annotation1: <Test #x"85 B103616263 B00109" @"abc" 9>
  annotation2: <Test #x"85 B103616263 85 B103646566 B5 B584 85 B10178 B584 84" @"abc" @"def" [[] @"x" []]>
  annotation3: <Test #x"85 85 B00101 B00102 85 85 B00103 B00104 B00105" @@1 2 @@3 4 5>
  annotation4: <NondeterministicTest
                #x"B7 85 B302616b B30161 85 B3026176 B00101 85 B302626b B30162 85 B3026276 B00102 84"
                {@ak a: @av 1 @bk b: @bv 2}>
  annotation5: <Test #x"85 B3026172 B4 B30152 85 B3026166 B30166 84" @ar <R @af f>>
  annotation6: <Test #x"B4 85 B3026172 B30152 85 B3026166 B30166 84" <@ar R @af f>>
  annotation7:
  # Stop reading symbols at @ -- this test has three separate annotations
  <Test #x"85 B30161 85 B30162 85 B30163 B584" @a@b@c[]>
  annotation8: @"Commas forbidden between @ and annotation" <ParseError "@,a b">
  annotation8a: @"Commas forbidden between @ and annotation in a collection" <ParseError "[@,a b]">
  annotation9: @"Commas forbidden between annotation and underlying" <ParseError "@a, b">
  annotation9a: @"Commas forbidden between annotation and underlying in a collection" <ParseError "[@a, b]">
  annotation10: @"Line comment that's just hash-newline" <Test #x"85 B100 B000" #
0>
  annotation11: @"Line comments: one hash-newline, one normal"
    <Test #x"85 B100 85 B1066e6f726d616c B000" #
# normal
0>
  annotation12: @"Interpreter-specification annotations"
    <Test #"\x85\xb4\xb3\x0binterpreter\xb1\x0a/some/path\x84\xb3\x05value"
     #!/some/path
     value>
  bytes2: <Test #x"B20568656c6c6f" #"hello">
  bytes2a: <Test @"Internal whitespace is allowed, not including commas" #x"B2 05 68 65 6c 6c 6f" #"hello">
  bytes2b: @"Commas forbidden in internal whitespace" <ParseError "#x\"B2, 05, 68, 65, 6c, 6c, 6f\"">
  bytes3: <Test #x"B203414243" #"ABC">
  bytes4: <Test #x"B203414243" #x"414243">
  bytes5: <Test #x"B203414a4e" #x" 41 4A 4e ">
  bytes6: @"Bytes must be 2-digits entire" <ParseError "#x\"414 243\"">
  bytes7: <Test #"\xB2\x06corymb" #[Y29yeW1i]>
  bytes8: <Test #"\xB2\x06corymb" #[Y29 yeW 1i]>
  bytes9: <Test #"\xB2\x02Hi" #[SGk=]>
  bytes10: <Test #"\xB2\x02Hi" #[SGk]>
  bytes11: <Test #"\xB2\x02Hi" #[S G k]>
  bytes12: @"Bytes syntax only supports \\x, not \\u" <ParseError "#\"\\u6c34\"">
  bytes13: <Test #x"B2 11 61 62 63 6c 34 f0 5c 2f 22 08 0c 0a 0d 09 78 79 7a" #"abc\x6c\x34\xf0\\/\"\b\f\n\r\txyz">
  delimiters0: <Test #x"B5808084" [#f #f]>
  delimiters1: @"Note no space between the falses here" <Test #x"B5808084" [#f#f]>
  delimiters2: <Test #x"B580B303666f6f84" [#f foo]>
  delimiters3: @"No space between the #f and the foo" <ParseError "[#ffoo]">
  delimiters4: @"Note no space after the #f" <Test #"\xB5\x80\x85\xB1\x0Ea line comment\x81\x84" [#f# a line comment
#t]>
  delimiters5:  @"Note no space after the #f" <Test #"\xB5\x80\x85\xB3\x03ann\x81\x84" [#f@ann #t]>
  dict0: <Test #x"B784" {}>
  dict1: <NondeterministicTest #x"b7 b10162 81 b30161 b00101 b5b00101b00102b0010384 b20163 b7 b30a66697273742d6e616d65 b109456c697a6162657468 84 b7 b3077375726e616d65 b109426c61636b77656c6c 84 84" { a: 1 "b": #t [1 2 3]: #"c" { first-name: "Elizabeth" }: { surname: "Blackwell" } }>
  dict2: @"Missing close brace" <ParseShort "{ a: b, c: d ">
  dict2a: @"Missing close brace" <ParseShort "{">
  dict3: @"Duplicate key" <ParseError "{ a: 1, a: 2 }">
  dict3a: @"Duplicate key" <DecodeError #x"b7 b00101 b00102 b00101 b00103 84">
  dict4: @"Unexpected close brace" <ParseError "}">
  dict5: @"Missing value" <DecodeError #x"b7 b00101 b00102 b00103 84">
  dict6: @"Comma not allowed between key and colon" <ParseError "{ a,: 1, b: 2 }">
  dict7: @"Comma not allowed between colon and value" <ParseError "{ a:, 1, b: 2 }">
  dict8: <NondeterministicTest #x"b7b30161b00101b30162b0010284" {,, a: 1,, b: 2,,}>
  double0: <Test #x"87080000000000000000" 0.0>
  double+0: <Test #x"87080000000000000000" +0.0>
  double-0: <Test #x"87088000000000000000" -0.0>
  double1: <Test #x"87083ff0000000000000" 1.0>
  double1a: <Test #x"87083ff0000000000000" 1e0>
  double1b: <Test #x"87083ff0000000000000" 1.0e0>
  double1c: <Test #x"87083ff0000000000000" 1e-0>
  double1d: <Test #x"87083ff0000000000000" 1.0e-0>
  double1e: <Test #x"87083ff0000000000000" 1e+0>
  double1f: <Test #x"87083ff0000000000000" 1.0e+0>
  double2: <Test #x"8708fe3cb7b759bf0426" -1.202e300>
  double3: <Test #x"8708123456789abcdef0" #xd"12 34 56 78  9a bc de f0">
  double4: @"Fewer than 16 digits" <ParseError "#xd\"12345678\"">
  double5: @"More than 16 digits" <ParseError "#xd\"123456789abcdef012\"">
  double6: @"Invalid chars" <ParseError "#xd\"12zz56789abcdef0\"">
  double7: @"Positive infinity" <Test #x"87087ff0000000000000" #xd"7ff0000000000000">
  double8: @"Negative infinity" <Test #x"8708fff0000000000000" #xd"fff0000000000000">
  double9: @"-qNaN" <Test #x"8708fff0000000000001" #xd"fff0000000000001">
  double10: @"-qNaN" <Test #x"8708fff0000000000111" #xd"fff0000000000111">
  double11: @"+qNaN" <Test #x"87087ff0000000000001" #xd"7ff0000000000001">
  double12: @"+qNaN" <Test #x"87087ff0000000000111" #xd"7ff0000000000111">
  double13: @"Bad spacing" <ParseError "#xd\"12345 6789abcdef0\"">
  double14: @"-sNaN" <Test #x"8708fff8000000000001" #xd"fff8000000000001">
  double15: @"-sNaN" <Test #x"8708fff8000000000111" #xd"fff8000000000111">
  double16: @"+sNaN" <Test #x"87087ff8000000000001" #xd"7ff8000000000001">
  double17: @"+sNaN" <Test #x"87087ff8000000000111" #xd"7ff8000000000111">
  int-98765432109876543210987654321098765432109: <Test #x"b012feddc125aed4226c770369269596ce3f0ad3" -98765432109876543210987654321098765432109>
  int-12345678123456781234567812345678: <Test #x"b00eff642cf6684f11d1dad08c4a10b2" -12345678123456781234567812345678>
  int-1234567812345678123456781234567: <Test #x"b00df06ae570d4b4fb62ae746dce79" -1234567812345678123456781234567>
  int-257: <Test #x"b002feff" -257>
  int-256: <Test #x"b002ff00" -256>
  int-255: <Test #x"b002ff01" -255>
  int-254: <Test #x"b002ff02" -254>
  int-129: <Test #x"b002ff7f" -129>
  int-128: <Test #x"b00180" -128>
  int-127: <Test #x"b00181" -127>
  int-4: <Test #x"b001fc" -4>
  int-3: <Test #x"b001fd" -3>
  int-2: <Test #x"b001fe" -2>
  int-1: <Test #x"b001ff" -1>
  int0: <Test #x"b000" 0>
  int+0: <Test #x"b000" +0>
  int-0: <Test #x"b000" -0>
  int1: <Test #x"b00101" 1>
  int12: <Test #x"b0010c" 12>
  int13: <Test #x"b0010d" 13>
  int127: <Test #x"b0017f" 127>
  int+127: <Test #x"b0017f" +127>
  int128: <Test #x"b0020080" 128>
  int255: <Test #x"b00200ff" 255>
  int256: <Test #x"b0020100" 256>
  int32767: <Test #x"b0027fff" 32767>
  int32768: <Test #x"b003008000" 32768>
  int65535: <Test #x"b00300ffff" 65535>
  int65536: <Test #x"b003010000" 65536>
  int131072: <Test #x"b003020000" 131072>
  int2500000000: <Test #x"b005009502f900" 2500000000>
  int1234567812345678123456781234567: <Test #x"b00d0f951a8f2b4b049d518b923187" 1234567812345678123456781234567>
  int12345678123456781234567812345678: <Test #x"b00e009bd30997b0ee2e252f73b5ef4e" 12345678123456781234567812345678>
  int87112285931760246646623899502532662132736: <Test #x"b012010000000000000000000000000000000000" 87112285931760246646623899502532662132736>
  int98765432109876543210987654321098765432109: <Test #x"b01201223eda512bdd9388fc96d96a6931c0f52d" 98765432109876543210987654321098765432109>
  list0: <Test #x"b584" []>
  list4: <Test #x"b5b00101b00102b00103b0010484" [1 2 3 4]>
  list4a: <Test #x"b5b00101b00102b00103b0010484" [1, 2, 3, 4]>
  list4b: <Test #x"b5b00101b00102b00103b0010484" [,, 1,, 2,, 3,, 4,,]>
  list5: <Test #x"b5b001feb001ffb000b0010184" [-2 -1 0 1]>
  list6: <Test #x"b5 b10568656c6c6f b3057468657265 b205776f726c64 b584 b684 81 80 84" ["hello" there #"world" [] #{} #t #f]>
  list7: <Test #x"b5 b303616263 b3032e2e2e b303646566 84" [abc ... def]>
  list8: @"Missing close bracket" <ParseShort "[">
  list9: @"Unexpected close bracket" <ParseError "]">
  list10: @"Missing end byte" <DecodeShort #x"b58080">
  list11: <Test #x"b5b0010184" [01]>
  list12: <Test #x"b5b0010c84" [12]>
  noinput0: @"No input at all" <DecodeEOF #x"">
  embed0: <Test #x"86b000" #:0>
  embed1: <Test #x"8686b000" #:#:0>
  embed2: <Test #x"b586b00086b10568656c6c6f84" [#:0 #:"hello"]>
  record1: <Test #x"b4 b30763617074757265 b4 b30764697363617264 84 84" <capture <discard>>>
  record2: <Test #x"b4 b3076f627365727665 b4 b305737065616b b4 b30764697363617264 84 b4 b30763617074757265 b4 b30764697363617264 84 84 84 84" <observe <speak <discard> <capture <discard>>>>>
  record2a: @"Commas not allowed in records" <ParseError "<observe <speak <discard>, <capture <discard>>>>">
  record3: <Test #x"b4 b5 b3067469746c6564 b306706572736f6e b00102 b3057468696e67 b00101 84 b00165 b109426c61636b77656c6c b4 b30464617465 b002071d b00102 b00103 84 b1024472 84" <[titled person 2 thing 1] 101 "Blackwell" <date 1821 2 3> "Dr">>
  record4: <Test #x"b4 b30764697363617264 84" <discard>>
  record5: <Test #x"b4b00107b58484" <7[]>>
  record6: <Test #x"b4b30764697363617264b308737572707269736584" <discard surprise>>
  record7: <Test #x"b4b10761537472696e67b00103b0010484" <"aString" 3 4>>
  record8: <Test #x"b4b4b3076469736361726484b00103b0010484" <<discard> 3 4>>
  record9: @"Missing record label" <ParseError "<>">
  record10: @"Missing close-angle-bracket" <ParseShort "<">
  record11: @"Unexpected close-angle-bracket" <ParseError ">">
  set0: <Test #x"b684" #{}>
  set1: <NondeterministicTest #x"b6b00101b00102b0010384" #{1 2 3}>
  set2: @"Missing close brace" <ParseShort "#{ 1 2 3 ">
  set2a: @"Missing close brace" <ParseShort "#{">
  set3: @"Duplicate value" <ParseError "#{a a}">
  set3a: @"Duplicate value" <DecodeError #x"b6 b00101 b00101 84">
  string0: <Test #x"b100" "">
  string3: <Test #x"b10568656c6c6f" "hello">
  string4: <Test #x"b1 14 616263e6b0b4e6b0b45c2f22080c0a0d0978797a" "abc\u6c34\u6C34\\/\"\b\f\n\r\txyz">
  string5: <Test #x"b104f09d849e" "\uD834\uDD1E">
  string6: @"Short unicode escape" <ParseError "\"\\u6c\"">
  string7: @"Short unicode escape" <ParseError "\"\\u6c3\"">
  surrogatepair0str: @"Unmatched high surrogate" <ParseError "\"blah\\uD834\"">
  surrogatepair1str: @"Unmatched low surrogate" <ParseError "\"\\uDD1Eblah\"">
  surrogatepair2str: @"Unmatched high surrogate" <ParseError "\"blah\\uD834blah\"">
  surrogatepair3str: @"Unmatched low surrogate" <ParseError "\"blah\\uDD1Eblah\"">
  surrogatepair4str: @"Swapped surrogates" <ParseError "\"blah\\uDD1E\\uD834blah\"">
  surrogatepair5str: @"Two high surrogates" <ParseError "\"blah\\uD834\\uD834blah\"">
  surrogatepair6str: @"Two low surrogates" <ParseError "\"blah\\uDD1E\\uDD1Eblah\"">
  surrogatepair0sym: @"Unmatched high surrogate" <ParseError "|blah\\uD834|">
  surrogatepair1sym: @"Unmatched low surrogate" <ParseError "|\\uDD1Eblah|">
  surrogatepair2sym: @"Unmatched high surrogate" <ParseError "|blah\\uD834blah|">
  surrogatepair3sym: @"Unmatched low surrogate" <ParseError "|blah\\uDD1Eblah|">
  surrogatepair4sym: @"Swapped surrogates" <ParseError "|blah\\uDD1E\\uD834blah|">
  surrogatepair5sym: @"Two high surrogates" <ParseError "|blah\\uD834\\uD834blah|">
  surrogatepair6sym: @"Two low surrogates" <ParseError "|blah\\uDD1E\\uDD1Eblah|">
  symbol0: <Test #x"b300" ||>
  symbol2: <Test #x"b30568656c6c6f" hello>
  symbol3: <Test #x"b305312d322d33" 1-2-3>
  symbol4: <Test #x"b305612d622d63" a-b-c>
  symbol5: <Test #x"b305612b622b63" a+b+c>
  symbol6: <Test #x"b3012b" +>
  symbol7: <Test #x"b3032b2b2b" +++>
  symbol8: <Test #x"b3012d" ->
  symbol9: <Test #x"b3032d2d2d" --->
  symbol10: <Test #x"b3022d61" -a>
  symbol11: <Test #x"b3042d2d2d61" ---a>
  symbol12: <Test #x"b3042d2d2d31" ---1>
  symbol13: <Test #x"b3042b312e78" +1.x>
  symbol14: <Test #x"b304f09d849e" |\uD834\uDD1E|>
  tag0: @"Unexpected end tag" <DecodeError #x"84">
  tag1: @"Invalid tag" <DecodeError #x"10">
  tag2: @"Invalid tag" <DecodeError #x"61b10110">
  whitespace0: @"Leading spaces have to eventually yield something" <ParseShort "   ">
  whitespace1: @"No input at all" <ParseEOF "">

  longlist14: <Test #x"b5808080808080808080808080808084"
               [#f #f #f #f #f
                #f #f #f #f #f
                #f #f #f #f]>
  longlist15: <Test #x"b580808080808080808080808080808084"
               [#f #f #f #f #f
                #f #f #f #f #f
                #f #f #f #f #f]>
  longlist100:
  <Test #x"b5
           80808080808080808080
           80808080808080808080
           80808080808080808080
           80808080808080808080
           80808080808080808080
           80808080808080808080
           80808080808080808080
           80808080808080808080
           80808080808080808080
           80808080808080808080
           84"
   [#f #f #f #f #f #f #f #f #f #f
    #f #f #f #f #f #f #f #f #f #f
    #f #f #f #f #f #f #f #f #f #f
    #f #f #f #f #f #f #f #f #f #f
    #f #f #f #f #f #f #f #f #f #f
    #f #f #f #f #f #f #f #f #f #f
    #f #f #f #f #f #f #f #f #f #f
    #f #f #f #f #f #f #f #f #f #f
    #f #f #f #f #f #f #f #f #f #f
    #f #f #f #f #f #f #f #f #f #f]>
  longlist200:
  <Test #x"b5
           80808080808080808080
           80808080808080808080
           80808080808080808080
           80808080808080808080
           80808080808080808080
           80808080808080808080
           80808080808080808080
           80808080808080808080
           80808080808080808080
           80808080808080808080
           80808080808080808080
           80808080808080808080
           80808080808080808080
           80808080808080808080
           80808080808080808080
           80808080808080808080
           80808080808080808080
           80808080808080808080
           80808080808080808080
           80808080808080808080
           84"
   [#f #f #f #f #f #f #f #f #f #f
    #f #f #f #f #f #f #f #f #f #f
    #f #f #f #f #f #f #f #f #f #f
    #f #f #f #f #f #f #f #f #f #f
    #f #f #f #f #f #f #f #f #f #f
    #f #f #f #f #f #f #f #f #f #f
    #f #f #f #f #f #f #f #f #f #f
    #f #f #f #f #f #f #f #f #f #f
    #f #f #f #f #f #f #f #f #f #f
    #f #f #f #f #f #f #f #f #f #f
    #f #f #f #f #f #f #f #f #f #f
    #f #f #f #f #f #f #f #f #f #f
    #f #f #f #f #f #f #f #f #f #f
    #f #f #f #f #f #f #f #f #f #f
    #f #f #f #f #f #f #f #f #f #f
    #f #f #f #f #f #f #f #f #f #f
    #f #f #f #f #f #f #f #f #f #f
    #f #f #f #f #f #f #f #f #f #f
    #f #f #f #f #f #f #f #f #f #f
    #f #f #f #f #f #f #f #f #f #f]>

  rfc8259-example1: <NondeterministicTest
                     #x"B7
                          B1 05 496d616765
                          B7
                            B1 03 494473
                              B5
                                B0 01 74
                                B0 02 03 AF
                                B0 02 00 EA
                                B0 03 00 97 89
                              84
                            B1 05 5469746c65
                              B1 14 566965772066726f6d203135746820466c6f6f72
                            B1 05 5769647468
                              B0 02 03 20
                            B1 06 486569676874
                              B0 02 02 58
                            B1 08 416e696d61746564
                              B3 05 66616c7365
                            B1 09 5468756d626e61696c
                              B7
                                B1 03 55726c
                                  B1 26 687474703a2f2f7777772e6578616d706c652e636f6d2f696d6167652f343831393839393433
                                B1 05 5769647468
                                  B0 01 64
                                B1 06 486569676874
                                  B0 01 7D
                              84
                          84
                        84"
                     {
                       "Image": {
                         "Width":  800,
                         "Height": 600,
                         "Title":  "View from 15th Floor",
                         "Thumbnail": {
                           "Url":    "http://www.example.com/image/481989943",
                           "Height": 125,
                           "Width":  100
                         },
                         "Animated" : false,
                         "IDs": [116, 943, 234, 38793]
                       }
                     }>

  rfc8259-example2: <NondeterministicTest
                     #x"b5
                          b7
                            b1 03 5a6970               b1 05 3934313037
                            b1 04 43697479             b1 0d 53414e204652414e434953434f
                            b1 05 5374617465           b1 02 4341
                            b1 07 41646472657373       b1 00
                            b1 07 436f756e747279       b1 02 5553
                            b1 08 4c61746974756465     8708 4042e226809d4952
                            b1 09 4c6f6e676974756465   8708 c05e99566cf41f21
                            b1 09 707265636973696f6e   b1 03 7a6970
                          84
                          b7
                            b1 03 5a6970               b1 05 3934303835
                            b1 04 43697479             b1 09 53554e4e5956414c45
                            b1 05 5374617465           b1 02 4341
                            b1 07 41646472657373       b1 00
                            b1 07 436f756e747279       b1 02 5553
                            b1 08 4c61746974756465     8708 4042af9d66adb403
                            b1 09 4c6f6e676974756465   8708 c05e81aa4fca42af
                            b1 09 707265636973696f6e   b1 03 7a6970
                          84
                        84"
                     [
                       {
                         "precision": "zip",
                         "Latitude":  37.7668,
                         "Longitude": -122.3959,
                         "Address":   "",
                         "City":      "SAN FRANCISCO",
                         "State":     "CA",
                         "Zip":       "94107",
                         "Country":   "US"
                       },
                       {
                         "precision": "zip",
                         "Latitude":  37.371991,
                         "Longitude": -122.026020,
                         "Address":   "",
                         "City":      "SUNNYVALE",
                         "State":     "CA",
                         "Zip":       "94085",
                         "Country":   "US"
                       }
                     ]>

}
>