1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
use std::fmt;
mod ascii;
pub use ascii::{parse_ascii_metadump_response, parse_ascii_response, parse_ascii_stats_response};
/// A value from memcached.
#[derive(Clone, Debug, PartialEq)]
pub struct Value {
/// The key.
pub key: Vec<u8>,
/// CAS identifier.
pub cas: Option<u64>,
/// Flags for this key.
///
/// Defaults to 0.
pub flags: u32,
/// Data for this key.
pub data: Vec<u8>,
}
/// Status of a memcached operation.
#[derive(Clone, Debug, PartialEq)]
pub enum Status {
/// The value was stored.
Stored,
/// The value was not stored.
NotStored,
/// The key was deleted.
Deleted,
/// The key was touched.
Touched,
/// The key already exists.
Exists,
/// The key was not found.
NotFound,
/// An error occurred for the given operation.
Error(ErrorKind),
}
/// Errors related to a memcached operation.
#[derive(Clone, Debug, PartialEq)]
pub enum ErrorKind {
/// General error that may or may not have come from either the server or this crate.
Generic(String),
/// The command sent by the client does not exist.
NonexistentCommand,
/// Protocol-level error i.e. an invalid response from memcached for the given operation.
Protocol(Option<String>),
/// An error from memcached related to CLIENT_ERROR.
Client(String),
/// An error from memcached related to SERVER_ERROR.
Server(String),
}
/// Response to a memcached operation.
#[derive(Clone, Debug, PartialEq)]
pub enum Response {
/// The status of a given operation, which may or may not have succeeded.
Status(Status),
/// Data response, which is only returned for reads.
Data(Option<Vec<Value>>),
/// Resulting value of a key after an increment/decrement operation.
IncrDecr(u64),
}
/// Metadump response.
#[derive(Clone, Debug, PartialEq)]
pub enum MetadumpResponse {
/// The server is busy running another LRU crawler operation.
Busy(String),
/// An invalid class ID was specified for the metadump.
BadClass(String),
/// A single key entry within the overall metadump operation.
Entry(KeyMetadata),
/// End of the metadump.
End,
}
/// Stats response.
#[derive(Clone, Debug, PartialEq)]
pub enum StatsResponse {
/// A stats entry, represented by a key and value.
Entry(String, String),
/// End of stats output.
End,
}
/// Metadata for a given key in a metadump operation.
#[derive(Clone, Debug, PartialEq)]
pub struct KeyMetadata {
/// The key.
pub key: Vec<u8>,
/// Expiration time of this key, as a Unix timestamp.
pub expiration: i64,
/// Last time this key was accessed, in seconds.
pub last_accessed: u64,
/// CAS identifier.
pub cas: u64,
/// Whether or not this key has ever been fetched.
pub fetched: bool,
/// Slab class ID.
pub class_id: u32,
/// Size, in bytes.
pub size: u32,
}
impl fmt::Display for Status {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::Stored => write!(f, "stored"),
Self::NotStored => write!(f, "not stored"),
Self::Deleted => write!(f, "deleted"),
Self::Touched => write!(f, "touched"),
Self::Exists => write!(f, "exists"),
Self::NotFound => write!(f, "not found"),
Self::Error(ek) => write!(f, "error: {}", ek),
}
}
}
impl fmt::Display for ErrorKind {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::Generic(s) => write!(f, "generic: {}", s),
Self::NonexistentCommand => write!(f, "command does not exist"),
Self::Protocol(s) => match s {
Some(s) => write!(f, "protocol: {}", s),
None => write!(f, "protocol"),
},
Self::Client(s) => write!(f, "client: {}", s),
Self::Server(s) => write!(f, "server: {}", s),
}
}
}
impl From<MetadumpResponse> for Status {
fn from(resp: MetadumpResponse) -> Self {
match resp {
MetadumpResponse::BadClass(s) => {
Status::Error(ErrorKind::Generic(format!("BADCLASS {}", s)))
}
MetadumpResponse::Busy(s) => Status::Error(ErrorKind::Generic(format!("BUSY {}", s))),
_ => unreachable!("Metadump Entry/End states should never be used as a Status!"),
}
}
}