@@ -29,6 +29,63 @@ Protocol::Redis - Redis protocol parser/encoder with asynchronous capabilities.
2929 {type => '+', data => 'OK'}
3030 ]});
3131
32+ # RESP3 supported with api 3 specified
33+ my $redis = Protocol::Redis->new(api => 3);
34+
35+ print $redis->encode({type => '%', data => {
36+ null => {type => '_', data => undef},
37+ bignum => {type => '(', data => '3492890328409238509324850943850943825024385'},
38+ string => {type => '$', data => 'this is a string'},
39+ # format prepended to verbatim strings (defaults to txt)
40+ verbatim => {type => '=', data => '*verbatim* string', format => 'mkd'},
41+ # set is unordered but specified as array
42+ booleans => {type => '~', data => [
43+ {type => '#', data => 1},
44+ {type => '#', data => 0},
45+ ]},
46+ # map is hashlike but can be specified as an
47+ # (even-sized) array to encode non-string keys
48+ special_map => {type => '%', data => [
49+ {type => ':', data => 42} => {type => '$', data => 'The answer'},
50+ {type => '_'} => {type => '$', data => 'No data'},
51+ ]},
52+ }, attributes => {
53+ coordinates => {type => '*', data => [
54+ {type => ',', data => '36.001516'},
55+ {type => ',', data => '-78.943319'},
56+ ]},
57+ });
58+
59+ # "|1\r\n\$11\r\ncoordinates\r\n*2\r\n,36.001516\r\n,-78.943319\r\n" .
60+ # "%6\r\n" .
61+ # "\$6\r\nbignum\r\n(3492890328409238509324850943850943825024385\r\n" .
62+ # "\$8\r\nbooleans\r\n~2\r\n#t\r\n#f\r\n" .
63+ # "\$4\r\nnull\r\n_\r\n" .
64+ # "\$11\r\nspecial_map\r\n%2\r\n:42\r\n\$10\r\nThe answer\r\n_\r\n\$7\r\nNo data\r\n" .
65+ # "\$6\r\nstring\r\n\$16\r\nthis is a string\r\n" .
66+ # "\$8\r\nverbatim\r\n=21\r\nmkd:*verbatim* string\r\n"
67+
68+ # sets represented in the protocol the same as arrays
69+ # remapping into a hash may be useful to access string set elements
70+ $redis->parse("~3\r\n+x\r\n+y\r\n+z\r\n");
71+ my %set = map {($_->{data} => 1)} @{$redis->get_message->{data}};
72+ die unless exists $set{x};
73+ print join ',', keys %set; # x,y,z in unspecified order
74+
75+ # verbatim strings are prefixed by a format
76+ # this will be returned as the format key
77+ $redis->parse("=16\r\nmkd:* one\n* two\n\r\n");
78+ my $verbatim = $redis->get_message;
79+ die unless $verbatim->{format} eq 'mkd';
80+ print $verbatim->{data};
81+ # * one
82+ # * two
83+
84+ # attributes are maps that apply to the following value
85+ $redis->parse("|1\r\n+hits\r\n:6\r\n\$4\r\nterm\r\n");
86+ my $term = $redis->get_message;
87+ print "$term->{data}: $term->{attributes}{hits}{data}\n";
88+
3289=head1 DESCRIPTION
3390
3491Redis protocol parser/encoder with asynchronous capabilities and L<pipelining|http://redis.io/topics/pipelining> support.
@@ -40,6 +97,80 @@ Protocol::Redis APIv1 uses
4097encoding/parsing and supports methods described further. Client libraries
4198should specify API version during Protocol::Redis construction.
4299
100+ API version 1 corresponds to the protocol now known as
101+ L<RESP2|https://github.com/redis/redis-specifications/blob/master/protocol/RESP2.md>
102+ and can also thusly be specified as API version 2. It supports the RESP2 data
103+ types C<+-:$*>.
104+
105+ =head1 APIv3
106+
107+ API version 3 supports the same methods as API version 1, corresponding to the
108+ L<RESP3|https://github.com/redis/redis-specifications/blob/master/protocol/RESP3.md>
109+ protocol. RESP3 contains support for several additional data types (null,
110+ boolean, double, big number, blob error, verbatim string, map, and set), data
111+ attributes, streamed strings and aggregate data, and explicitly specified push
112+ data so that asynchronous and synchronous responses can share a connection. A
113+ client must request RESP3 support from the server with the HELLO command to use
114+ these features.
115+
116+ APIv3 supports the RESP2 data types C<+-:$*> as well as the RESP3-specific data
117+ types C<< _,#!=(%~|> >>, with the following implementation notes:
118+
119+ =over
120+
121+ =item * Verbatim String
122+
123+ The Verbatim String type, specified with the initial byte C<=>, is treated the
124+ same as the Blob String type C<$> except that the first three bytes specify
125+ the C<format>, followed by a colon C<:>, and the remaining bytes are the string
126+ data. When parsing, the C<format> will be returned as a separate key and not
127+ included in the string C<data>. When encoding, a C<format> can be specified and
128+ otherwise defaults to C<txt>, and will be prepended to the string data.
129+
130+ =item * Big Number
131+
132+ The Big Number type, specified with the initial byte C<(>, is parsed to a
133+ L<Math::BigInt> object, which can be used in numeric or string operations
134+ without losing precision.
135+
136+ =item * Map
137+
138+ The Map type, specified with the initial byte C<%>, is represented in Perl as a
139+ hash. The keys of a Map are allowed to be any data type, but for simplicity
140+ they are coerced to strings as required by Perl hashes, which the specification
141+ allows. When encoding a Map, a hash reference is normally passed, but an array
142+ reference of alternating keys and values may also be passed to allow specifying
143+ non-string keys. If passed as an array, the values will be encoded in the order
144+ specified, but the Map type is defined as unordered.
145+
146+ =item * Attribute
147+
148+ The Attribute type, specified with the initial byte C<|>, is much like the Map
149+ type, but instead of acting as a value in the message, it is applied as the
150+ C<attributes> key of the following value. Like Map, its keys are coerced to
151+ strings as it is represented as a Perl hash.
152+
153+ =item * Set
154+
155+ The Set type, specified with the initial byte C<~>, is represented as an array,
156+ since a Set can contain values of any data type, which native Perl hashes
157+ cannot represent as keys, and the specification does not require enforcing
158+ element uniqueness. If desired, the higher level client and server should
159+ handle deduplication of Set elements, and should also be aware that the type
160+ is defined as unordered and the values are likely to be tested for existence
161+ rather than position.
162+
163+ =item * Push
164+
165+ The Push type, specified with the initial byte C<< > >>, is treated no
166+ differently from an Array, but a client supporting RESP3 must be prepared to
167+ handle a Push value at any time rather than in response to a command. An
168+ asynchronous client would generally execute a predefined callback when a Push
169+ value is received; a synchronous client must also take this into consideration
170+ for how and when it reads messages.
171+
172+ =back
173+
43174=head2 C<new>
44175
45176 my $redis = Protocol::Redis->new(api => 1);
0 commit comments