I am trying to create striped down redis clone in Rust. I got stuck trying to implement redis protocol. I want to have a struct that would encapsulate incoming packet and parse it appropriately to its data type and command.
My data types are simple Strings or Ints, but one thing is kinda different for Array data type i would like to use Vec<T> and this is where my problems begin.
So i created struct that represents my incoming packet.
What to want to archive with this struct to be able to just do:
let parsed_value = ProtocolPacket::new(data: &[u8])
struct ProtocolPacket <T> { // <-- this <T> is only because of ProtocolPacketData<T>
command: ProtocolPacketCommand,
data: ProtocolPacketData<T>,
}
impl <T>ProtocolPacket <T> {
fn new(packet: &[u8]) -> ProtocolPacket<T> {
let packet = packet.into_iter();
let command = ProtocolPacketCommand::new(packet.next().unwrap()); // <-- This is working
// Delete \r \n
packet.next_back().unwrap();
packet.next_back().unwrap();
let data = packet.as_slice();
let data = ProtocolPacketData::new(data);
ProtocolPacket{
command: command,
data: data,
}
}
enum ProtocolPacketData <T> {
SimpleString(String),
Error(String),
Integer(i64),
String(String),
Array(Vec<T>),
}
impl <T> ProtocolPacketData <T> {
pub fn new(rest: &[u8]) -> ProtocolPacketData<T> {
let rest = rest.into_iter();
let data_type = rest.next().unwrap();
// Strip last 2 bytes -> \r\n
rest.next_back().unwrap();
rest.next_back().unwrap();
match data_type.to_string().chars().next().unwrap() {
'+' => handle_packet_simplestring(rest.as_slice()), <-- Function call that returns ProtocolPacketData<String>
'-' => unimplemented!()
':' => unimplemented!()
'$' => unimplemented!()
'*' => unimplemented!()
'%' => unimplemented!()
_ => unimplemented!()
}
}
}
fn handle_packet_simplestring<T>(packet_value: &[u8]) -> ProtocolPacketData<String>{
let data = String::from_utf8_lossy(packet_value);
ProtocolPacketData::SimpleString(data.to_string())
}
This is where my error occours
match data_type.to_string().chars().next().unwrap() {
'+' => handle_packet_simplestring(rest.as_slice()), <-- Function call that returns ProtocolPacketData<String>
'-' => unimplemented!()
':' => unimplemented!()
'$' => unimplemented!()
'*' => unimplemented!()
'%' => unimplemented!()
_ => unimplemented!()
}
I get an error
mismatched types
expected enum ProtocolPacketData<T>
found enum ProtocolPacketData<std::string::String>
How can i make this work and is this even viable way to do this? Thanks, Sam