async_memcached/parser/
mod.rs

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