refactor string / byte reads from buffer
This commit is contained in:
25
src/buffer.rs
Normal file
25
src/buffer.rs
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
use bytes::{Buf, Bytes};
|
||||||
|
|
||||||
|
use crate::{Result, errors::AppError};
|
||||||
|
|
||||||
|
pub fn try_get_string<B: Buf>(buf: &mut B) -> Result<String> {
|
||||||
|
let len = buf.try_get_u16()? as usize;
|
||||||
|
|
||||||
|
if buf.remaining() <= len {
|
||||||
|
return Err(AppError::IncompleteBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(String::from_utf8(buf.copy_to_bytes(len).to_vec())?)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn try_get_bytes<B: Buf>(buf: &mut B) -> Result<Bytes> {
|
||||||
|
let len = buf.try_get_u32()? as usize;
|
||||||
|
|
||||||
|
if buf.remaining() < len {
|
||||||
|
return Err(AppError::IncompleteBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
let data = buf.copy_to_bytes(len);
|
||||||
|
|
||||||
|
Ok(data)
|
||||||
|
}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
|
|
||||||
use bytes::{Buf as _, BufMut as _, BytesMut};
|
use bytes::{BufMut as _, BytesMut};
|
||||||
|
|
||||||
use crate::{Result, connection::Connection, database::Database, errors::AppError};
|
use crate::{Result, buffer::try_get_string, connection::Connection, database::Database};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Delete {
|
pub struct Delete {
|
||||||
@@ -29,13 +29,7 @@ impl Delete {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse(bytes: &mut Cursor<&[u8]>) -> Result<Self> {
|
pub fn parse(bytes: &mut Cursor<&[u8]>) -> Result<Self> {
|
||||||
let key_length = bytes.try_get_u16()? as usize;
|
let key = try_get_string(bytes)?;
|
||||||
|
|
||||||
if bytes.remaining() < key_length {
|
|
||||||
return Err(AppError::IncompleteCommandBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
let key = String::from_utf8(bytes.copy_to_bytes(key_length).to_vec())?;
|
|
||||||
|
|
||||||
Ok(Self { key })
|
Ok(Self { key })
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use std::io::Cursor;
|
|||||||
|
|
||||||
use bytes::{Buf as _, Bytes};
|
use bytes::{Buf as _, Bytes};
|
||||||
|
|
||||||
use crate::{Result, connection::Connection, database::Database, errors::AppError};
|
use crate::{Result, buffer::try_get_string, connection::Connection, database::Database};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Expire {
|
pub struct Expire {
|
||||||
@@ -22,14 +22,7 @@ impl Expire {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse(bytes: &mut Cursor<&[u8]>) -> Result<Self> {
|
pub fn parse(bytes: &mut Cursor<&[u8]>) -> Result<Self> {
|
||||||
let key_length = bytes.try_get_u16()? as usize;
|
let key = try_get_string(bytes)?;
|
||||||
|
|
||||||
if bytes.remaining() < key_length {
|
|
||||||
return Err(AppError::IncompleteCommandBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
let key = String::from_utf8(bytes.copy_to_bytes(key_length).to_vec())?;
|
|
||||||
|
|
||||||
let seconds = bytes.try_get_u64()?;
|
let seconds = bytes.try_get_u64()?;
|
||||||
|
|
||||||
Ok(Self { key, seconds })
|
Ok(Self { key, seconds })
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
|
|
||||||
use bytes::{Buf as _, BufMut as _, BytesMut};
|
use bytes::{BufMut as _, BytesMut};
|
||||||
|
|
||||||
use crate::{Result, connection::Connection, database::Database, errors::AppError};
|
use crate::{Result, buffer::try_get_string, connection::Connection, database::Database};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Get {
|
pub struct Get {
|
||||||
@@ -31,13 +31,7 @@ impl Get {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse(bytes: &mut Cursor<&[u8]>) -> Result<Self> {
|
pub fn parse(bytes: &mut Cursor<&[u8]>) -> Result<Self> {
|
||||||
let key_length = bytes.try_get_u16()? as usize;
|
let key = try_get_string(bytes)?;
|
||||||
|
|
||||||
if bytes.remaining() < key_length {
|
|
||||||
return Err(AppError::IncompleteCommandBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
let key = String::from_utf8(bytes.copy_to_bytes(key_length).to_vec())?;
|
|
||||||
|
|
||||||
Ok(Self { key })
|
Ok(Self { key })
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
|
|
||||||
use bytes::{Buf as _, Bytes};
|
use bytes::Bytes;
|
||||||
|
|
||||||
use crate::{Result, connection::Connection, database::Database, errors::AppError};
|
use crate::{Result, buffer::try_get_string, connection::Connection, database::Database};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Has {
|
pub struct Has {
|
||||||
@@ -21,13 +21,7 @@ impl Has {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse(bytes: &mut Cursor<&[u8]>) -> Result<Self> {
|
pub fn parse(bytes: &mut Cursor<&[u8]>) -> Result<Self> {
|
||||||
let key_length = bytes.try_get_u16()? as usize;
|
let key = try_get_string(bytes)?;
|
||||||
|
|
||||||
if bytes.remaining() < key_length {
|
|
||||||
return Err(AppError::IncompleteCommandBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
let key = String::from_utf8(bytes.copy_to_bytes(key_length).to_vec())?;
|
|
||||||
|
|
||||||
Ok(Self { key })
|
Ok(Self { key })
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ mod ttl;
|
|||||||
|
|
||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
|
|
||||||
use bytes::{Buf, BytesMut};
|
use bytes::BytesMut;
|
||||||
use delete::Delete;
|
use delete::Delete;
|
||||||
use expire::Expire;
|
use expire::Expire;
|
||||||
use get::Get;
|
use get::Get;
|
||||||
@@ -17,7 +17,9 @@ use persist::Persist;
|
|||||||
use set::Set;
|
use set::Set;
|
||||||
use ttl::Ttl;
|
use ttl::Ttl;
|
||||||
|
|
||||||
use crate::{Result, connection::Connection, database::Database, errors::AppError};
|
use crate::{
|
||||||
|
Result, buffer::try_get_string, connection::Connection, database::Database, errors::AppError,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Command {
|
pub enum Command {
|
||||||
@@ -46,13 +48,7 @@ impl Command {
|
|||||||
pub fn parse(bytes: &BytesMut) -> Result<(Self, u64)> {
|
pub fn parse(bytes: &BytesMut) -> Result<(Self, u64)> {
|
||||||
let mut buffer = Cursor::new(&bytes[..]);
|
let mut buffer = Cursor::new(&bytes[..]);
|
||||||
|
|
||||||
let name_length = buffer.try_get_u16()? as usize;
|
let name = try_get_string(&mut buffer)?;
|
||||||
|
|
||||||
if buffer.remaining() < name_length {
|
|
||||||
return Err(AppError::IncompleteCommandBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
let name = String::from_utf8(buffer.copy_to_bytes(name_length).to_vec())?;
|
|
||||||
|
|
||||||
Self::parse_inner(name, &mut buffer)
|
Self::parse_inner(name, &mut buffer)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
|
|
||||||
use bytes::{Buf as _, Bytes};
|
use bytes::Bytes;
|
||||||
|
|
||||||
use crate::{Result, connection::Connection, database::Database, errors::AppError};
|
use crate::{Result, buffer::try_get_string, connection::Connection, database::Database};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Persist {
|
pub struct Persist {
|
||||||
@@ -21,13 +21,7 @@ impl Persist {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse(bytes: &mut Cursor<&[u8]>) -> Result<Self> {
|
pub fn parse(bytes: &mut Cursor<&[u8]>) -> Result<Self> {
|
||||||
let key_length = bytes.try_get_u16()? as usize;
|
let key = try_get_string(bytes)?;
|
||||||
|
|
||||||
if bytes.remaining() < key_length {
|
|
||||||
return Err(AppError::IncompleteCommandBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
let key = String::from_utf8(bytes.copy_to_bytes(key_length).to_vec())?;
|
|
||||||
|
|
||||||
Ok(Self { key })
|
Ok(Self { key })
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,12 @@
|
|||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
|
|
||||||
use crate::{Result, connection::Connection, database::Database, errors::AppError};
|
use crate::{
|
||||||
|
Result,
|
||||||
|
buffer::{try_get_bytes, try_get_string},
|
||||||
|
connection::Connection,
|
||||||
|
database::Database,
|
||||||
|
errors::AppError,
|
||||||
|
};
|
||||||
use bytes::{Buf as _, Bytes};
|
use bytes::{Buf as _, Bytes};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@@ -20,21 +26,9 @@ impl Set {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse(bytes: &mut Cursor<&[u8]>) -> Result<Self> {
|
pub fn parse(bytes: &mut Cursor<&[u8]>) -> Result<Self> {
|
||||||
let key_length = bytes.try_get_u16()? as usize;
|
let key = try_get_string(bytes)?;
|
||||||
|
|
||||||
if bytes.remaining() < key_length {
|
let data = try_get_bytes(bytes)?;
|
||||||
return Err(AppError::IncompleteCommandBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
let key = String::from_utf8(bytes.copy_to_bytes(key_length).to_vec())?;
|
|
||||||
|
|
||||||
let value_length = bytes.try_get_u32()? as usize;
|
|
||||||
|
|
||||||
if bytes.remaining() < value_length {
|
|
||||||
return Err(AppError::IncompleteCommandBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
let data = bytes.copy_to_bytes(value_length);
|
|
||||||
|
|
||||||
let expiration: Option<u64> = match bytes.try_get_u8()? {
|
let expiration: Option<u64> = match bytes.try_get_u8()? {
|
||||||
1 => Some(bytes.try_get_u64()?),
|
1 => Some(bytes.try_get_u64()?),
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
|
|
||||||
use bytes::{Buf as _, BufMut, Bytes, BytesMut};
|
use bytes::{BufMut, Bytes, BytesMut};
|
||||||
|
|
||||||
use crate::{Result, connection::Connection, database::Database, errors::AppError};
|
use crate::{Result, buffer::try_get_string, connection::Connection, database::Database};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Ttl {
|
pub struct Ttl {
|
||||||
@@ -29,13 +29,7 @@ impl Ttl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse(bytes: &mut Cursor<&[u8]>) -> Result<Self> {
|
pub fn parse(bytes: &mut Cursor<&[u8]>) -> Result<Self> {
|
||||||
let key_length = bytes.try_get_u16()? as usize;
|
let key = try_get_string(bytes)?;
|
||||||
|
|
||||||
if bytes.remaining() < key_length {
|
|
||||||
return Err(AppError::IncompleteCommandBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
let key = String::from_utf8(bytes.copy_to_bytes(key_length).to_vec())?;
|
|
||||||
|
|
||||||
Ok(Self { key })
|
Ok(Self { key })
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ pub enum AppError {
|
|||||||
Io(#[from] std::io::Error),
|
Io(#[from] std::io::Error),
|
||||||
#[error("A TryGetError occurred")]
|
#[error("A TryGetError occurred")]
|
||||||
TryGet(#[from] bytes::TryGetError),
|
TryGet(#[from] bytes::TryGetError),
|
||||||
#[error("The buffer is missing data for a complete command")]
|
#[error("The buffer is missing data")]
|
||||||
IncompleteCommandBuffer,
|
IncompleteBuffer,
|
||||||
#[error("A Utf8Error occurred")]
|
#[error("A Utf8Error occurred")]
|
||||||
FromUtf8(#[from] std::string::FromUtf8Error),
|
FromUtf8(#[from] std::string::FromUtf8Error),
|
||||||
#[error("The command {0} was not recognized")]
|
#[error("The command {0} was not recognized")]
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ use errors::AppError;
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub mod tests;
|
pub mod tests;
|
||||||
|
|
||||||
|
pub mod buffer;
|
||||||
pub mod client;
|
pub mod client;
|
||||||
pub mod commands;
|
pub mod commands;
|
||||||
pub mod config;
|
pub mod config;
|
||||||
|
|||||||
Reference in New Issue
Block a user