render_example_test.gno
3.09 Kb · 92 lines
1package bencodedemo
2
3// ExampleRender pins the realm's Render output as a testable example. The
4// refusal table is the library's strictness contract, so this doubles as a
5// conformance test.
6func ExampleRender() {
7 print(Render(""))
8 // Output:
9 // # Bencode
10 //
11 // The BitTorrent serialization format, demoing the [`p/moul/x/daily/bencode`](/p/moul/x/daily/bencode/v0) library.
12 //
13 // ## The four types
14 //
15 // | encoding | kind | reads as |
16 // | --- | --- | --- |
17 // | `i42e` | int | 42 |
18 // | `i-7e` | int | -7 |
19 // | `4:spam` | string | spam |
20 // | `0:` | string | _(empty string)_ |
21 // | `li1ei2ei3ee` | list | 3 item(s) |
22 // | `d3:cow3:moo4:spam4:eggse` | dict | 2 key(s): cow, spam |
23 //
24 // ## A torrent, decoded
25 //
26 // - dict, 2 key(s)
27 // - **announce**: string udp://tracker\.example
28 // - **info**:
29 // - dict, 3 key(s)
30 // - **length**: int `262144`
31 // - **name**: string disk\.img
32 // - **piece length**: int `16384`
33 //
34 // The `info` sub-dictionary re-encodes to `d6:lengthi262144e4:name8:disk.img12:piece lengthi16384ee`, 56 bytes. Hash those bytes and you have the infohash, which is why the decoder is not allowed to tidy anything up on the way through.
35 //
36 // ## What it refuses
37 //
38 // | input | why | error |
39 // | --- | --- | --- |
40 // | `i007e` | leading zeros in an integer | bencode: input is not canonical |
41 // | `i-0e` | negative zero | bencode: input is not canonical |
42 // | `03:abc` | leading zeros in a string length | bencode: input is not canonical |
43 // | `d4:spam4:eggs3:cow3:mooe` | dictionary keys out of order | bencode: input is not canonical |
44 // | `d3:cow3:moo3:cow3:mooe` | duplicate dictionary key | bencode: input is not canonical |
45 // | `i1ei2e` | a second value after the first | bencode: trailing data after top-level value |
46 //
47 // > Every one of those parses. A decoder that accepted them and re-emitted the canonical form would change the identity of the document it was handed.
48 //
49 // Decode your own: [`d3:cow3:mooe`](/r/moul/x/daily/bencodedemo/v0:d3:cow3:mooe)
50}
51
52// ExampleRenderDecode pins the caller-supplied decode path: the tree, and the
53// round trip that says the input was already canonical.
54func ExampleRenderDecode() {
55 print(Render("/d3:cowl1:ai7ee4:spam4:eggse"))
56 // Output:
57 // # Bencode
58 //
59 // The BitTorrent serialization format, demoing the [`p/moul/x/daily/bencode`](/p/moul/x/daily/bencode/v0) library.
60 //
61 // ## Your input
62 //
63 // d3:cowl1:ai7ee4:spam4:eggse
64 //
65 // - dict, 2 key(s)
66 // - **cow**:
67 // - list, 2 item(s)
68 // - string a
69 // - int `7`
70 // - **spam**: string eggs
71 //
72 // Re-encodes to d3:cowl1:ai7ee4:spam4:eggse, byte for byte.
73 //
74 // [back to the demo](/r/moul/x/daily/bencodedemo/v0)
75}
76
77// ExampleRenderReject pins what a non-canonical paste looks like.
78func ExampleRenderReject() {
79 print(Render("/i007e"))
80 // Output:
81 // # Bencode
82 //
83 // The BitTorrent serialization format, demoing the [`p/moul/x/daily/bencode`](/p/moul/x/daily/bencode/v0) library.
84 //
85 // ## Your input
86 //
87 // i007e
88 //
89 // Rejected: bencode: input is not canonical
90 //
91 // [back to the demo](/r/moul/x/daily/bencodedemo/v0)
92}