redis_protocol/resp2/
utils.rs1use crate::{
2 error::RedisProtocolError,
3 resp2::types::{OwnedFrame, RangeFrame},
4 utils::digits_in_usize,
5};
6use alloc::{borrow::ToOwned, string::String, vec::Vec};
7
8#[cfg(feature = "bytes")]
9use crate::resp2::types::BytesFrame;
10#[cfg(feature = "bytes")]
11use bytes::{Bytes, BytesMut};
12#[cfg(feature = "bytes")]
13use bytes_utils::Str;
14
15pub fn bulkstring_encode_len(b: &[u8]) -> usize {
16 1 + digits_in_usize(b.len()) + 2 + b.len() + 2
17}
18
19pub fn simplestring_encode_len(s: &[u8]) -> usize {
20 1 + s.len() + 2
21}
22
23pub fn error_encode_len(s: &str) -> usize {
24 1 + s.as_bytes().len() + 2
25}
26
27pub fn integer_encode_len(i: i64, int_as_bulkstring: bool) -> usize {
28 let prefix = if i < 0 { 1 } else { 0 };
29 let digits = digits_in_usize(i.unsigned_abs() as usize);
30
31 if int_as_bulkstring {
32 1 + digits_in_usize(digits + prefix) + 2 + prefix + digits + 2
33 } else {
34 1 + digits + 2 + prefix
35 }
36}
37
38pub fn build_owned_frame(buf: &[u8], frame: &RangeFrame) -> Result<OwnedFrame, RedisProtocolError> {
40 Ok(match frame {
41 RangeFrame::Error((start, end)) => OwnedFrame::Error(String::from_utf8(buf[*start .. *end].to_vec())?),
42 RangeFrame::SimpleString((start, end)) => OwnedFrame::SimpleString(buf[*start .. *end].to_owned()),
43 RangeFrame::BulkString((start, end)) => OwnedFrame::BulkString(buf[*start .. *end].to_owned()),
44 RangeFrame::Integer(i) => OwnedFrame::Integer(*i),
45 RangeFrame::Null => OwnedFrame::Null,
46 RangeFrame::Array(frames) => {
47 let mut out = Vec::with_capacity(frames.len());
49 for frame in frames.iter() {
50 out.push(build_owned_frame(buf, frame)?);
51 }
52 OwnedFrame::Array(out)
53 },
54 })
55}
56
57#[cfg(feature = "bytes")]
59pub fn build_bytes_frame(buf: &Bytes, frame: &RangeFrame) -> Result<BytesFrame, RedisProtocolError> {
60 Ok(match frame {
61 RangeFrame::Error((start, end)) => {
62 let bytes = buf.slice(start .. end);
63 BytesFrame::Error(Str::from_inner(bytes)?)
64 },
65 RangeFrame::SimpleString((start, end)) => {
66 let bytes = buf.slice(start .. end);
67 BytesFrame::SimpleString(bytes)
68 },
69 RangeFrame::BulkString((start, end)) => {
70 let bytes = buf.slice(start .. end);
71 BytesFrame::BulkString(bytes)
72 },
73 RangeFrame::Integer(i) => BytesFrame::Integer(*i),
74 RangeFrame::Null => BytesFrame::Null,
75 RangeFrame::Array(frames) => {
76 let mut out = Vec::with_capacity(frames.len());
78 for frame in frames.iter() {
79 out.push(build_bytes_frame(buf, frame)?);
80 }
81 BytesFrame::Array(out)
82 },
83 })
84}
85
86#[cfg(feature = "bytes")]
92pub fn freeze_parse(
93 buf: &mut BytesMut,
94 frame: &RangeFrame,
95 amt: usize,
96) -> Result<(BytesFrame, Bytes), RedisProtocolError> {
97 let buffer = buf.split_to(amt).freeze();
98 let frame = build_bytes_frame(&buffer, frame)?;
99 Ok((frame, buffer))
100}
101
102#[cfg(test)]
103mod tests {
104 use super::*;
105
106 #[test]
107 fn should_get_encode_len_simplestring() {
108 let ss1 = "Ok";
109 let ss2 = "FooBarBaz";
110 let ss3 = "-&#$@9232";
111
112 assert_eq!(simplestring_encode_len(ss1.as_bytes()), 5);
113 assert_eq!(simplestring_encode_len(ss2.as_bytes()), 12);
114 assert_eq!(simplestring_encode_len(ss3.as_bytes()), 12);
115 }
116
117 #[test]
118 fn should_get_encode_len_error() {
119 let e1 = "MOVED 3999 127.0.0.1:6381";
120 let e2 = "ERR unknown command 'foobar'";
121 let e3 = "WRONGTYPE Operation against a key holding the wrong kind of value";
122
123 assert_eq!(error_encode_len(e1), 28);
124 assert_eq!(error_encode_len(e2), 31);
125 assert_eq!(error_encode_len(e3), 68);
126 }
127
128 #[test]
129 fn should_get_encode_len_integer() {
130 assert_eq!(integer_encode_len(38473, false), 8);
131 assert_eq!(integer_encode_len(-74834, false), 9);
132 }
133
134 #[test]
135 fn should_get_encode_len_integer_as_bulkstring() {
136 assert_eq!(integer_encode_len(38473, true), 11);
138 assert_eq!(integer_encode_len(-74834, true), 12);
140 }
141}