Skip to content

Commit 5c23e2e

Browse files
committed
Added RefBulkString to help support byte slices as command arguments.
fix #127
1 parent 37dd582 commit 5c23e2e

3 files changed

Lines changed: 81 additions & 0 deletions

File tree

src/resp/bulk_string.rs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,62 @@ impl fmt::Display for BulkString {
7676
f.write_str(String::from_utf8_lossy(&self.0).as_ref())
7777
}
7878
}
79+
80+
/// Represents a reference to the [Bulk String](https://redis.io/docs/reference/protocol-spec/#resp-bulk-strings) RESP type
81+
#[derive(Serialize, Hash, PartialEq, Eq, Clone)]
82+
pub struct RefBulkString<'a>(
83+
#[serde(
84+
serialize_with = "serialize_byte_buf"
85+
)]
86+
&'a [u8],
87+
);
88+
89+
impl<'a> RefBulkString<'a> {
90+
/// Constructs a new `RefBulkString` from a byte slice
91+
#[inline]
92+
pub fn new(bytes: &'a [u8]) -> Self {
93+
Self(bytes)
94+
}
95+
96+
/// Returns the internal buffer as a byte slice
97+
#[inline]
98+
pub fn as_bytes(&self) -> &[u8] {
99+
self.0
100+
}
101+
}
102+
103+
impl<'a> Deref for RefBulkString<'a> {
104+
type Target = [u8];
105+
106+
#[inline]
107+
fn deref(&self) -> &Self::Target {
108+
self.0
109+
}
110+
}
111+
112+
impl<'a> From<&'a [u8]> for RefBulkString<'a> {
113+
#[inline]
114+
fn from(bytes: &'a [u8]) -> Self {
115+
Self(bytes)
116+
}
117+
}
118+
119+
impl<'a, const N: usize> From<&'a [u8; N]> for RefBulkString<'a> {
120+
#[inline]
121+
fn from(bytes: &'a [u8; N]) -> Self {
122+
Self(bytes.as_slice())
123+
}
124+
}
125+
126+
impl<'a> fmt::Debug for RefBulkString<'a> {
127+
#[inline]
128+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
129+
f.debug_tuple("RefBulkString").field(&self.0).finish()
130+
}
131+
}
132+
133+
impl<'a> fmt::Display for RefBulkString<'a> {
134+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
135+
f.write_str(String::from_utf8_lossy(self.0).as_ref())
136+
}
137+
}

src/tests/arg_serializer.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
use bytes::BytesMut;
2+
use serde::Serialize;
3+
use crate::resp::{ArgSerializer, BulkString, RefBulkString};
4+
5+
#[test]
6+
pub fn byte_slice() {
7+
let mut buffer = BytesMut::new();
8+
let mut serializer = ArgSerializer::from_buffer(&mut buffer);
9+
RefBulkString::from(b"foo").serialize(&mut serializer).unwrap();
10+
RefBulkString::from(b"bar").serialize(&mut serializer).unwrap();
11+
assert_eq!("$3\r\nfoo\r\n$3\r\nbar\r\n", str::from_utf8(buffer.freeze().as_ref()).unwrap());
12+
}
13+
14+
#[test]
15+
pub fn bute_vec() {
16+
let mut buffer = BytesMut::new();
17+
let mut serializer = ArgSerializer::from_buffer(&mut buffer);
18+
BulkString::from(b"foo".to_vec()).serialize(&mut serializer).unwrap();
19+
BulkString::from(b"bar".to_vec()).serialize(&mut serializer).unwrap();
20+
assert_eq!("$3\r\nfoo\r\n$3\r\nbar\r\n", str::from_utf8(buffer.freeze().as_ref()).unwrap());
21+
}

src/tests/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
mod arg_serializer;
12
mod bitmap_commands;
23
mod bloom_commands;
34
mod buffer_decoder;

0 commit comments

Comments
 (0)