mcmc_rs/lib.rs
1//! Minimal Rust client for Memcached
2//!
3//! This crate provides working with memcached server.
4//! All methods implemented.
5//! Available TCP/Unix/UDP/TLS connections.
6//!
7//! - [Connection] is a Enum that represents a
8//! connection to memcached server.
9//! - [Pipeline] is a structure that represents a
10//! pipeline of memcached commands.
11//! - [WatchStream] is a structure that represents a
12//! stream of watch events.
13//! - [ClientCrc32] is a structure that represents a
14//! Cluster connections with ModN hashing.
15//! - [ClientHashRing] is a structure that represents a
16//! Cluster connections with Ring hashing.
17//! - [ClientRendezvous] is a structure that represents a
18//! Cluster connections with Rendezvous hashing.
19//!
20//! # Examples
21//!
22//! ```
23//! use smol::{block_on, io};
24//!
25//! use mcmc_rs::Connection;
26//!
27//! fn main() -> io::Result<()> {
28//! block_on(async {
29//! let mut conn = Connection::default().await?;
30//! conn.set(b"key", 0, 0, false, b"value").await?;
31//! let item = conn.get(b"key").await?.unwrap();
32//! println!("{item:#?}");
33//! Ok(())
34//! })
35//! }
36//! ```
37
38use std::collections::HashMap;
39use std::io::Write;
40
41use async_native_tls::{Certificate, TlsConnector, TlsStream};
42use crc32fast::hash as crc32;
43use deadpool::managed;
44use hashring::HashRing;
45use hrw_hash::HrwNodes;
46
47#[cfg(all(feature = "smol-runtime", feature = "tokio-runtime"))]
48compile_error!(
49 "feature \"smol-runtime\" and feature \"tokio-runtime\" cannot be enabled at the same time"
50);
51#[cfg(feature = "smol-runtime")]
52mod rt {
53 pub use smol::fs;
54 pub use smol::io::{self, BufReader, Cursor};
55 pub use smol::net::{TcpStream, UdpSocket, unix::UnixStream};
56 pub use smol::prelude::*;
57}
58#[cfg(feature = "tokio-runtime")]
59mod rt {
60 pub use std::io::Cursor;
61 pub use tokio::fs;
62 pub use tokio::io::{
63 self, AsyncBufRead, AsyncBufReadExt, AsyncReadExt, AsyncWrite, AsyncWriteExt, BufReader,
64 };
65 pub use tokio::net::{TcpStream, UdpSocket, UnixStream};
66}
67use rt::*;
68
69pub enum AddrArg<'a> {
70 Tcp(&'a str),
71 Unix(&'a str),
72 Udp(&'a str, &'a str),
73 Tls(&'a str, u16, &'a str),
74}
75
76pub struct Manager<'a>(AddrArg<'a>);
77impl<'a> Manager<'a> {
78 /// # Example
79 ///
80 /// ```
81 /// use mcmc_rs::{AddrArg, Manager, Pool};
82 /// # use smol::{io, block_on};
83 /// #
84 /// # block_on(async {
85 /// for a in [
86 /// AddrArg::Tcp("127.0.0.1:11211"),
87 /// AddrArg::Unix("/tmp/memcached0.sock"),
88 /// AddrArg::Udp("127.0.0.1:0", "127.0.0.1:11214"),
89 /// AddrArg::Tls("localhost", 11216, "cert.pem"),
90 /// ] {
91 /// let mgr = Manager::new(a);
92 /// let pool = Pool::builder(mgr).build().unwrap();
93 /// let mut conn = pool.get().await.unwrap();
94 /// let result = conn.version().await?;
95 /// assert!(result.chars().any(|x| x.is_numeric()));
96 /// }
97 /// # Ok::<(), io::Error>(())
98 /// # }).unwrap()
99 /// ```
100 pub fn new(addr: AddrArg<'a>) -> Self {
101 Self(addr)
102 }
103}
104
105impl<'a> managed::Manager for Manager<'a> {
106 type Type = Connection;
107 type Error = io::Error;
108
109 async fn create(&self) -> Result<Connection, io::Error> {
110 match self.0 {
111 AddrArg::Tcp(addr) => Connection::tcp_connect(addr).await,
112 AddrArg::Unix(addr) => Connection::unix_connect(addr).await,
113 AddrArg::Udp(bind_addr, connect_addr) => {
114 Connection::udp_connect(bind_addr, connect_addr).await
115 }
116 AddrArg::Tls(hostname, port, ca_path) => {
117 Connection::tls_connect(hostname, port, ca_path).await
118 }
119 }
120 }
121
122 async fn recycle(
123 &self,
124 conn: &mut Connection,
125 _: &managed::Metrics,
126 ) -> managed::RecycleResult<io::Error> {
127 match conn.version().await {
128 Ok(_) => Ok(()),
129 Err(e) => Err(e.into()),
130 }
131 }
132}
133
134pub type Pool<'a> = managed::Pool<Manager<'a>>;
135
136pub enum StatsArg {
137 Settings,
138 Items,
139 Sizes,
140 Slabs,
141 Conns,
142}
143
144pub enum SlabsAutomoveArg {
145 Zero,
146 One,
147 Two,
148}
149
150pub enum LruCrawlerArg {
151 Enable,
152 Disable,
153}
154
155pub enum LruCrawlerCrawlArg<'a> {
156 Classids(&'a [usize]),
157 All,
158}
159
160pub enum LruCrawlerMetadumpArg<'a> {
161 Classids(&'a [usize]),
162 All,
163 Hash,
164}
165
166pub enum LruCrawlerMgdumpArg<'a> {
167 Classids(&'a [usize]),
168 All,
169 Hash,
170}
171
172pub enum WatchArg {
173 Fetchers,
174 Mutations,
175 Evictions,
176 Connevents,
177 Proxyreqs,
178 Proxyevents,
179 Proxyuser,
180 Deletions,
181}
182
183pub enum LruMode {
184 Flat,
185 Segmented,
186}
187
188pub enum LruArg {
189 Tune {
190 percent_hot: u8,
191 percent_warm: u8,
192 max_hot_factor: f32,
193 max_warm_factor: f32,
194 },
195 Mode(LruMode),
196 TempTtl(i64),
197}
198
199#[derive(Debug, PartialEq)]
200pub struct Item {
201 pub key: String,
202 pub flags: u32,
203 pub cas_unique: Option<u64>,
204 pub data_block: Vec<u8>,
205}
206
207#[derive(Debug, PartialEq)]
208pub enum PipelineResponse {
209 Bool(bool),
210 OptionItem(Option<Item>),
211 VecItem(Vec<Item>),
212 String(String),
213 OptionString(Option<String>),
214 VecString(Vec<String>),
215 Unit(()),
216 Value(Option<u64>),
217 HashMap(HashMap<String, String>),
218 MetaGet(MgItem),
219 MetaSet(MsItem),
220 MetaDelete(MdItem),
221 MetaArithmetic(MaItem),
222}
223
224pub enum MsMode {
225 Add,
226 Append,
227 Prepend,
228 Replace,
229 Set,
230}
231
232pub enum MaMode {
233 Incr,
234 Decr,
235}
236
237pub enum MsFlag {
238 Base64Key,
239 ReturnCas,
240 CompareCas(u64),
241 NewCas(u64),
242 SetFlags(u32),
243 Invalidate,
244 ReturnKey,
245 Opaque(String),
246 ReturnSize,
247 Ttl(i64),
248 Mode(MsMode),
249 Autovivify(i64),
250}
251
252pub enum MgFlag {
253 Base64Key,
254 ReturnCas,
255 CheckCas(u64),
256 ReturnFlags,
257 ReturnHit,
258 ReturnKey,
259 ReturnLastAccess,
260 Opaque(String),
261 ReturnSize,
262 ReturnTtl,
263 UnBump,
264 ReturnValue,
265 NewCas(u64),
266 Autovivify(i64),
267 RecacheTtl(i64),
268 UpdateTtl(i64),
269}
270
271pub enum MdFlag {
272 Base64Key,
273 CompareCas(u64),
274 NewCas(u64),
275 Invalidate,
276 ReturnKey,
277 Opaque(String),
278 UpdateTtl(i64),
279 LeaveKey,
280}
281
282pub enum MaFlag {
283 Base64Key,
284 CompareCas(u64),
285 NewCas(u64),
286 AutoCreate(i64),
287 InitValue(u64),
288 DeltaApply(u64),
289 UpdateTtl(i64),
290 Mode(MaMode),
291 Opaque(String),
292 ReturnTtl,
293 ReturnCas,
294 ReturnValue,
295 ReturnKey,
296}
297
298#[derive(Debug, PartialEq)]
299pub struct MgItem {
300 pub success: bool,
301 pub base64_key: bool,
302 pub cas: Option<u64>,
303 pub flags: Option<u32>,
304 pub hit: Option<u8>,
305 pub key: Option<String>,
306 pub last_access_ttl: Option<i64>,
307 pub opaque: Option<String>,
308 pub size: Option<usize>,
309 pub ttl: Option<i64>,
310 pub data_block: Option<Vec<u8>>,
311 pub won_recache: bool,
312 pub stale: bool,
313 pub already_win: bool,
314}
315
316#[derive(Debug, PartialEq)]
317pub struct MsItem {
318 pub success: bool,
319 pub cas: Option<u64>,
320 pub key: Option<String>,
321 pub opaque: Option<String>,
322 pub size: Option<usize>,
323 pub base64_key: bool,
324}
325
326#[derive(Debug, PartialEq)]
327pub struct MdItem {
328 pub success: bool,
329 pub key: Option<String>,
330 pub opaque: Option<String>,
331 pub base64_key: bool,
332}
333
334#[derive(Debug, PartialEq)]
335pub struct MaItem {
336 pub success: bool,
337 pub opaque: Option<String>,
338 pub ttl: Option<i64>,
339 pub cas: Option<u64>,
340 pub number: Option<u64>,
341 pub key: Option<String>,
342 pub base64_key: bool,
343}
344
345async fn parse_storage_rp<S: AsyncBufRead + AsyncWrite + Unpin>(
346 s: &mut S,
347 noreply: bool,
348) -> io::Result<bool> {
349 if noreply {
350 return Ok(true);
351 }
352 let mut line = String::new();
353 s.read_line(&mut line).await?;
354 match line.as_str() {
355 "STORED\r\n" => Ok(true),
356 "NOT_STORED\r\n" | "EXISTS\r\n" | "NOT_FOUND\r\n" => Ok(false),
357 _ => Err(io::Error::other(line)),
358 }
359}
360
361async fn parse_retrieval_rp<S: AsyncBufRead + AsyncWrite + Unpin>(
362 s: &mut S,
363) -> io::Result<Vec<Item>> {
364 let mut line = String::new();
365 s.read_line(&mut line).await?;
366 let mut items = Vec::new();
367 while line.starts_with("VALUE") {
368 let mut split = line.split(' ');
369 split.next();
370 let (key, flags, bytes, cas_unique) = (
371 split.next().unwrap().to_string(),
372 split.next().unwrap().parse().unwrap(),
373 split.next().unwrap().trim_end().parse().unwrap(),
374 split.next().map(|x| x.trim_end().parse().unwrap()),
375 );
376 let mut data_block = vec![0; bytes + 2];
377 s.read_exact(&mut data_block).await?;
378 data_block.truncate(bytes);
379 items.push(Item {
380 key,
381 flags,
382 cas_unique,
383 data_block,
384 });
385 line.clear();
386 s.read_line(&mut line).await?;
387 }
388 if line == "END\r\n" {
389 Ok(items)
390 } else {
391 Err(io::Error::other(line))
392 }
393}
394
395async fn parse_version_rp<S: AsyncBufRead + AsyncWrite + Unpin>(s: &mut S) -> io::Result<String> {
396 let mut line = String::new();
397 let n = s.read_line(&mut line).await?;
398 if line.starts_with("VERSION") {
399 Ok(line[8..n - 2].to_string())
400 } else {
401 Err(io::Error::other(line))
402 }
403}
404
405async fn parse_ok_rp<S: AsyncBufRead + AsyncWrite + Unpin>(
406 s: &mut S,
407 noreply: bool,
408) -> io::Result<()> {
409 if noreply {
410 return Ok(());
411 }
412 let mut line = String::new();
413 s.read_line(&mut line).await?;
414 if line == "OK\r\n" {
415 Ok(())
416 } else {
417 Err(io::Error::other(line))
418 }
419}
420
421async fn parse_delete_rp<S: AsyncBufRead + AsyncWrite + Unpin>(
422 s: &mut S,
423 noreply: bool,
424) -> io::Result<bool> {
425 if noreply {
426 return Ok(true);
427 }
428 let mut line = String::new();
429 s.read_line(&mut line).await?;
430 match line.as_str() {
431 "DELETED\r\n" => Ok(true),
432 "NOT_FOUND\r\n" => Ok(false),
433 _ => Err(io::Error::other(line)),
434 }
435}
436
437async fn parse_auth_rp<S: AsyncBufRead + AsyncWrite + Unpin>(s: &mut S) -> io::Result<()> {
438 let mut line = String::new();
439 s.read_line(&mut line).await?;
440 match line.as_str() {
441 "STORED\r\n" => Ok(()),
442 _ => Err(io::Error::other(line)),
443 }
444}
445
446async fn parse_incr_decr_rp<S: AsyncBufRead + AsyncWrite + Unpin>(
447 s: &mut S,
448 noreply: bool,
449) -> io::Result<Option<u64>> {
450 if noreply {
451 return Ok(None);
452 }
453 let mut line = String::new();
454 s.read_line(&mut line).await?;
455 if line == "NOT_FOUND\r\n" {
456 return Ok(None);
457 }
458 match line.trim_end().parse() {
459 Ok(v) => Ok(Some(v)),
460 Err(_) => Err(io::Error::other(line)),
461 }
462}
463
464async fn parse_touch_rp<S: AsyncBufRead + AsyncWrite + Unpin>(
465 s: &mut S,
466 noreply: bool,
467) -> io::Result<bool> {
468 if noreply {
469 return Ok(true);
470 }
471 let mut line = String::new();
472 s.read_line(&mut line).await?;
473 if line == "TOUCHED\r\n" {
474 Ok(true)
475 } else if line == "NOT_FOUND\r\n" {
476 Ok(false)
477 } else {
478 Err(io::Error::other(line))
479 }
480}
481
482async fn parse_stats_rp<S: AsyncBufRead + AsyncWrite + Unpin>(
483 s: &mut S,
484) -> io::Result<HashMap<String, String>> {
485 let mut items = HashMap::new();
486 let mut data = String::new();
487 s.read_line(&mut data).await?;
488 while data != "END\r\n" {
489 if data.starts_with("STAT") {
490 let mut split = data.split(' ');
491 split.next();
492 let (k, v) = (
493 split.next().unwrap().to_string(),
494 split.next().unwrap().trim_end().to_string(),
495 );
496 items.insert(k, v);
497 data.clear();
498 s.read_line(&mut data).await?;
499 } else {
500 return Err(io::Error::other(data));
501 }
502 }
503 Ok(items)
504}
505
506async fn parse_lru_crawler_metadump_rp<S: AsyncBufRead + AsyncWrite + Unpin>(
507 s: &mut S,
508) -> io::Result<Vec<String>> {
509 let mut line = String::new();
510 s.read_line(&mut line).await?;
511 let mut items = Vec::new();
512 while line.starts_with("key=") {
513 items.push(line.trim_end().to_string());
514 line.clear();
515 s.read_line(&mut line).await?;
516 }
517 if line == "END\r\n" {
518 Ok(items)
519 } else {
520 Err(io::Error::other(line))
521 }
522}
523
524async fn parse_lru_crawler_mgdump_rp<S: AsyncBufRead + AsyncWrite + Unpin>(
525 s: &mut S,
526) -> io::Result<Vec<String>> {
527 let mut line = String::new();
528 s.read_line(&mut line).await?;
529 let mut items = Vec::new();
530 while line.starts_with("mg ") {
531 let mut split = line.split(' ');
532 split.next();
533 items.push(split.next().unwrap().trim_end().to_string());
534 line.clear();
535 s.read_line(&mut line).await?;
536 }
537 if line == "EN\r\n" {
538 Ok(items)
539 } else {
540 Err(io::Error::other(line))
541 }
542}
543
544async fn parse_mn_rp<S: AsyncBufRead + AsyncWrite + Unpin>(s: &mut S) -> io::Result<()> {
545 let mut line = String::new();
546 s.read_line(&mut line).await?;
547 if line == "MN\r\n" {
548 Ok(())
549 } else {
550 Err(io::Error::other(line))
551 }
552}
553
554async fn parse_me_rp<S: AsyncBufRead + AsyncWrite + Unpin>(
555 s: &mut S,
556) -> io::Result<Option<String>> {
557 let mut line = String::new();
558 let n = s.read_line(&mut line).await?;
559 if line == "EN\r\n" {
560 Ok(None)
561 } else if line.starts_with("ME") {
562 Ok(Some(line[3..n - 2].to_string()))
563 } else {
564 Err(io::Error::other(line))
565 }
566}
567
568async fn parse_mg_rp<S: AsyncBufRead + AsyncWrite + Unpin>(s: &mut S) -> io::Result<MgItem> {
569 let mut line = String::new();
570 s.read_line(&mut line).await?;
571 let success;
572 let (
573 mut base64_key,
574 mut cas,
575 mut flags,
576 mut hit,
577 mut key,
578 mut last_access_ttl,
579 mut opaque,
580 mut size,
581 mut ttl,
582 mut data_block,
583 mut won_recache,
584 mut stale,
585 mut already_win,
586 ) = (
587 false, None, None, None, None, None, None, None, None, None, false, false, false,
588 );
589 let mut split = line.trim_end().split(' ');
590 let data_len = if line.starts_with("VA") {
591 success = true;
592 split.next();
593 Some(split.next().unwrap().parse().unwrap())
594 } else if line.starts_with("HD") {
595 success = true;
596 split.next();
597 None
598 } else if line.starts_with("EN") {
599 success = false;
600 split.next();
601 None
602 } else {
603 return Err(io::Error::other(line));
604 };
605 for flag in split {
606 let f = &flag[1..];
607 match &flag[..1] {
608 "b" => base64_key = true,
609 "c" => cas = Some(f.parse().unwrap()),
610 "f" => flags = Some(f.parse().unwrap()),
611 "h" => hit = Some(f.parse().unwrap()),
612 "k" => key = Some(f.to_string()),
613 "l" => last_access_ttl = Some(f.parse().unwrap()),
614 "O" => opaque = Some(f.to_string()),
615 "s" => size = Some(f.parse().unwrap()),
616 "t" => ttl = Some(f.parse().unwrap()),
617 "W" => won_recache = true,
618 "X" => stale = true,
619 "Z" => already_win = true,
620 other => unreachable!("unexpected mg flag: {other}"),
621 }
622 }
623 if let Some(a) = data_len {
624 let mut buf = vec![0; a + 2];
625 s.read_exact(&mut buf).await?;
626 buf.truncate(a);
627 data_block = Some(buf);
628 }
629 Ok(MgItem {
630 success,
631 base64_key,
632 cas,
633 flags,
634 hit,
635 key,
636 last_access_ttl,
637 opaque,
638 size,
639 ttl,
640 data_block,
641 won_recache,
642 stale,
643 already_win,
644 })
645}
646
647async fn parse_ms_rp<S: AsyncBufRead + AsyncWrite + Unpin>(s: &mut S) -> io::Result<MsItem> {
648 let mut line = String::new();
649 s.read_line(&mut line).await?;
650 let success;
651 let (mut cas, mut key, mut opaque, mut size, mut base64_key) = (None, None, None, None, false);
652 if line.starts_with("HD") {
653 success = true
654 } else if line.starts_with("NS") || line.starts_with("EX") || line.starts_with("NF") {
655 success = false
656 } else {
657 return Err(io::Error::other(line));
658 }
659 let mut split = line.trim_end().split(' ');
660 split.next();
661 for flag in split {
662 let f = &flag[1..];
663 match &flag[..1] {
664 "c" => cas = Some(f.parse().unwrap()),
665 "k" => key = Some(f.to_string()),
666 "O" => opaque = Some(f.to_string()),
667 "s" => size = Some(f.parse().unwrap()),
668 "b" => base64_key = true,
669 other => unreachable!("unexpected ms flag: {other}"),
670 }
671 }
672 Ok(MsItem {
673 success,
674 cas,
675 opaque,
676 key,
677 size,
678 base64_key,
679 })
680}
681
682async fn parse_md_rp<S: AsyncBufRead + AsyncWrite + Unpin>(s: &mut S) -> io::Result<MdItem> {
683 let mut line = String::new();
684 s.read_line(&mut line).await?;
685 let success;
686 let (mut key, mut opaque, mut base64_key) = (None, None, false);
687 if line.starts_with("HD") {
688 success = true
689 } else if line.starts_with("NF") || line.starts_with("EX") {
690 success = false
691 } else {
692 return Err(io::Error::other(line));
693 }
694 let mut split = line.trim_end().split(' ');
695 split.next();
696 for flag in split {
697 let f = &flag[1..];
698 match &flag[..1] {
699 "k" => key = Some(f.to_string()),
700 "O" => opaque = Some(f.to_string()),
701 "b" => base64_key = true,
702 other => unreachable!("unexpected md flag: {other}"),
703 }
704 }
705 Ok(MdItem {
706 success,
707 key,
708 opaque,
709 base64_key,
710 })
711}
712
713async fn parse_ma_rp<S: AsyncBufRead + AsyncWrite + Unpin>(s: &mut S) -> io::Result<MaItem> {
714 let mut line = String::new();
715 s.read_line(&mut line).await?;
716 let success;
717 let (mut opaque, mut ttl, mut cas, mut number, mut key, mut base64_key) =
718 (None, None, None, None, None, false);
719 let mut split = line.trim_end().split(' ');
720 let data_len = if line.starts_with("VA") {
721 split.next();
722 success = true;
723 Some(split.next().unwrap().parse().unwrap())
724 } else if line.starts_with("HD") {
725 split.next();
726 success = true;
727 None
728 } else if line.starts_with("NS") || line.starts_with("EX") || line.starts_with("NF") {
729 split.next();
730 success = false;
731 None
732 } else {
733 return Err(io::Error::other(line));
734 };
735 for flag in split {
736 let f = &flag[1..];
737 match &flag[..1] {
738 "O" => opaque = Some(f.to_string()),
739 "t" => ttl = Some(f.parse().unwrap()),
740 "c" => cas = Some(f.parse().unwrap()),
741 "k" => key = Some(f.to_string()),
742 "b" => base64_key = true,
743 other => unreachable!("unexpected ma flag: {other}"),
744 }
745 }
746 if let Some(a) = data_len {
747 let mut buf = String::with_capacity(a + 2);
748 s.read_line(&mut buf).await?;
749 buf.truncate(a);
750 number = Some(buf.parse().unwrap());
751 }
752 Ok(MaItem {
753 success,
754 opaque,
755 ttl,
756 cas,
757 number,
758 key,
759 base64_key,
760 })
761}
762
763fn build_storage_cmd(
764 command_name: &[u8],
765 key: &[u8],
766 flags: u32,
767 exptime: i64,
768 cas_unique: Option<u64>,
769 noreply: bool,
770 data_block: &[u8],
771) -> Vec<u8> {
772 let mut w = Vec::from(command_name);
773 w.push(b' ');
774 w.extend(key);
775 w.push(b' ');
776 write!(&mut w, "{flags} {exptime} {}", data_block.len()).unwrap();
777 if let Some(x) = cas_unique {
778 write!(&mut w, " {x}").unwrap()
779 }
780 if noreply {
781 w.extend(b" noreply")
782 }
783 w.extend(b"\r\n");
784 w.extend(data_block);
785 w.extend(b"\r\n");
786 w
787}
788
789fn build_retrieval_cmd(command_name: &[u8], exptime: Option<i64>, keys: &[&[u8]]) -> Vec<u8> {
790 let mut w = Vec::from(command_name);
791 if let Some(x) = exptime {
792 write!(&mut w, " {x}").unwrap()
793 }
794 keys.iter().for_each(|&x| {
795 w.push(b' ');
796 w.extend(x)
797 });
798 w.extend(b"\r\n");
799 w
800}
801
802fn build_version_cmd() -> &'static [u8] {
803 b"version\r\n"
804}
805
806fn build_quit_cmd() -> &'static [u8] {
807 b"quit\r\n"
808}
809
810fn build_shutdown_cmd(graceful: bool) -> &'static [u8] {
811 if graceful {
812 b"shutdown graceful\r\n"
813 } else {
814 b"shutdown\r\n"
815 }
816}
817
818fn build_cache_memlimit_cmd(limit: usize, noreply: bool) -> Vec<u8> {
819 let mut w = Vec::new();
820 write!(
821 &mut w,
822 "cache_memlimit {limit}{}\r\n",
823 if noreply { " noreply" } else { "" }
824 )
825 .unwrap();
826 w
827}
828
829fn build_flush_all_cmd(exptime: Option<i64>, noreply: bool) -> Vec<u8> {
830 let mut w = Vec::from(b"flush_all");
831 if let Some(x) = exptime {
832 write!(&mut w, " {x}").unwrap()
833 }
834 if noreply {
835 w.extend(b" noreply")
836 }
837 w.extend(b"\r\n");
838 w
839}
840
841fn build_delete_cmd(key: &[u8], noreply: bool) -> Vec<u8> {
842 let mut w = Vec::from(b"delete ");
843 w.extend(key);
844 if noreply {
845 w.extend(b" noreply")
846 }
847 w.extend(b"\r\n");
848 w
849}
850
851fn build_auth_cmd(username: &[u8], password: &[u8]) -> Vec<u8> {
852 let mut w = Vec::new();
853 write!(
854 &mut w,
855 "set _ _ _ {}\r\n",
856 username.len() + password.len() + 1
857 )
858 .unwrap();
859 w.extend(username);
860 w.push(b' ');
861 w.extend(password);
862 w.extend(b"\r\n");
863 w
864}
865
866fn build_incr_decr_cmd(command_name: &[u8], key: &[u8], value: u64, noreply: bool) -> Vec<u8> {
867 let mut w = Vec::from(command_name);
868 w.push(b' ');
869 w.extend(key);
870 write!(
871 &mut w,
872 " {value}{}\r\n",
873 if noreply { " noreply" } else { "" }
874 )
875 .unwrap();
876 w
877}
878
879fn build_touch_cmd(key: &[u8], exptime: i64, noreply: bool) -> Vec<u8> {
880 let mut w = Vec::from(b"touch ");
881 w.extend(key);
882 write!(
883 &mut w,
884 " {exptime}{}\r\n",
885 if noreply { " noreply" } else { "" }
886 )
887 .unwrap();
888 w
889}
890
891fn build_stats_cmd(arg: Option<StatsArg>) -> &'static [u8] {
892 match arg {
893 Some(a) => match a {
894 StatsArg::Settings => b"stats settings\r\n",
895 StatsArg::Items => b"stats items\r\n",
896 StatsArg::Sizes => b"stats sizes\r\n",
897 StatsArg::Slabs => b"stats slabs\r\n",
898 StatsArg::Conns => b"stats conns\r\n",
899 },
900 None => b"stats\r\n",
901 }
902}
903
904fn build_slabs_automove_cmd(arg: SlabsAutomoveArg) -> &'static [u8] {
905 match arg {
906 SlabsAutomoveArg::Zero => b"slabs automove 0\r\n",
907 SlabsAutomoveArg::One => b"slabs automove 1\r\n",
908 SlabsAutomoveArg::Two => b"slabs automove 2\r\n",
909 }
910}
911
912fn build_lru_crawler_cmd(arg: LruCrawlerArg) -> &'static [u8] {
913 match arg {
914 LruCrawlerArg::Enable => b"lru_crawler enable\r\n",
915 LruCrawlerArg::Disable => b"lru_crawler disable\r\n",
916 }
917}
918
919fn build_lru_clawler_sleep_cmd(microseconds: usize) -> Vec<u8> {
920 let mut w = Vec::new();
921 write!(&mut w, "lru_crawler sleep {microseconds}\r\n").unwrap();
922 w
923}
924
925fn build_lru_crawler_tocrawl_cmd(arg: u32) -> Vec<u8> {
926 let mut w = Vec::new();
927 write!(&mut w, "lru_crawler tocrawl {arg}\r\n").unwrap();
928 w
929}
930
931fn build_lru_clawler_crawl_cmd(arg: LruCrawlerCrawlArg) -> Vec<u8> {
932 let mut w = Vec::from(b"lru_crawler crawl ");
933 match arg {
934 LruCrawlerCrawlArg::Classids(ids) => ids.iter().enumerate().for_each(|(index, id)| {
935 if index == 0 {
936 write!(&mut w, "{}", id).unwrap()
937 } else {
938 write!(&mut w, ",{}", id).unwrap()
939 }
940 }),
941 LruCrawlerCrawlArg::All => w.extend(b"all"),
942 }
943 w.extend(b"\r\n");
944 w
945}
946
947fn build_slabs_reassign_cmd(source_class: isize, dest_class: isize) -> Vec<u8> {
948 let mut w = Vec::new();
949 write!(&mut w, "slabs reassign {source_class} {dest_class}\r\n").unwrap();
950 w
951}
952
953fn build_lru_clawler_metadump_cmd(arg: LruCrawlerMetadumpArg) -> Vec<u8> {
954 let mut w = Vec::from(b"lru_crawler metadump ");
955 match arg {
956 LruCrawlerMetadumpArg::Classids(ids) => ids.iter().enumerate().for_each(|(index, id)| {
957 if index == 0 {
958 write!(&mut w, "{}", id).unwrap()
959 } else {
960 write!(&mut w, ",{}", id).unwrap()
961 }
962 }),
963 LruCrawlerMetadumpArg::All => w.extend(b"all"),
964 LruCrawlerMetadumpArg::Hash => w.extend(b"hash"),
965 }
966 w.extend(b"\r\n");
967 w
968}
969
970fn build_lru_clawler_mgdump_cmd(arg: LruCrawlerMgdumpArg) -> Vec<u8> {
971 let mut w = Vec::from(b"lru_crawler mgdump ");
972 match arg {
973 LruCrawlerMgdumpArg::Classids(ids) => ids.iter().enumerate().for_each(|(index, id)| {
974 if index == 0 {
975 write!(&mut w, "{}", id).unwrap()
976 } else {
977 write!(&mut w, ",{}", id).unwrap()
978 }
979 }),
980 LruCrawlerMgdumpArg::All => w.extend(b"all"),
981 LruCrawlerMgdumpArg::Hash => w.extend(b"hash"),
982 }
983 w.extend(b"\r\n");
984 w
985}
986
987fn build_mn_cmd() -> &'static [u8] {
988 b"mn\r\n"
989}
990
991fn build_me_cmd(key: &[u8]) -> Vec<u8> {
992 let mut w = Vec::from(b"me ");
993 w.extend(key);
994 w.extend(b"\r\n");
995 w
996}
997
998fn build_watch_cmd(arg: &[WatchArg]) -> Vec<u8> {
999 let mut w = Vec::from(b"watch");
1000 arg.iter().for_each(|a| {
1001 w.extend(match a {
1002 WatchArg::Fetchers => b" fetchers".as_slice(),
1003 WatchArg::Mutations => b" mutations",
1004 WatchArg::Evictions => b" evictions",
1005 WatchArg::Connevents => b" connevents",
1006 WatchArg::Proxyreqs => b" proxyreqs",
1007 WatchArg::Proxyevents => b" proxyevents",
1008 WatchArg::Proxyuser => b" proxyuser",
1009 WatchArg::Deletions => b" deletions",
1010 })
1011 });
1012 w.extend(b"\r\n");
1013 w
1014}
1015
1016fn build_mc_cmd(
1017 command_name: &[u8],
1018 key: &[u8],
1019 flags: &[u8],
1020 data_block: Option<&[u8]>,
1021) -> Vec<u8> {
1022 let mut w = Vec::from(command_name);
1023 w.push(b' ');
1024 w.extend(key);
1025 if let Some(x) = data_block {
1026 write!(&mut w, " {}", x.len()).unwrap();
1027 w.extend(flags);
1028 w.extend(b"\r\n");
1029 w.extend(x);
1030 w.extend(b"\r\n");
1031 } else {
1032 w.extend(flags);
1033 w.extend(b"\r\n");
1034 }
1035 w
1036}
1037
1038fn build_ms_flags(flags: &[MsFlag]) -> Vec<u8> {
1039 let mut w = Vec::new();
1040 flags.iter().for_each(|x| match x {
1041 MsFlag::Base64Key => w.extend(b" b"),
1042 MsFlag::ReturnCas => w.extend(b" c"),
1043 MsFlag::CompareCas(token) => write!(&mut w, " C{token}").unwrap(),
1044 MsFlag::NewCas(token) => write!(&mut w, " E{token}").unwrap(),
1045 MsFlag::SetFlags(token) => write!(&mut w, " F{token}").unwrap(),
1046 MsFlag::Invalidate => w.extend(b" I"),
1047 MsFlag::ReturnKey => w.extend(b" k"),
1048 MsFlag::Opaque(token) => write!(&mut w, " O{token}").unwrap(),
1049 MsFlag::ReturnSize => w.extend(b" s"),
1050 MsFlag::Ttl(token) => write!(&mut w, " T{token}").unwrap(),
1051 MsFlag::Mode(token) => match token {
1052 MsMode::Add => w.extend(b" ME"),
1053 MsMode::Append => w.extend(b" MA"),
1054 MsMode::Prepend => w.extend(b" MP"),
1055 MsMode::Replace => w.extend(b" MR"),
1056 MsMode::Set => w.extend(b" MS"),
1057 },
1058 MsFlag::Autovivify(token) => write!(&mut w, " N{token}").unwrap(),
1059 });
1060 w
1061}
1062
1063fn build_mg_flags(flags: &[MgFlag]) -> Vec<u8> {
1064 let mut w = Vec::new();
1065 flags.iter().for_each(|x| match x {
1066 MgFlag::Base64Key => w.extend(b" b"),
1067 MgFlag::ReturnCas => w.extend(b" c"),
1068 MgFlag::CheckCas(token) => write!(&mut w, " C{token}").unwrap(),
1069 MgFlag::ReturnFlags => w.extend(b" f"),
1070 MgFlag::ReturnHit => w.extend(b" h"),
1071 MgFlag::ReturnKey => w.extend(b" k"),
1072 MgFlag::ReturnLastAccess => w.extend(b" l"),
1073 MgFlag::Opaque(token) => write!(&mut w, " O{token}").unwrap(),
1074 MgFlag::ReturnSize => w.extend(b" s"),
1075 MgFlag::ReturnTtl => w.extend(b" t"),
1076 MgFlag::UnBump => w.extend(b" u"),
1077 MgFlag::ReturnValue => w.extend(b" v"),
1078 MgFlag::NewCas(token) => write!(&mut w, " E{token}").unwrap(),
1079 MgFlag::Autovivify(token) => write!(&mut w, " N{token}").unwrap(),
1080 MgFlag::RecacheTtl(token) => write!(&mut w, " R{token}").unwrap(),
1081 MgFlag::UpdateTtl(token) => write!(&mut w, " T{token}").unwrap(),
1082 });
1083 w
1084}
1085
1086fn build_md_flags(flags: &[MdFlag]) -> Vec<u8> {
1087 let mut w = Vec::new();
1088 flags.iter().for_each(|x| match x {
1089 MdFlag::Base64Key => w.extend(b" b"),
1090 MdFlag::CompareCas(token) => write!(&mut w, " C{token}").unwrap(),
1091 MdFlag::NewCas(token) => write!(&mut w, " E{token}").unwrap(),
1092 MdFlag::Invalidate => w.extend(b" I"),
1093 MdFlag::ReturnKey => w.extend(b" k"),
1094 MdFlag::Opaque(token) => write!(&mut w, " O{token}").unwrap(),
1095 MdFlag::UpdateTtl(token) => write!(&mut w, " T{token}").unwrap(),
1096 MdFlag::LeaveKey => w.extend(b" x"),
1097 });
1098 w
1099}
1100
1101fn build_ma_flags(flags: &[MaFlag]) -> Vec<u8> {
1102 let mut w = Vec::new();
1103 flags.iter().for_each(|x| match x {
1104 MaFlag::Base64Key => w.extend(b" b"),
1105 MaFlag::CompareCas(token) => write!(&mut w, " C{token}").unwrap(),
1106 MaFlag::NewCas(token) => write!(&mut w, " E{token}").unwrap(),
1107 MaFlag::AutoCreate(token) => write!(&mut w, " N{token}").unwrap(),
1108 MaFlag::InitValue(token) => write!(&mut w, " J{token}").unwrap(),
1109 MaFlag::DeltaApply(token) => write!(&mut w, " D{token}").unwrap(),
1110 MaFlag::UpdateTtl(token) => write!(&mut w, " T{token}").unwrap(),
1111 MaFlag::Mode(token) => match token {
1112 MaMode::Incr => w.extend(b" M+"),
1113 MaMode::Decr => w.extend(b" M-"),
1114 },
1115 MaFlag::Opaque(token) => write!(&mut w, " O{token}").unwrap(),
1116 MaFlag::ReturnTtl => w.extend(b" t"),
1117 MaFlag::ReturnCas => w.extend(b" c"),
1118 MaFlag::ReturnValue => w.extend(b" v"),
1119 MaFlag::ReturnKey => w.extend(b" k"),
1120 });
1121 w
1122}
1123
1124fn build_lru_cmd(arg: LruArg) -> Vec<u8> {
1125 let mut w = Vec::new();
1126 match arg {
1127 LruArg::Tune {
1128 percent_hot,
1129 percent_warm,
1130 max_hot_factor,
1131 max_warm_factor,
1132 } => write!(
1133 &mut w,
1134 "lru tune {percent_hot} {percent_warm} {max_hot_factor} {max_warm_factor}\r\n"
1135 )
1136 .unwrap(),
1137 LruArg::Mode(mode) => match mode {
1138 LruMode::Flat => w.extend(b"lru mode flat\r\n"),
1139 LruMode::Segmented => w.extend(b"lru mode segmented\r\n"),
1140 },
1141 LruArg::TempTtl(ttl) => write!(&mut w, "lru temp_ttl {ttl}\r\n").unwrap(),
1142 }
1143 w
1144}
1145
1146async fn udp_send_cmd(s: &mut UdpSocket, r: &mut u16, cmd: &[u8]) -> io::Result<()> {
1147 *r = r.wrapping_add(1);
1148 let mut msg = Vec::from(r.to_be_bytes());
1149 msg.extend([0, 0, 0, 1, 0, 0]);
1150 msg.extend(cmd);
1151 s.send(&msg).await?;
1152 Ok(())
1153}
1154
1155async fn udp_recv_rp(s: &mut UdpSocket, r: &u16) -> io::Result<Vec<u8>> {
1156 let mut count_datagrams = 0;
1157 let mut result = HashMap::new();
1158 loop {
1159 let mut buf = [0; 1400];
1160 let n = s.recv(&mut buf).await?;
1161 if n < 8 {
1162 return Err(io::Error::other("Invalid UDP header"));
1163 }
1164 let request_id = u16::from_be_bytes([buf[0], buf[1]]);
1165 let sequence_number = u16::from_be_bytes([buf[2], buf[3]]);
1166 let total_number_datagrams = u16::from_be_bytes([buf[4], buf[5]]);
1167 if *r != request_id {
1168 continue;
1169 }
1170 count_datagrams += 1;
1171 result.insert(sequence_number, buf[8..n].to_vec());
1172 if total_number_datagrams == count_datagrams {
1173 break;
1174 }
1175 }
1176 Ok((0..count_datagrams)
1177 .flat_map(|x| result.remove(&x).unwrap())
1178 .collect())
1179}
1180
1181async fn version_cmd_udp(s: &mut UdpSocket, r: &mut u16) -> io::Result<String> {
1182 udp_send_cmd(s, r, build_version_cmd()).await?;
1183 parse_version_rp(&mut Cursor::new(udp_recv_rp(s, r).await?)).await
1184}
1185
1186pub async fn version_cmd<S: AsyncBufRead + AsyncWrite + Unpin>(s: &mut S) -> io::Result<String> {
1187 s.write_all(build_version_cmd()).await?;
1188 s.flush().await?;
1189 parse_version_rp(s).await
1190}
1191
1192async fn quit_cmd_udp(s: &mut UdpSocket, r: &mut u16) -> io::Result<()> {
1193 udp_send_cmd(s, r, build_quit_cmd()).await
1194}
1195
1196async fn quit_cmd<S: AsyncBufRead + AsyncWrite + Unpin>(s: &mut S) -> io::Result<()> {
1197 s.write_all(build_quit_cmd()).await?;
1198 s.flush().await
1199}
1200
1201async fn shutdown_cmd_udp(s: &mut UdpSocket, r: &mut u16, graceful: bool) -> io::Result<()> {
1202 udp_send_cmd(s, r, build_shutdown_cmd(graceful)).await
1203}
1204
1205async fn shutdown_cmd<S: AsyncBufRead + AsyncWrite + Unpin>(
1206 s: &mut S,
1207 graceful: bool,
1208) -> io::Result<()> {
1209 s.write_all(build_shutdown_cmd(graceful)).await?;
1210 s.flush().await
1211}
1212
1213async fn cache_memlimit_cmd_udp(
1214 s: &mut UdpSocket,
1215 r: &mut u16,
1216 limit: usize,
1217 noreply: bool,
1218) -> io::Result<()> {
1219 udp_send_cmd(s, r, &build_cache_memlimit_cmd(limit, noreply)).await?;
1220 if noreply {
1221 Ok(())
1222 } else {
1223 parse_ok_rp(&mut Cursor::new(udp_recv_rp(s, r).await?), noreply).await
1224 }
1225}
1226
1227async fn cache_memlimit_cmd<S: AsyncBufRead + AsyncWrite + Unpin>(
1228 s: &mut S,
1229 limit: usize,
1230 noreply: bool,
1231) -> io::Result<()> {
1232 s.write_all(&build_cache_memlimit_cmd(limit, noreply))
1233 .await?;
1234 s.flush().await?;
1235 parse_ok_rp(s, noreply).await
1236}
1237
1238async fn flush_all_cmd_udp(
1239 s: &mut UdpSocket,
1240 r: &mut u16,
1241 exptime: Option<i64>,
1242 noreply: bool,
1243) -> io::Result<()> {
1244 udp_send_cmd(s, r, &build_flush_all_cmd(exptime, noreply)).await?;
1245 if noreply {
1246 Ok(())
1247 } else {
1248 parse_ok_rp(&mut Cursor::new(udp_recv_rp(s, r).await?), noreply).await
1249 }
1250}
1251
1252async fn flush_all_cmd<S: AsyncBufRead + AsyncWrite + Unpin>(
1253 s: &mut S,
1254 exptime: Option<i64>,
1255 noreply: bool,
1256) -> io::Result<()> {
1257 s.write_all(&build_flush_all_cmd(exptime, noreply)).await?;
1258 s.flush().await?;
1259 parse_ok_rp(s, noreply).await
1260}
1261
1262async fn storage_cmd_udp(
1263 s: &mut UdpSocket,
1264 r: &mut u16,
1265 command_name: &[u8],
1266 key: &[u8],
1267 flags: u32,
1268 exptime: i64,
1269 cas_unique: Option<u64>,
1270 noreply: bool,
1271 data_block: &[u8],
1272) -> io::Result<bool> {
1273 udp_send_cmd(
1274 s,
1275 r,
1276 &build_storage_cmd(
1277 command_name,
1278 key,
1279 flags,
1280 exptime,
1281 cas_unique,
1282 noreply,
1283 data_block,
1284 ),
1285 )
1286 .await?;
1287 if noreply {
1288 Ok(true)
1289 } else {
1290 parse_storage_rp(&mut Cursor::new(udp_recv_rp(s, r).await?), noreply).await
1291 }
1292}
1293
1294pub async fn storage_cmd<S: AsyncBufRead + AsyncWrite + Unpin>(
1295 s: &mut S,
1296 command_name: &[u8],
1297 key: &[u8],
1298 flags: u32,
1299 exptime: i64,
1300 cas_unique: Option<u64>,
1301 noreply: bool,
1302 data_block: &[u8],
1303) -> io::Result<bool> {
1304 s.write_all(&build_storage_cmd(
1305 command_name,
1306 key,
1307 flags,
1308 exptime,
1309 cas_unique,
1310 noreply,
1311 data_block,
1312 ))
1313 .await?;
1314 s.flush().await?;
1315 parse_storage_rp(s, noreply).await
1316}
1317
1318async fn delete_cmd_udp(
1319 s: &mut UdpSocket,
1320 r: &mut u16,
1321 key: &[u8],
1322 noreply: bool,
1323) -> io::Result<bool> {
1324 udp_send_cmd(s, r, &build_delete_cmd(key, noreply)).await?;
1325 if noreply {
1326 Ok(true)
1327 } else {
1328 parse_delete_rp(&mut Cursor::new(udp_recv_rp(s, r).await?), noreply).await
1329 }
1330}
1331
1332async fn delete_cmd<S: AsyncBufRead + AsyncWrite + Unpin>(
1333 s: &mut S,
1334 key: &[u8],
1335 noreply: bool,
1336) -> io::Result<bool> {
1337 s.write_all(&build_delete_cmd(key, noreply)).await?;
1338 s.flush().await?;
1339 parse_delete_rp(s, noreply).await
1340}
1341
1342async fn auth_cmd<S: AsyncBufRead + AsyncWrite + Unpin>(
1343 s: &mut S,
1344 username: &[u8],
1345 password: &[u8],
1346) -> io::Result<()> {
1347 s.write_all(&build_auth_cmd(username, password)).await?;
1348 s.flush().await?;
1349 parse_auth_rp(s).await
1350}
1351
1352async fn incr_decr_cmd_udp(
1353 s: &mut UdpSocket,
1354 r: &mut u16,
1355 command_name: &[u8],
1356 key: &[u8],
1357 value: u64,
1358 noreply: bool,
1359) -> io::Result<Option<u64>> {
1360 udp_send_cmd(
1361 s,
1362 r,
1363 &build_incr_decr_cmd(command_name, key, value, noreply),
1364 )
1365 .await?;
1366 if noreply {
1367 Ok(None)
1368 } else {
1369 parse_incr_decr_rp(&mut Cursor::new(udp_recv_rp(s, r).await?), noreply).await
1370 }
1371}
1372
1373pub async fn incr_decr_cmd<S: AsyncBufRead + AsyncWrite + Unpin>(
1374 s: &mut S,
1375 command_name: &[u8],
1376 key: &[u8],
1377 value: u64,
1378 noreply: bool,
1379) -> io::Result<Option<u64>> {
1380 s.write_all(&build_incr_decr_cmd(command_name, key, value, noreply))
1381 .await?;
1382 s.flush().await?;
1383 parse_incr_decr_rp(s, noreply).await
1384}
1385
1386async fn touch_cmd_udp(
1387 s: &mut UdpSocket,
1388 r: &mut u16,
1389 key: &[u8],
1390 exptime: i64,
1391 noreply: bool,
1392) -> io::Result<bool> {
1393 udp_send_cmd(s, r, &build_touch_cmd(key, exptime, noreply)).await?;
1394 if noreply {
1395 Ok(true)
1396 } else {
1397 parse_touch_rp(&mut Cursor::new(udp_recv_rp(s, r).await?), noreply).await
1398 }
1399}
1400
1401async fn touch_cmd<S: AsyncBufRead + AsyncWrite + Unpin>(
1402 s: &mut S,
1403 key: &[u8],
1404 exptime: i64,
1405 noreply: bool,
1406) -> io::Result<bool> {
1407 s.write_all(&build_touch_cmd(key, exptime, noreply)).await?;
1408 s.flush().await?;
1409 parse_touch_rp(s, noreply).await
1410}
1411
1412async fn retrieval_cmd_udp(
1413 s: &mut UdpSocket,
1414 r: &mut u16,
1415 command_name: &[u8],
1416 exptime: Option<i64>,
1417 keys: &[&[u8]],
1418) -> io::Result<Vec<Item>> {
1419 udp_send_cmd(s, r, &build_retrieval_cmd(command_name, exptime, keys)).await?;
1420 parse_retrieval_rp(&mut Cursor::new(udp_recv_rp(s, r).await?)).await
1421}
1422
1423pub async fn retrieval_cmd<S: AsyncBufRead + AsyncWrite + Unpin>(
1424 s: &mut S,
1425 command_name: &[u8],
1426 exptime: Option<i64>,
1427 keys: &[&[u8]],
1428) -> io::Result<Vec<Item>> {
1429 s.write_all(&build_retrieval_cmd(command_name, exptime, keys))
1430 .await?;
1431 s.flush().await?;
1432 parse_retrieval_rp(s).await
1433}
1434
1435async fn stats_cmd_udp(
1436 s: &mut UdpSocket,
1437 r: &mut u16,
1438 arg: Option<StatsArg>,
1439) -> io::Result<HashMap<String, String>> {
1440 udp_send_cmd(s, r, build_stats_cmd(arg)).await?;
1441 parse_stats_rp(&mut Cursor::new(udp_recv_rp(s, r).await?)).await
1442}
1443
1444async fn stats_cmd<S: AsyncBufRead + AsyncWrite + Unpin>(
1445 s: &mut S,
1446 arg: Option<StatsArg>,
1447) -> io::Result<HashMap<String, String>> {
1448 s.write_all(build_stats_cmd(arg)).await?;
1449 s.flush().await?;
1450 parse_stats_rp(s).await
1451}
1452
1453async fn slabs_automove_cmd_udp(
1454 s: &mut UdpSocket,
1455 r: &mut u16,
1456 arg: SlabsAutomoveArg,
1457) -> io::Result<()> {
1458 udp_send_cmd(s, r, build_slabs_automove_cmd(arg)).await?;
1459 parse_ok_rp(&mut Cursor::new(udp_recv_rp(s, r).await?), false).await
1460}
1461
1462async fn slabs_automove_cmd<S: AsyncBufRead + AsyncWrite + Unpin>(
1463 s: &mut S,
1464 arg: SlabsAutomoveArg,
1465) -> io::Result<()> {
1466 s.write_all(build_slabs_automove_cmd(arg)).await?;
1467 s.flush().await?;
1468 parse_ok_rp(s, false).await
1469}
1470
1471async fn lru_crawler_cmd_udp(s: &mut UdpSocket, r: &mut u16, arg: LruCrawlerArg) -> io::Result<()> {
1472 udp_send_cmd(s, r, build_lru_crawler_cmd(arg)).await?;
1473 parse_ok_rp(&mut Cursor::new(udp_recv_rp(s, r).await?), false).await
1474}
1475
1476async fn lru_crawler_cmd<S: AsyncBufRead + AsyncWrite + Unpin>(
1477 s: &mut S,
1478 arg: LruCrawlerArg,
1479) -> io::Result<()> {
1480 s.write_all(build_lru_crawler_cmd(arg)).await?;
1481 s.flush().await?;
1482 parse_ok_rp(s, false).await
1483}
1484
1485async fn lru_crawler_sleep_cmd_udp(
1486 s: &mut UdpSocket,
1487 r: &mut u16,
1488 microseconds: usize,
1489) -> io::Result<()> {
1490 udp_send_cmd(s, r, &build_lru_clawler_sleep_cmd(microseconds)).await?;
1491 parse_ok_rp(&mut Cursor::new(udp_recv_rp(s, r).await?), false).await
1492}
1493
1494async fn lru_crawler_sleep_cmd<S: AsyncBufRead + AsyncWrite + Unpin>(
1495 s: &mut S,
1496 microseconds: usize,
1497) -> io::Result<()> {
1498 s.write_all(&build_lru_clawler_sleep_cmd(microseconds))
1499 .await?;
1500 s.flush().await?;
1501 parse_ok_rp(s, false).await
1502}
1503
1504async fn lru_crawler_tocrawl_cmd_udp(s: &mut UdpSocket, r: &mut u16, arg: u32) -> io::Result<()> {
1505 udp_send_cmd(s, r, &build_lru_crawler_tocrawl_cmd(arg)).await?;
1506 parse_ok_rp(&mut Cursor::new(udp_recv_rp(s, r).await?), false).await
1507}
1508
1509async fn lru_crawler_tocrawl_cmd<S: AsyncBufRead + AsyncWrite + Unpin>(
1510 s: &mut S,
1511 arg: u32,
1512) -> io::Result<()> {
1513 s.write_all(&build_lru_crawler_tocrawl_cmd(arg)).await?;
1514 s.flush().await?;
1515 parse_ok_rp(s, false).await
1516}
1517
1518async fn lru_crawler_crawl_cmd_udp(
1519 s: &mut UdpSocket,
1520 r: &mut u16,
1521 arg: LruCrawlerCrawlArg<'_>,
1522) -> io::Result<()> {
1523 udp_send_cmd(s, r, &build_lru_clawler_crawl_cmd(arg)).await?;
1524 parse_ok_rp(&mut Cursor::new(udp_recv_rp(s, r).await?), false).await
1525}
1526
1527async fn lru_crawler_crawl_cmd<S: AsyncBufRead + AsyncWrite + Unpin>(
1528 s: &mut S,
1529 arg: LruCrawlerCrawlArg<'_>,
1530) -> io::Result<()> {
1531 s.write_all(&build_lru_clawler_crawl_cmd(arg)).await?;
1532 s.flush().await?;
1533 parse_ok_rp(s, false).await
1534}
1535
1536async fn slabs_reassign_cmd_udp(
1537 s: &mut UdpSocket,
1538 r: &mut u16,
1539 source_class: isize,
1540 dest_class: isize,
1541) -> io::Result<()> {
1542 udp_send_cmd(s, r, &build_slabs_reassign_cmd(source_class, dest_class)).await?;
1543 parse_ok_rp(&mut Cursor::new(udp_recv_rp(s, r).await?), false).await
1544}
1545
1546async fn slabs_reassign_cmd<S: AsyncBufRead + AsyncWrite + Unpin>(
1547 s: &mut S,
1548 source_class: isize,
1549 dest_class: isize,
1550) -> io::Result<()> {
1551 s.write_all(&build_slabs_reassign_cmd(source_class, dest_class))
1552 .await?;
1553 s.flush().await?;
1554 parse_ok_rp(s, false).await
1555}
1556
1557async fn lru_crawler_metadump_cmd<S: AsyncBufRead + AsyncWrite + Unpin>(
1558 s: &mut S,
1559 arg: LruCrawlerMetadumpArg<'_>,
1560) -> io::Result<Vec<String>> {
1561 s.write_all(&build_lru_clawler_metadump_cmd(arg)).await?;
1562 s.flush().await?;
1563 parse_lru_crawler_metadump_rp(s).await
1564}
1565
1566async fn lru_crawler_mgdump_cmd<S: AsyncBufRead + AsyncWrite + Unpin>(
1567 s: &mut S,
1568 arg: LruCrawlerMgdumpArg<'_>,
1569) -> io::Result<Vec<String>> {
1570 s.write_all(&build_lru_clawler_mgdump_cmd(arg)).await?;
1571 s.flush().await?;
1572 parse_lru_crawler_mgdump_rp(s).await
1573}
1574
1575async fn mn_cmd_udp(s: &mut UdpSocket, r: &mut u16) -> io::Result<()> {
1576 udp_send_cmd(s, r, build_mn_cmd()).await?;
1577 parse_mn_rp(&mut Cursor::new(udp_recv_rp(s, r).await?)).await
1578}
1579
1580async fn mn_cmd<S: AsyncBufRead + AsyncWrite + Unpin>(s: &mut S) -> io::Result<()> {
1581 s.write_all(build_mn_cmd()).await?;
1582 s.flush().await?;
1583 parse_mn_rp(s).await
1584}
1585
1586async fn me_cmd_udp(s: &mut UdpSocket, r: &mut u16, key: &[u8]) -> io::Result<Option<String>> {
1587 udp_send_cmd(s, r, &build_me_cmd(key)).await?;
1588 parse_me_rp(&mut Cursor::new(udp_recv_rp(s, r).await?)).await
1589}
1590
1591async fn me_cmd<S: AsyncBufRead + AsyncWrite + Unpin>(
1592 s: &mut S,
1593 key: &[u8],
1594) -> io::Result<Option<String>> {
1595 s.write_all(&build_me_cmd(key)).await?;
1596 s.flush().await?;
1597 parse_me_rp(s).await
1598}
1599
1600async fn execute_cmd<S: AsyncBufRead + AsyncWrite + Unpin>(
1601 s: &mut S,
1602 cmds: &[Vec<u8>],
1603) -> io::Result<Vec<PipelineResponse>> {
1604 s.write_all(&cmds.concat()).await?;
1605 s.flush().await?;
1606 let mut result = Vec::new();
1607 for cmd in cmds {
1608 if cmd.starts_with(b"gets ")
1609 || cmd.starts_with(b"get ")
1610 || cmd.starts_with(b"gats ")
1611 || cmd.starts_with(b"gat ")
1612 {
1613 if (cmd.starts_with(b"gat") && cmd.iter().filter(|x| x == &&b' ').count() == 2)
1614 || (cmd.starts_with(b"get") && cmd.iter().filter(|x| x == &&b' ').count() == 1)
1615 {
1616 result.push(PipelineResponse::OptionItem(
1617 parse_retrieval_rp(s).await?.pop(),
1618 ))
1619 } else {
1620 result.push(PipelineResponse::VecItem(parse_retrieval_rp(s).await?))
1621 }
1622 } else if cmd.starts_with(b"set _ _ _ ") {
1623 result.push(PipelineResponse::Unit(parse_auth_rp(s).await?))
1624 } else if cmd.starts_with(b"set ")
1625 || cmd.starts_with(b"add ")
1626 || cmd.starts_with(b"replace ")
1627 || cmd.starts_with(b"append ")
1628 || cmd.starts_with(b"prepend ")
1629 || cmd.starts_with(b"cas ")
1630 {
1631 let mut split = cmd.split(|x| x == &b'\r');
1632 let n = split.next().unwrap();
1633 result.push(PipelineResponse::Bool(
1634 parse_storage_rp(s, n.ends_with(b"noreply")).await?,
1635 ))
1636 } else if cmd == build_version_cmd() {
1637 result.push(PipelineResponse::String(parse_version_rp(s).await?))
1638 } else if cmd.starts_with(b"delete ") {
1639 result.push(PipelineResponse::Bool(
1640 parse_delete_rp(s, cmd.ends_with(b"noreply\r\n")).await?,
1641 ))
1642 } else if cmd.starts_with(b"incr ") || cmd.starts_with(b"decr ") {
1643 result.push(PipelineResponse::Value(
1644 parse_incr_decr_rp(s, cmd.ends_with(b"noreply\r\n")).await?,
1645 ))
1646 } else if cmd.starts_with(b"touch ") {
1647 result.push(PipelineResponse::Bool(
1648 parse_touch_rp(s, cmd.ends_with(b"noreply\r\n")).await?,
1649 ))
1650 } else if cmd == build_quit_cmd() || cmd.starts_with(b"shutdown") {
1651 result.push(PipelineResponse::Unit(()))
1652 } else if cmd.starts_with(b"flush_all") || cmd.starts_with(b"cache_memlimit ") {
1653 result.push(PipelineResponse::Unit(
1654 parse_ok_rp(s, cmd.ends_with(b"noreply\r\n")).await?,
1655 ))
1656 } else if cmd.starts_with(b"slabs automove ")
1657 || cmd.starts_with(b"slabs reassign ")
1658 || cmd.starts_with(b"lru_crawler sleep ")
1659 || cmd.starts_with(b"lru_crawler crawl ")
1660 || cmd.starts_with(b"lru_crawler tocrawl ")
1661 || cmd == build_lru_crawler_cmd(LruCrawlerArg::Enable)
1662 || cmd == build_lru_crawler_cmd(LruCrawlerArg::Disable)
1663 {
1664 result.push(PipelineResponse::Unit(parse_ok_rp(s, false).await?))
1665 } else if cmd == build_mn_cmd() {
1666 result.push(PipelineResponse::Unit(parse_mn_rp(s).await?))
1667 } else if cmd.starts_with(b"stats") {
1668 result.push(PipelineResponse::HashMap(parse_stats_rp(s).await?))
1669 } else if cmd.starts_with(b"lru_crawler metadump ") {
1670 result.push(PipelineResponse::VecString(
1671 parse_lru_crawler_metadump_rp(s).await?,
1672 ))
1673 } else if cmd.starts_with(b"lru_crawler mgdump ") {
1674 result.push(PipelineResponse::VecString(
1675 parse_lru_crawler_mgdump_rp(s).await?,
1676 ))
1677 } else if cmd.starts_with(b"mg ") {
1678 result.push(PipelineResponse::MetaGet(parse_mg_rp(s).await?))
1679 } else if cmd.starts_with(b"ms ") {
1680 result.push(PipelineResponse::MetaSet(parse_ms_rp(s).await?))
1681 } else if cmd.starts_with(b"md ") {
1682 result.push(PipelineResponse::MetaDelete(parse_md_rp(s).await?))
1683 } else if cmd.starts_with(b"ma ") {
1684 result.push(PipelineResponse::MetaArithmetic(parse_ma_rp(s).await?))
1685 } else if cmd.starts_with(b"lru ") {
1686 result.push(PipelineResponse::Unit(parse_ok_rp(s, false).await?))
1687 } else {
1688 assert!(cmd.starts_with(b"me "));
1689 result.push(PipelineResponse::OptionString(parse_me_rp(s).await?))
1690 }
1691 }
1692 Ok(result)
1693}
1694
1695async fn watch_cmd<S: AsyncBufRead + AsyncWrite + Unpin>(
1696 s: &mut S,
1697 arg: &[WatchArg],
1698) -> io::Result<()> {
1699 s.write_all(&build_watch_cmd(arg)).await?;
1700 s.flush().await?;
1701 parse_ok_rp(s, false).await
1702}
1703
1704async fn ms_cmd_udp(
1705 s: &mut UdpSocket,
1706 r: &mut u16,
1707 key: &[u8],
1708 flags: &[MsFlag],
1709 data_block: &[u8],
1710) -> io::Result<MsItem> {
1711 udp_send_cmd(
1712 s,
1713 r,
1714 &build_mc_cmd(b"ms", key, &build_ms_flags(flags), Some(data_block)),
1715 )
1716 .await?;
1717 parse_ms_rp(&mut Cursor::new(udp_recv_rp(s, r).await?)).await
1718}
1719
1720async fn ms_cmd<S: AsyncBufRead + AsyncWrite + Unpin>(
1721 s: &mut S,
1722 key: &[u8],
1723 flags: &[MsFlag],
1724 data_block: &[u8],
1725) -> io::Result<MsItem> {
1726 s.write_all(&build_mc_cmd(
1727 b"ms",
1728 key,
1729 &build_ms_flags(flags),
1730 Some(data_block),
1731 ))
1732 .await?;
1733 s.flush().await?;
1734 parse_ms_rp(s).await
1735}
1736
1737async fn mg_cmd_udp(
1738 s: &mut UdpSocket,
1739 r: &mut u16,
1740 key: &[u8],
1741 flags: &[MgFlag],
1742) -> io::Result<MgItem> {
1743 udp_send_cmd(
1744 s,
1745 r,
1746 &build_mc_cmd(b"mg", key, &build_mg_flags(flags), None),
1747 )
1748 .await?;
1749 parse_mg_rp(&mut Cursor::new(udp_recv_rp(s, r).await?)).await
1750}
1751
1752async fn mg_cmd<S: AsyncBufRead + AsyncWrite + Unpin>(
1753 s: &mut S,
1754 key: &[u8],
1755 flags: &[MgFlag],
1756) -> io::Result<MgItem> {
1757 s.write_all(&build_mc_cmd(b"mg", key, &build_mg_flags(flags), None))
1758 .await?;
1759 s.flush().await?;
1760 parse_mg_rp(s).await
1761}
1762
1763async fn md_cmd_udp(
1764 s: &mut UdpSocket,
1765 r: &mut u16,
1766 key: &[u8],
1767 flags: &[MdFlag],
1768) -> io::Result<MdItem> {
1769 udp_send_cmd(
1770 s,
1771 r,
1772 &build_mc_cmd(b"md", key, &build_md_flags(flags), None),
1773 )
1774 .await?;
1775 parse_md_rp(&mut Cursor::new(udp_recv_rp(s, r).await?)).await
1776}
1777
1778async fn md_cmd<S: AsyncBufRead + AsyncWrite + Unpin>(
1779 s: &mut S,
1780 key: &[u8],
1781 flags: &[MdFlag],
1782) -> io::Result<MdItem> {
1783 s.write_all(&build_mc_cmd(b"md", key, &build_md_flags(flags), None))
1784 .await?;
1785 s.flush().await?;
1786 parse_md_rp(s).await
1787}
1788
1789async fn ma_cmd_udp(
1790 s: &mut UdpSocket,
1791 r: &mut u16,
1792 key: &[u8],
1793 flags: &[MaFlag],
1794) -> io::Result<MaItem> {
1795 udp_send_cmd(
1796 s,
1797 r,
1798 &build_mc_cmd(b"ma", key, &build_ma_flags(flags), None),
1799 )
1800 .await?;
1801 parse_ma_rp(&mut Cursor::new(udp_recv_rp(s, r).await?)).await
1802}
1803
1804async fn ma_cmd<S: AsyncBufRead + AsyncWrite + Unpin>(
1805 s: &mut S,
1806 key: &[u8],
1807 flags: &[MaFlag],
1808) -> io::Result<MaItem> {
1809 s.write_all(&build_mc_cmd(b"ma", key, &build_ma_flags(flags), None))
1810 .await?;
1811 s.flush().await?;
1812 parse_ma_rp(s).await
1813}
1814
1815async fn lru_cmd_udp(s: &mut UdpSocket, r: &mut u16, arg: LruArg) -> io::Result<()> {
1816 udp_send_cmd(s, r, &build_lru_cmd(arg)).await?;
1817 parse_ok_rp(&mut Cursor::new(udp_recv_rp(s, r).await?), false).await
1818}
1819
1820async fn lru_cmd<S: AsyncBufRead + AsyncWrite + Unpin>(s: &mut S, arg: LruArg) -> io::Result<()> {
1821 s.write_all(&build_lru_cmd(arg)).await?;
1822 s.flush().await?;
1823 parse_ok_rp(s, false).await
1824}
1825
1826pub enum Connection {
1827 Tcp(BufReader<TcpStream>),
1828 Unix(BufReader<UnixStream>),
1829 Udp(UdpSocket, u16),
1830 Tls(BufReader<TlsStream<TcpStream>>),
1831}
1832impl Connection {
1833 /// # Example
1834 ///
1835 /// ```
1836 /// # use mcmc_rs::Connection;
1837 /// # use smol::{io, block_on};
1838 /// #
1839 /// # block_on(async {
1840 /// let mut conn = Connection::default().await?;
1841 /// # Ok::<(), io::Error>(())
1842 /// # }).unwrap()
1843 /// ```
1844 pub async fn default() -> io::Result<Self> {
1845 Ok(Connection::Tcp(BufReader::new(
1846 TcpStream::connect("127.0.0.1:11211").await?,
1847 )))
1848 }
1849
1850 /// # Example
1851 ///
1852 /// ```
1853 /// # use mcmc_rs::Connection;
1854 /// # use smol::{io, block_on};
1855 /// #
1856 /// # block_on(async {
1857 /// let mut conn = Connection::tcp_connect("127.0.0.1:11211").await?;
1858 /// # Ok::<(), io::Error>(())
1859 /// # }).unwrap()
1860 /// ```
1861 pub async fn tcp_connect(addr: &str) -> io::Result<Self> {
1862 Ok(Connection::Tcp(BufReader::new(
1863 TcpStream::connect(addr).await?,
1864 )))
1865 }
1866
1867 /// # Example
1868 ///
1869 /// ```
1870 /// # use mcmc_rs::Connection;
1871 /// # use smol::{io, block_on};
1872 /// #
1873 /// # block_on(async {
1874 /// let mut conn = Connection::unix_connect("/tmp/memcached0.sock").await?;
1875 /// # Ok::<(), io::Error>(())
1876 /// # }).unwrap()
1877 /// ```
1878 pub async fn unix_connect(path: &str) -> io::Result<Self> {
1879 Ok(Connection::Unix(BufReader::new(
1880 UnixStream::connect(path).await?,
1881 )))
1882 }
1883
1884 /// # Example
1885 ///
1886 /// ```
1887 /// # use mcmc_rs::Connection;
1888 /// # use smol::{io, block_on};
1889 /// #
1890 /// # block_on(async {
1891 /// let mut conn = Connection::udp_connect("127.0.0.1:0", "127.0.0.1:11214").await?;
1892 /// # Ok::<(), io::Error>(())
1893 /// # }).unwrap()
1894 pub async fn udp_connect(bind_addr: &str, connect_addr: &str) -> io::Result<Self> {
1895 let s = UdpSocket::bind(bind_addr).await?;
1896 s.connect(connect_addr).await?;
1897 Ok(Connection::Udp(s, 0))
1898 }
1899
1900 /// # Example
1901 ///
1902 /// ```
1903 /// # use mcmc_rs::Connection;
1904 /// # use smol::{io, block_on};
1905 /// #
1906 /// # block_on(async {
1907 /// let mut conn = Connection::tls_connect("localhost", 11216, "cert.pem").await?;
1908 /// # Ok::<(), io::Error>(())
1909 /// # }).unwrap()
1910 pub async fn tls_connect(hostname: &str, port: u16, ca_path: &str) -> io::Result<Self> {
1911 let cert = fs::read(ca_path).await?;
1912 let tcp_stream = TcpStream::connect(format!("{hostname}:{port}")).await?;
1913 let connector =
1914 TlsConnector::new().add_root_certificate(Certificate::from_pem(&cert).unwrap());
1915 Ok(Connection::Tls(BufReader::new(
1916 connector.connect(hostname, tcp_stream).await.unwrap(),
1917 )))
1918 }
1919
1920 /// # Example
1921 ///
1922 /// ```
1923 /// # use mcmc_rs::Connection;
1924 /// # use smol::{io, block_on};
1925 /// #
1926 /// # block_on(async {
1927 /// for mut c in [
1928 /// Connection::default().await?,
1929 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
1930 /// Connection::udp_connect("127.0.0.1:0", "127.0.0.1:11214").await?,
1931 /// Connection::tls_connect("localhost", 11216, "cert.pem").await?,
1932 /// ] {
1933 /// let result = c.version().await?;
1934 /// assert!(result.chars().any(|x| x.is_numeric()));
1935 /// }
1936 /// # Ok::<(), io::Error>(())
1937 /// # }).unwrap()
1938 /// ```
1939 pub async fn version(&mut self) -> io::Result<String> {
1940 match self {
1941 Connection::Tcp(s) => version_cmd(s).await,
1942 Connection::Unix(s) => version_cmd(s).await,
1943 Connection::Udp(s, r) => version_cmd_udp(s, r).await,
1944 Connection::Tls(s) => version_cmd(s).await,
1945 }
1946 }
1947
1948 /// # Example
1949 ///
1950 /// ```
1951 /// # use mcmc_rs::Connection;
1952 /// # use smol::{io, block_on};
1953 /// #
1954 /// # block_on(async {
1955 /// for mut c in [
1956 /// Connection::default().await?,
1957 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
1958 /// Connection::udp_connect("127.0.0.1:0", "127.0.0.1:11214").await?,
1959 /// Connection::tls_connect("localhost", 11216, "cert.pem").await?,
1960 /// ] {
1961 /// c.quit().await?;
1962 /// }
1963 /// # Ok::<(), io::Error>(())
1964 /// # }).unwrap()
1965 /// ```
1966 pub async fn quit(mut self) -> io::Result<()> {
1967 match &mut self {
1968 Connection::Tcp(s) => quit_cmd(s).await,
1969 Connection::Unix(s) => quit_cmd(s).await,
1970 Connection::Udp(s, r) => quit_cmd_udp(s, r).await,
1971 Connection::Tls(s) => quit_cmd(s).await,
1972 }
1973 }
1974
1975 /// # Example
1976 ///
1977 /// ```
1978 /// # use mcmc_rs::Connection;
1979 /// # use smol::{io, block_on};
1980 /// #
1981 /// # block_on(async {
1982 /// for mut c in [
1983 /// Connection::tcp_connect("127.0.0.1:11213").await?,
1984 /// Connection::unix_connect("/tmp/memcached1.sock").await?,
1985 /// Connection::udp_connect("127.0.0.1:0", "127.0.0.1:11215").await?,
1986 /// Connection::tls_connect("localhost", 11217, "cert.pem").await?,
1987 /// ] {
1988 /// c.shutdown(true).await?;
1989 /// }
1990 /// # Ok::<(), io::Error>(())
1991 /// # }).unwrap()
1992 /// ```
1993 pub async fn shutdown(mut self, graceful: bool) -> io::Result<()> {
1994 match &mut self {
1995 Connection::Tcp(s) => shutdown_cmd(s, graceful).await,
1996 Connection::Unix(s) => shutdown_cmd(s, graceful).await,
1997 Connection::Udp(s, r) => shutdown_cmd_udp(s, r, graceful).await,
1998 Connection::Tls(s) => shutdown_cmd(s, graceful).await,
1999 }
2000 }
2001
2002 /// # Example
2003 ///
2004 /// ```
2005 /// # use mcmc_rs::Connection;
2006 /// # use smol::{io, block_on};
2007 /// #
2008 /// # block_on(async {
2009 /// for mut c in [
2010 /// Connection::default().await?,
2011 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
2012 /// Connection::udp_connect("127.0.0.1:0", "127.0.0.1:11214").await?,
2013 /// Connection::tls_connect("localhost", 11216, "cert.pem").await?,
2014 /// ] {
2015 /// c.cache_memlimit(10, true).await?;
2016 /// }
2017 /// # Ok::<(), io::Error>(())
2018 /// # }).unwrap()
2019 /// ```
2020 pub async fn cache_memlimit(&mut self, limit: usize, noreply: bool) -> io::Result<()> {
2021 match self {
2022 Connection::Tcp(s) => cache_memlimit_cmd(s, limit, noreply).await,
2023 Connection::Unix(s) => cache_memlimit_cmd(s, limit, noreply).await,
2024 Connection::Udp(s, r) => cache_memlimit_cmd_udp(s, r, limit, noreply).await,
2025 Connection::Tls(s) => cache_memlimit_cmd(s, limit, noreply).await,
2026 }
2027 }
2028
2029 /// # Example
2030 ///
2031 /// ```
2032 /// # use mcmc_rs::Connection;
2033 /// # use smol::{io, block_on};
2034 /// #
2035 /// # block_on(async {
2036 /// for mut c in [
2037 /// Connection::default().await?,
2038 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
2039 /// Connection::udp_connect("127.0.0.1:0", "127.0.0.1:11214").await?,
2040 /// Connection::tls_connect("localhost", 11216, "cert.pem").await?,
2041 /// ] {
2042 /// c.flush_all(Some(999), true).await?;
2043 /// }
2044 /// # Ok::<(), io::Error>(())
2045 /// # }).unwrap()
2046 /// ```
2047 pub async fn flush_all(&mut self, exptime: Option<i64>, noreply: bool) -> io::Result<()> {
2048 match self {
2049 Connection::Tcp(s) => flush_all_cmd(s, exptime, noreply).await,
2050 Connection::Unix(s) => flush_all_cmd(s, exptime, noreply).await,
2051 Connection::Udp(s, r) => flush_all_cmd_udp(s, r, exptime, noreply).await,
2052 Connection::Tls(s) => flush_all_cmd(s, exptime, noreply).await,
2053 }
2054 }
2055
2056 /// # Example
2057 ///
2058 /// ```
2059 /// # use mcmc_rs::Connection;
2060 /// # use smol::{io, block_on};
2061 /// #
2062 /// # block_on(async {
2063 /// for mut c in [
2064 /// Connection::default().await?,
2065 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
2066 /// Connection::udp_connect("127.0.0.1:0", "127.0.0.1:11214").await?,
2067 /// Connection::tls_connect("localhost", 11216, "cert.pem").await?,
2068 /// ] {
2069 /// let result = c.set(b"key", 0, -1, true, b"value").await?;
2070 /// assert!(result);
2071 /// }
2072 /// # Ok::<(), io::Error>(())
2073 /// # }).unwrap()
2074 /// ```
2075 pub async fn set(
2076 &mut self,
2077 key: impl AsRef<[u8]>,
2078 flags: u32,
2079 exptime: i64,
2080 noreply: bool,
2081 data_block: impl AsRef<[u8]>,
2082 ) -> io::Result<bool> {
2083 match self {
2084 Connection::Tcp(s) => {
2085 storage_cmd(
2086 s,
2087 b"set",
2088 key.as_ref(),
2089 flags,
2090 exptime,
2091 None,
2092 noreply,
2093 data_block.as_ref(),
2094 )
2095 .await
2096 }
2097 Connection::Unix(s) => {
2098 storage_cmd(
2099 s,
2100 b"set",
2101 key.as_ref(),
2102 flags,
2103 exptime,
2104 None,
2105 noreply,
2106 data_block.as_ref(),
2107 )
2108 .await
2109 }
2110 Connection::Udp(s, r) => {
2111 storage_cmd_udp(
2112 s,
2113 r,
2114 b"set",
2115 key.as_ref(),
2116 flags,
2117 exptime,
2118 None,
2119 noreply,
2120 data_block.as_ref(),
2121 )
2122 .await
2123 }
2124 Connection::Tls(s) => {
2125 storage_cmd(
2126 s,
2127 b"set",
2128 key.as_ref(),
2129 flags,
2130 exptime,
2131 None,
2132 noreply,
2133 data_block.as_ref(),
2134 )
2135 .await
2136 }
2137 }
2138 }
2139
2140 /// # Example
2141 ///
2142 /// ```
2143 /// # use mcmc_rs::Connection;
2144 /// # use smol::{io, block_on};
2145 /// #
2146 /// # block_on(async {
2147 /// for mut c in [
2148 /// Connection::default().await?,
2149 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
2150 /// Connection::udp_connect("127.0.0.1:0", "127.0.0.1:11214").await?,
2151 /// Connection::tls_connect("localhost", 11216, "cert.pem").await?,
2152 /// ] {
2153 /// let result = c.add(b"key", 0, -1, true, b"value").await?;
2154 /// assert!(result);
2155 /// }
2156 /// # Ok::<(), io::Error>(())
2157 /// # }).unwrap()
2158 /// ```
2159 pub async fn add(
2160 &mut self,
2161 key: impl AsRef<[u8]>,
2162 flags: u32,
2163 exptime: i64,
2164 noreply: bool,
2165 data_block: impl AsRef<[u8]>,
2166 ) -> io::Result<bool> {
2167 match self {
2168 Connection::Tcp(s) => {
2169 storage_cmd(
2170 s,
2171 b"add",
2172 key.as_ref(),
2173 flags,
2174 exptime,
2175 None,
2176 noreply,
2177 data_block.as_ref(),
2178 )
2179 .await
2180 }
2181 Connection::Unix(s) => {
2182 storage_cmd(
2183 s,
2184 b"add",
2185 key.as_ref(),
2186 flags,
2187 exptime,
2188 None,
2189 noreply,
2190 data_block.as_ref(),
2191 )
2192 .await
2193 }
2194 Connection::Udp(s, r) => {
2195 storage_cmd_udp(
2196 s,
2197 r,
2198 b"add",
2199 key.as_ref(),
2200 flags,
2201 exptime,
2202 None,
2203 noreply,
2204 data_block.as_ref(),
2205 )
2206 .await
2207 }
2208 Connection::Tls(s) => {
2209 storage_cmd(
2210 s,
2211 b"add",
2212 key.as_ref(),
2213 flags,
2214 exptime,
2215 None,
2216 noreply,
2217 data_block.as_ref(),
2218 )
2219 .await
2220 }
2221 }
2222 }
2223
2224 /// # Example
2225 ///
2226 /// ```
2227 /// # use mcmc_rs::Connection;
2228 /// # use smol::{io, block_on};
2229 /// #
2230 /// # block_on(async {
2231 /// for mut c in [
2232 /// Connection::default().await?,
2233 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
2234 /// Connection::udp_connect("127.0.0.1:0", "127.0.0.1:11214").await?,
2235 /// Connection::tls_connect("localhost", 11216, "cert.pem").await?,
2236 /// ] {
2237 /// let result = c.replace(b"key", 0, -1, true, b"value").await?;
2238 /// assert!(result);
2239 /// }
2240 /// # Ok::<(), io::Error>(())
2241 /// # }).unwrap()
2242 /// ```
2243 pub async fn replace(
2244 &mut self,
2245 key: impl AsRef<[u8]>,
2246 flags: u32,
2247 exptime: i64,
2248 noreply: bool,
2249 data_block: impl AsRef<[u8]>,
2250 ) -> io::Result<bool> {
2251 match self {
2252 Connection::Tcp(s) => {
2253 storage_cmd(
2254 s,
2255 b"replace",
2256 key.as_ref(),
2257 flags,
2258 exptime,
2259 None,
2260 noreply,
2261 data_block.as_ref(),
2262 )
2263 .await
2264 }
2265 Connection::Unix(s) => {
2266 storage_cmd(
2267 s,
2268 b"replace",
2269 key.as_ref(),
2270 flags,
2271 exptime,
2272 None,
2273 noreply,
2274 data_block.as_ref(),
2275 )
2276 .await
2277 }
2278 Connection::Udp(s, r) => {
2279 storage_cmd_udp(
2280 s,
2281 r,
2282 b"replace",
2283 key.as_ref(),
2284 flags,
2285 exptime,
2286 None,
2287 noreply,
2288 data_block.as_ref(),
2289 )
2290 .await
2291 }
2292 Connection::Tls(s) => {
2293 storage_cmd(
2294 s,
2295 b"replace",
2296 key.as_ref(),
2297 flags,
2298 exptime,
2299 None,
2300 noreply,
2301 data_block.as_ref(),
2302 )
2303 .await
2304 }
2305 }
2306 }
2307
2308 /// # Example
2309 ///
2310 /// ```
2311 /// # use mcmc_rs::Connection;
2312 /// # use smol::{io, block_on};
2313 /// #
2314 /// # block_on(async {
2315 /// for mut c in [
2316 /// Connection::default().await?,
2317 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
2318 /// Connection::udp_connect("127.0.0.1:0", "127.0.0.1:11214").await?,
2319 /// Connection::tls_connect("localhost", 11216, "cert.pem").await?,
2320 /// ] {
2321 /// let result = c.append(b"key", 0, -1, true, b"value").await?;
2322 /// assert!(result);
2323 /// }
2324 /// # Ok::<(), io::Error>(())
2325 /// # }).unwrap()
2326 /// ```
2327 pub async fn append(
2328 &mut self,
2329 key: impl AsRef<[u8]>,
2330 flags: u32,
2331 exptime: i64,
2332 noreply: bool,
2333 data_block: impl AsRef<[u8]>,
2334 ) -> io::Result<bool> {
2335 match self {
2336 Connection::Tcp(s) => {
2337 storage_cmd(
2338 s,
2339 b"append",
2340 key.as_ref(),
2341 flags,
2342 exptime,
2343 None,
2344 noreply,
2345 data_block.as_ref(),
2346 )
2347 .await
2348 }
2349 Connection::Unix(s) => {
2350 storage_cmd(
2351 s,
2352 b"append",
2353 key.as_ref(),
2354 flags,
2355 exptime,
2356 None,
2357 noreply,
2358 data_block.as_ref(),
2359 )
2360 .await
2361 }
2362 Connection::Udp(s, r) => {
2363 storage_cmd_udp(
2364 s,
2365 r,
2366 b"append",
2367 key.as_ref(),
2368 flags,
2369 exptime,
2370 None,
2371 noreply,
2372 data_block.as_ref(),
2373 )
2374 .await
2375 }
2376 Connection::Tls(s) => {
2377 storage_cmd(
2378 s,
2379 b"append",
2380 key.as_ref(),
2381 flags,
2382 exptime,
2383 None,
2384 noreply,
2385 data_block.as_ref(),
2386 )
2387 .await
2388 }
2389 }
2390 }
2391
2392 /// # Example
2393 ///
2394 /// ```
2395 /// # use mcmc_rs::Connection;
2396 /// # use smol::{io, block_on};
2397 /// #
2398 /// # block_on(async {
2399 /// for mut c in [
2400 /// Connection::default().await?,
2401 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
2402 /// Connection::udp_connect("127.0.0.1:0", "127.0.0.1:11214").await?,
2403 /// Connection::tls_connect("localhost", 11216, "cert.pem").await?,
2404 /// ] {
2405 /// let result = c.prepend(b"key", 0, -1, true, b"value").await?;
2406 /// assert!(result);
2407 /// }
2408 /// # Ok::<(), io::Error>(())
2409 /// # }).unwrap()
2410 /// ```
2411 pub async fn prepend(
2412 &mut self,
2413 key: impl AsRef<[u8]>,
2414 flags: u32,
2415 exptime: i64,
2416 noreply: bool,
2417 data_block: impl AsRef<[u8]>,
2418 ) -> io::Result<bool> {
2419 match self {
2420 Connection::Tcp(s) => {
2421 storage_cmd(
2422 s,
2423 b"prepend",
2424 key.as_ref(),
2425 flags,
2426 exptime,
2427 None,
2428 noreply,
2429 data_block.as_ref(),
2430 )
2431 .await
2432 }
2433 Connection::Unix(s) => {
2434 storage_cmd(
2435 s,
2436 b"prepend",
2437 key.as_ref(),
2438 flags,
2439 exptime,
2440 None,
2441 noreply,
2442 data_block.as_ref(),
2443 )
2444 .await
2445 }
2446 Connection::Udp(s, r) => {
2447 storage_cmd_udp(
2448 s,
2449 r,
2450 b"prepend",
2451 key.as_ref(),
2452 flags,
2453 exptime,
2454 None,
2455 noreply,
2456 data_block.as_ref(),
2457 )
2458 .await
2459 }
2460 Connection::Tls(s) => {
2461 storage_cmd(
2462 s,
2463 b"prepend",
2464 key.as_ref(),
2465 flags,
2466 exptime,
2467 None,
2468 noreply,
2469 data_block.as_ref(),
2470 )
2471 .await
2472 }
2473 }
2474 }
2475
2476 /// # Example
2477 ///
2478 /// ```
2479 /// # use mcmc_rs::Connection;
2480 /// # use smol::{io, block_on};
2481 /// #
2482 /// # block_on(async {
2483 /// for mut c in [
2484 /// Connection::default().await?,
2485 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
2486 /// Connection::udp_connect("127.0.0.1:0", "127.0.0.1:11214").await?,
2487 /// Connection::tls_connect("localhost", 11216, "cert.pem").await?,
2488 /// ] {
2489 /// let result = c.cas(b"key", 0, -1, 0, true, b"value").await?;
2490 /// assert!(result);
2491 /// }
2492 /// # Ok::<(), io::Error>(())
2493 /// # }).unwrap()
2494 /// ```
2495 pub async fn cas(
2496 &mut self,
2497 key: impl AsRef<[u8]>,
2498 flags: u32,
2499 exptime: i64,
2500 cas_unique: u64,
2501 noreply: bool,
2502 data_block: impl AsRef<[u8]>,
2503 ) -> io::Result<bool> {
2504 match self {
2505 Connection::Tcp(s) => {
2506 storage_cmd(
2507 s,
2508 b"cas",
2509 key.as_ref(),
2510 flags,
2511 exptime,
2512 Some(cas_unique),
2513 noreply,
2514 data_block.as_ref(),
2515 )
2516 .await
2517 }
2518 Connection::Unix(s) => {
2519 storage_cmd(
2520 s,
2521 b"cas",
2522 key.as_ref(),
2523 flags,
2524 exptime,
2525 Some(cas_unique),
2526 noreply,
2527 data_block.as_ref(),
2528 )
2529 .await
2530 }
2531 Connection::Udp(s, r) => {
2532 storage_cmd_udp(
2533 s,
2534 r,
2535 b"cas",
2536 key.as_ref(),
2537 flags,
2538 exptime,
2539 Some(cas_unique),
2540 noreply,
2541 data_block.as_ref(),
2542 )
2543 .await
2544 }
2545 Connection::Tls(s) => {
2546 storage_cmd(
2547 s,
2548 b"cas",
2549 key.as_ref(),
2550 flags,
2551 exptime,
2552 Some(cas_unique),
2553 noreply,
2554 data_block.as_ref(),
2555 )
2556 .await
2557 }
2558 }
2559 }
2560
2561 /// # Example
2562 ///
2563 /// ```
2564 /// # use mcmc_rs::Connection;
2565 /// # use smol::{io, block_on};
2566 /// #
2567 /// # block_on(async {
2568 /// for mut c in [
2569 /// Connection::tcp_connect("127.0.0.1:11212").await?,
2570 /// Connection::unix_connect("/tmp/memcached2.sock").await?,
2571 /// Connection::tls_connect("localhost", 11218, "cert.pem").await?,
2572 /// ] {
2573 /// c.auth(b"a", b"a").await?;
2574 /// }
2575 /// # Ok::<(), io::Error>(())
2576 /// # }).unwrap()
2577 /// ```
2578 pub async fn auth(
2579 &mut self,
2580 username: impl AsRef<[u8]>,
2581 password: impl AsRef<[u8]>,
2582 ) -> io::Result<()> {
2583 match self {
2584 Connection::Tcp(s) => auth_cmd(s, username.as_ref(), password.as_ref()).await,
2585 Connection::Unix(s) => auth_cmd(s, username.as_ref(), password.as_ref()).await,
2586 Connection::Udp(_s, _r) => {
2587 unreachable!("Cannot enable UDP while using binary SASL authentication.")
2588 }
2589 Connection::Tls(s) => auth_cmd(s, username.as_ref(), password.as_ref()).await,
2590 }
2591 }
2592
2593 /// # Example
2594 ///
2595 /// ```
2596 /// # use mcmc_rs::Connection;
2597 /// # use smol::{io, block_on};
2598 /// #
2599 /// # block_on(async {
2600 /// for mut c in [
2601 /// Connection::default().await?,
2602 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
2603 /// Connection::udp_connect("127.0.0.1:0", "127.0.0.1:11214").await?,
2604 /// Connection::tls_connect("localhost", 11216, "cert.pem").await?,
2605 /// ] {
2606 /// let result = c.delete(b"key", true).await?;
2607 /// assert!(result);
2608 /// }
2609 /// # Ok::<(), io::Error>(())
2610 /// # }).unwrap()
2611 /// ```
2612 pub async fn delete(&mut self, key: impl AsRef<[u8]>, noreply: bool) -> io::Result<bool> {
2613 match self {
2614 Connection::Tcp(s) => delete_cmd(s, key.as_ref(), noreply).await,
2615 Connection::Unix(s) => delete_cmd(s, key.as_ref(), noreply).await,
2616 Connection::Udp(s, r) => delete_cmd_udp(s, r, key.as_ref(), noreply).await,
2617 Connection::Tls(s) => delete_cmd(s, key.as_ref(), noreply).await,
2618 }
2619 }
2620
2621 /// # Example
2622 ///
2623 /// ```
2624 /// # use mcmc_rs::Connection;
2625 /// # use smol::{io, block_on};
2626 /// #
2627 /// # block_on(async {
2628 /// for mut c in [
2629 /// Connection::default().await?,
2630 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
2631 /// Connection::udp_connect("127.0.0.1:0", "127.0.0.1:11214").await?,
2632 /// Connection::tls_connect("localhost", 11216, "cert.pem").await?,
2633 /// ] {
2634 /// let result = c.incr(b"key", 1, true).await?;
2635 /// assert!(result.is_none());
2636 /// }
2637 /// # Ok::<(), io::Error>(())
2638 /// # }).unwrap()
2639 /// ```
2640 pub async fn incr(
2641 &mut self,
2642 key: impl AsRef<[u8]>,
2643 value: u64,
2644 noreply: bool,
2645 ) -> io::Result<Option<u64>> {
2646 match self {
2647 Connection::Tcp(s) => incr_decr_cmd(s, b"incr", key.as_ref(), value, noreply).await,
2648 Connection::Unix(s) => incr_decr_cmd(s, b"incr", key.as_ref(), value, noreply).await,
2649 Connection::Udp(s, r) => {
2650 incr_decr_cmd_udp(s, r, b"incr", key.as_ref(), value, noreply).await
2651 }
2652 Connection::Tls(s) => incr_decr_cmd(s, b"incr", key.as_ref(), value, noreply).await,
2653 }
2654 }
2655
2656 /// # Example
2657 ///
2658 /// ```
2659 /// # use mcmc_rs::Connection;
2660 /// # use smol::{io, block_on};
2661 /// #
2662 /// # block_on(async {
2663 /// for mut c in [
2664 /// Connection::default().await?,
2665 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
2666 /// Connection::udp_connect("127.0.0.1:0", "127.0.0.1:11214").await?,
2667 /// Connection::tls_connect("localhost", 11216, "cert.pem").await?,
2668 /// ] {
2669 /// let result = c.decr(b"key", 1, true).await?;
2670 /// assert!(result.is_none());
2671 /// }
2672 /// # Ok::<(), io::Error>(())
2673 /// # }).unwrap()
2674 /// ```
2675 pub async fn decr(
2676 &mut self,
2677 key: impl AsRef<[u8]>,
2678 value: u64,
2679 noreply: bool,
2680 ) -> io::Result<Option<u64>> {
2681 match self {
2682 Connection::Tcp(s) => incr_decr_cmd(s, b"decr", key.as_ref(), value, noreply).await,
2683 Connection::Unix(s) => incr_decr_cmd(s, b"decr", key.as_ref(), value, noreply).await,
2684 Connection::Udp(s, r) => {
2685 incr_decr_cmd_udp(s, r, b"decr", key.as_ref(), value, noreply).await
2686 }
2687 Connection::Tls(s) => incr_decr_cmd(s, b"decr", key.as_ref(), value, noreply).await,
2688 }
2689 }
2690
2691 /// # Example
2692 ///
2693 /// ```
2694 /// # use mcmc_rs::Connection;
2695 /// # use smol::{io, block_on};
2696 /// #
2697 /// # block_on(async {
2698 /// for mut c in [
2699 /// Connection::default().await?,
2700 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
2701 /// Connection::udp_connect("127.0.0.1:0", "127.0.0.1:11214").await?,
2702 /// Connection::tls_connect("localhost", 11216, "cert.pem").await?,
2703 /// ] {
2704 /// let result = c.touch(b"key", -1, true).await?;
2705 /// assert!(result);
2706 /// }
2707 /// # Ok::<(), io::Error>(())
2708 /// # }).unwrap()
2709 /// ```
2710 pub async fn touch(
2711 &mut self,
2712 key: impl AsRef<[u8]>,
2713 exptime: i64,
2714 noreply: bool,
2715 ) -> io::Result<bool> {
2716 match self {
2717 Connection::Tcp(s) => touch_cmd(s, key.as_ref(), exptime, noreply).await,
2718 Connection::Unix(s) => touch_cmd(s, key.as_ref(), exptime, noreply).await,
2719 Connection::Udp(s, r) => touch_cmd_udp(s, r, key.as_ref(), exptime, noreply).await,
2720 Connection::Tls(s) => touch_cmd(s, key.as_ref(), exptime, noreply).await,
2721 }
2722 }
2723
2724 /// # Example
2725 ///
2726 /// ```
2727 /// # use mcmc_rs::Connection;
2728 /// # use smol::{io, block_on};
2729 /// #
2730 /// # block_on(async {
2731 /// for mut c in [
2732 /// Connection::default().await?,
2733 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
2734 /// Connection::udp_connect("127.0.0.1:0", "127.0.0.1:11214").await?,
2735 /// Connection::tls_connect("localhost", 11216, "cert.pem").await?,
2736 /// ] {
2737 /// assert!(c.set(b"k1", 0, 0, false, b"v1").await?);
2738 /// let result = c.get(b"k1").await?;
2739 /// assert_eq!(result.unwrap().key, "k1");
2740 /// }
2741 /// # Ok::<(), io::Error>(())
2742 /// # }).unwrap()
2743 /// ```
2744 pub async fn get(&mut self, key: impl AsRef<[u8]>) -> io::Result<Option<Item>> {
2745 match self {
2746 Connection::Tcp(s) => Ok(retrieval_cmd(s, b"get", None, &[key.as_ref()]).await?.pop()),
2747 Connection::Unix(s) => Ok(retrieval_cmd(s, b"get", None, &[key.as_ref()]).await?.pop()),
2748 Connection::Udp(s, r) => Ok(retrieval_cmd_udp(s, r, b"get", None, &[key.as_ref()])
2749 .await?
2750 .pop()),
2751 Connection::Tls(s) => Ok(retrieval_cmd(s, b"get", None, &[key.as_ref()]).await?.pop()),
2752 }
2753 }
2754
2755 /// # Example
2756 ///
2757 /// ```
2758 /// # use mcmc_rs::Connection;
2759 /// # use smol::{io, block_on};
2760 /// #
2761 /// # block_on(async {
2762 /// for mut c in [
2763 /// Connection::default().await?,
2764 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
2765 /// Connection::udp_connect("127.0.0.1:0", "127.0.0.1:11214").await?,
2766 /// Connection::tls_connect("localhost", 11216, "cert.pem").await?,
2767 /// ] {
2768 /// assert!(c.set(b"k2", 0, 0, false, b"v2").await?);
2769 /// let result = c.gets(b"k2").await?;
2770 /// assert_eq!(result.unwrap().key, "k2");
2771 /// }
2772 /// # Ok::<(), io::Error>(())
2773 /// # }).unwrap()
2774 /// ```
2775 pub async fn gets(&mut self, key: impl AsRef<[u8]>) -> io::Result<Option<Item>> {
2776 match self {
2777 Connection::Tcp(s) => Ok(retrieval_cmd(s, b"gets", None, &[key.as_ref()])
2778 .await?
2779 .pop()),
2780 Connection::Unix(s) => Ok(retrieval_cmd(s, b"gets", None, &[key.as_ref()])
2781 .await?
2782 .pop()),
2783 Connection::Udp(s, r) => Ok(retrieval_cmd_udp(s, r, b"gets", None, &[key.as_ref()])
2784 .await?
2785 .pop()),
2786 Connection::Tls(s) => Ok(retrieval_cmd(s, b"gets", None, &[key.as_ref()])
2787 .await?
2788 .pop()),
2789 }
2790 }
2791
2792 /// # Example
2793 ///
2794 /// ```
2795 /// # use mcmc_rs::Connection;
2796 /// # use smol::{io, block_on};
2797 /// #
2798 /// # block_on(async {
2799 /// for mut c in [
2800 /// Connection::default().await?,
2801 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
2802 /// Connection::udp_connect("127.0.0.1:0", "127.0.0.1:11214").await?,
2803 /// Connection::tls_connect("localhost", 11216, "cert.pem").await?,
2804 /// ] {
2805 /// assert!(c.set(b"k3", 0, 0, false, b"v3").await?);
2806 /// let result = c.gat(0, b"k3").await?;
2807 /// assert_eq!(result.unwrap().key, "k3");
2808 /// }
2809 /// # Ok::<(), io::Error>(())
2810 /// # }).unwrap()
2811 /// ```
2812 pub async fn gat(&mut self, exptime: i64, key: impl AsRef<[u8]>) -> io::Result<Option<Item>> {
2813 match self {
2814 Connection::Tcp(s) => Ok(retrieval_cmd(s, b"gat", Some(exptime), &[key.as_ref()])
2815 .await?
2816 .pop()),
2817 Connection::Unix(s) => Ok(retrieval_cmd(s, b"gat", Some(exptime), &[key.as_ref()])
2818 .await?
2819 .pop()),
2820 Connection::Udp(s, r) => {
2821 Ok(
2822 retrieval_cmd_udp(s, r, b"gat", Some(exptime), &[key.as_ref()])
2823 .await?
2824 .pop(),
2825 )
2826 }
2827 Connection::Tls(s) => Ok(retrieval_cmd(s, b"gat", Some(exptime), &[key.as_ref()])
2828 .await?
2829 .pop()),
2830 }
2831 }
2832
2833 /// # Example
2834 ///
2835 /// ```
2836 /// # use mcmc_rs::Connection;
2837 /// # use smol::{io, block_on};
2838 /// #
2839 /// # block_on(async {
2840 /// for mut c in [
2841 /// Connection::default().await?,
2842 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
2843 /// Connection::udp_connect("127.0.0.1:0", "127.0.0.1:11214").await?,
2844 /// Connection::tls_connect("localhost", 11216, "cert.pem").await?,
2845 /// ] {
2846 /// assert!(c.set(b"k4", 0, 0, false, b"v4").await?);
2847 /// let result = c.gats(0, b"k4").await?;
2848 /// assert_eq!(result.unwrap().key, "k4");
2849 /// }
2850 /// # Ok::<(), io::Error>(())
2851 /// # }).unwrap()
2852 /// ```
2853 pub async fn gats(&mut self, exptime: i64, key: impl AsRef<[u8]>) -> io::Result<Option<Item>> {
2854 match self {
2855 Connection::Tcp(s) => Ok(retrieval_cmd(s, b"gats", Some(exptime), &[key.as_ref()])
2856 .await?
2857 .pop()),
2858 Connection::Unix(s) => Ok(retrieval_cmd(s, b"gats", Some(exptime), &[key.as_ref()])
2859 .await?
2860 .pop()),
2861 Connection::Udp(s, r) => {
2862 Ok(
2863 retrieval_cmd_udp(s, r, b"gats", Some(exptime), &[key.as_ref()])
2864 .await?
2865 .pop(),
2866 )
2867 }
2868 Connection::Tls(s) => Ok(retrieval_cmd(s, b"gats", Some(exptime), &[key.as_ref()])
2869 .await?
2870 .pop()),
2871 }
2872 }
2873
2874 /// # Example
2875 ///
2876 /// ```
2877 /// # use mcmc_rs::Connection;
2878 /// # use smol::{io, block_on};
2879 /// #
2880 /// # block_on(async {
2881 /// for mut c in [
2882 /// Connection::default().await?,
2883 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
2884 /// Connection::udp_connect("127.0.0.1:0", "127.0.0.1:11214").await?,
2885 /// Connection::tls_connect("localhost", 11216, "cert.pem").await?,
2886 /// ] {
2887 /// assert!(c.set(b"k8", 0, 0, false, b"v8").await?);
2888 /// let result = c.get_multi(&[b"k8"]).await?;
2889 /// assert_eq!(result[0].key, "k8");
2890 /// }
2891 /// # Ok::<(), io::Error>(())
2892 /// # }).unwrap()
2893 /// ```
2894 pub async fn get_multi(&mut self, keys: &[impl AsRef<[u8]>]) -> io::Result<Vec<Item>> {
2895 match self {
2896 Connection::Tcp(s) => {
2897 retrieval_cmd(
2898 s,
2899 b"get",
2900 None,
2901 &keys.iter().map(|x| x.as_ref()).collect::<Vec<&[u8]>>(),
2902 )
2903 .await
2904 }
2905 Connection::Unix(s) => {
2906 retrieval_cmd(
2907 s,
2908 b"get",
2909 None,
2910 &keys.iter().map(|x| x.as_ref()).collect::<Vec<&[u8]>>(),
2911 )
2912 .await
2913 }
2914 Connection::Udp(s, r) => {
2915 retrieval_cmd_udp(
2916 s,
2917 r,
2918 b"get",
2919 None,
2920 &keys.iter().map(|x| x.as_ref()).collect::<Vec<&[u8]>>(),
2921 )
2922 .await
2923 }
2924 Connection::Tls(s) => {
2925 retrieval_cmd(
2926 s,
2927 b"get",
2928 None,
2929 &keys.iter().map(|x| x.as_ref()).collect::<Vec<&[u8]>>(),
2930 )
2931 .await
2932 }
2933 }
2934 }
2935
2936 /// # Example
2937 ///
2938 /// ```
2939 /// # use mcmc_rs::Connection;
2940 /// # use smol::{io, block_on};
2941 /// #
2942 /// # block_on(async {
2943 /// for mut c in [
2944 /// Connection::default().await?,
2945 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
2946 /// Connection::udp_connect("127.0.0.1:0", "127.0.0.1:11214").await?,
2947 /// Connection::tls_connect("localhost", 11216, "cert.pem").await?,
2948 /// ] {
2949 /// assert!(c.set(b"k7", 0, 0, false, b"v7").await?);
2950 /// let result = c.gets_multi(&[b"k7"]).await?;
2951 /// assert_eq!(result[0].key, "k7");
2952 /// }
2953 /// # Ok::<(), io::Error>(())
2954 /// # }).unwrap()
2955 /// ```
2956 pub async fn gets_multi(&mut self, keys: &[impl AsRef<[u8]>]) -> io::Result<Vec<Item>> {
2957 match self {
2958 Connection::Tcp(s) => {
2959 retrieval_cmd(
2960 s,
2961 b"gets",
2962 None,
2963 &keys.iter().map(|x| x.as_ref()).collect::<Vec<&[u8]>>(),
2964 )
2965 .await
2966 }
2967 Connection::Unix(s) => {
2968 retrieval_cmd(
2969 s,
2970 b"gets",
2971 None,
2972 &keys.iter().map(|x| x.as_ref()).collect::<Vec<&[u8]>>(),
2973 )
2974 .await
2975 }
2976 Connection::Udp(s, r) => {
2977 retrieval_cmd_udp(
2978 s,
2979 r,
2980 b"gets",
2981 None,
2982 &keys.iter().map(|x| x.as_ref()).collect::<Vec<&[u8]>>(),
2983 )
2984 .await
2985 }
2986 Connection::Tls(s) => {
2987 retrieval_cmd(
2988 s,
2989 b"gets",
2990 None,
2991 &keys.iter().map(|x| x.as_ref()).collect::<Vec<&[u8]>>(),
2992 )
2993 .await
2994 }
2995 }
2996 }
2997
2998 /// # Example
2999 ///
3000 /// ```
3001 /// # use mcmc_rs::Connection;
3002 /// # use smol::{io, block_on};
3003 /// #
3004 /// # block_on(async {
3005 /// for mut c in [
3006 /// Connection::default().await?,
3007 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
3008 /// Connection::udp_connect("127.0.0.1:0", "127.0.0.1:11214").await?,
3009 /// Connection::tls_connect("localhost", 11216, "cert.pem").await?,
3010 /// ] {
3011 /// assert!(c.set(b"k6", 0, 0, false, b"v6").await?);
3012 /// let result = c.gat_multi(0, &[b"k6"]).await?;
3013 /// assert_eq!(result[0].key, "k6");
3014 /// }
3015 /// # Ok::<(), io::Error>(())
3016 /// # }).unwrap()
3017 /// ```
3018 pub async fn gat_multi(
3019 &mut self,
3020 exptime: i64,
3021 keys: &[impl AsRef<[u8]>],
3022 ) -> io::Result<Vec<Item>> {
3023 match self {
3024 Connection::Tcp(s) => {
3025 retrieval_cmd(
3026 s,
3027 b"gat",
3028 Some(exptime),
3029 &keys.iter().map(|x| x.as_ref()).collect::<Vec<&[u8]>>(),
3030 )
3031 .await
3032 }
3033 Connection::Unix(s) => {
3034 retrieval_cmd(
3035 s,
3036 b"gat",
3037 Some(exptime),
3038 &keys.iter().map(|x| x.as_ref()).collect::<Vec<&[u8]>>(),
3039 )
3040 .await
3041 }
3042 Connection::Udp(s, r) => {
3043 retrieval_cmd_udp(
3044 s,
3045 r,
3046 b"gat",
3047 Some(exptime),
3048 &keys.iter().map(|x| x.as_ref()).collect::<Vec<&[u8]>>(),
3049 )
3050 .await
3051 }
3052 Connection::Tls(s) => {
3053 retrieval_cmd(
3054 s,
3055 b"gat",
3056 Some(exptime),
3057 &keys.iter().map(|x| x.as_ref()).collect::<Vec<&[u8]>>(),
3058 )
3059 .await
3060 }
3061 }
3062 }
3063
3064 /// # Example
3065 ///
3066 /// ```
3067 /// # use mcmc_rs::Connection;
3068 /// # use smol::{io, block_on};
3069 /// #
3070 /// # block_on(async {
3071 /// for mut c in [
3072 /// Connection::default().await?,
3073 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
3074 /// Connection::udp_connect("127.0.0.1:0", "127.0.0.1:11214").await?,
3075 /// Connection::tls_connect("localhost", 11216, "cert.pem").await?,
3076 /// ] {
3077 /// assert!(c.set(b"k5", 0, 0, false, b"v5").await?);
3078 /// let result = c.gats_multi(0, &[b"k5"]).await?;
3079 /// assert_eq!(result[0].key, "k5");
3080 /// }
3081 /// # Ok::<(), io::Error>(())
3082 /// # }).unwrap()
3083 /// ```
3084 pub async fn gats_multi(
3085 &mut self,
3086 exptime: i64,
3087 keys: &[impl AsRef<[u8]>],
3088 ) -> io::Result<Vec<Item>> {
3089 match self {
3090 Connection::Tcp(s) => {
3091 retrieval_cmd(
3092 s,
3093 b"gats",
3094 Some(exptime),
3095 &keys.iter().map(|x| x.as_ref()).collect::<Vec<&[u8]>>(),
3096 )
3097 .await
3098 }
3099 Connection::Unix(s) => {
3100 retrieval_cmd(
3101 s,
3102 b"gats",
3103 Some(exptime),
3104 &keys.iter().map(|x| x.as_ref()).collect::<Vec<&[u8]>>(),
3105 )
3106 .await
3107 }
3108 Connection::Udp(s, r) => {
3109 retrieval_cmd_udp(
3110 s,
3111 r,
3112 b"gats",
3113 Some(exptime),
3114 &keys.iter().map(|x| x.as_ref()).collect::<Vec<&[u8]>>(),
3115 )
3116 .await
3117 }
3118 Connection::Tls(s) => {
3119 retrieval_cmd(
3120 s,
3121 b"gats",
3122 Some(exptime),
3123 &keys.iter().map(|x| x.as_ref()).collect::<Vec<&[u8]>>(),
3124 )
3125 .await
3126 }
3127 }
3128 }
3129
3130 /// # Example
3131 ///
3132 /// ```
3133 /// # use mcmc_rs::Connection;
3134 /// # use smol::{io, block_on};
3135 /// #
3136 /// # block_on(async {
3137 /// for mut c in [
3138 /// Connection::default().await?,
3139 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
3140 /// Connection::udp_connect("127.0.0.1:0", "127.0.0.1:11214").await?,
3141 /// Connection::tls_connect("localhost", 11216, "cert.pem").await?,
3142 /// ] {
3143 /// let result = c.stats(None).await?;
3144 /// assert!(result.len() > 0);
3145 /// }
3146 /// # Ok::<(), io::Error>(())
3147 /// # }).unwrap()
3148 /// ```
3149 pub async fn stats(&mut self, arg: Option<StatsArg>) -> io::Result<HashMap<String, String>> {
3150 match self {
3151 Connection::Tcp(s) => stats_cmd(s, arg).await,
3152 Connection::Unix(s) => stats_cmd(s, arg).await,
3153 Connection::Udp(s, r) => stats_cmd_udp(s, r, arg).await,
3154 Connection::Tls(s) => stats_cmd(s, arg).await,
3155 }
3156 }
3157
3158 /// # Example
3159 ///
3160 /// ```
3161 /// # use mcmc_rs::{Connection, SlabsAutomoveArg};
3162 /// # use smol::{io, block_on};
3163 /// #
3164 /// # block_on(async {
3165 /// for mut c in [
3166 /// Connection::default().await?,
3167 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
3168 /// Connection::udp_connect("127.0.0.1:0", "127.0.0.1:11214").await?,
3169 /// Connection::tls_connect("localhost", 11216, "cert.pem").await?,
3170 /// ] {
3171 /// c.slabs_automove(SlabsAutomoveArg::Zero).await?;
3172 /// }
3173 /// # Ok::<(), io::Error>(())
3174 /// # }).unwrap()
3175 /// ```
3176 pub async fn slabs_automove(&mut self, arg: SlabsAutomoveArg) -> io::Result<()> {
3177 match self {
3178 Connection::Tcp(s) => slabs_automove_cmd(s, arg).await,
3179 Connection::Unix(s) => slabs_automove_cmd(s, arg).await,
3180 Connection::Udp(s, r) => slabs_automove_cmd_udp(s, r, arg).await,
3181 Connection::Tls(s) => slabs_automove_cmd(s, arg).await,
3182 }
3183 }
3184
3185 /// # Example
3186 ///
3187 /// ```
3188 /// # use mcmc_rs::{Connection, LruCrawlerArg};
3189 /// # use smol::{io, block_on};
3190 /// #
3191 /// # block_on(async {
3192 /// for mut c in [
3193 /// Connection::default().await?,
3194 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
3195 /// Connection::udp_connect("127.0.0.1:0", "127.0.0.1:11214").await?,
3196 /// Connection::tls_connect("localhost", 11216, "cert.pem").await?,
3197 /// ] {
3198 /// let result = c.lru_crawler(LruCrawlerArg::Enable).await;
3199 /// assert!(result.is_err());
3200 /// }
3201 /// # Ok::<(), io::Error>(())
3202 /// # }).unwrap()
3203 /// ```
3204 pub async fn lru_crawler(&mut self, arg: LruCrawlerArg) -> io::Result<()> {
3205 match self {
3206 Connection::Tcp(s) => lru_crawler_cmd(s, arg).await,
3207 Connection::Unix(s) => lru_crawler_cmd(s, arg).await,
3208 Connection::Udp(s, r) => lru_crawler_cmd_udp(s, r, arg).await,
3209 Connection::Tls(s) => lru_crawler_cmd(s, arg).await,
3210 }
3211 }
3212
3213 /// # Example
3214 ///
3215 /// ```
3216 /// # use mcmc_rs::Connection;
3217 /// # use smol::{io, block_on};
3218 /// #
3219 /// # block_on(async {
3220 /// for mut c in [
3221 /// Connection::default().await?,
3222 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
3223 /// Connection::udp_connect("127.0.0.1:0", "127.0.0.1:11214").await?,
3224 /// Connection::tls_connect("localhost", 11216, "cert.pem").await?,
3225 /// ] {
3226 /// c.lru_crawler_sleep(1_000_000).await?;
3227 /// }
3228 /// # Ok::<(), io::Error>(())
3229 /// # }).unwrap()
3230 /// ```
3231 pub async fn lru_crawler_sleep(&mut self, microseconds: usize) -> io::Result<()> {
3232 match self {
3233 Connection::Tcp(s) => lru_crawler_sleep_cmd(s, microseconds).await,
3234 Connection::Unix(s) => lru_crawler_sleep_cmd(s, microseconds).await,
3235 Connection::Udp(s, r) => lru_crawler_sleep_cmd_udp(s, r, microseconds).await,
3236 Connection::Tls(s) => lru_crawler_sleep_cmd(s, microseconds).await,
3237 }
3238 }
3239
3240 /// # Example
3241 ///
3242 /// ```
3243 /// # use mcmc_rs::Connection;
3244 /// # use smol::{io, block_on};
3245 /// #
3246 /// # block_on(async {
3247 /// for mut c in [
3248 /// Connection::default().await?,
3249 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
3250 /// Connection::udp_connect("127.0.0.1:0", "127.0.0.1:11214").await?,
3251 /// Connection::tls_connect("localhost", 11216, "cert.pem").await?,
3252 /// ] {
3253 /// c.lru_crawler_tocrawl(0).await?;
3254 /// }
3255 /// # Ok::<(), io::Error>(())
3256 /// # }).unwrap()
3257 /// ```
3258 pub async fn lru_crawler_tocrawl(&mut self, arg: u32) -> io::Result<()> {
3259 match self {
3260 Connection::Tcp(s) => lru_crawler_tocrawl_cmd(s, arg).await,
3261 Connection::Unix(s) => lru_crawler_tocrawl_cmd(s, arg).await,
3262 Connection::Udp(s, r) => lru_crawler_tocrawl_cmd_udp(s, r, arg).await,
3263 Connection::Tls(s) => lru_crawler_tocrawl_cmd(s, arg).await,
3264 }
3265 }
3266
3267 /// # Example
3268 ///
3269 /// ```
3270 /// # use mcmc_rs::{Connection, LruCrawlerCrawlArg};
3271 /// # use smol::{io, block_on};
3272 /// #
3273 /// # block_on(async {
3274 /// for mut c in [
3275 /// Connection::default().await?,
3276 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
3277 /// Connection::udp_connect("127.0.0.1:0", "127.0.0.1:11214").await?,
3278 /// Connection::tls_connect("localhost", 11216, "cert.pem").await?,
3279 /// ] {
3280 /// c.lru_crawler_crawl(LruCrawlerCrawlArg::All).await?;
3281 /// }
3282 /// # Ok::<(), io::Error>(())
3283 /// # }).unwrap()
3284 /// ```
3285 pub async fn lru_crawler_crawl(&mut self, arg: LruCrawlerCrawlArg<'_>) -> io::Result<()> {
3286 match self {
3287 Connection::Tcp(s) => lru_crawler_crawl_cmd(s, arg).await,
3288 Connection::Unix(s) => lru_crawler_crawl_cmd(s, arg).await,
3289 Connection::Udp(s, r) => lru_crawler_crawl_cmd_udp(s, r, arg).await,
3290 Connection::Tls(s) => lru_crawler_crawl_cmd(s, arg).await,
3291 }
3292 }
3293
3294 /// # Example
3295 ///
3296 /// ```
3297 /// # use mcmc_rs::Connection;
3298 /// # use smol::{io, block_on};
3299 /// #
3300 /// # block_on(async {
3301 /// for mut c in [
3302 /// Connection::default().await?,
3303 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
3304 /// Connection::udp_connect("127.0.0.1:0", "127.0.0.1:11214").await?,
3305 /// Connection::tls_connect("localhost", 11216, "cert.pem").await?,
3306 /// ] {
3307 /// let result = c.slabs_reassign(1, 2).await;
3308 /// assert!(result.is_err());
3309 /// }
3310 /// # Ok::<(), io::Error>(())
3311 /// # }).unwrap()
3312 /// ```
3313 pub async fn slabs_reassign(
3314 &mut self,
3315 source_class: isize,
3316 dest_class: isize,
3317 ) -> io::Result<()> {
3318 match self {
3319 Connection::Tcp(s) => slabs_reassign_cmd(s, source_class, dest_class).await,
3320 Connection::Unix(s) => slabs_reassign_cmd(s, source_class, dest_class).await,
3321 Connection::Udp(s, r) => slabs_reassign_cmd_udp(s, r, source_class, dest_class).await,
3322 Connection::Tls(s) => slabs_reassign_cmd(s, source_class, dest_class).await,
3323 }
3324 }
3325
3326 /// # Example
3327 ///
3328 /// ```
3329 /// # use mcmc_rs::{Connection, LruCrawlerMetadumpArg};
3330 /// # use smol::{io, block_on};
3331 /// #
3332 /// # block_on(async {
3333 /// for mut c in [
3334 /// Connection::default().await?,
3335 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
3336 /// Connection::tls_connect("localhost", 11216, "cert.pem").await?,
3337 /// ] {
3338 /// let result = c
3339 /// .lru_crawler_metadump(LruCrawlerMetadumpArg::Classids(&[2]))
3340 /// .await?;
3341 /// assert!(result.is_empty());
3342 /// }
3343 /// # Ok::<(), io::Error>(())
3344 /// # }).unwrap()
3345 /// ```
3346 pub async fn lru_crawler_metadump(
3347 &mut self,
3348 arg: LruCrawlerMetadumpArg<'_>,
3349 ) -> io::Result<Vec<String>> {
3350 match self {
3351 Connection::Tcp(s) => lru_crawler_metadump_cmd(s, arg).await,
3352 Connection::Unix(s) => lru_crawler_metadump_cmd(s, arg).await,
3353 Connection::Udp(_s, _r) => unreachable!("this command not work with udp connection!"),
3354 Connection::Tls(s) => lru_crawler_metadump_cmd(s, arg).await,
3355 }
3356 }
3357
3358 /// # Example
3359 ///
3360 /// ```
3361 /// # use mcmc_rs::{Connection, LruCrawlerMgdumpArg};
3362 /// # use smol::{io, block_on};
3363 /// #
3364 /// # block_on(async {
3365 /// for mut c in [
3366 /// Connection::default().await?,
3367 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
3368 /// Connection::tls_connect("localhost", 11216, "cert.pem").await?,
3369 /// ] {
3370 /// let result = c
3371 /// .lru_crawler_mgdump(LruCrawlerMgdumpArg::Classids(&[2]))
3372 /// .await?;
3373 /// assert!(result.is_empty());
3374 /// }
3375 /// # Ok::<(), io::Error>(())
3376 /// # }).unwrap()
3377 /// ```
3378 pub async fn lru_crawler_mgdump(
3379 &mut self,
3380 arg: LruCrawlerMgdumpArg<'_>,
3381 ) -> io::Result<Vec<String>> {
3382 match self {
3383 Connection::Tcp(s) => lru_crawler_mgdump_cmd(s, arg).await,
3384 Connection::Unix(s) => lru_crawler_mgdump_cmd(s, arg).await,
3385 Connection::Udp(_s, _r) => unreachable!("this command not work with udp connection!"),
3386 Connection::Tls(s) => lru_crawler_mgdump_cmd(s, arg).await,
3387 }
3388 }
3389
3390 /// # Example
3391 ///
3392 /// ```
3393 /// # use mcmc_rs::Connection;
3394 /// # use smol::{io, block_on};
3395 /// #
3396 /// # block_on(async {
3397 /// for mut c in [
3398 /// Connection::default().await?,
3399 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
3400 /// Connection::udp_connect("127.0.0.1:0", "127.0.0.1:11214").await?,
3401 /// Connection::tls_connect("localhost", 11216, "cert.pem").await?,
3402 /// ] {
3403 /// c.mn().await?;
3404 /// }
3405 /// # Ok::<(), io::Error>(())
3406 /// # }).unwrap()
3407 /// ```
3408 pub async fn mn(&mut self) -> io::Result<()> {
3409 match self {
3410 Connection::Tcp(s) => mn_cmd(s).await,
3411 Connection::Unix(s) => mn_cmd(s).await,
3412 Connection::Udp(s, r) => mn_cmd_udp(s, r).await,
3413 Connection::Tls(s) => mn_cmd(s).await,
3414 }
3415 }
3416
3417 /// # Example
3418 ///
3419 /// ```
3420 /// # use mcmc_rs::{Connection, LruCrawlerCrawlArg};
3421 /// # use smol::{io, block_on};
3422 /// #
3423 /// # block_on(async {
3424 /// for mut c in [
3425 /// Connection::default().await?,
3426 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
3427 /// Connection::udp_connect("127.0.0.1:0", "127.0.0.1:11214").await?,
3428 /// Connection::tls_connect("localhost", 11216, "cert.pem").await?,
3429 /// ] {
3430 /// c.set(b"k9", 0, 0, false, b"v9").await?;
3431 /// assert!(c.me(b"k9").await?.is_some());
3432 /// }
3433 /// # Ok::<(), io::Error>(())
3434 /// # }).unwrap()
3435 /// ```
3436 pub async fn me(&mut self, key: impl AsRef<[u8]>) -> io::Result<Option<String>> {
3437 match self {
3438 Connection::Tcp(s) => me_cmd(s, key.as_ref()).await,
3439 Connection::Unix(s) => me_cmd(s, key.as_ref()).await,
3440 Connection::Udp(s, r) => me_cmd_udp(s, r, key.as_ref()).await,
3441 Connection::Tls(s) => me_cmd(s, key.as_ref()).await,
3442 }
3443 }
3444
3445 /// # Example
3446 ///
3447 /// ```
3448 /// # use mcmc_rs::{Connection, WatchArg};
3449 /// # use smol::{io, block_on};
3450 /// #
3451 /// # block_on(async {
3452 /// for mut c in [
3453 /// Connection::default().await?,
3454 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
3455 /// Connection::tls_connect("localhost", 11216, "cert.pem").await?,
3456 /// ] {
3457 /// assert!(c.watch(&[WatchArg::Fetchers]).await.is_ok())
3458 /// }
3459 /// # Ok::<(), io::Error>(())
3460 /// # }).unwrap()
3461 /// ```
3462 pub async fn watch(mut self, arg: &[WatchArg]) -> io::Result<WatchStream> {
3463 match &mut self {
3464 Connection::Tcp(s) => watch_cmd(s, arg).await?,
3465 Connection::Unix(s) => watch_cmd(s, arg).await?,
3466 Connection::Udp(_s, _r) => unreachable!("this command not work with udp!"),
3467 Connection::Tls(s) => watch_cmd(s, arg).await?,
3468 };
3469 Ok(WatchStream(self))
3470 }
3471
3472 pub fn pipeline(&mut self) -> Pipeline<'_> {
3473 Pipeline::new(self)
3474 }
3475
3476 /// # Example
3477 ///
3478 /// ```
3479 /// # use mcmc_rs::{Connection, MgFlag, MgItem};
3480 /// # use smol::{io, block_on};
3481 /// #
3482 /// # block_on(async {
3483 /// for mut c in [
3484 /// Connection::default().await?,
3485 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
3486 /// Connection::udp_connect("127.0.0.1:0", "127.0.0.1:11214").await?,
3487 /// Connection::tls_connect("localhost", 11216, "cert.pem").await?,
3488 /// ] {
3489 /// let result = c
3490 /// .mg(
3491 /// b"44OG44K544OI",
3492 /// &[
3493 /// MgFlag::Base64Key,
3494 /// MgFlag::ReturnCas,
3495 /// MgFlag::CheckCas(99),
3496 /// MgFlag::ReturnFlags,
3497 /// MgFlag::ReturnHit,
3498 /// MgFlag::ReturnKey,
3499 /// MgFlag::ReturnLastAccess,
3500 /// MgFlag::Opaque("opaque".to_string()),
3501 /// MgFlag::ReturnSize,
3502 /// MgFlag::ReturnTtl,
3503 /// MgFlag::UnBump,
3504 /// MgFlag::ReturnValue,
3505 /// MgFlag::NewCas(0),
3506 /// MgFlag::Autovivify(-1),
3507 /// MgFlag::RecacheTtl(-1),
3508 /// MgFlag::UpdateTtl(-1),
3509 /// ],
3510 /// )
3511 /// .await?;
3512 /// assert_eq!(
3513 /// result,
3514 /// MgItem {
3515 /// success: true,
3516 /// base64_key: false,
3517 /// cas: Some(0),
3518 /// flags: Some(0),
3519 /// hit: Some(0),
3520 /// key: Some("テスト".to_string()),
3521 /// last_access_ttl: Some(0),
3522 /// opaque: Some("opaque".to_string()),
3523 /// size: Some(0),
3524 /// ttl: Some(-1),
3525 /// data_block: Some(vec![]),
3526 /// already_win: false,
3527 /// won_recache: true,
3528 /// stale: false,
3529 /// }
3530 /// );
3531 /// }
3532 /// # Ok::<(), io::Error>(())
3533 /// # }).unwrap()
3534 /// ```
3535 pub async fn mg(&mut self, key: impl AsRef<[u8]>, flags: &[MgFlag]) -> io::Result<MgItem> {
3536 match self {
3537 Connection::Tcp(s) => mg_cmd(s, key.as_ref(), flags).await,
3538 Connection::Unix(s) => mg_cmd(s, key.as_ref(), flags).await,
3539 Connection::Udp(s, r) => mg_cmd_udp(s, r, key.as_ref(), flags).await,
3540 Connection::Tls(s) => mg_cmd(s, key.as_ref(), flags).await,
3541 }
3542 }
3543
3544 /// # Example
3545 ///
3546 /// ```
3547 /// # use mcmc_rs::{Connection, MsFlag, MsMode, MsItem};
3548 /// # use smol::{io, block_on};
3549 /// #
3550 /// # block_on(async {
3551 /// for mut c in [
3552 /// Connection::default().await?,
3553 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
3554 /// Connection::udp_connect("127.0.0.1:0", "127.0.0.1:11214").await?,
3555 /// Connection::tls_connect("localhost", 11216, "cert.pem").await?,
3556 /// ] {
3557 /// let result = c
3558 /// .ms(
3559 /// b"44OG44K544OI",
3560 /// &[
3561 /// MsFlag::Base64Key,
3562 /// MsFlag::ReturnCas,
3563 /// MsFlag::CompareCas(0),
3564 /// MsFlag::NewCas(0),
3565 /// MsFlag::SetFlags(0),
3566 /// MsFlag::Invalidate,
3567 /// MsFlag::ReturnKey,
3568 /// MsFlag::Opaque("opaque".to_string()),
3569 /// MsFlag::ReturnSize,
3570 /// MsFlag::Ttl(-1),
3571 /// MsFlag::Mode(MsMode::Set),
3572 /// MsFlag::Autovivify(0),
3573 /// ],
3574 /// b"hi",
3575 /// )
3576 /// .await?;
3577 /// assert_eq!(
3578 /// result,
3579 /// MsItem {
3580 /// success: false,
3581 /// cas: Some(0),
3582 /// key: Some("44OG44K544OI".to_string()),
3583 /// opaque: Some("opaque".to_string()),
3584 /// size: Some(2),
3585 /// base64_key: true
3586 /// }
3587 /// );
3588 /// }
3589 /// # Ok::<(), io::Error>(())
3590 /// # }).unwrap()
3591 /// ```
3592 pub async fn ms(
3593 &mut self,
3594 key: impl AsRef<[u8]>,
3595 flags: &[MsFlag],
3596 data_block: impl AsRef<[u8]>,
3597 ) -> io::Result<MsItem> {
3598 match self {
3599 Connection::Tcp(s) => ms_cmd(s, key.as_ref(), flags, data_block.as_ref()).await,
3600 Connection::Unix(s) => ms_cmd(s, key.as_ref(), flags, data_block.as_ref()).await,
3601 Connection::Udp(s, r) => {
3602 ms_cmd_udp(s, r, key.as_ref(), flags, data_block.as_ref()).await
3603 }
3604 Connection::Tls(s) => ms_cmd(s, key.as_ref(), flags, data_block.as_ref()).await,
3605 }
3606 }
3607
3608 /// # Example
3609 ///
3610 /// ```
3611 /// # use mcmc_rs::{Connection, MdFlag, MdItem};
3612 /// # use smol::{io, block_on};
3613 /// #
3614 /// # block_on(async {
3615 /// for mut c in [
3616 /// Connection::default().await?,
3617 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
3618 /// Connection::udp_connect("127.0.0.1:0", "127.0.0.1:11214").await?,
3619 /// Connection::tls_connect("localhost", 11216, "cert.pem").await?,
3620 /// ] {
3621 /// let result = c
3622 /// .md(
3623 /// b"44OG44K544OI",
3624 /// &[
3625 /// MdFlag::Base64Key,
3626 /// MdFlag::CompareCas(0),
3627 /// MdFlag::NewCas(0),
3628 /// MdFlag::Invalidate,
3629 /// MdFlag::ReturnKey,
3630 /// MdFlag::Opaque("opaque".to_string()),
3631 /// MdFlag::UpdateTtl(-1),
3632 /// MdFlag::LeaveKey,
3633 /// ],
3634 /// )
3635 /// .await?;
3636 /// assert_eq!(
3637 /// result,
3638 /// MdItem {
3639 /// success: false,
3640 /// key: Some("44OG44K544OI".to_string()),
3641 /// opaque: Some("opaque".to_string()),
3642 /// base64_key: true
3643 /// }
3644 /// );
3645 /// }
3646 /// # Ok::<(), io::Error>(())
3647 /// # }).unwrap()
3648 /// ```
3649 pub async fn md(&mut self, key: impl AsRef<[u8]>, flags: &[MdFlag]) -> io::Result<MdItem> {
3650 match self {
3651 Connection::Tcp(s) => md_cmd(s, key.as_ref(), flags).await,
3652 Connection::Unix(s) => md_cmd(s, key.as_ref(), flags).await,
3653 Connection::Udp(s, r) => md_cmd_udp(s, r, key.as_ref(), flags).await,
3654 Connection::Tls(s) => md_cmd(s, key.as_ref(), flags).await,
3655 }
3656 }
3657
3658 /// # Example
3659 ///
3660 /// ```
3661 /// # use mcmc_rs::{Connection, MaFlag, MaMode, MaItem};
3662 /// # use smol::{io, block_on};
3663 /// #
3664 /// # block_on(async {
3665 /// for mut c in [
3666 /// Connection::default().await?,
3667 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
3668 /// Connection::udp_connect("127.0.0.1:0", "127.0.0.1:11214").await?,
3669 /// Connection::tls_connect("localhost", 11216, "cert.pem").await?,
3670 /// ] {
3671 /// let result = c
3672 /// .ma(
3673 /// b"aGk=",
3674 /// &[
3675 /// MaFlag::Base64Key,
3676 /// MaFlag::CompareCas(0),
3677 /// MaFlag::NewCas(0),
3678 /// MaFlag::AutoCreate(0),
3679 /// MaFlag::InitValue(0),
3680 /// MaFlag::DeltaApply(0),
3681 /// MaFlag::UpdateTtl(0),
3682 /// MaFlag::Mode(MaMode::Incr),
3683 /// MaFlag::Opaque("opaque".to_string()),
3684 /// MaFlag::ReturnTtl,
3685 /// MaFlag::ReturnCas,
3686 /// MaFlag::ReturnValue,
3687 /// MaFlag::ReturnKey,
3688 /// ],
3689 /// )
3690 /// .await?;
3691 /// assert_eq!(
3692 /// result,
3693 /// MaItem {
3694 /// success: true,
3695 /// opaque: Some("opaque".to_string()),
3696 /// ttl: Some(-1),
3697 /// cas: Some(0),
3698 /// number: Some(0),
3699 /// key: Some("aGk=".to_string()),
3700 /// base64_key: true
3701 /// }
3702 /// );
3703 /// }
3704 /// # Ok::<(), io::Error>(())
3705 /// # }).unwrap()
3706 /// ```
3707 pub async fn ma(&mut self, key: impl AsRef<[u8]>, flags: &[MaFlag]) -> io::Result<MaItem> {
3708 match self {
3709 Connection::Tcp(s) => ma_cmd(s, key.as_ref(), flags).await,
3710 Connection::Unix(s) => ma_cmd(s, key.as_ref(), flags).await,
3711 Connection::Udp(s, r) => ma_cmd_udp(s, r, key.as_ref(), flags).await,
3712 Connection::Tls(s) => ma_cmd(s, key.as_ref(), flags).await,
3713 }
3714 }
3715
3716 /// # Example
3717 ///
3718 /// ```
3719 /// use mcmc_rs::{Connection, LruArg, LruMode};
3720 /// # use smol::{io, block_on};
3721 /// #
3722 /// # block_on(async {
3723 /// for mut c in [
3724 /// Connection::default().await?,
3725 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
3726 /// Connection::udp_connect("127.0.0.1:0", "127.0.0.1:11214").await?,
3727 /// Connection::tls_connect("localhost", 11216, "cert.pem").await?,
3728 /// ] {
3729 /// assert!(c.lru(LruArg::Mode(LruMode::Flat)).await.is_ok())
3730 /// }
3731 /// # Ok::<(), io::Error>(())
3732 /// # }).unwrap()
3733 /// ```
3734 pub async fn lru(&mut self, arg: LruArg) -> io::Result<()> {
3735 match self {
3736 Connection::Tcp(s) => lru_cmd(s, arg).await,
3737 Connection::Unix(s) => lru_cmd(s, arg).await,
3738 Connection::Udp(s, r) => lru_cmd_udp(s, r, arg).await,
3739 Connection::Tls(s) => lru_cmd(s, arg).await,
3740 }
3741 }
3742}
3743
3744pub struct WatchStream(Connection);
3745impl WatchStream {
3746 /// # Example
3747 ///
3748 /// ```
3749 /// use mcmc_rs::{Connection, WatchArg};
3750 /// # use smol::{io, block_on};
3751 /// #
3752 /// # block_on(async {
3753 ///
3754 /// for (mut c1, mut c2) in [
3755 /// (Connection::default().await?, Connection::default().await?),
3756 /// (
3757 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
3758 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
3759 /// ),
3760 /// (
3761 /// Connection::tls_connect("localhost", 11216, "cert.pem").await?,
3762 /// Connection::tls_connect("localhost", 11216, "cert.pem").await?,
3763 /// ),
3764 /// ] {
3765 /// let mut w = c1.watch(&[WatchArg::Fetchers]).await?;
3766 /// c2.get(b"key").await?;
3767 /// let result = w.message().await?;
3768 /// assert!(result.is_some())
3769 /// }
3770 /// # Ok::<(), io::Error>(())
3771 /// # }).unwrap()
3772 /// ```
3773 pub async fn message(&mut self) -> io::Result<Option<String>> {
3774 let mut line = String::new();
3775 let n = match &mut self.0 {
3776 Connection::Tcp(s) => s.read_line(&mut line).await?,
3777 Connection::Unix(s) => s.read_line(&mut line).await?,
3778 Connection::Udp(_s, _r) => unreachable!("this command not work with udp connection"),
3779 Connection::Tls(s) => s.read_line(&mut line).await?,
3780 };
3781 if n == 0 {
3782 Ok(None)
3783 } else {
3784 Ok(Some(line.trim_end().to_string()))
3785 }
3786 }
3787}
3788
3789pub struct ClientCrc32(Vec<Connection>);
3790impl ClientCrc32 {
3791 /// # Example
3792 ///
3793 /// ```
3794 /// use mcmc_rs::{ClientCrc32, Connection};
3795 /// # use smol::{io, block_on};
3796 /// #
3797 /// # block_on(async {
3798 /// let mut client = ClientCrc32::new(vec![
3799 /// Connection::default().await?,
3800 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
3801 /// ]);
3802 /// # Ok::<(), io::Error>(())
3803 /// # }).unwrap()
3804 /// ```
3805 pub fn new(conns: Vec<Connection>) -> Self {
3806 Self(conns)
3807 }
3808
3809 /// # Example
3810 ///
3811 /// ```
3812 /// use mcmc_rs::{ClientCrc32, Connection};
3813 /// # use smol::{io, block_on};
3814 /// #
3815 /// # block_on(async {
3816 /// let mut client = ClientCrc32::new(vec![
3817 /// Connection::default().await?,
3818 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
3819 /// ]);
3820 ///
3821 /// assert!(client.set(b"k7", 0, 0, false, b"v7").await?);
3822 /// assert_eq!(client.get(b"k7").await?.unwrap().key, "k7");
3823 /// # Ok::<(), io::Error>(())
3824 /// # }).unwrap()
3825 /// ```
3826 pub async fn get(&mut self, key: impl AsRef<[u8]>) -> io::Result<Option<Item>> {
3827 let size = self.0.len();
3828 self.0[crc32(key.as_ref()) as usize % size]
3829 .get(key.as_ref())
3830 .await
3831 }
3832
3833 /// # Example
3834 ///
3835 /// ```
3836 /// use mcmc_rs::{ClientCrc32, Connection};
3837 /// # use smol::{io, block_on};
3838 /// #
3839 /// # block_on(async {
3840 /// let mut client = ClientCrc32::new(vec![
3841 /// Connection::default().await?,
3842 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
3843 /// ]);
3844 ///
3845 /// assert!(client.set(b"k8", 0, 0, false, b"v8").await?);
3846 /// assert_eq!(client.gets(b"k8").await?.unwrap().key, "k8");
3847 /// # Ok::<(), io::Error>(())
3848 /// # }).unwrap()
3849 /// ```
3850 pub async fn gets(&mut self, key: impl AsRef<[u8]>) -> io::Result<Option<Item>> {
3851 let size = self.0.len();
3852 self.0[crc32(key.as_ref()) as usize % size]
3853 .gets(key.as_ref())
3854 .await
3855 }
3856
3857 /// # Example
3858 ///
3859 /// ```
3860 /// # use mcmc_rs::{Connection, ClientCrc32};
3861 /// # use smol::{io, block_on};
3862 /// #
3863 /// # block_on(async {
3864 /// let mut client = ClientCrc32::new(vec![
3865 /// Connection::default().await?,
3866 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
3867 /// ]);
3868 /// assert!(client.set(b"k9", 0, 0, false, b"v9").await?);
3869 /// let result = client.gat(0, b"k9").await?;
3870 /// assert_eq!(result.unwrap().key, "k9");
3871 /// # Ok::<(), io::Error>(())
3872 /// # }).unwrap()
3873 /// ```
3874 pub async fn gat(&mut self, exptime: i64, key: impl AsRef<[u8]>) -> io::Result<Option<Item>> {
3875 let size = self.0.len();
3876 self.0[crc32(key.as_ref()) as usize % size]
3877 .gat(exptime, key.as_ref())
3878 .await
3879 }
3880
3881 /// # Example
3882 ///
3883 /// ```
3884 /// # use mcmc_rs::{Connection, ClientCrc32};
3885 /// # use smol::{io, block_on};
3886 /// #
3887 /// # block_on(async {
3888 /// let mut client = ClientCrc32::new(vec![
3889 /// Connection::default().await?,
3890 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
3891 /// ]);
3892 /// assert!(client.set(b"k10", 0, 0, false, b"v10").await?);
3893 /// let result = client.gats(0, b"k10").await?;
3894 /// assert_eq!(result.unwrap().key, "k10");
3895 /// # Ok::<(), io::Error>(())
3896 /// # }).unwrap()
3897 /// ```
3898 pub async fn gats(&mut self, exptime: i64, key: impl AsRef<[u8]>) -> io::Result<Option<Item>> {
3899 let size = self.0.len();
3900 self.0[crc32(key.as_ref()) as usize % size]
3901 .gats(exptime, key.as_ref())
3902 .await
3903 }
3904
3905 /// # Example
3906 ///
3907 /// ```
3908 /// use mcmc_rs::{ClientCrc32, Connection};
3909 /// # use smol::{io, block_on};
3910 /// #
3911 /// # block_on(async {
3912 /// let mut client = ClientCrc32::new(vec![
3913 /// Connection::default().await?,
3914 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
3915 /// ]);
3916 ///
3917 /// assert!(client.set(b"key", 0, -1, true, b"value").await?);
3918 /// # Ok::<(), io::Error>(())
3919 /// # }).unwrap()
3920 /// ```
3921 pub async fn set(
3922 &mut self,
3923 key: impl AsRef<[u8]>,
3924 flags: u32,
3925 exptime: i64,
3926 noreply: bool,
3927 data_block: impl AsRef<[u8]>,
3928 ) -> io::Result<bool> {
3929 let size = self.0.len();
3930 self.0[crc32(key.as_ref()) as usize % size]
3931 .set(key.as_ref(), flags, exptime, noreply, data_block.as_ref())
3932 .await
3933 }
3934
3935 /// # Example
3936 ///
3937 /// ```
3938 /// use mcmc_rs::{ClientCrc32, Connection};
3939 /// # use smol::{io, block_on};
3940 /// #
3941 /// # block_on(async {
3942 /// let mut client = ClientCrc32::new(vec![
3943 /// Connection::default().await?,
3944 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
3945 /// ]);
3946 ///
3947 /// assert!(client.add(b"key", 0, -1, true, b"value").await?);
3948 /// # Ok::<(), io::Error>(())
3949 /// # }).unwrap()
3950 /// ```
3951 pub async fn add(
3952 &mut self,
3953 key: impl AsRef<[u8]>,
3954 flags: u32,
3955 exptime: i64,
3956 noreply: bool,
3957 data_block: impl AsRef<[u8]>,
3958 ) -> io::Result<bool> {
3959 let size = self.0.len();
3960 self.0[crc32(key.as_ref()) as usize % size]
3961 .add(key.as_ref(), flags, exptime, noreply, data_block.as_ref())
3962 .await
3963 }
3964
3965 /// # Example
3966 ///
3967 /// ```
3968 /// use mcmc_rs::{ClientCrc32, Connection};
3969 /// # use smol::{io, block_on};
3970 /// #
3971 /// # block_on(async {
3972 /// let mut client = ClientCrc32::new(vec![
3973 /// Connection::default().await?,
3974 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
3975 /// ]);
3976 ///
3977 /// assert!(client.replace(b"key", 0, -1, true, b"value").await?);
3978 /// # Ok::<(), io::Error>(())
3979 /// # }).unwrap()
3980 /// ```
3981 pub async fn replace(
3982 &mut self,
3983 key: impl AsRef<[u8]>,
3984 flags: u32,
3985 exptime: i64,
3986 noreply: bool,
3987 data_block: impl AsRef<[u8]>,
3988 ) -> io::Result<bool> {
3989 let size = self.0.len();
3990 self.0[crc32(key.as_ref()) as usize % size]
3991 .replace(key.as_ref(), flags, exptime, noreply, data_block.as_ref())
3992 .await
3993 }
3994
3995 /// # Example
3996 ///
3997 /// ```
3998 /// use mcmc_rs::{ClientCrc32, Connection};
3999 /// # use smol::{io, block_on};
4000 /// #
4001 /// # block_on(async {
4002 /// let mut client = ClientCrc32::new(vec![
4003 /// Connection::default().await?,
4004 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
4005 /// ]);
4006 ///
4007 /// assert!(client.append(b"key", 0, -1, true, b"value").await?);
4008 /// # Ok::<(), io::Error>(())
4009 /// # }).unwrap()
4010 /// ```
4011 pub async fn append(
4012 &mut self,
4013 key: impl AsRef<[u8]>,
4014 flags: u32,
4015 exptime: i64,
4016 noreply: bool,
4017 data_block: impl AsRef<[u8]>,
4018 ) -> io::Result<bool> {
4019 let size = self.0.len();
4020 self.0[crc32(key.as_ref()) as usize % size]
4021 .append(key.as_ref(), flags, exptime, noreply, data_block.as_ref())
4022 .await
4023 }
4024
4025 /// # Example
4026 ///
4027 /// ```
4028 /// use mcmc_rs::{ClientCrc32, Connection};
4029 /// # use smol::{io, block_on};
4030 /// #
4031 /// # block_on(async {
4032 /// let mut client = ClientCrc32::new(vec![
4033 /// Connection::default().await?,
4034 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
4035 /// ]);
4036 ///
4037 /// assert!(client.prepend(b"key", 0, -1, true, b"value").await?);
4038 /// # Ok::<(), io::Error>(())
4039 /// # }).unwrap()
4040 /// ```
4041 pub async fn prepend(
4042 &mut self,
4043 key: impl AsRef<[u8]>,
4044 flags: u32,
4045 exptime: i64,
4046 noreply: bool,
4047 data_block: impl AsRef<[u8]>,
4048 ) -> io::Result<bool> {
4049 let size = self.0.len();
4050 self.0[crc32(key.as_ref()) as usize % size]
4051 .prepend(key.as_ref(), flags, exptime, noreply, data_block.as_ref())
4052 .await
4053 }
4054
4055 /// # Example
4056 ///
4057 /// ```
4058 /// use mcmc_rs::{ClientCrc32, Connection};
4059 /// # use smol::{io, block_on};
4060 /// #
4061 /// # block_on(async {
4062 /// let mut client = ClientCrc32::new(vec![
4063 /// Connection::default().await?,
4064 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
4065 /// ]);
4066 ///
4067 /// assert!(client.cas(b"key", 0, -1, 0, true, b"value").await?);
4068 /// # Ok::<(), io::Error>(())
4069 /// # }).unwrap()
4070 /// ```
4071 pub async fn cas(
4072 &mut self,
4073 key: impl AsRef<[u8]>,
4074 flags: u32,
4075 exptime: i64,
4076 cas_unique: u64,
4077 noreply: bool,
4078 data_block: impl AsRef<[u8]>,
4079 ) -> io::Result<bool> {
4080 let size = self.0.len();
4081 self.0[crc32(key.as_ref()) as usize % size]
4082 .cas(
4083 key.as_ref(),
4084 flags,
4085 exptime,
4086 cas_unique,
4087 noreply,
4088 data_block.as_ref(),
4089 )
4090 .await
4091 }
4092
4093 /// # Example
4094 ///
4095 /// ```
4096 /// use mcmc_rs::{ClientCrc32, Connection};
4097 /// # use smol::{io, block_on};
4098 /// #
4099 /// # block_on(async {
4100 /// let mut client = ClientCrc32::new(vec![
4101 /// Connection::default().await?,
4102 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
4103 /// ]);
4104 ///
4105 /// assert!(client.delete(b"key", true).await?);
4106 /// # Ok::<(), io::Error>(())
4107 /// # }).unwrap()
4108 /// ```
4109 pub async fn delete(&mut self, key: impl AsRef<[u8]>, noreply: bool) -> io::Result<bool> {
4110 let size = self.0.len();
4111 self.0[crc32(key.as_ref()) as usize % size]
4112 .delete(key.as_ref(), noreply)
4113 .await
4114 }
4115
4116 /// # Example
4117 ///
4118 /// ```
4119 /// use mcmc_rs::{ClientCrc32, Connection};
4120 /// # use smol::{io, block_on};
4121 /// #
4122 /// # block_on(async {
4123 /// let mut client = ClientCrc32::new(vec![
4124 /// Connection::default().await?,
4125 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
4126 /// ]);
4127 ///
4128 /// assert!(client.incr(b"key", 1, true).await?.is_none());
4129 /// # Ok::<(), io::Error>(())
4130 /// # }).unwrap()
4131 /// ```
4132 pub async fn incr(
4133 &mut self,
4134 key: impl AsRef<[u8]>,
4135 value: u64,
4136 noreply: bool,
4137 ) -> io::Result<Option<u64>> {
4138 let size = self.0.len();
4139 self.0[crc32(key.as_ref()) as usize % size]
4140 .incr(key.as_ref(), value, noreply)
4141 .await
4142 }
4143
4144 /// # Example
4145 ///
4146 /// ```
4147 /// use mcmc_rs::{ClientCrc32, Connection};
4148 /// # use smol::{io, block_on};
4149 /// #
4150 /// # block_on(async {
4151 /// let mut client = ClientCrc32::new(vec![
4152 /// Connection::default().await?,
4153 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
4154 /// ]);
4155 ///
4156 /// assert!(client.decr(b"key", 1, true).await?.is_none());
4157 /// # Ok::<(), io::Error>(())
4158 /// # }).unwrap()
4159 /// ```
4160 pub async fn decr(
4161 &mut self,
4162 key: impl AsRef<[u8]>,
4163 value: u64,
4164 noreply: bool,
4165 ) -> io::Result<Option<u64>> {
4166 let size = self.0.len();
4167 self.0[crc32(key.as_ref()) as usize % size]
4168 .decr(key.as_ref(), value, noreply)
4169 .await
4170 }
4171
4172 /// # Example
4173 ///
4174 /// ```
4175 /// use mcmc_rs::{ClientCrc32, Connection};
4176 /// # use smol::{io, block_on};
4177 /// #
4178 /// # block_on(async {
4179 /// let mut client = ClientCrc32::new(vec![
4180 /// Connection::default().await?,
4181 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
4182 /// ]);
4183 ///
4184 /// assert!(client.touch(b"key", -1, true).await?);
4185 /// # Ok::<(), io::Error>(())
4186 /// # }).unwrap()
4187 /// ```
4188 pub async fn touch(
4189 &mut self,
4190 key: impl AsRef<[u8]>,
4191 exptime: i64,
4192 noreply: bool,
4193 ) -> io::Result<bool> {
4194 let size = self.0.len();
4195 self.0[crc32(key.as_ref()) as usize % size]
4196 .touch(key.as_ref(), exptime, noreply)
4197 .await
4198 }
4199
4200 /// # Example
4201 ///
4202 /// ```
4203 /// use mcmc_rs::{ClientCrc32, Connection};
4204 /// # use smol::{io, block_on};
4205 /// #
4206 /// # block_on(async {
4207 /// let mut client = ClientCrc32::new(vec![
4208 /// Connection::default().await?,
4209 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
4210 /// ]);
4211 /// assert!(client.set(b"k11", 0, 0, false, b"v11").await?);
4212 /// assert!(client.me(b"k11").await?.is_some());
4213 /// # Ok::<(), io::Error>(())
4214 /// # }).unwrap()
4215 /// ```
4216 pub async fn me(&mut self, key: impl AsRef<[u8]>) -> io::Result<Option<String>> {
4217 let size = self.0.len();
4218 self.0[crc32(key.as_ref()) as usize % size]
4219 .me(key.as_ref())
4220 .await
4221 }
4222
4223 /// # Example
4224 ///
4225 /// ```
4226 /// use mcmc_rs::{ClientCrc32, Connection, MgFlag, MgItem};
4227 /// # use smol::{io, block_on};
4228 /// #
4229 /// # block_on(async {
4230 /// let mut client = ClientCrc32::new(vec![
4231 /// Connection::default().await?,
4232 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
4233 /// ]);
4234 /// let result = client
4235 /// .mg(
4236 /// b"44OG44K544OI",
4237 /// &[
4238 /// MgFlag::Base64Key,
4239 /// MgFlag::ReturnCas,
4240 /// MgFlag::ReturnFlags,
4241 /// MgFlag::ReturnHit,
4242 /// MgFlag::ReturnKey,
4243 /// MgFlag::ReturnLastAccess,
4244 /// MgFlag::Opaque("opaque".to_string()),
4245 /// MgFlag::ReturnSize,
4246 /// MgFlag::ReturnTtl,
4247 /// MgFlag::UnBump,
4248 /// MgFlag::ReturnValue,
4249 /// MgFlag::NewCas(0),
4250 /// MgFlag::Autovivify(-1),
4251 /// MgFlag::RecacheTtl(-1),
4252 /// MgFlag::UpdateTtl(-1),
4253 /// ],
4254 /// )
4255 /// .await?;
4256 /// assert_eq!(
4257 /// result,
4258 /// MgItem {
4259 /// success: true,
4260 /// base64_key: false,
4261 /// cas: Some(0),
4262 /// flags: Some(0),
4263 /// hit: Some(0),
4264 /// key: Some("テスト".to_string()),
4265 /// last_access_ttl: Some(0),
4266 /// opaque: Some("opaque".to_string()),
4267 /// size: Some(0),
4268 /// ttl: Some(-1),
4269 /// data_block: Some(vec![]),
4270 /// already_win: false,
4271 /// won_recache: true,
4272 /// stale: false,
4273 /// }
4274 /// );
4275 /// # Ok::<(), io::Error>(())
4276 /// # }).unwrap()
4277 /// ```
4278 pub async fn mg(&mut self, key: impl AsRef<[u8]>, flags: &[MgFlag]) -> io::Result<MgItem> {
4279 let size = self.0.len();
4280 self.0[crc32(key.as_ref()) as usize % size]
4281 .mg(key.as_ref(), flags)
4282 .await
4283 }
4284
4285 /// # Example
4286 ///
4287 /// ```
4288 /// use mcmc_rs::{ClientCrc32, Connection, MsFlag, MsItem, MsMode};
4289 /// # use smol::{io, block_on};
4290 /// #
4291 /// # block_on(async {
4292 /// let mut client = ClientCrc32::new(vec![
4293 /// Connection::default().await?,
4294 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
4295 /// ]);
4296 /// let result = client
4297 /// .ms(
4298 /// b"44OG44K544OI",
4299 /// &[
4300 /// MsFlag::Base64Key,
4301 /// MsFlag::ReturnCas,
4302 /// MsFlag::CompareCas(0),
4303 /// MsFlag::NewCas(0),
4304 /// MsFlag::SetFlags(0),
4305 /// MsFlag::Invalidate,
4306 /// MsFlag::ReturnKey,
4307 /// MsFlag::Opaque("opaque".to_string()),
4308 /// MsFlag::ReturnSize,
4309 /// MsFlag::Ttl(-1),
4310 /// MsFlag::Mode(MsMode::Set),
4311 /// MsFlag::Autovivify(0),
4312 /// ],
4313 /// b"hi",
4314 /// )
4315 /// .await?;
4316 /// assert_eq!(
4317 /// result,
4318 /// MsItem {
4319 /// success: false,
4320 /// cas: Some(0),
4321 /// key: Some("44OG44K544OI".to_string()),
4322 /// opaque: Some("opaque".to_string()),
4323 /// size: Some(2),
4324 /// base64_key: true
4325 /// }
4326 /// );
4327 /// # Ok::<(), io::Error>(())
4328 /// # }).unwrap()
4329 /// ```
4330 pub async fn ms(
4331 &mut self,
4332 key: impl AsRef<[u8]>,
4333 flags: &[MsFlag],
4334 data_block: impl AsRef<[u8]>,
4335 ) -> io::Result<MsItem> {
4336 let size = self.0.len();
4337 self.0[crc32(key.as_ref()) as usize % size]
4338 .ms(key.as_ref(), flags, data_block.as_ref())
4339 .await
4340 }
4341
4342 /// # Example
4343 ///
4344 /// ```
4345 /// use mcmc_rs::{ClientCrc32, Connection, MdFlag, MdItem};
4346 /// # use smol::{io, block_on};
4347 /// #
4348 /// # block_on(async {
4349 /// let mut client = ClientCrc32::new(vec![
4350 /// Connection::default().await?,
4351 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
4352 /// ]);
4353 /// let result = client
4354 /// .md(
4355 /// b"44OG44K544OI",
4356 /// &[
4357 /// MdFlag::Base64Key,
4358 /// MdFlag::CompareCas(0),
4359 /// MdFlag::NewCas(0),
4360 /// MdFlag::Invalidate,
4361 /// MdFlag::ReturnKey,
4362 /// MdFlag::Opaque("opaque".to_string()),
4363 /// MdFlag::UpdateTtl(-1),
4364 /// MdFlag::LeaveKey,
4365 /// ],
4366 /// )
4367 /// .await?;
4368 /// assert_eq!(
4369 /// result,
4370 /// MdItem {
4371 /// success: false,
4372 /// key: Some("44OG44K544OI".to_string()),
4373 /// opaque: Some("opaque".to_string()),
4374 /// base64_key: true
4375 /// }
4376 /// );
4377 /// # Ok::<(), io::Error>(())
4378 /// # }).unwrap()
4379 /// ```
4380 pub async fn md(&mut self, key: impl AsRef<[u8]>, flags: &[MdFlag]) -> io::Result<MdItem> {
4381 let size = self.0.len();
4382 self.0[crc32(key.as_ref()) as usize % size]
4383 .md(key.as_ref(), flags)
4384 .await
4385 }
4386
4387 /// # Example
4388 ///
4389 /// ```
4390 /// use mcmc_rs::{ClientCrc32, Connection, MaFlag, MaItem, MaMode};
4391 /// # use smol::{io, block_on};
4392 /// #
4393 /// # block_on(async {
4394 /// let mut client = ClientCrc32::new(vec![
4395 /// Connection::default().await?,
4396 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
4397 /// ]);
4398 /// let result = client
4399 /// .ma(
4400 /// b"aGk=",
4401 /// &[
4402 /// MaFlag::Base64Key,
4403 /// MaFlag::CompareCas(0),
4404 /// MaFlag::NewCas(0),
4405 /// MaFlag::AutoCreate(0),
4406 /// MaFlag::InitValue(0),
4407 /// MaFlag::DeltaApply(0),
4408 /// MaFlag::UpdateTtl(0),
4409 /// MaFlag::Mode(MaMode::Incr),
4410 /// MaFlag::Opaque("opaque".to_string()),
4411 /// MaFlag::ReturnTtl,
4412 /// MaFlag::ReturnCas,
4413 /// MaFlag::ReturnValue,
4414 /// MaFlag::ReturnKey,
4415 /// ],
4416 /// )
4417 /// .await?;
4418 /// assert_eq!(
4419 /// result,
4420 /// MaItem {
4421 /// success: true,
4422 /// opaque: Some("opaque".to_string()),
4423 /// ttl: Some(-1),
4424 /// cas: Some(0),
4425 /// number: Some(0),
4426 /// key: Some("aGk=".to_string()),
4427 /// base64_key: true
4428 /// }
4429 /// );
4430 /// # Ok::<(), io::Error>(())
4431 /// # }).unwrap()
4432 /// ```
4433 pub async fn ma(&mut self, key: impl AsRef<[u8]>, flags: &[MaFlag]) -> io::Result<MaItem> {
4434 let size = self.0.len();
4435 self.0[crc32(key.as_ref()) as usize % size]
4436 .ma(key.as_ref(), flags)
4437 .await
4438 }
4439}
4440
4441pub struct ClientHashRing(Vec<Connection>, HashRing<usize>);
4442impl ClientHashRing {
4443 /// # Example
4444 ///
4445 /// ```
4446 /// use mcmc_rs::{ClientHashRing, Connection};
4447 /// # use smol::{io, block_on};
4448 /// #
4449 /// # block_on(async {
4450 /// let mut client = ClientHashRing::new(vec![
4451 /// Connection::default().await?,
4452 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
4453 /// ]);
4454 /// # Ok::<(), io::Error>(())
4455 /// # }).unwrap()
4456 pub fn new(conns: Vec<Connection>) -> Self {
4457 let mut ring = HashRing::new();
4458 ring.batch_add((0..conns.len()).collect());
4459 Self(conns, ring)
4460 }
4461
4462 /// # Example
4463 ///
4464 /// ```
4465 /// use mcmc_rs::{ClientHashRing, Connection};
4466 /// # use smol::{io, block_on};
4467 /// #
4468 /// # block_on(async {
4469 /// let mut client = ClientHashRing::new(vec![
4470 /// Connection::default().await?,
4471 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
4472 /// ]);
4473 ///
4474 /// assert!(client.set(b"k7", 0, 0, false, b"v7").await?);
4475 /// assert_eq!(client.get(b"k7").await?.unwrap().key, "k7");
4476 /// # Ok::<(), io::Error>(())
4477 /// # }).unwrap()
4478 /// ```
4479 pub async fn get(&mut self, key: impl AsRef<[u8]>) -> io::Result<Option<Item>> {
4480 let i = *self.1.get(&key.as_ref()).unwrap();
4481 self.0[i].get(key.as_ref()).await
4482 }
4483
4484 /// # Example
4485 ///
4486 /// ```
4487 /// use mcmc_rs::{ClientHashRing, Connection};
4488 /// # use smol::{io, block_on};
4489 /// #
4490 /// # block_on(async {
4491 /// let mut client = ClientHashRing::new(vec![
4492 /// Connection::default().await?,
4493 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
4494 /// ]);
4495 ///
4496 /// assert!(client.set(b"k8", 0, 0, false, b"v8").await?);
4497 /// assert_eq!(client.gets(b"k8").await?.unwrap().key, "k8");
4498 /// # Ok::<(), io::Error>(())
4499 /// # }).unwrap()
4500 /// ```
4501 pub async fn gets(&mut self, key: impl AsRef<[u8]>) -> io::Result<Option<Item>> {
4502 let i = *self.1.get(&key.as_ref()).unwrap();
4503 self.0[i].gets(key.as_ref()).await
4504 }
4505
4506 /// # Example
4507 ///
4508 /// ```
4509 /// # use mcmc_rs::{Connection, ClientHashRing};
4510 /// # use smol::{io, block_on};
4511 /// #
4512 /// # block_on(async {
4513 /// let mut client = ClientHashRing::new(vec![
4514 /// Connection::default().await?,
4515 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
4516 /// ]);
4517 /// assert!(client.set(b"k9", 0, 0, false, b"v9").await?);
4518 /// let result = client.gat(0, b"k9").await?;
4519 /// assert_eq!(result.unwrap().key, "k9");
4520 /// # Ok::<(), io::Error>(())
4521 /// # }).unwrap()
4522 /// ```
4523 pub async fn gat(&mut self, exptime: i64, key: impl AsRef<[u8]>) -> io::Result<Option<Item>> {
4524 let i = *self.1.get(&key.as_ref()).unwrap();
4525 self.0[i].gat(exptime, key.as_ref()).await
4526 }
4527
4528 /// # Example
4529 ///
4530 /// ```
4531 /// # use mcmc_rs::{Connection, ClientHashRing};
4532 /// # use smol::{io, block_on};
4533 /// #
4534 /// # block_on(async {
4535 /// let mut client = ClientHashRing::new(vec![
4536 /// Connection::default().await?,
4537 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
4538 /// ]);
4539 /// assert!(client.set(b"k10", 0, 0, false, b"v10").await?);
4540 /// let result = client.gats(0, b"k10").await?;
4541 /// assert_eq!(result.unwrap().key, "k10");
4542 /// # Ok::<(), io::Error>(())
4543 /// # }).unwrap()
4544 /// ```
4545 pub async fn gats(&mut self, exptime: i64, key: impl AsRef<[u8]>) -> io::Result<Option<Item>> {
4546 let i = *self.1.get(&key.as_ref()).unwrap();
4547 self.0[i].gats(exptime, key.as_ref()).await
4548 }
4549
4550 /// # Example
4551 ///
4552 /// ```
4553 /// use mcmc_rs::{ClientHashRing, Connection};
4554 /// # use smol::{io, block_on};
4555 /// #
4556 /// # block_on(async {
4557 /// let mut client = ClientHashRing::new(vec![
4558 /// Connection::default().await?,
4559 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
4560 /// ]);
4561 ///
4562 /// assert!(client.set(b"key", 0, -1, true, b"value").await?);
4563 /// # Ok::<(), io::Error>(())
4564 /// # }).unwrap()
4565 /// ```
4566 pub async fn set(
4567 &mut self,
4568 key: impl AsRef<[u8]>,
4569 flags: u32,
4570 exptime: i64,
4571 noreply: bool,
4572 data_block: impl AsRef<[u8]>,
4573 ) -> io::Result<bool> {
4574 let i = *self.1.get(&key.as_ref()).unwrap();
4575 self.0[i]
4576 .set(key.as_ref(), flags, exptime, noreply, data_block.as_ref())
4577 .await
4578 }
4579
4580 /// # Example
4581 ///
4582 /// ```
4583 /// use mcmc_rs::{ClientHashRing, Connection};
4584 /// # use smol::{io, block_on};
4585 /// #
4586 /// # block_on(async {
4587 /// let mut client = ClientHashRing::new(vec![
4588 /// Connection::default().await?,
4589 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
4590 /// ]);
4591 ///
4592 /// assert!(client.add(b"key", 0, -1, true, b"value").await?);
4593 /// # Ok::<(), io::Error>(())
4594 /// # }).unwrap()
4595 /// ```
4596 pub async fn add(
4597 &mut self,
4598 key: impl AsRef<[u8]>,
4599 flags: u32,
4600 exptime: i64,
4601 noreply: bool,
4602 data_block: impl AsRef<[u8]>,
4603 ) -> io::Result<bool> {
4604 let i = *self.1.get(&key.as_ref()).unwrap();
4605 self.0[i]
4606 .add(key.as_ref(), flags, exptime, noreply, data_block.as_ref())
4607 .await
4608 }
4609
4610 /// # Example
4611 ///
4612 /// ```
4613 /// use mcmc_rs::{ClientHashRing, Connection};
4614 /// # use smol::{io, block_on};
4615 /// #
4616 /// # block_on(async {
4617 /// let mut client = ClientHashRing::new(vec![
4618 /// Connection::default().await?,
4619 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
4620 /// ]);
4621 ///
4622 /// assert!(client.replace(b"key", 0, -1, true, b"value").await?);
4623 /// # Ok::<(), io::Error>(())
4624 /// # }).unwrap()
4625 /// ```
4626 pub async fn replace(
4627 &mut self,
4628 key: impl AsRef<[u8]>,
4629 flags: u32,
4630 exptime: i64,
4631 noreply: bool,
4632 data_block: impl AsRef<[u8]>,
4633 ) -> io::Result<bool> {
4634 let i = *self.1.get(&key.as_ref()).unwrap();
4635 self.0[i]
4636 .replace(key.as_ref(), flags, exptime, noreply, data_block.as_ref())
4637 .await
4638 }
4639
4640 /// # Example
4641 ///
4642 /// ```
4643 /// use mcmc_rs::{ClientHashRing, Connection};
4644 /// # use smol::{io, block_on};
4645 /// #
4646 /// # block_on(async {
4647 /// let mut client = ClientHashRing::new(vec![
4648 /// Connection::default().await?,
4649 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
4650 /// ]);
4651 ///
4652 /// assert!(client.append(b"key", 0, -1, true, b"value").await?);
4653 /// # Ok::<(), io::Error>(())
4654 /// # }).unwrap()
4655 /// ```
4656 pub async fn append(
4657 &mut self,
4658 key: impl AsRef<[u8]>,
4659 flags: u32,
4660 exptime: i64,
4661 noreply: bool,
4662 data_block: impl AsRef<[u8]>,
4663 ) -> io::Result<bool> {
4664 let i = *self.1.get(&key.as_ref()).unwrap();
4665 self.0[i]
4666 .append(key.as_ref(), flags, exptime, noreply, data_block.as_ref())
4667 .await
4668 }
4669
4670 /// # Example
4671 ///
4672 /// ```
4673 /// use mcmc_rs::{ClientHashRing, Connection};
4674 /// # use smol::{io, block_on};
4675 /// #
4676 /// # block_on(async {
4677 /// let mut client = ClientHashRing::new(vec![
4678 /// Connection::default().await?,
4679 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
4680 /// ]);
4681 ///
4682 /// assert!(client.prepend(b"key", 0, -1, true, b"value").await?);
4683 /// # Ok::<(), io::Error>(())
4684 /// # }).unwrap()
4685 /// ```
4686 pub async fn prepend(
4687 &mut self,
4688 key: impl AsRef<[u8]>,
4689 flags: u32,
4690 exptime: i64,
4691 noreply: bool,
4692 data_block: impl AsRef<[u8]>,
4693 ) -> io::Result<bool> {
4694 let i = *self.1.get(&key.as_ref()).unwrap();
4695 self.0[i]
4696 .prepend(key.as_ref(), flags, exptime, noreply, data_block.as_ref())
4697 .await
4698 }
4699
4700 /// # Example
4701 ///
4702 /// ```
4703 /// use mcmc_rs::{ClientHashRing, Connection};
4704 /// # use smol::{io, block_on};
4705 /// #
4706 /// # block_on(async {
4707 /// let mut client = ClientHashRing::new(vec![
4708 /// Connection::default().await?,
4709 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
4710 /// ]);
4711 ///
4712 /// assert!(client.cas(b"key", 0, -1, 0, true, b"value").await?);
4713 /// # Ok::<(), io::Error>(())
4714 /// # }).unwrap()
4715 /// ```
4716 pub async fn cas(
4717 &mut self,
4718 key: impl AsRef<[u8]>,
4719 flags: u32,
4720 exptime: i64,
4721 cas_unique: u64,
4722 noreply: bool,
4723 data_block: impl AsRef<[u8]>,
4724 ) -> io::Result<bool> {
4725 let i = *self.1.get(&key.as_ref()).unwrap();
4726 self.0[i]
4727 .cas(
4728 key.as_ref(),
4729 flags,
4730 exptime,
4731 cas_unique,
4732 noreply,
4733 data_block.as_ref(),
4734 )
4735 .await
4736 }
4737
4738 /// # Example
4739 ///
4740 /// ```
4741 /// use mcmc_rs::{ClientHashRing, Connection};
4742 /// # use smol::{io, block_on};
4743 /// #
4744 /// # block_on(async {
4745 /// let mut client = ClientHashRing::new(vec![
4746 /// Connection::default().await?,
4747 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
4748 /// ]);
4749 ///
4750 /// assert!(client.delete(b"key", true).await?);
4751 /// # Ok::<(), io::Error>(())
4752 /// # }).unwrap()
4753 /// ```
4754 pub async fn delete(&mut self, key: impl AsRef<[u8]>, noreply: bool) -> io::Result<bool> {
4755 let i = *self.1.get(&key.as_ref()).unwrap();
4756 self.0[i].delete(key.as_ref(), noreply).await
4757 }
4758
4759 /// # Example
4760 ///
4761 /// ```
4762 /// use mcmc_rs::{ClientHashRing, Connection};
4763 /// # use smol::{io, block_on};
4764 /// #
4765 /// # block_on(async {
4766 /// let mut client = ClientHashRing::new(vec![
4767 /// Connection::default().await?,
4768 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
4769 /// ]);
4770 ///
4771 /// assert!(client.incr(b"key", 1, true).await?.is_none());
4772 /// # Ok::<(), io::Error>(())
4773 /// # }).unwrap()
4774 /// ```
4775 pub async fn incr(
4776 &mut self,
4777 key: impl AsRef<[u8]>,
4778 value: u64,
4779 noreply: bool,
4780 ) -> io::Result<Option<u64>> {
4781 let i = *self.1.get(&key.as_ref()).unwrap();
4782 self.0[i].incr(key.as_ref(), value, noreply).await
4783 }
4784
4785 /// # Example
4786 ///
4787 /// ```
4788 /// use mcmc_rs::{ClientHashRing, Connection};
4789 /// # use smol::{io, block_on};
4790 /// #
4791 /// # block_on(async {
4792 /// let mut client = ClientHashRing::new(vec![
4793 /// Connection::default().await?,
4794 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
4795 /// ]);
4796 ///
4797 /// assert!(client.decr(b"key", 1, true).await?.is_none());
4798 /// # Ok::<(), io::Error>(())
4799 /// # }).unwrap()
4800 /// ```
4801 pub async fn decr(
4802 &mut self,
4803 key: impl AsRef<[u8]>,
4804 value: u64,
4805 noreply: bool,
4806 ) -> io::Result<Option<u64>> {
4807 let i = *self.1.get(&key.as_ref()).unwrap();
4808 self.0[i].decr(key.as_ref(), value, noreply).await
4809 }
4810
4811 /// # Example
4812 ///
4813 /// ```
4814 /// use mcmc_rs::{ClientHashRing, Connection};
4815 /// # use smol::{io, block_on};
4816 /// #
4817 /// # block_on(async {
4818 /// let mut client = ClientHashRing::new(vec![
4819 /// Connection::default().await?,
4820 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
4821 /// ]);
4822 ///
4823 /// assert!(client.touch(b"key", -1, true).await?);
4824 /// # Ok::<(), io::Error>(())
4825 /// # }).unwrap()
4826 /// ```
4827 pub async fn touch(
4828 &mut self,
4829 key: impl AsRef<[u8]>,
4830 exptime: i64,
4831 noreply: bool,
4832 ) -> io::Result<bool> {
4833 let i = *self.1.get(&key.as_ref()).unwrap();
4834 self.0[i].touch(key.as_ref(), exptime, noreply).await
4835 }
4836
4837 /// # Example
4838 ///
4839 /// ```
4840 /// use mcmc_rs::{ClientHashRing, Connection};
4841 /// # use smol::{io, block_on};
4842 /// #
4843 /// # block_on(async {
4844 /// let mut client = ClientHashRing::new(vec![
4845 /// Connection::default().await?,
4846 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
4847 /// ]);
4848 /// assert!(client.set(b"k11", 0, 0, false, b"v11").await?);
4849 /// assert!(client.me(b"k11").await?.is_some());
4850 /// # Ok::<(), io::Error>(())
4851 /// # }).unwrap()
4852 /// ```
4853 pub async fn me(&mut self, key: impl AsRef<[u8]>) -> io::Result<Option<String>> {
4854 let i = *self.1.get(&key.as_ref()).unwrap();
4855 self.0[i].me(key.as_ref()).await
4856 }
4857
4858 /// # Example
4859 ///
4860 /// ```
4861 /// use mcmc_rs::{ClientHashRing, Connection, MgFlag, MgItem};
4862 /// # use smol::{io, block_on};
4863 /// #
4864 /// # block_on(async {
4865 /// let mut client = ClientHashRing::new(vec![
4866 /// Connection::default().await?,
4867 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
4868 /// ]);
4869 /// let result = client
4870 /// .mg(
4871 /// b"44OG44K544OI",
4872 /// &[
4873 /// MgFlag::Base64Key,
4874 /// MgFlag::ReturnCas,
4875 /// MgFlag::ReturnFlags,
4876 /// MgFlag::ReturnHit,
4877 /// MgFlag::ReturnKey,
4878 /// MgFlag::ReturnLastAccess,
4879 /// MgFlag::Opaque("opaque".to_string()),
4880 /// MgFlag::ReturnSize,
4881 /// MgFlag::ReturnTtl,
4882 /// MgFlag::UnBump,
4883 /// MgFlag::ReturnValue,
4884 /// MgFlag::NewCas(0),
4885 /// MgFlag::Autovivify(-1),
4886 /// MgFlag::RecacheTtl(-1),
4887 /// MgFlag::UpdateTtl(-1),
4888 /// ],
4889 /// )
4890 /// .await?;
4891 /// assert_eq!(
4892 /// result,
4893 /// MgItem {
4894 /// success: true,
4895 /// base64_key: false,
4896 /// cas: Some(0),
4897 /// flags: Some(0),
4898 /// hit: Some(0),
4899 /// key: Some("テスト".to_string()),
4900 /// last_access_ttl: Some(0),
4901 /// opaque: Some("opaque".to_string()),
4902 /// size: Some(0),
4903 /// ttl: Some(-1),
4904 /// data_block: Some(vec![]),
4905 /// already_win: false,
4906 /// won_recache: true,
4907 /// stale: false,
4908 /// }
4909 /// );
4910 /// # Ok::<(), io::Error>(())
4911 /// # }).unwrap()
4912 /// ```
4913 pub async fn mg(&mut self, key: impl AsRef<[u8]>, flags: &[MgFlag]) -> io::Result<MgItem> {
4914 let i = *self.1.get(&key.as_ref()).unwrap();
4915 self.0[i].mg(key.as_ref(), flags).await
4916 }
4917
4918 /// # Example
4919 ///
4920 /// ```
4921 /// use mcmc_rs::{ClientHashRing, Connection, MsFlag, MsItem, MsMode};
4922 /// # use smol::{io, block_on};
4923 /// #
4924 /// # block_on(async {
4925 /// let mut client = ClientHashRing::new(vec![
4926 /// Connection::default().await?,
4927 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
4928 /// ]);
4929 /// let result = client
4930 /// .ms(
4931 /// b"44OG44K544OI",
4932 /// &[
4933 /// MsFlag::Base64Key,
4934 /// MsFlag::ReturnCas,
4935 /// MsFlag::CompareCas(0),
4936 /// MsFlag::NewCas(0),
4937 /// MsFlag::SetFlags(0),
4938 /// MsFlag::Invalidate,
4939 /// MsFlag::ReturnKey,
4940 /// MsFlag::Opaque("opaque".to_string()),
4941 /// MsFlag::ReturnSize,
4942 /// MsFlag::Ttl(-1),
4943 /// MsFlag::Mode(MsMode::Set),
4944 /// MsFlag::Autovivify(0),
4945 /// ],
4946 /// b"hi",
4947 /// )
4948 /// .await?;
4949 /// assert_eq!(
4950 /// result,
4951 /// MsItem {
4952 /// success: false,
4953 /// cas: Some(0),
4954 /// key: Some("44OG44K544OI".to_string()),
4955 /// opaque: Some("opaque".to_string()),
4956 /// size: Some(2),
4957 /// base64_key: true
4958 /// }
4959 /// );
4960 /// # Ok::<(), io::Error>(())
4961 /// # }).unwrap()
4962 /// ```
4963 pub async fn ms(
4964 &mut self,
4965 key: impl AsRef<[u8]>,
4966 flags: &[MsFlag],
4967 data_block: impl AsRef<[u8]>,
4968 ) -> io::Result<MsItem> {
4969 let i = *self.1.get(&key.as_ref()).unwrap();
4970 self.0[i].ms(key.as_ref(), flags, data_block.as_ref()).await
4971 }
4972
4973 /// # Example
4974 ///
4975 /// ```
4976 /// use mcmc_rs::{ClientHashRing, Connection, MdFlag, MdItem};
4977 /// # use smol::{io, block_on};
4978 /// #
4979 /// # block_on(async {
4980 /// let mut client = ClientHashRing::new(vec![
4981 /// Connection::default().await?,
4982 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
4983 /// ]);
4984 /// let result = client
4985 /// .md(
4986 /// b"44OG44K544OI",
4987 /// &[
4988 /// MdFlag::Base64Key,
4989 /// MdFlag::CompareCas(0),
4990 /// MdFlag::NewCas(0),
4991 /// MdFlag::Invalidate,
4992 /// MdFlag::ReturnKey,
4993 /// MdFlag::Opaque("opaque".to_string()),
4994 /// MdFlag::UpdateTtl(-1),
4995 /// MdFlag::LeaveKey,
4996 /// ],
4997 /// )
4998 /// .await?;
4999 /// assert_eq!(
5000 /// result,
5001 /// MdItem {
5002 /// success: false,
5003 /// key: Some("44OG44K544OI".to_string()),
5004 /// opaque: Some("opaque".to_string()),
5005 /// base64_key: true
5006 /// }
5007 /// );
5008 /// # Ok::<(), io::Error>(())
5009 /// # }).unwrap()
5010 /// ```
5011 pub async fn md(&mut self, key: impl AsRef<[u8]>, flags: &[MdFlag]) -> io::Result<MdItem> {
5012 let i = *self.1.get(&key.as_ref()).unwrap();
5013 self.0[i].md(key.as_ref(), flags).await
5014 }
5015
5016 /// # Example
5017 ///
5018 /// ```
5019 /// use mcmc_rs::{ClientHashRing, Connection, MaFlag, MaItem, MaMode};
5020 /// # use smol::{io, block_on};
5021 /// #
5022 /// # block_on(async {
5023 /// let mut client = ClientHashRing::new(vec![
5024 /// Connection::default().await?,
5025 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
5026 /// ]);
5027 /// let result = client
5028 /// .ma(
5029 /// b"aGk=",
5030 /// &[
5031 /// MaFlag::Base64Key,
5032 /// MaFlag::CompareCas(0),
5033 /// MaFlag::NewCas(0),
5034 /// MaFlag::AutoCreate(0),
5035 /// MaFlag::InitValue(0),
5036 /// MaFlag::DeltaApply(0),
5037 /// MaFlag::UpdateTtl(0),
5038 /// MaFlag::Mode(MaMode::Incr),
5039 /// MaFlag::Opaque("opaque".to_string()),
5040 /// MaFlag::ReturnTtl,
5041 /// MaFlag::ReturnCas,
5042 /// MaFlag::ReturnValue,
5043 /// MaFlag::ReturnKey,
5044 /// ],
5045 /// )
5046 /// .await?;
5047 /// assert_eq!(
5048 /// result,
5049 /// MaItem {
5050 /// success: true,
5051 /// opaque: Some("opaque".to_string()),
5052 /// ttl: Some(-1),
5053 /// cas: Some(0),
5054 /// number: Some(0),
5055 /// key: Some("aGk=".to_string()),
5056 /// base64_key: true
5057 /// }
5058 /// );
5059 /// # Ok::<(), io::Error>(())
5060 /// # }).unwrap()
5061 /// ```
5062 pub async fn ma(&mut self, key: impl AsRef<[u8]>, flags: &[MaFlag]) -> io::Result<MaItem> {
5063 let i = *self.1.get(&key.as_ref()).unwrap();
5064 self.0[i].ma(key.as_ref(), flags).await
5065 }
5066}
5067
5068pub struct ClientRendezvous(Vec<Connection>, HrwNodes<usize>);
5069impl ClientRendezvous {
5070 /// # Example
5071 ///
5072 /// ```
5073 /// use mcmc_rs::{ClientRendezvous, Connection};
5074 /// # use smol::{io, block_on};
5075 /// #
5076 /// # block_on(async {
5077 /// let mut client = ClientRendezvous::new(vec![
5078 /// Connection::default().await?,
5079 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
5080 /// ]);
5081 /// # Ok::<(), io::Error>(())
5082 /// # }).unwrap()
5083 pub fn new(conns: Vec<Connection>) -> Self {
5084 let hrw = HrwNodes::new(0..conns.len());
5085 Self(conns, hrw)
5086 }
5087
5088 /// # Example
5089 ///
5090 /// ```
5091 /// use mcmc_rs::{ClientRendezvous, Connection};
5092 /// # use smol::{io, block_on};
5093 /// #
5094 /// # block_on(async {
5095 /// let mut client = ClientRendezvous::new(vec![
5096 /// Connection::default().await?,
5097 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
5098 /// ]);
5099 ///
5100 /// assert!(client.set(b"k7", 0, 0, false, b"v7").await?);
5101 /// assert_eq!(client.get(b"k7").await?.unwrap().key, "k7");
5102 /// # Ok::<(), io::Error>(())
5103 /// # }).unwrap()
5104 /// ```
5105 pub async fn get(&mut self, key: impl AsRef<[u8]>) -> io::Result<Option<Item>> {
5106 let i = *self.1.sorted(&key.as_ref()).next().unwrap();
5107 self.0[i].get(key.as_ref()).await
5108 }
5109
5110 /// # Example
5111 ///
5112 /// ```
5113 /// use mcmc_rs::{ClientRendezvous, Connection};
5114 /// # use smol::{io, block_on};
5115 /// #
5116 /// # block_on(async {
5117 /// let mut client = ClientRendezvous::new(vec![
5118 /// Connection::default().await?,
5119 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
5120 /// ]);
5121 ///
5122 /// assert!(client.set(b"k8", 0, 0, false, b"v8").await?);
5123 /// assert_eq!(client.gets(b"k8").await?.unwrap().key, "k8");
5124 /// # Ok::<(), io::Error>(())
5125 /// # }).unwrap()
5126 /// ```
5127 pub async fn gets(&mut self, key: impl AsRef<[u8]>) -> io::Result<Option<Item>> {
5128 let i = *self.1.sorted(&key.as_ref()).next().unwrap();
5129 self.0[i].gets(key.as_ref()).await
5130 }
5131
5132 /// # Example
5133 ///
5134 /// ```
5135 /// # use mcmc_rs::{Connection, ClientRendezvous};
5136 /// # use smol::{io, block_on};
5137 /// #
5138 /// # block_on(async {
5139 /// let mut client = ClientRendezvous::new(vec![
5140 /// Connection::default().await?,
5141 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
5142 /// ]);
5143 /// assert!(client.set(b"k9", 0, 0, false, b"v9").await?);
5144 /// let result = client.gat(0, b"k9").await?;
5145 /// assert_eq!(result.unwrap().key, "k9");
5146 /// # Ok::<(), io::Error>(())
5147 /// # }).unwrap()
5148 /// ```
5149 pub async fn gat(&mut self, exptime: i64, key: impl AsRef<[u8]>) -> io::Result<Option<Item>> {
5150 let i = *self.1.sorted(&key.as_ref()).next().unwrap();
5151 self.0[i].gat(exptime, key.as_ref()).await
5152 }
5153
5154 /// # Example
5155 ///
5156 /// ```
5157 /// # use mcmc_rs::{Connection, ClientRendezvous};
5158 /// # use smol::{io, block_on};
5159 /// #
5160 /// # block_on(async {
5161 /// let mut client = ClientRendezvous::new(vec![
5162 /// Connection::default().await?,
5163 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
5164 /// ]);
5165 /// assert!(client.set(b"k10", 0, 0, false, b"v10").await?);
5166 /// let result = client.gats(0, b"k10").await?;
5167 /// assert_eq!(result.unwrap().key, "k10");
5168 /// # Ok::<(), io::Error>(())
5169 /// # }).unwrap()
5170 /// ```
5171 pub async fn gats(&mut self, exptime: i64, key: impl AsRef<[u8]>) -> io::Result<Option<Item>> {
5172 let i = *self.1.sorted(&key.as_ref()).next().unwrap();
5173 self.0[i].gats(exptime, key.as_ref()).await
5174 }
5175
5176 /// # Example
5177 ///
5178 /// ```
5179 /// use mcmc_rs::{ClientRendezvous, Connection};
5180 /// # use smol::{io, block_on};
5181 /// #
5182 /// # block_on(async {
5183 /// let mut client = ClientRendezvous::new(vec![
5184 /// Connection::default().await?,
5185 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
5186 /// ]);
5187 ///
5188 /// assert!(client.set(b"key", 0, -1, true, b"value").await?);
5189 /// # Ok::<(), io::Error>(())
5190 /// # }).unwrap()
5191 /// ```
5192 pub async fn set(
5193 &mut self,
5194 key: impl AsRef<[u8]>,
5195 flags: u32,
5196 exptime: i64,
5197 noreply: bool,
5198 data_block: impl AsRef<[u8]>,
5199 ) -> io::Result<bool> {
5200 let i = *self.1.sorted(&key.as_ref()).next().unwrap();
5201 self.0[i]
5202 .set(key.as_ref(), flags, exptime, noreply, data_block.as_ref())
5203 .await
5204 }
5205
5206 /// # Example
5207 ///
5208 /// ```
5209 /// use mcmc_rs::{ClientRendezvous, Connection};
5210 /// # use smol::{io, block_on};
5211 /// #
5212 /// # block_on(async {
5213 /// let mut client = ClientRendezvous::new(vec![
5214 /// Connection::default().await?,
5215 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
5216 /// ]);
5217 ///
5218 /// assert!(client.add(b"key", 0, -1, true, b"value").await?);
5219 /// # Ok::<(), io::Error>(())
5220 /// # }).unwrap()
5221 /// ```
5222 pub async fn add(
5223 &mut self,
5224 key: impl AsRef<[u8]>,
5225 flags: u32,
5226 exptime: i64,
5227 noreply: bool,
5228 data_block: impl AsRef<[u8]>,
5229 ) -> io::Result<bool> {
5230 let i = *self.1.sorted(&key.as_ref()).next().unwrap();
5231 self.0[i]
5232 .add(key.as_ref(), flags, exptime, noreply, data_block.as_ref())
5233 .await
5234 }
5235
5236 /// # Example
5237 ///
5238 /// ```
5239 /// use mcmc_rs::{ClientRendezvous, Connection};
5240 /// # use smol::{io, block_on};
5241 /// #
5242 /// # block_on(async {
5243 /// let mut client = ClientRendezvous::new(vec![
5244 /// Connection::default().await?,
5245 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
5246 /// ]);
5247 ///
5248 /// assert!(client.replace(b"key", 0, -1, true, b"value").await?);
5249 /// # Ok::<(), io::Error>(())
5250 /// # }).unwrap()
5251 /// ```
5252 pub async fn replace(
5253 &mut self,
5254 key: impl AsRef<[u8]>,
5255 flags: u32,
5256 exptime: i64,
5257 noreply: bool,
5258 data_block: impl AsRef<[u8]>,
5259 ) -> io::Result<bool> {
5260 let i = *self.1.sorted(&key.as_ref()).next().unwrap();
5261 self.0[i]
5262 .replace(key.as_ref(), flags, exptime, noreply, data_block.as_ref())
5263 .await
5264 }
5265
5266 /// # Example
5267 ///
5268 /// ```
5269 /// use mcmc_rs::{ClientRendezvous, Connection};
5270 /// # use smol::{io, block_on};
5271 /// #
5272 /// # block_on(async {
5273 /// let mut client = ClientRendezvous::new(vec![
5274 /// Connection::default().await?,
5275 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
5276 /// ]);
5277 ///
5278 /// assert!(client.append(b"key", 0, -1, true, b"value").await?);
5279 /// # Ok::<(), io::Error>(())
5280 /// # }).unwrap()
5281 /// ```
5282 pub async fn append(
5283 &mut self,
5284 key: impl AsRef<[u8]>,
5285 flags: u32,
5286 exptime: i64,
5287 noreply: bool,
5288 data_block: impl AsRef<[u8]>,
5289 ) -> io::Result<bool> {
5290 let i = *self.1.sorted(&key.as_ref()).next().unwrap();
5291 self.0[i]
5292 .append(key.as_ref(), flags, exptime, noreply, data_block.as_ref())
5293 .await
5294 }
5295
5296 /// # Example
5297 ///
5298 /// ```
5299 /// use mcmc_rs::{ClientRendezvous, Connection};
5300 /// # use smol::{io, block_on};
5301 /// #
5302 /// # block_on(async {
5303 /// let mut client = ClientRendezvous::new(vec![
5304 /// Connection::default().await?,
5305 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
5306 /// ]);
5307 ///
5308 /// assert!(client.prepend(b"key", 0, -1, true, b"value").await?);
5309 /// # Ok::<(), io::Error>(())
5310 /// # }).unwrap()
5311 /// ```
5312 pub async fn prepend(
5313 &mut self,
5314 key: impl AsRef<[u8]>,
5315 flags: u32,
5316 exptime: i64,
5317 noreply: bool,
5318 data_block: impl AsRef<[u8]>,
5319 ) -> io::Result<bool> {
5320 let i = *self.1.sorted(&key.as_ref()).next().unwrap();
5321 self.0[i]
5322 .prepend(key.as_ref(), flags, exptime, noreply, data_block.as_ref())
5323 .await
5324 }
5325
5326 /// # Example
5327 ///
5328 /// ```
5329 /// use mcmc_rs::{ClientRendezvous, Connection};
5330 /// # use smol::{io, block_on};
5331 /// #
5332 /// # block_on(async {
5333 /// let mut client = ClientRendezvous::new(vec![
5334 /// Connection::default().await?,
5335 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
5336 /// ]);
5337 ///
5338 /// assert!(client.cas(b"key", 0, -1, 0, true, b"value").await?);
5339 /// # Ok::<(), io::Error>(())
5340 /// # }).unwrap()
5341 /// ```
5342 pub async fn cas(
5343 &mut self,
5344 key: impl AsRef<[u8]>,
5345 flags: u32,
5346 exptime: i64,
5347 cas_unique: u64,
5348 noreply: bool,
5349 data_block: impl AsRef<[u8]>,
5350 ) -> io::Result<bool> {
5351 let i = *self.1.sorted(&key.as_ref()).next().unwrap();
5352 self.0[i]
5353 .cas(
5354 key.as_ref(),
5355 flags,
5356 exptime,
5357 cas_unique,
5358 noreply,
5359 data_block.as_ref(),
5360 )
5361 .await
5362 }
5363
5364 /// # Example
5365 ///
5366 /// ```
5367 /// use mcmc_rs::{ClientRendezvous, Connection};
5368 /// # use smol::{io, block_on};
5369 /// #
5370 /// # block_on(async {
5371 /// let mut client = ClientRendezvous::new(vec![
5372 /// Connection::default().await?,
5373 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
5374 /// ]);
5375 ///
5376 /// assert!(client.delete(b"key", true).await?);
5377 /// # Ok::<(), io::Error>(())
5378 /// # }).unwrap()
5379 /// ```
5380 pub async fn delete(&mut self, key: impl AsRef<[u8]>, noreply: bool) -> io::Result<bool> {
5381 let i = *self.1.sorted(&key.as_ref()).next().unwrap();
5382 self.0[i].delete(key.as_ref(), noreply).await
5383 }
5384
5385 /// # Example
5386 ///
5387 /// ```
5388 /// use mcmc_rs::{ClientRendezvous, Connection};
5389 /// # use smol::{io, block_on};
5390 /// #
5391 /// # block_on(async {
5392 /// let mut client = ClientRendezvous::new(vec![
5393 /// Connection::default().await?,
5394 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
5395 /// ]);
5396 ///
5397 /// assert!(client.incr(b"key", 1, true).await?.is_none());
5398 /// # Ok::<(), io::Error>(())
5399 /// # }).unwrap()
5400 /// ```
5401 pub async fn incr(
5402 &mut self,
5403 key: impl AsRef<[u8]>,
5404 value: u64,
5405 noreply: bool,
5406 ) -> io::Result<Option<u64>> {
5407 let i = *self.1.sorted(&key.as_ref()).next().unwrap();
5408 self.0[i].incr(key.as_ref(), value, noreply).await
5409 }
5410
5411 /// # Example
5412 ///
5413 /// ```
5414 /// use mcmc_rs::{ClientRendezvous, Connection};
5415 /// # use smol::{io, block_on};
5416 /// #
5417 /// # block_on(async {
5418 /// let mut client = ClientRendezvous::new(vec![
5419 /// Connection::default().await?,
5420 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
5421 /// ]);
5422 ///
5423 /// assert!(client.decr(b"key", 1, true).await?.is_none());
5424 /// # Ok::<(), io::Error>(())
5425 /// # }).unwrap()
5426 /// ```
5427 pub async fn decr(
5428 &mut self,
5429 key: impl AsRef<[u8]>,
5430 value: u64,
5431 noreply: bool,
5432 ) -> io::Result<Option<u64>> {
5433 let i = *self.1.sorted(&key.as_ref()).next().unwrap();
5434 self.0[i].decr(key.as_ref(), value, noreply).await
5435 }
5436
5437 /// # Example
5438 ///
5439 /// ```
5440 /// use mcmc_rs::{ClientRendezvous, Connection};
5441 /// # use smol::{io, block_on};
5442 /// #
5443 /// # block_on(async {
5444 /// let mut client = ClientRendezvous::new(vec![
5445 /// Connection::default().await?,
5446 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
5447 /// ]);
5448 ///
5449 /// assert!(client.touch(b"key", -1, true).await?);
5450 /// # Ok::<(), io::Error>(())
5451 /// # }).unwrap()
5452 /// ```
5453 pub async fn touch(
5454 &mut self,
5455 key: impl AsRef<[u8]>,
5456 exptime: i64,
5457 noreply: bool,
5458 ) -> io::Result<bool> {
5459 let i = *self.1.sorted(&key.as_ref()).next().unwrap();
5460 self.0[i].touch(key.as_ref(), exptime, noreply).await
5461 }
5462
5463 /// # Example
5464 ///
5465 /// ```
5466 /// use mcmc_rs::{ClientRendezvous, Connection};
5467 /// # use smol::{io, block_on};
5468 /// #
5469 /// # block_on(async {
5470 /// let mut client = ClientRendezvous::new(vec![
5471 /// Connection::default().await?,
5472 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
5473 /// ]);
5474 /// assert!(client.set(b"k11", 0, 0, false, b"v11").await?);
5475 /// assert!(client.me(b"k11").await?.is_some());
5476 /// # Ok::<(), io::Error>(())
5477 /// # }).unwrap()
5478 /// ```
5479 pub async fn me(&mut self, key: impl AsRef<[u8]>) -> io::Result<Option<String>> {
5480 let i = *self.1.sorted(&key.as_ref()).next().unwrap();
5481 self.0[i].me(key.as_ref()).await
5482 }
5483
5484 /// # Example
5485 ///
5486 /// ```
5487 /// use mcmc_rs::{ClientRendezvous, Connection, MgFlag, MgItem};
5488 /// # use smol::{io, block_on};
5489 /// #
5490 /// # block_on(async {
5491 /// let mut client = ClientRendezvous::new(vec![
5492 /// Connection::default().await?,
5493 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
5494 /// ]);
5495 /// let result = client
5496 /// .mg(
5497 /// b"44OG44K544OI",
5498 /// &[
5499 /// MgFlag::Base64Key,
5500 /// MgFlag::ReturnCas,
5501 /// MgFlag::ReturnFlags,
5502 /// MgFlag::ReturnHit,
5503 /// MgFlag::ReturnKey,
5504 /// MgFlag::ReturnLastAccess,
5505 /// MgFlag::Opaque("opaque".to_string()),
5506 /// MgFlag::ReturnSize,
5507 /// MgFlag::ReturnTtl,
5508 /// MgFlag::UnBump,
5509 /// MgFlag::ReturnValue,
5510 /// MgFlag::NewCas(0),
5511 /// MgFlag::Autovivify(-1),
5512 /// MgFlag::RecacheTtl(-1),
5513 /// MgFlag::UpdateTtl(-1),
5514 /// ],
5515 /// )
5516 /// .await?;
5517 /// assert_eq!(
5518 /// result,
5519 /// MgItem {
5520 /// success: true,
5521 /// base64_key: false,
5522 /// cas: Some(0),
5523 /// flags: Some(0),
5524 /// hit: Some(0),
5525 /// key: Some("テスト".to_string()),
5526 /// last_access_ttl: Some(0),
5527 /// opaque: Some("opaque".to_string()),
5528 /// size: Some(0),
5529 /// ttl: Some(-1),
5530 /// data_block: Some(vec![]),
5531 /// already_win: false,
5532 /// won_recache: true,
5533 /// stale: false,
5534 /// }
5535 /// );
5536 /// # Ok::<(), io::Error>(())
5537 /// # }).unwrap()
5538 /// ```
5539 pub async fn mg(&mut self, key: impl AsRef<[u8]>, flags: &[MgFlag]) -> io::Result<MgItem> {
5540 let i = *self.1.sorted(&key.as_ref()).next().unwrap();
5541 self.0[i].mg(key.as_ref(), flags).await
5542 }
5543
5544 /// # Example
5545 ///
5546 /// ```
5547 /// use mcmc_rs::{ClientRendezvous, Connection, MsFlag, MsItem, MsMode};
5548 /// # use smol::{io, block_on};
5549 /// #
5550 /// # block_on(async {
5551 /// let mut client = ClientRendezvous::new(vec![
5552 /// Connection::default().await?,
5553 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
5554 /// ]);
5555 /// let result = client
5556 /// .ms(
5557 /// b"44OG44K544OI",
5558 /// &[
5559 /// MsFlag::Base64Key,
5560 /// MsFlag::ReturnCas,
5561 /// MsFlag::CompareCas(0),
5562 /// MsFlag::NewCas(0),
5563 /// MsFlag::SetFlags(0),
5564 /// MsFlag::Invalidate,
5565 /// MsFlag::ReturnKey,
5566 /// MsFlag::Opaque("opaque".to_string()),
5567 /// MsFlag::ReturnSize,
5568 /// MsFlag::Ttl(-1),
5569 /// MsFlag::Mode(MsMode::Set),
5570 /// MsFlag::Autovivify(0),
5571 /// ],
5572 /// b"hi",
5573 /// )
5574 /// .await?;
5575 /// assert_eq!(
5576 /// result,
5577 /// MsItem {
5578 /// success: false,
5579 /// cas: Some(0),
5580 /// key: Some("44OG44K544OI".to_string()),
5581 /// opaque: Some("opaque".to_string()),
5582 /// size: Some(2),
5583 /// base64_key: true
5584 /// }
5585 /// );
5586 /// # Ok::<(), io::Error>(())
5587 /// # }).unwrap()
5588 /// ```
5589 pub async fn ms(
5590 &mut self,
5591 key: impl AsRef<[u8]>,
5592 flags: &[MsFlag],
5593 data_block: impl AsRef<[u8]>,
5594 ) -> io::Result<MsItem> {
5595 let i = *self.1.sorted(&key.as_ref()).next().unwrap();
5596 self.0[i].ms(key.as_ref(), flags, data_block.as_ref()).await
5597 }
5598
5599 /// # Example
5600 ///
5601 /// ```
5602 /// use mcmc_rs::{ClientRendezvous, Connection, MdFlag, MdItem};
5603 /// # use smol::{io, block_on};
5604 /// #
5605 /// # block_on(async {
5606 /// let mut client = ClientRendezvous::new(vec![
5607 /// Connection::default().await?,
5608 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
5609 /// ]);
5610 /// let result = client
5611 /// .md(
5612 /// b"44OG44K544OI",
5613 /// &[
5614 /// MdFlag::Base64Key,
5615 /// MdFlag::CompareCas(0),
5616 /// MdFlag::NewCas(0),
5617 /// MdFlag::Invalidate,
5618 /// MdFlag::ReturnKey,
5619 /// MdFlag::Opaque("opaque".to_string()),
5620 /// MdFlag::UpdateTtl(-1),
5621 /// MdFlag::LeaveKey,
5622 /// ],
5623 /// )
5624 /// .await?;
5625 /// assert_eq!(
5626 /// result,
5627 /// MdItem {
5628 /// success: false,
5629 /// key: Some("44OG44K544OI".to_string()),
5630 /// opaque: Some("opaque".to_string()),
5631 /// base64_key: true
5632 /// }
5633 /// );
5634 /// # Ok::<(), io::Error>(())
5635 /// # }).unwrap()
5636 /// ```
5637 pub async fn md(&mut self, key: impl AsRef<[u8]>, flags: &[MdFlag]) -> io::Result<MdItem> {
5638 let i = *self.1.sorted(&key.as_ref()).next().unwrap();
5639 self.0[i].md(key.as_ref(), flags).await
5640 }
5641
5642 /// # Example
5643 ///
5644 /// ```
5645 /// use mcmc_rs::{ClientRendezvous, Connection, MaFlag, MaItem, MaMode};
5646 /// # use smol::{io, block_on};
5647 /// #
5648 /// # block_on(async {
5649 /// let mut client = ClientRendezvous::new(vec![
5650 /// Connection::default().await?,
5651 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
5652 /// ]);
5653 /// let result = client
5654 /// .ma(
5655 /// b"aGk=",
5656 /// &[
5657 /// MaFlag::Base64Key,
5658 /// MaFlag::CompareCas(0),
5659 /// MaFlag::NewCas(0),
5660 /// MaFlag::AutoCreate(0),
5661 /// MaFlag::InitValue(0),
5662 /// MaFlag::DeltaApply(0),
5663 /// MaFlag::UpdateTtl(0),
5664 /// MaFlag::Mode(MaMode::Incr),
5665 /// MaFlag::Opaque("opaque".to_string()),
5666 /// MaFlag::ReturnTtl,
5667 /// MaFlag::ReturnCas,
5668 /// MaFlag::ReturnValue,
5669 /// MaFlag::ReturnKey,
5670 /// ],
5671 /// )
5672 /// .await?;
5673 /// assert_eq!(
5674 /// result,
5675 /// MaItem {
5676 /// success: true,
5677 /// opaque: Some("opaque".to_string()),
5678 /// ttl: Some(-1),
5679 /// cas: Some(0),
5680 /// number: Some(0),
5681 /// key: Some("aGk=".to_string()),
5682 /// base64_key: true
5683 /// }
5684 /// );
5685 /// # Ok::<(), io::Error>(())
5686 /// # }).unwrap()
5687 /// ```
5688 pub async fn ma(&mut self, key: impl AsRef<[u8]>, flags: &[MaFlag]) -> io::Result<MaItem> {
5689 let i = *self.1.sorted(&key.as_ref()).next().unwrap();
5690 self.0[i].ma(key.as_ref(), flags).await
5691 }
5692}
5693
5694pub struct Pipeline<'a>(&'a mut Connection, Vec<Vec<u8>>);
5695impl<'a> Pipeline<'a> {
5696 /// # Example
5697 ///
5698 /// ```
5699 /// use mcmc_rs::Connection;
5700 /// # use smol::{io, block_on};
5701 /// #
5702 /// # block_on(async {
5703 /// let mut conn = Connection::default().await?;
5704 /// conn.pipeline();
5705 /// # Ok::<(), io::Error>(())
5706 /// # }).unwrap()
5707 /// ```
5708 fn new(conn: &'a mut Connection) -> Self {
5709 Self(conn, Vec::new())
5710 }
5711
5712 /// # Example
5713 ///
5714 /// ```
5715 /// use mcmc_rs::{Connection, PipelineResponse};
5716 /// # use smol::{io, block_on};
5717 /// #
5718 /// # block_on(async {
5719 /// for mut c in [
5720 /// Connection::default().await?,
5721 /// Connection::unix_connect("/tmp/memcached0.sock").await?,
5722 /// Connection::tls_connect("localhost", 11216, "cert.pem").await?,
5723 /// ] {
5724 /// let result = c
5725 /// .pipeline()
5726 /// .set(b"key", 0, -1, false, b"value")
5727 /// .get("key")
5728 /// .execute()
5729 /// .await?;
5730 /// assert_eq!(
5731 /// result,
5732 /// [
5733 /// PipelineResponse::Bool(true),
5734 /// PipelineResponse::OptionItem(None),
5735 /// ]
5736 /// );
5737 /// }
5738 /// # Ok::<(), io::Error>(())
5739 /// # }).unwrap()
5740 /// ```
5741 pub async fn execute(self) -> io::Result<Vec<PipelineResponse>> {
5742 if self.1.is_empty() {
5743 return Ok(Vec::new());
5744 };
5745 match self.0 {
5746 Connection::Tcp(s) => execute_cmd(s, &self.1).await,
5747 Connection::Unix(s) => execute_cmd(s, &self.1).await,
5748 Connection::Udp(_s, _r) => todo!(),
5749 Connection::Tls(s) => execute_cmd(s, &self.1).await,
5750 }
5751 }
5752
5753 /// # Example
5754 ///
5755 /// ```
5756 /// use mcmc_rs::Connection;
5757 /// # use smol::{io, block_on};
5758 /// #
5759 /// # block_on(async {
5760 /// let mut conn = Connection::default().await?;
5761 /// conn.pipeline().version();
5762 /// # Ok::<(), io::Error>(())
5763 /// # }).unwrap()
5764 /// ```
5765 pub fn version(mut self) -> Self {
5766 self.1.push(build_version_cmd().to_vec());
5767 self
5768 }
5769
5770 /// # Example
5771 ///
5772 /// ```
5773 /// use mcmc_rs::Connection;
5774 /// # use smol::{io, block_on};
5775 /// #
5776 /// # block_on(async {
5777 /// let mut conn = Connection::default().await?;
5778 /// conn.pipeline().quit();
5779 /// # Ok::<(), io::Error>(())
5780 /// # }).unwrap()
5781 /// ```
5782 pub fn quit(mut self) -> Self {
5783 self.1.push(build_quit_cmd().to_vec());
5784 self
5785 }
5786
5787 /// # Example
5788 ///
5789 /// ```
5790 /// use mcmc_rs::Connection;
5791 /// # use smol::{io, block_on};
5792 /// #
5793 /// # block_on(async {
5794 /// let mut conn = Connection::default().await?;
5795 /// conn.pipeline().shutdown(false);
5796 /// # Ok::<(), io::Error>(())
5797 /// # }).unwrap()
5798 /// ```
5799 pub fn shutdown(mut self, graceful: bool) -> Self {
5800 self.1.push(build_shutdown_cmd(graceful).to_vec());
5801 self
5802 }
5803
5804 /// # Example
5805 ///
5806 /// ```
5807 /// use mcmc_rs::Connection;
5808 /// # use smol::{io, block_on};
5809 /// #
5810 /// # block_on(async {
5811 /// let mut conn = Connection::default().await?;
5812 /// conn.pipeline().cache_memlimit(1, false);
5813 /// # Ok::<(), io::Error>(())
5814 /// # }).unwrap()
5815 /// ```
5816 pub fn cache_memlimit(mut self, limit: usize, noreply: bool) -> Self {
5817 self.1
5818 .push(build_cache_memlimit_cmd(limit, noreply).to_vec());
5819 self
5820 }
5821
5822 /// # Example
5823 ///
5824 /// ```
5825 /// use mcmc_rs::Connection;
5826 /// # use smol::{io, block_on};
5827 /// #
5828 /// # block_on(async {
5829 /// let mut conn = Connection::default().await?;
5830 /// conn.pipeline().flush_all(None, false);
5831 /// # Ok::<(), io::Error>(())
5832 /// # }).unwrap()
5833 /// ```
5834 pub fn flush_all(mut self, exptime: Option<i64>, noreply: bool) -> Self {
5835 self.1.push(build_flush_all_cmd(exptime, noreply).to_vec());
5836 self
5837 }
5838
5839 /// # Example
5840 ///
5841 /// ```
5842 /// use mcmc_rs::Connection;
5843 /// # use smol::{io, block_on};
5844 /// #
5845 /// # block_on(async {
5846 /// let mut conn = Connection::default().await?;
5847 /// conn.pipeline().set(b"key", 0, 0, false, b"value");
5848 /// # Ok::<(), io::Error>(())
5849 /// # }).unwrap()
5850 /// ```
5851 pub fn set(
5852 mut self,
5853 key: impl AsRef<[u8]>,
5854 flags: u32,
5855 exptime: i64,
5856 noreply: bool,
5857 data_block: impl AsRef<[u8]>,
5858 ) -> Self {
5859 self.1.push(build_storage_cmd(
5860 b"set",
5861 key.as_ref(),
5862 flags,
5863 exptime,
5864 None,
5865 noreply,
5866 data_block.as_ref(),
5867 ));
5868 self
5869 }
5870
5871 /// # Example
5872 ///
5873 /// ```
5874 /// use mcmc_rs::Connection;
5875 /// # use smol::{io, block_on};
5876 /// #
5877 /// # block_on(async {
5878 /// let mut conn = Connection::default().await?;
5879 /// conn.pipeline().add(b"key", 0, 0, false, b"value");
5880 /// # Ok::<(), io::Error>(())
5881 /// # }).unwrap()
5882 /// ```
5883 pub fn add(
5884 mut self,
5885 key: impl AsRef<[u8]>,
5886 flags: u32,
5887 exptime: i64,
5888 noreply: bool,
5889 data_block: impl AsRef<[u8]>,
5890 ) -> Self {
5891 self.1.push(build_storage_cmd(
5892 b"add",
5893 key.as_ref(),
5894 flags,
5895 exptime,
5896 None,
5897 noreply,
5898 data_block.as_ref(),
5899 ));
5900 self
5901 }
5902
5903 /// # Example
5904 ///
5905 /// ```
5906 /// use mcmc_rs::Connection;
5907 /// # use smol::{io, block_on};
5908 /// #
5909 /// # block_on(async {
5910 /// let mut conn = Connection::default().await?;
5911 /// conn.pipeline().replace(b"key", 0, 0, false, b"value");
5912 /// # Ok::<(), io::Error>(())
5913 /// # }).unwrap()
5914 /// ```
5915 pub fn replace(
5916 mut self,
5917 key: impl AsRef<[u8]>,
5918 flags: u32,
5919 exptime: i64,
5920 noreply: bool,
5921 data_block: impl AsRef<[u8]>,
5922 ) -> Self {
5923 self.1.push(build_storage_cmd(
5924 b"replace",
5925 key.as_ref(),
5926 flags,
5927 exptime,
5928 None,
5929 noreply,
5930 data_block.as_ref(),
5931 ));
5932 self
5933 }
5934
5935 /// # Example
5936 ///
5937 /// ```
5938 /// use mcmc_rs::Connection;
5939 /// # use smol::{io, block_on};
5940 /// #
5941 /// # block_on(async {
5942 /// let mut conn = Connection::default().await?;
5943 /// conn.pipeline().append(b"key", 0, 0, false, b"value");
5944 /// # Ok::<(), io::Error>(())
5945 /// # }).unwrap()
5946 /// ```
5947 pub fn append(
5948 mut self,
5949 key: impl AsRef<[u8]>,
5950 flags: u32,
5951 exptime: i64,
5952 noreply: bool,
5953 data_block: impl AsRef<[u8]>,
5954 ) -> Self {
5955 self.1.push(build_storage_cmd(
5956 b"append",
5957 key.as_ref(),
5958 flags,
5959 exptime,
5960 None,
5961 noreply,
5962 data_block.as_ref(),
5963 ));
5964 self
5965 }
5966
5967 /// # Example
5968 ///
5969 /// ```
5970 /// use mcmc_rs::Connection;
5971 /// # use smol::{io, block_on};
5972 /// #
5973 /// # block_on(async {
5974 /// let mut conn = Connection::default().await?;
5975 /// conn.pipeline().prepend(b"key", 0, 0, false, b"value");
5976 /// # Ok::<(), io::Error>(())
5977 /// # }).unwrap()
5978 /// ```
5979 pub fn prepend(
5980 mut self,
5981 key: impl AsRef<[u8]>,
5982 flags: u32,
5983 exptime: i64,
5984 noreply: bool,
5985 data_block: impl AsRef<[u8]>,
5986 ) -> Self {
5987 self.1.push(build_storage_cmd(
5988 b"prepend",
5989 key.as_ref(),
5990 flags,
5991 exptime,
5992 None,
5993 noreply,
5994 data_block.as_ref(),
5995 ));
5996 self
5997 }
5998
5999 /// # Example
6000 ///
6001 /// ```
6002 /// use mcmc_rs::Connection;
6003 /// # use smol::{io, block_on};
6004 /// #
6005 /// # block_on(async {
6006 /// let mut conn = Connection::default().await?;
6007 /// conn.pipeline().cas(b"key", 0, 0, 0, false, b"value");
6008 /// # Ok::<(), io::Error>(())
6009 /// # }).unwrap()
6010 /// ```
6011 pub fn cas(
6012 mut self,
6013 key: impl AsRef<[u8]>,
6014 flags: u32,
6015 exptime: i64,
6016 cas_unique: u64,
6017 noreply: bool,
6018 data_block: impl AsRef<[u8]>,
6019 ) -> Self {
6020 self.1.push(build_storage_cmd(
6021 b"cas",
6022 key.as_ref(),
6023 flags,
6024 exptime,
6025 Some(cas_unique),
6026 noreply,
6027 data_block.as_ref(),
6028 ));
6029 self
6030 }
6031
6032 /// # Example
6033 ///
6034 /// ```
6035 /// use mcmc_rs::Connection;
6036 /// # use smol::{io, block_on};
6037 /// #
6038 /// # block_on(async {
6039 /// let mut conn = Connection::default().await?;
6040 /// conn.pipeline().auth(b"username", b"password");
6041 /// # Ok::<(), io::Error>(())
6042 /// # }).unwrap()
6043 /// ```
6044 pub fn auth(mut self, username: impl AsRef<[u8]>, password: impl AsRef<[u8]>) -> Self {
6045 self.1
6046 .push(build_auth_cmd(username.as_ref(), password.as_ref()));
6047 self
6048 }
6049
6050 /// # Example
6051 ///
6052 /// ```
6053 /// use mcmc_rs::Connection;
6054 /// # use smol::{io, block_on};
6055 /// #
6056 /// # block_on(async {
6057 /// let mut conn = Connection::default().await?;
6058 /// conn.pipeline().delete(b"key", false);
6059 /// # Ok::<(), io::Error>(())
6060 /// # }).unwrap()
6061 /// ```
6062 pub fn delete(mut self, key: impl AsRef<[u8]>, noreply: bool) -> Self {
6063 self.1.push(build_delete_cmd(key.as_ref(), noreply));
6064 self
6065 }
6066
6067 /// # Example
6068 ///
6069 /// ```
6070 /// use mcmc_rs::Connection;
6071 /// # use smol::{io, block_on};
6072 /// #
6073 /// # block_on(async {
6074 /// let mut conn = Connection::default().await?;
6075 /// conn.pipeline().incr(b"key", 1, false);
6076 /// # Ok::<(), io::Error>(())
6077 /// # }).unwrap()
6078 /// ```
6079 pub fn incr(mut self, key: impl AsRef<[u8]>, value: u64, noreply: bool) -> Self {
6080 self.1
6081 .push(build_incr_decr_cmd(b"incr", key.as_ref(), value, noreply));
6082 self
6083 }
6084
6085 /// # Example
6086 ///
6087 /// ```
6088 /// use mcmc_rs::Connection;
6089 /// # use smol::{io, block_on};
6090 /// #
6091 /// # block_on(async {
6092 /// let mut conn = Connection::default().await?;
6093 /// conn.pipeline().decr(b"key", 1, false);
6094 /// # Ok::<(), io::Error>(())
6095 /// # }).unwrap()
6096 /// ```
6097 pub fn decr(mut self, key: impl AsRef<[u8]>, value: u64, noreply: bool) -> Self {
6098 self.1
6099 .push(build_incr_decr_cmd(b"decr", key.as_ref(), value, noreply));
6100 self
6101 }
6102
6103 /// # Example
6104 ///
6105 /// ```
6106 /// use mcmc_rs::Connection;
6107 /// # use smol::{io, block_on};
6108 /// #
6109 /// # block_on(async {
6110 /// let mut conn = Connection::default().await?;
6111 /// conn.pipeline().touch(b"key", 1, false);
6112 /// # Ok::<(), io::Error>(())
6113 /// # }).unwrap()
6114 /// ```
6115 pub fn touch(mut self, key: impl AsRef<[u8]>, exptime: i64, noreply: bool) -> Self {
6116 self.1.push(build_touch_cmd(key.as_ref(), exptime, noreply));
6117 self
6118 }
6119
6120 /// # Example
6121 ///
6122 /// ```
6123 /// use mcmc_rs::Connection;
6124 /// # use smol::{io, block_on};
6125 /// #
6126 /// # block_on(async {
6127 /// let mut conn = Connection::default().await?;
6128 /// conn.pipeline().get(b"key");
6129 /// # Ok::<(), io::Error>(())
6130 /// # }).unwrap()
6131 /// ```
6132 pub fn get(mut self, key: impl AsRef<[u8]>) -> Self {
6133 self.1
6134 .push(build_retrieval_cmd(b"get", None, &[key.as_ref()]));
6135 self
6136 }
6137
6138 /// # Example
6139 ///
6140 /// ```
6141 /// use mcmc_rs::Connection;
6142 /// # use smol::{io, block_on};
6143 /// #
6144 /// # block_on(async {
6145 /// let mut conn = Connection::default().await?;
6146 /// conn.pipeline().gets(b"key");
6147 /// # Ok::<(), io::Error>(())
6148 /// # }).unwrap()
6149 /// ```
6150 pub fn gets(mut self, key: impl AsRef<[u8]>) -> Self {
6151 self.1
6152 .push(build_retrieval_cmd(b"gets", None, &[key.as_ref()]));
6153 self
6154 }
6155
6156 /// # Example
6157 ///
6158 /// ```
6159 /// use mcmc_rs::Connection;
6160 /// # use smol::{io, block_on};
6161 /// #
6162 /// # block_on(async {
6163 /// let mut conn = Connection::default().await?;
6164 /// conn.pipeline().gat(0, b"key");
6165 /// # Ok::<(), io::Error>(())
6166 /// # }).unwrap()
6167 /// ```
6168 pub fn gat(mut self, exptime: i64, key: impl AsRef<[u8]>) -> Self {
6169 self.1
6170 .push(build_retrieval_cmd(b"gat", Some(exptime), &[key.as_ref()]));
6171 self
6172 }
6173
6174 /// # Example
6175 ///
6176 /// ```
6177 /// use mcmc_rs::Connection;
6178 /// # use smol::{io, block_on};
6179 /// #
6180 /// # block_on(async {
6181 /// let mut conn = Connection::default().await?;
6182 /// conn.pipeline().gats(0, b"key");
6183 /// # Ok::<(), io::Error>(())
6184 /// # }).unwrap()
6185 /// ```
6186 pub fn gats(mut self, exptime: i64, key: impl AsRef<[u8]>) -> Self {
6187 self.1
6188 .push(build_retrieval_cmd(b"gats", Some(exptime), &[key.as_ref()]));
6189 self
6190 }
6191
6192 /// # Example
6193 ///
6194 /// ```
6195 /// use mcmc_rs::Connection;
6196 /// # use smol::{io, block_on};
6197 /// #
6198 /// # block_on(async {
6199 /// let mut conn = Connection::default().await?;
6200 /// conn.pipeline()
6201 /// .get_multi(&[b"key".as_slice(), b"key2".as_slice()]);
6202 /// # Ok::<(), io::Error>(())
6203 /// # }).unwrap()
6204 /// ```
6205 pub fn get_multi(mut self, keys: &[impl AsRef<[u8]>]) -> Self {
6206 self.1.push(build_retrieval_cmd(
6207 b"get",
6208 None,
6209 &keys.iter().map(|x| x.as_ref()).collect::<Vec<&[u8]>>(),
6210 ));
6211 self
6212 }
6213
6214 /// # Example
6215 ///
6216 /// ```
6217 /// use mcmc_rs::Connection;
6218 /// # use smol::{io, block_on};
6219 /// #
6220 /// # block_on(async {
6221 /// let mut conn = Connection::default().await?;
6222 /// conn.pipeline()
6223 /// .gets_multi(&[b"key".as_slice(), b"key2".as_slice()]);
6224 /// # Ok::<(), io::Error>(())
6225 /// # }).unwrap()
6226 /// ```
6227 pub fn gets_multi(mut self, keys: &[impl AsRef<[u8]>]) -> Self {
6228 self.1.push(build_retrieval_cmd(
6229 b"gets",
6230 None,
6231 &keys.iter().map(|x| x.as_ref()).collect::<Vec<&[u8]>>(),
6232 ));
6233 self
6234 }
6235
6236 /// # Example
6237 ///
6238 /// ```
6239 /// use mcmc_rs::Connection;
6240 /// # use smol::{io, block_on};
6241 /// #
6242 /// # block_on(async {
6243 /// let mut conn = Connection::default().await?;
6244 /// conn.pipeline()
6245 /// .gat_multi(0, &[b"key".as_slice(), b"key2".as_slice()]);
6246 /// # Ok::<(), io::Error>(())
6247 /// # }).unwrap()
6248 /// ```
6249 pub fn gat_multi(mut self, exptime: i64, keys: &[impl AsRef<[u8]>]) -> Self {
6250 self.1.push(build_retrieval_cmd(
6251 b"gat",
6252 Some(exptime),
6253 &keys.iter().map(|x| x.as_ref()).collect::<Vec<&[u8]>>(),
6254 ));
6255 self
6256 }
6257
6258 /// # Example
6259 ///
6260 /// ```
6261 /// use mcmc_rs::Connection;
6262 /// # use smol::{io, block_on};
6263 /// #
6264 /// # block_on(async {
6265 /// let mut conn = Connection::default().await?;
6266 /// conn.pipeline()
6267 /// .gats_multi(0, &[b"key".as_slice(), b"key2".as_slice()]);
6268 /// # Ok::<(), io::Error>(())
6269 /// # }).unwrap()
6270 /// ```
6271 pub fn gats_multi(mut self, exptime: i64, keys: &[impl AsRef<[u8]>]) -> Self {
6272 self.1.push(build_retrieval_cmd(
6273 b"gats",
6274 Some(exptime),
6275 &keys.iter().map(|x| x.as_ref()).collect::<Vec<&[u8]>>(),
6276 ));
6277 self
6278 }
6279
6280 /// # Example
6281 ///
6282 /// ```
6283 /// use mcmc_rs::Connection;
6284 /// # use smol::{io, block_on};
6285 /// #
6286 /// # block_on(async {
6287 /// let mut conn = Connection::default().await?;
6288 /// conn.pipeline().stats(None);
6289 /// # Ok::<(), io::Error>(())
6290 /// # }).unwrap()
6291 /// ```
6292 pub fn stats(mut self, arg: Option<StatsArg>) -> Self {
6293 self.1.push(build_stats_cmd(arg).to_vec());
6294 self
6295 }
6296
6297 /// # Example
6298 ///
6299 /// ```
6300 /// use mcmc_rs::{Connection, SlabsAutomoveArg};
6301 /// # use smol::{io, block_on};
6302 /// #
6303 /// # block_on(async {
6304 /// let mut conn = Connection::default().await?;
6305 /// conn.pipeline().slabs_automove(SlabsAutomoveArg::Zero);
6306 /// # Ok::<(), io::Error>(())
6307 /// # }).unwrap()
6308 /// ```
6309 pub fn slabs_automove(mut self, arg: SlabsAutomoveArg) -> Self {
6310 self.1.push(build_slabs_automove_cmd(arg).to_vec());
6311 self
6312 }
6313
6314 /// # Example
6315 ///
6316 /// ```
6317 /// use mcmc_rs::{Connection, LruCrawlerArg};
6318 /// # use smol::{io, block_on};
6319 /// #
6320 /// # block_on(async {
6321 /// let mut conn = Connection::default().await?;
6322 /// conn.pipeline().lru_crawler(LruCrawlerArg::Enable);
6323 /// # Ok::<(), io::Error>(())
6324 /// # }).unwrap()
6325 /// ```
6326 pub fn lru_crawler(mut self, arg: LruCrawlerArg) -> Self {
6327 self.1.push(build_lru_crawler_cmd(arg).to_vec());
6328 self
6329 }
6330
6331 /// # Example
6332 ///
6333 /// ```
6334 /// use mcmc_rs::Connection;
6335 /// # use smol::{io, block_on};
6336 /// #
6337 /// # block_on(async {
6338 /// let mut conn = Connection::default().await?;
6339 /// conn.pipeline().lru_crawler_sleep(0);
6340 /// # Ok::<(), io::Error>(())
6341 /// # }).unwrap()
6342 /// ```
6343 pub fn lru_crawler_sleep(mut self, microseconds: usize) -> Self {
6344 self.1.push(build_lru_clawler_sleep_cmd(microseconds));
6345 self
6346 }
6347
6348 /// # Example
6349 ///
6350 /// ```
6351 /// use mcmc_rs::Connection;
6352 /// # use smol::{io, block_on};
6353 /// #
6354 /// # block_on(async {
6355 /// let mut conn = Connection::default().await?;
6356 /// conn.pipeline().lru_crawler_tocrawl(0);
6357 /// # Ok::<(), io::Error>(())
6358 /// # }).unwrap()
6359 /// ```
6360 pub fn lru_crawler_tocrawl(mut self, arg: u32) -> Self {
6361 self.1.push(build_lru_crawler_tocrawl_cmd(arg));
6362 self
6363 }
6364
6365 /// # Example
6366 ///
6367 /// ```
6368 /// use mcmc_rs::{Connection, LruCrawlerCrawlArg};
6369 /// # use smol::{io, block_on};
6370 /// #
6371 /// # block_on(async {
6372 /// let mut conn = Connection::default().await?;
6373 /// conn.pipeline().lru_crawler_crawl(LruCrawlerCrawlArg::All);
6374 /// # Ok::<(), io::Error>(())
6375 /// # }).unwrap()
6376 /// ```
6377 pub fn lru_crawler_crawl(mut self, arg: LruCrawlerCrawlArg<'_>) -> Self {
6378 self.1.push(build_lru_clawler_crawl_cmd(arg));
6379 self
6380 }
6381
6382 /// # Example
6383 ///
6384 /// ```
6385 /// use mcmc_rs::Connection;
6386 /// # use smol::{io, block_on};
6387 /// #
6388 /// # block_on(async {
6389 /// let mut conn = Connection::default().await?;
6390 /// conn.pipeline().slabs_reassign(1, 2);
6391 /// # Ok::<(), io::Error>(())
6392 /// # }).unwrap()
6393 /// ```
6394 pub fn slabs_reassign(mut self, source_class: isize, dest_class: isize) -> Self {
6395 self.1
6396 .push(build_slabs_reassign_cmd(source_class, dest_class));
6397 self
6398 }
6399
6400 /// # Example
6401 ///
6402 /// ```
6403 /// use mcmc_rs::{Connection, LruCrawlerMetadumpArg};
6404 /// # use smol::{io, block_on};
6405 /// #
6406 /// # block_on(async {
6407 /// let mut conn = Connection::default().await?;
6408 /// conn.pipeline()
6409 /// .lru_crawler_metadump(LruCrawlerMetadumpArg::All);
6410 /// # Ok::<(), io::Error>(())
6411 /// # }).unwrap()
6412 /// ```
6413 pub fn lru_crawler_metadump(mut self, arg: LruCrawlerMetadumpArg<'_>) -> Self {
6414 self.1.push(build_lru_clawler_metadump_cmd(arg));
6415 self
6416 }
6417
6418 /// # Example
6419 ///
6420 /// ```
6421 /// use mcmc_rs::{Connection, LruCrawlerMgdumpArg};
6422 /// # use smol::{io, block_on};
6423 /// #
6424 /// # block_on(async {
6425 /// let mut conn = Connection::default().await?;
6426 /// conn.pipeline().lru_crawler_mgdump(LruCrawlerMgdumpArg::All);
6427 /// # Ok::<(), io::Error>(())
6428 /// # }).unwrap()
6429 /// ```
6430 pub fn lru_crawler_mgdump(mut self, arg: LruCrawlerMgdumpArg<'_>) -> Self {
6431 self.1.push(build_lru_clawler_mgdump_cmd(arg));
6432 self
6433 }
6434
6435 /// # Example
6436 ///
6437 /// ```
6438 /// use mcmc_rs::Connection;
6439 /// # use smol::{io, block_on};
6440 /// #
6441 /// # block_on(async {
6442 /// let mut conn = Connection::default().await?;
6443 /// conn.pipeline().mn();
6444 /// # Ok::<(), io::Error>(())
6445 /// # }).unwrap()
6446 /// ```
6447 pub fn mn(mut self) -> Self {
6448 self.1.push(build_mn_cmd().to_vec());
6449 self
6450 }
6451
6452 /// # Example
6453 ///
6454 /// ```
6455 /// use mcmc_rs::Connection;
6456 /// # use smol::{io, block_on};
6457 /// #
6458 /// # block_on(async {
6459 /// let mut conn = Connection::default().await?;
6460 /// conn.pipeline().me(b"key");
6461 /// # Ok::<(), io::Error>(())
6462 /// # }).unwrap()
6463 /// ```
6464 pub fn me(mut self, key: impl AsRef<[u8]>) -> Self {
6465 self.1.push(build_me_cmd(key.as_ref()));
6466 self
6467 }
6468
6469 /// # Example
6470 ///
6471 /// ```
6472 /// use mcmc_rs::{Connection, MgFlag};
6473 /// # use smol::{io, block_on};
6474 /// #
6475 /// # block_on(async {
6476 /// let mut conn = Connection::default().await?;
6477 /// conn.pipeline().mg(b"key", &[MgFlag::Base64Key]);
6478 /// # Ok::<(), io::Error>(())
6479 /// # }).unwrap()
6480 /// ```
6481 pub fn mg(mut self, key: impl AsRef<[u8]>, flags: &[MgFlag]) -> Self {
6482 self.1.push(build_mc_cmd(
6483 b"mg",
6484 key.as_ref(),
6485 &build_mg_flags(flags),
6486 None,
6487 ));
6488 self
6489 }
6490
6491 /// # Example
6492 ///
6493 /// ```
6494 /// use mcmc_rs::{Connection, MsFlag};
6495 /// # use smol::{io, block_on};
6496 /// #
6497 /// # block_on(async {
6498 /// let mut conn = Connection::default().await?;
6499 /// conn.pipeline().ms(b"key", &[MsFlag::Base64Key], b"value");
6500 /// # Ok::<(), io::Error>(())
6501 /// # }).unwrap()
6502 /// ```
6503 pub fn ms(
6504 mut self,
6505 key: impl AsRef<[u8]>,
6506 flags: &[MsFlag],
6507 data_block: impl AsRef<[u8]>,
6508 ) -> Self {
6509 self.1.push(build_mc_cmd(
6510 b"ms",
6511 key.as_ref(),
6512 &build_ms_flags(flags),
6513 Some(data_block.as_ref()),
6514 ));
6515 self
6516 }
6517
6518 /// # Example
6519 ///
6520 /// ```
6521 /// use mcmc_rs::{Connection, MdFlag};
6522 /// # use smol::{io, block_on};
6523 /// #
6524 /// # block_on(async {
6525 /// let mut conn = Connection::default().await?;
6526 /// conn.pipeline().md(b"key", &[MdFlag::ReturnKey]);
6527 /// # Ok::<(), io::Error>(())
6528 /// # }).unwrap()
6529 /// ```
6530 pub fn md(mut self, key: impl AsRef<[u8]>, flags: &[MdFlag]) -> Self {
6531 self.1.push(build_mc_cmd(
6532 b"md",
6533 key.as_ref(),
6534 &build_md_flags(flags),
6535 None,
6536 ));
6537 self
6538 }
6539
6540 /// # Example
6541 ///
6542 /// ```
6543 /// use mcmc_rs::{Connection, MaFlag};
6544 /// # use smol::{io, block_on};
6545 /// #
6546 /// # block_on(async {
6547 /// let mut conn = Connection::default().await?;
6548 /// conn.pipeline().ma(b"key", &[MaFlag::Base64Key]);
6549 /// # Ok::<(), io::Error>(())
6550 /// # }).unwrap()
6551 /// ```
6552 pub fn ma(mut self, key: impl AsRef<[u8]>, flags: &[MaFlag]) -> Self {
6553 self.1.push(build_mc_cmd(
6554 b"ma",
6555 key.as_ref(),
6556 &build_ma_flags(flags),
6557 None,
6558 ));
6559 self
6560 }
6561
6562 /// # Example
6563 ///
6564 /// ```
6565 /// use mcmc_rs::{Connection, LruArg, LruMode};
6566 /// # use smol::{io, block_on};
6567 /// #
6568 /// # block_on(async {
6569 /// let mut conn = Connection::default().await?;
6570 /// conn.pipeline().lru(LruArg::Mode(LruMode::Flat));
6571 /// # Ok::<(), io::Error>(())
6572 /// # }).unwrap()
6573 /// ```
6574 pub fn lru(mut self, arg: LruArg) -> Self {
6575 self.1.push(build_lru_cmd(arg));
6576 self
6577 }
6578}
6579
6580#[cfg(test)]
6581mod tests {
6582 use super::*;
6583 use smol::block_on;
6584
6585 #[test]
6586 fn test_version() {
6587 block_on(async {
6588 let mut c = Cursor::new(b"version\r\nVERSION 1.2.3\r\n".to_vec());
6589 assert_eq!("1.2.3", version_cmd(&mut c).await.unwrap());
6590
6591 let mut c = Cursor::new(b"version\r\nERROR\r\n".to_vec());
6592 assert!(version_cmd(&mut c).await.is_err())
6593 })
6594 }
6595
6596 #[test]
6597 fn test_quit() {
6598 block_on(async {
6599 let mut c = Cursor::new(b"quit\r\n".to_vec());
6600 assert!(quit_cmd(&mut c).await.is_ok())
6601 })
6602 }
6603
6604 #[test]
6605 fn test_shutdown() {
6606 block_on(async {
6607 let mut c = Cursor::new(b"shutdown\r\n".to_vec());
6608 assert!(shutdown_cmd(&mut c, false).await.is_ok());
6609
6610 let mut c = Cursor::new(b"shutdown graceful\r\n".to_vec());
6611 assert!(shutdown_cmd(&mut c, true).await.is_ok())
6612 })
6613 }
6614
6615 #[test]
6616 fn test_cache_memlimit() {
6617 block_on(async {
6618 let mut c = Cursor::new(b"cache_memlimit 1\r\nOK\r\n".to_vec());
6619 assert!(cache_memlimit_cmd(&mut c, 1, false).await.is_ok());
6620
6621 let mut c = Cursor::new(b"cache_memlimit 1 noreply\r\n".to_vec());
6622 assert!(cache_memlimit_cmd(&mut c, 1, true).await.is_ok());
6623
6624 let mut c = Cursor::new(b"cache_memlimit 1\r\nERROR\r\n".to_vec());
6625 assert!(cache_memlimit_cmd(&mut c, 1, false).await.is_err());
6626 })
6627 }
6628
6629 #[test]
6630 fn test_flush_all() {
6631 block_on(async {
6632 let mut c = Cursor::new(b"flush_all\r\nOK\r\n".to_vec());
6633 assert!(flush_all_cmd(&mut c, None, false).await.is_ok());
6634
6635 let mut c = Cursor::new(b"flush_all 1 noreply\r\n".to_vec());
6636 assert!(flush_all_cmd(&mut c, Some(1), true).await.is_ok());
6637
6638 let mut c = Cursor::new(b"flush_all\r\nERROR\r\n".to_vec());
6639 assert!(flush_all_cmd(&mut c, None, false).await.is_err());
6640 })
6641 }
6642
6643 #[test]
6644 fn test_storage() {
6645 block_on(async {
6646 let mut c = Cursor::new(b"cas key 0 0 0 0\r\nvalue\r\nSTORED\r\n".to_vec());
6647 assert!(
6648 storage_cmd(&mut c, b"cas", b"key", 0, 0, Some(0), false, b"value")
6649 .await
6650 .unwrap()
6651 );
6652
6653 let mut c = Cursor::new(b"append key 0 0 0 noreply\r\nvalue\r\n".to_vec());
6654 assert!(
6655 storage_cmd(&mut c, b"append", b"key", 0, 0, None, true, b"value")
6656 .await
6657 .unwrap()
6658 );
6659
6660 let mut c = Cursor::new(b"prepend key 0 0 0\r\nvalue\r\nNOT_STORED\r\n".to_vec());
6661 assert!(
6662 !storage_cmd(&mut c, b"prepend", b"key", 0, 0, None, false, b"value")
6663 .await
6664 .unwrap()
6665 );
6666
6667 let mut c = Cursor::new(b"add key 0 0 0\r\nvalue\r\nERROR\r\n".to_vec());
6668 assert!(
6669 storage_cmd(&mut c, b"add", b"key", 0, 0, None, false, b"value")
6670 .await
6671 .is_err()
6672 )
6673 })
6674 }
6675
6676 #[test]
6677 fn test_delete() {
6678 block_on(async {
6679 let mut c = Cursor::new(b"delete key\r\nDELETED\r\n".to_vec());
6680 assert!(delete_cmd(&mut c, b"key", false).await.unwrap());
6681
6682 let mut c = Cursor::new(b"delete key\r\nNOT_FOUND\r\n".to_vec());
6683 assert!(!delete_cmd(&mut c, b"key", false).await.unwrap());
6684
6685 let mut c = Cursor::new(b"delete key noreply\r\n".to_vec());
6686 assert!(delete_cmd(&mut c, b"key", true).await.unwrap());
6687
6688 let mut c = Cursor::new(b"delete key\r\nERROR\r\n".to_vec());
6689 assert!(delete_cmd(&mut c, b"key", false).await.is_err());
6690 })
6691 }
6692
6693 #[test]
6694 fn test_auth() {
6695 block_on(async {
6696 let mut c = Cursor::new(b"set _ _ _ 3\r\na b\r\nSTORED\r\n".to_vec());
6697 assert!(auth_cmd(&mut c, b"a", b"b").await.is_ok());
6698
6699 let mut c = Cursor::new(b"set _ _ _ 3\r\na b\r\nERROR\r\n".to_vec());
6700 assert!(auth_cmd(&mut c, b"a", b"b").await.is_err());
6701 })
6702 }
6703
6704 #[test]
6705 fn test_incr_decr() {
6706 block_on(async {
6707 let mut c = Cursor::new(b"incr key 1\r\n2\r\n".to_vec());
6708 assert_eq!(
6709 incr_decr_cmd(&mut c, b"incr", b"key", 1, false)
6710 .await
6711 .unwrap(),
6712 Some(2)
6713 );
6714
6715 let mut c = Cursor::new(b"incr key 1 noreply\r\n".to_vec());
6716 assert!(
6717 incr_decr_cmd(&mut c, b"incr", b"key", 1, true)
6718 .await
6719 .unwrap()
6720 .is_none(),
6721 );
6722
6723 let mut c = Cursor::new(b"incr key 1\r\nNOT_FOUND\r\n".to_vec());
6724 assert!(
6725 incr_decr_cmd(&mut c, b"incr", b"key", 1, false)
6726 .await
6727 .unwrap()
6728 .is_none()
6729 );
6730
6731 let mut c = Cursor::new(b"incr key 1\r\nERROR\r\n".to_vec());
6732 assert!(
6733 incr_decr_cmd(&mut c, b"incr", b"key", 1, false)
6734 .await
6735 .is_err()
6736 );
6737 })
6738 }
6739
6740 #[test]
6741 fn test_touch() {
6742 block_on(async {
6743 let mut c = Cursor::new(b"touch key 0\r\nTOUCHED\r\n".to_vec());
6744 assert!(touch_cmd(&mut c, b"key", 0, false).await.unwrap());
6745
6746 let mut c = Cursor::new(b"touch key 0\r\nNOT_FOUND\r\n".to_vec());
6747 assert!(!touch_cmd(&mut c, b"key", 0, false).await.unwrap());
6748
6749 let mut c = Cursor::new(b"touch key 0 noreply\r\n".to_vec());
6750 assert!(touch_cmd(&mut c, b"key", 0, true).await.unwrap());
6751
6752 let mut c = Cursor::new(b"touch key 0\r\nERROR\r\n".to_vec());
6753 assert!(touch_cmd(&mut c, b"key", 0, false).await.is_err())
6754 })
6755 }
6756
6757 #[test]
6758 fn test_retrieval() {
6759 block_on(async {
6760 let mut c = Cursor::new(b"gets key\r\nEND\r\n".to_vec());
6761 assert_eq!(
6762 retrieval_cmd(&mut c, b"gets", None, &[b"key"])
6763 .await
6764 .unwrap(),
6765 vec![]
6766 );
6767
6768 let mut c = Cursor::new(b"gat 0 key\r\nVALUE key 0 1\r\na\r\nEND\r\n".to_vec());
6769 assert_eq!(
6770 retrieval_cmd(&mut c, b"gat", Some(0), &[b"key"])
6771 .await
6772 .unwrap(),
6773 vec![Item {
6774 key: "key".to_string(),
6775 flags: 0,
6776 cas_unique: None,
6777 data_block: b"a".to_vec(),
6778 }]
6779 );
6780
6781 let mut c = Cursor::new(
6782 b"gats 0 key key2\r\nVALUE key 0 1 0\r\na\r\nVALUE key2 0 1 0\r\na\r\nEND\r\n"
6783 .to_vec(),
6784 );
6785 assert_eq!(
6786 retrieval_cmd(&mut c, b"gats", Some(0), &[b"key", b"key2"])
6787 .await
6788 .unwrap(),
6789 vec![
6790 Item {
6791 key: "key".to_string(),
6792 flags: 0,
6793 cas_unique: Some(0),
6794 data_block: b"a".to_vec()
6795 },
6796 Item {
6797 key: "key2".to_string(),
6798 flags: 0,
6799 cas_unique: Some(0),
6800 data_block: b"a".to_vec()
6801 }
6802 ]
6803 );
6804
6805 let mut c = Cursor::new(b"get key\r\nERROR\r\n".to_vec());
6806 assert!(
6807 retrieval_cmd(&mut c, b"get", None, &[b"key"])
6808 .await
6809 .is_err()
6810 )
6811 })
6812 }
6813
6814 #[test]
6815 fn test_stats() {
6816 block_on(async {
6817 let mut c =
6818 Cursor::new(b"stats\r\nSTAT version 1.2.3\r\nSTAT threads 4\r\nEND\r\n".to_vec());
6819 assert_eq!(
6820 stats_cmd(&mut c, None).await.unwrap(),
6821 HashMap::from([
6822 ("version".to_string(), "1.2.3".to_string()),
6823 ("threads".to_string(), "4".to_string()),
6824 ])
6825 );
6826
6827 let mut c = Cursor::new(b"stats settings\r\nERROR\r\n".to_vec());
6828 assert!(stats_cmd(&mut c, Some(StatsArg::Settings)).await.is_err());
6829
6830 let mut c = Cursor::new(b"stats items\r\nERROR\r\n".to_vec());
6831 assert!(stats_cmd(&mut c, Some(StatsArg::Items)).await.is_err());
6832
6833 let mut c = Cursor::new(b"stats sizes\r\nERROR\r\n".to_vec());
6834 assert!(stats_cmd(&mut c, Some(StatsArg::Sizes)).await.is_err());
6835
6836 let mut c = Cursor::new(b"stats slabs\r\nERROR\r\n".to_vec());
6837 assert!(stats_cmd(&mut c, Some(StatsArg::Slabs)).await.is_err());
6838
6839 let mut c = Cursor::new(b"stats conns\r\nERROR\r\n".to_vec());
6840 assert!(stats_cmd(&mut c, Some(StatsArg::Conns)).await.is_err())
6841 })
6842 }
6843
6844 #[test]
6845 fn test_slabs_automove() {
6846 block_on(async {
6847 let mut c = Cursor::new(b"slabs automove 0\r\nOK\r\n".to_vec());
6848 assert!(
6849 slabs_automove_cmd(&mut c, SlabsAutomoveArg::Zero)
6850 .await
6851 .is_ok()
6852 );
6853
6854 let mut c = Cursor::new(b"slabs automove 1\r\nERROR\r\n".to_vec());
6855 assert!(
6856 slabs_automove_cmd(&mut c, SlabsAutomoveArg::One)
6857 .await
6858 .is_err()
6859 );
6860
6861 let mut c = Cursor::new(b"slabs automove 2\r\nERROR\r\n".to_vec());
6862 assert!(
6863 slabs_automove_cmd(&mut c, SlabsAutomoveArg::Two)
6864 .await
6865 .is_err()
6866 )
6867 })
6868 }
6869
6870 #[test]
6871 fn test_lru_crawler() {
6872 block_on(async {
6873 let mut c = Cursor::new(b"lru_crawler enable\r\nOK\r\n".to_vec());
6874 assert!(lru_crawler_cmd(&mut c, LruCrawlerArg::Enable).await.is_ok());
6875
6876 let mut c = Cursor::new(b"lru_crawler disable\r\nERROR\r\n".to_vec());
6877 assert!(
6878 lru_crawler_cmd(&mut c, LruCrawlerArg::Disable)
6879 .await
6880 .is_err()
6881 )
6882 })
6883 }
6884
6885 #[test]
6886 fn test_lru_crawler_sleep() {
6887 block_on(async {
6888 let mut c = Cursor::new(b"lru_crawler sleep 1000000\r\nOK\r\n".to_vec());
6889 assert!(lru_crawler_sleep_cmd(&mut c, 1_000_000).await.is_ok());
6890
6891 let mut c = Cursor::new(b"lru_crawler sleep 0\r\nERROR\r\n".to_vec());
6892 assert!(lru_crawler_sleep_cmd(&mut c, 0).await.is_err())
6893 })
6894 }
6895
6896 #[test]
6897 fn test_lru_crawler_tocrawl() {
6898 block_on(async {
6899 let mut c = Cursor::new(b"lru_crawler tocrawl 0\r\nOK\r\n".to_vec());
6900 assert!(lru_crawler_tocrawl_cmd(&mut c, 0).await.is_ok());
6901
6902 let mut c = Cursor::new(b"lru_crawler tocrawl 0\r\nERROR\r\n".to_vec());
6903 assert!(lru_crawler_tocrawl_cmd(&mut c, 0).await.is_err())
6904 })
6905 }
6906
6907 #[test]
6908 fn test_lru_crawler_crawl() {
6909 block_on(async {
6910 let mut c = Cursor::new(b"lru_crawler crawl 1,2,3\r\nOK\r\n".to_vec());
6911 assert!(
6912 lru_crawler_crawl_cmd(&mut c, LruCrawlerCrawlArg::Classids(&[1, 2, 3]))
6913 .await
6914 .is_ok()
6915 );
6916
6917 let mut c = Cursor::new(b"lru_crawler crawl all\r\nERROR\r\n".to_vec());
6918 assert!(
6919 lru_crawler_crawl_cmd(&mut c, LruCrawlerCrawlArg::All)
6920 .await
6921 .is_err()
6922 )
6923 })
6924 }
6925
6926 #[test]
6927 fn test_slabs_reassign() {
6928 block_on(async {
6929 let mut c = Cursor::new(b"slabs reassign 1 10\r\nOK\r\n".to_vec());
6930 assert!(slabs_reassign_cmd(&mut c, 1, 10).await.is_ok());
6931
6932 let mut c = Cursor::new(b"slabs reassign 1 10\r\nERROR\r\n".to_vec());
6933 assert!(slabs_reassign_cmd(&mut c, 1, 10).await.is_err())
6934 })
6935 }
6936
6937 #[test]
6938 fn test_lru_crawler_metadump() {
6939 block_on(async {
6940 let mut c = Cursor::new(b"lru_crawler metadump all\r\nkey=key exp=-1 la=1745299782 cas=2 fetch=no cls=1 size=63 flags=0\r\nkey=key2 exp=-1 la=1745299782 cas=2 fetch=no cls=1 size=63 flags=0\r\nEND\r\n".to_vec());
6941 assert_eq!(
6942 lru_crawler_metadump_cmd(&mut c, LruCrawlerMetadumpArg::All)
6943 .await
6944 .unwrap(),
6945 [
6946 "key=key exp=-1 la=1745299782 cas=2 fetch=no cls=1 size=63 flags=0",
6947 "key=key2 exp=-1 la=1745299782 cas=2 fetch=no cls=1 size=63 flags=0"
6948 ]
6949 );
6950
6951 let mut c = Cursor::new(b"lru_crawler metadump 1,2,3\r\nERROR\r\n".to_vec());
6952 assert!(
6953 lru_crawler_metadump_cmd(&mut c, LruCrawlerMetadumpArg::Classids(&[1, 2, 3]))
6954 .await
6955 .is_err()
6956 );
6957
6958 let mut c = Cursor::new(b"lru_crawler metadump hash\r\nERROR\r\n".to_vec());
6959 assert!(
6960 lru_crawler_metadump_cmd(&mut c, LruCrawlerMetadumpArg::Hash)
6961 .await
6962 .is_err()
6963 )
6964 })
6965 }
6966
6967 #[test]
6968 fn test_lru_crawler_mgdump() {
6969 block_on(async {
6970 let mut c =
6971 Cursor::new(b"lru_crawler mgdump 1,2,3\r\nmg key\r\nmg key2\r\nEN\r\n".to_vec());
6972 assert_eq!(
6973 lru_crawler_mgdump_cmd(&mut c, LruCrawlerMgdumpArg::Classids(&[1, 2, 3]))
6974 .await
6975 .unwrap(),
6976 ["key", "key2"]
6977 );
6978
6979 let mut c = Cursor::new(b"lru_crawler mgdump all\r\nERROR\r\n".to_vec());
6980 assert!(
6981 lru_crawler_mgdump_cmd(&mut c, LruCrawlerMgdumpArg::All)
6982 .await
6983 .is_err()
6984 );
6985
6986 let mut c = Cursor::new(b"lru_crawler mgdump hash\r\nERROR\r\n".to_vec());
6987 assert!(
6988 lru_crawler_mgdump_cmd(&mut c, LruCrawlerMgdumpArg::Hash)
6989 .await
6990 .is_err()
6991 )
6992 })
6993 }
6994
6995 #[test]
6996 fn test_mn() {
6997 block_on(async {
6998 let mut c = Cursor::new(b"mn\r\nMN\r\n".to_vec());
6999 assert!(mn_cmd(&mut c).await.is_ok());
7000
7001 let mut c = Cursor::new(b"mn\r\nERROR\r\n".to_vec());
7002 assert!(mn_cmd(&mut c).await.is_err())
7003 })
7004 }
7005
7006 #[test]
7007 fn test_me() {
7008 block_on(async {
7009 let mut c = Cursor::new(b"me key\r\nEN\r\n".to_vec());
7010 assert!(me_cmd(&mut c, b"key").await.unwrap().is_none());
7011
7012 let mut c = Cursor::new(
7013 b"me key\r\nME key exp=-1 la=3 cas=2 fetch=no cls=1 size=63\r\n".to_vec(),
7014 );
7015 assert_eq!(
7016 me_cmd(&mut c, b"key").await.unwrap().unwrap(),
7017 "key exp=-1 la=3 cas=2 fetch=no cls=1 size=63"
7018 );
7019
7020 let mut c = Cursor::new(b"me key\r\nERROR\r\n".to_vec());
7021 assert!(me_cmd(&mut c, b"key").await.is_err());
7022 })
7023 }
7024
7025 #[test]
7026 fn test_pipeline() {
7027 block_on(async {
7028 let cmds = [
7029 b"version\r\n".to_vec(),
7030 b"quit\r\n".to_vec(),
7031 b"shutdown\r\n".to_vec(),
7032 b"cache_memlimit 1\r\n".to_vec(),
7033 b"cache_memlimit 1 noreply\r\n".to_vec(),
7034 b"flush_all\r\n".to_vec(),
7035 b"flush_all 1 noreply\r\n".to_vec(),
7036 b"cas key 0 0 5 0\r\nvalue\r\n".to_vec(),
7037 b"append key 0 0 5 noreply\r\nvalue\r\n".to_vec(),
7038 b"delete key\r\n".to_vec(),
7039 b"delete key noreply\r\n".to_vec(),
7040 b"set _ _ _ 3\r\na b\r\n".to_vec(),
7041 b"incr key 1\r\n".to_vec(),
7042 b"incr key 1 noreply\r\n".to_vec(),
7043 b"touch key 0\r\n".to_vec(),
7044 b"touch key 0 noreply\r\n".to_vec(),
7045 b"gets key\r\n".to_vec(),
7046 b"get key key2\r\n".to_vec(),
7047 b"gat 0 key key2\r\n".to_vec(),
7048 b"gats 0 key\r\n".to_vec(),
7049 b"stats\r\n".to_vec(),
7050 b"slabs automove 0\r\n".to_vec(),
7051 b"lru_crawler enable\r\n".to_vec(),
7052 b"lru_crawler disable\r\n".to_vec(),
7053 b"lru_crawler sleep 1000000\r\n".to_vec(),
7054 b"lru_crawler tocrawl 0\r\n".to_vec(),
7055 b"lru_crawler crawl 1,2,3\r\n".to_vec(),
7056 b"slabs reassign 1 10\r\n".to_vec(),
7057 b"lru_crawler metadump all\r\n".to_vec(),
7058 b"lru_crawler mgdump 3\r\n".to_vec(),
7059 b"mn\r\n".to_vec(),
7060 b"me key\r\n".to_vec(),
7061 b"mg 44OG44K544OI b c f h k l Oopaque s t u E0 N0 R0 T0 v\r\n".to_vec(),
7062 b"ms 44OG44K544OI 2 b c C0 E0 F0 I k Oopaque s T0 MS N0\r\nhi\r\n".to_vec(),
7063 b"md 44OG44K544OI b C0 E0 I k Oopaque T0 x\r\n".to_vec(),
7064 b"ma 44OG44K544OI b C0 E0 N0 J0 D0 T0 M+ Oopaque t c v k\r\n".to_vec(),
7065 b"lru mode flat\r\n".to_vec(),
7066 ];
7067 let rps = [
7068 b"VERSION 1.2.3\r\n".to_vec(),
7069 b"OK\r\n".to_vec(),
7070 b"OK\r\n".to_vec(),
7071 b"STORED\r\n".to_vec(),
7072 b"DELETED\r\n".to_vec(),
7073 b"STORED\r\n".to_vec(),
7074 b"2\r\n".to_vec(),
7075 b"TOUCHED\r\n".to_vec(),
7076 b"END\r\n".to_vec(),
7077 b"END\r\n".to_vec(),
7078 b"VALUE key 0 1 0\r\na\r\nVALUE key2 0 1 0\r\na\r\nEND\r\n".to_vec(),
7079 b"VALUE key 0 1 0\r\na\r\nEND\r\n".to_vec(),
7080 b"STAT version 1.2.3\r\nSTAT threads 4\r\nEND\r\n".to_vec(),
7081 b"OK\r\n".to_vec(),
7082 b"OK\r\n".to_vec(),
7083 b"OK\r\n".to_vec(),
7084 b"OK\r\n".to_vec(),
7085 b"OK\r\n".to_vec(),
7086 b"OK\r\n".to_vec(),
7087 b"OK\r\n".to_vec(),
7088 b"key=key exp=-1 la=1745299782 cas=2 fetch=no cls=1 size=63 flags=0\r\nkey=key2 exp=-1 la=1745299782 cas=2 fetch=no cls=1 size=63 flags=0\r\nEND\r\n".to_vec(),
7089 b"mg key\r\nmg key2\r\nEN\r\n".to_vec(),
7090 b"MN\r\n".to_vec(),
7091 b"ME key exp=-1 la=3 cas=2 fetch=no cls=1 size=63\r\n".to_vec(),
7092 b"VA 1 b c0 f0 h0 k44OG44K544OI l0 Oopaque s0 t0 W X Z\r\nA\r\n".to_vec(),
7093 b"HD b c0 k44OG44K544OI Oopaque s0\r\n".to_vec(),
7094 b"HD k44OG44K544OI Oopaque b\r\n".to_vec(),
7095 b"VA 2 Oopaque t0 c0 k44OG44K544OI b\r\n10\r\n".to_vec(),
7096 b"OK\r\n".to_vec(),
7097 ];
7098 let mut c = Cursor::new([cmds.concat(), rps.concat()].concat().to_vec());
7099 assert_eq!(
7100 execute_cmd(&mut c, &cmds).await.unwrap(),
7101 [
7102 PipelineResponse::String("1.2.3".to_string()),
7103 PipelineResponse::Unit(()),
7104 PipelineResponse::Unit(()),
7105 PipelineResponse::Unit(()),
7106 PipelineResponse::Unit(()),
7107 PipelineResponse::Unit(()),
7108 PipelineResponse::Unit(()),
7109 PipelineResponse::Bool(true),
7110 PipelineResponse::Bool(true),
7111 PipelineResponse::Bool(true),
7112 PipelineResponse::Bool(true),
7113 PipelineResponse::Unit(()),
7114 PipelineResponse::Value(Some(2)),
7115 PipelineResponse::Value(None),
7116 PipelineResponse::Bool(true),
7117 PipelineResponse::Bool(true),
7118 PipelineResponse::OptionItem(None),
7119 PipelineResponse::VecItem(Vec::new()),
7120 PipelineResponse::VecItem(vec![
7121 Item {
7122 key: "key".to_string(),
7123 flags: 0,
7124 cas_unique: Some(0),
7125 data_block: b"a".to_vec()
7126 },
7127 Item {
7128 key: "key2".to_string(),
7129 flags: 0,
7130 cas_unique: Some(0),
7131 data_block: b"a".to_vec()
7132 }
7133 ]),
7134 PipelineResponse::OptionItem(Some(Item {
7135 key: "key".to_string(),
7136 flags: 0,
7137 cas_unique: Some(0),
7138 data_block: b"a".to_vec()
7139 })),
7140 PipelineResponse::HashMap(HashMap::from([
7141 ("threads".to_string(), "4".to_string()),
7142 ("version".to_string(), "1.2.3".to_string())
7143 ])),
7144 PipelineResponse::Unit(()),
7145 PipelineResponse::Unit(()),
7146 PipelineResponse::Unit(()),
7147 PipelineResponse::Unit(()),
7148 PipelineResponse::Unit(()),
7149 PipelineResponse::Unit(()),
7150 PipelineResponse::Unit(()),
7151 PipelineResponse::VecString(vec![
7152 "key=key exp=-1 la=1745299782 cas=2 fetch=no cls=1 size=63 flags=0"
7153 .to_string(),
7154 "key=key2 exp=-1 la=1745299782 cas=2 fetch=no cls=1 size=63 flags=0"
7155 .to_string()
7156 ]),
7157 PipelineResponse::VecString(vec!["key".to_string(), "key2".to_string()]),
7158 PipelineResponse::Unit(()),
7159 PipelineResponse::OptionString(Some(
7160 "key exp=-1 la=3 cas=2 fetch=no cls=1 size=63".to_string()
7161 )),
7162 PipelineResponse::MetaGet(MgItem {
7163 success: true,
7164 base64_key: true,
7165 cas: Some(0),
7166 flags: Some(0),
7167 hit: Some(0),
7168 key: Some("44OG44K544OI".to_string()),
7169 last_access_ttl: Some(0),
7170 opaque: Some("opaque".to_string()),
7171 size: Some(0),
7172 ttl: Some(0),
7173 data_block: Some(b"A".to_vec()),
7174 won_recache: true,
7175 stale: true,
7176 already_win: true
7177 }),
7178 PipelineResponse::MetaSet(MsItem {
7179 success: true,
7180 cas: Some(0),
7181 key: Some("44OG44K544OI".to_string()),
7182 opaque: Some("opaque".to_string()),
7183 size: Some(0),
7184 base64_key: true
7185 }),
7186 PipelineResponse::MetaDelete(MdItem {
7187 success: true,
7188 key: Some("44OG44K544OI".to_string()),
7189 opaque: Some("opaque".to_string()),
7190 base64_key: true
7191 }),
7192 PipelineResponse::MetaArithmetic(MaItem {
7193 success: true,
7194 opaque: Some("opaque".to_string()),
7195 ttl: Some(0),
7196 cas: Some(0),
7197 number: Some(10),
7198 key: Some("44OG44K544OI".to_string()),
7199 base64_key: true
7200 }),
7201 PipelineResponse::Unit(()),
7202 ]
7203 );
7204
7205 let cmds = [b"version\r\n".to_vec(), b"quit\r\n".to_vec()];
7206 let rps = [b"ERROR\r\n".to_vec(), b"OK\r\n".to_vec()];
7207 let mut c = Cursor::new([cmds.concat(), rps.concat()].concat().to_vec());
7208 assert!(execute_cmd(&mut c, &cmds).await.is_err());
7209 })
7210 }
7211
7212 #[test]
7213 fn test_watch() {
7214 block_on(async {
7215 let mut c = Cursor::new(b"watch fetchers mutations evictions connevents proxyreqs proxyevents proxyuser deletions\r\nOK\r\n".to_vec());
7216 assert!(
7217 watch_cmd(
7218 &mut c,
7219 &[
7220 WatchArg::Fetchers,
7221 WatchArg::Mutations,
7222 WatchArg::Evictions,
7223 WatchArg::Connevents,
7224 WatchArg::Proxyreqs,
7225 WatchArg::Proxyevents,
7226 WatchArg::Proxyuser,
7227 WatchArg::Deletions
7228 ]
7229 )
7230 .await
7231 .is_ok()
7232 );
7233
7234 let mut c = Cursor::new(b"watch fetchers mutations\r\nERROR\r\n".to_vec());
7235 assert!(
7236 watch_cmd(&mut c, &[WatchArg::Fetchers, WatchArg::Mutations])
7237 .await
7238 .is_err()
7239 );
7240 })
7241 }
7242
7243 #[test]
7244 fn test_mg() {
7245 block_on(async {
7246 let mut c = Cursor::new(b"mg key b\r\nEN b\r\n".to_vec());
7247 assert_eq!(
7248 mg_cmd(&mut c, b"key", &[MgFlag::Base64Key]).await.unwrap(),
7249 MgItem {
7250 success: false,
7251 base64_key: true,
7252 cas: None,
7253 flags: None,
7254 hit: None,
7255 key: None,
7256 last_access_ttl: None,
7257 opaque: None,
7258 size: None,
7259 ttl: None,
7260 data_block: None,
7261 already_win: false,
7262 won_recache: false,
7263 stale: false,
7264 }
7265 );
7266
7267 let mut c = Cursor::new(b"mg 44OG44K544OI b c C0 f h k l Oopaque s t u E0 N0 R0 T0\r\nHD b c0 f0 h0 k44OG44K544OI l0 Oopaque s0 t0 W X Z\r\n".to_vec());
7268 assert_eq!(
7269 mg_cmd(
7270 &mut c,
7271 b"44OG44K544OI",
7272 &[
7273 MgFlag::Base64Key,
7274 MgFlag::ReturnCas,
7275 MgFlag::CheckCas(0),
7276 MgFlag::ReturnFlags,
7277 MgFlag::ReturnHit,
7278 MgFlag::ReturnKey,
7279 MgFlag::ReturnLastAccess,
7280 MgFlag::Opaque("opaque".to_string()),
7281 MgFlag::ReturnSize,
7282 MgFlag::ReturnTtl,
7283 MgFlag::UnBump,
7284 MgFlag::NewCas(0),
7285 MgFlag::Autovivify(0),
7286 MgFlag::RecacheTtl(0),
7287 MgFlag::UpdateTtl(0),
7288 ]
7289 )
7290 .await
7291 .unwrap(),
7292 MgItem {
7293 success: true,
7294 base64_key: true,
7295 cas: Some(0),
7296 flags: Some(0),
7297 hit: Some(0),
7298 key: Some("44OG44K544OI".to_string()),
7299 last_access_ttl: Some(0),
7300 opaque: Some("opaque".to_string()),
7301 size: Some(0),
7302 ttl: Some(0),
7303 data_block: None,
7304 already_win: true,
7305 won_recache: true,
7306 stale: true,
7307 }
7308 );
7309
7310 let mut c = Cursor::new(b"mg 44OG44K544OI b c C0 f h k l Oopaque s t u E0 N0 R0 T0 v\r\nVA 1 b c0 f0 h0 k44OG44K544OI l0 Oopaque s0 t0 W X Z\r\nA\r\n".to_vec());
7311 assert_eq!(
7312 mg_cmd(
7313 &mut c,
7314 b"44OG44K544OI",
7315 &[
7316 MgFlag::Base64Key,
7317 MgFlag::ReturnCas,
7318 MgFlag::CheckCas(0),
7319 MgFlag::ReturnFlags,
7320 MgFlag::ReturnHit,
7321 MgFlag::ReturnKey,
7322 MgFlag::ReturnLastAccess,
7323 MgFlag::Opaque("opaque".to_string()),
7324 MgFlag::ReturnSize,
7325 MgFlag::ReturnTtl,
7326 MgFlag::UnBump,
7327 MgFlag::ReturnValue,
7328 MgFlag::NewCas(0),
7329 MgFlag::Autovivify(0),
7330 MgFlag::RecacheTtl(0),
7331 MgFlag::UpdateTtl(0),
7332 ]
7333 )
7334 .await
7335 .unwrap(),
7336 MgItem {
7337 success: true,
7338 base64_key: true,
7339 cas: Some(0),
7340 flags: Some(0),
7341 hit: Some(0),
7342 key: Some("44OG44K544OI".to_string()),
7343 last_access_ttl: Some(0),
7344 opaque: Some("opaque".to_string()),
7345 size: Some(0),
7346 ttl: Some(0),
7347 data_block: Some(b"A".to_vec()),
7348 already_win: true,
7349 won_recache: true,
7350 stale: true,
7351 }
7352 );
7353
7354 let mut c = Cursor::new(
7355 b"mg 44OG44K544OI b c f h k l Oopaque s t u E0 N0 R0 T0 v\r\nERROR\r\n".to_vec(),
7356 );
7357 assert!(
7358 mg_cmd(
7359 &mut c,
7360 b"44OG44K544OI",
7361 &[
7362 MgFlag::Base64Key,
7363 MgFlag::ReturnCas,
7364 MgFlag::ReturnFlags,
7365 MgFlag::ReturnHit,
7366 MgFlag::ReturnKey,
7367 MgFlag::ReturnLastAccess,
7368 MgFlag::Opaque("opaque".to_string()),
7369 MgFlag::ReturnSize,
7370 MgFlag::ReturnTtl,
7371 MgFlag::UnBump,
7372 MgFlag::ReturnValue,
7373 MgFlag::NewCas(0),
7374 MgFlag::Autovivify(0),
7375 MgFlag::RecacheTtl(0),
7376 MgFlag::UpdateTtl(0),
7377 ]
7378 )
7379 .await
7380 .is_err(),
7381 );
7382 })
7383 }
7384
7385 #[test]
7386 fn test_ms() {
7387 block_on(async {
7388 let mut c = Cursor::new(
7389 b"ms 44OG44K544OI 2 b c C0 E0 F0 I k Oopaque s T0 MP N0\r\nhi\r\nNF\r\n".to_vec(),
7390 );
7391 assert_eq!(
7392 ms_cmd(
7393 &mut c,
7394 b"44OG44K544OI",
7395 &[
7396 MsFlag::Base64Key,
7397 MsFlag::ReturnCas,
7398 MsFlag::CompareCas(0),
7399 MsFlag::NewCas(0),
7400 MsFlag::SetFlags(0),
7401 MsFlag::Invalidate,
7402 MsFlag::ReturnKey,
7403 MsFlag::Opaque("opaque".to_string()),
7404 MsFlag::ReturnSize,
7405 MsFlag::Ttl(0),
7406 MsFlag::Mode(MsMode::Prepend),
7407 MsFlag::Autovivify(0)
7408 ],
7409 b"hi"
7410 )
7411 .await
7412 .unwrap(),
7413 MsItem {
7414 success: false,
7415 cas: None,
7416 key: None,
7417 opaque: None,
7418 size: None,
7419 base64_key: false
7420 }
7421 );
7422
7423 let mut c = Cursor::new(b"ms 44OG44K544OI 2 MR\r\nhi\r\nEX\r\n".to_vec());
7424 assert_eq!(
7425 ms_cmd(
7426 &mut c,
7427 b"44OG44K544OI",
7428 &[MsFlag::Mode(MsMode::Replace)],
7429 b"hi"
7430 )
7431 .await
7432 .unwrap(),
7433 MsItem {
7434 success: false,
7435 cas: None,
7436 key: None,
7437 opaque: None,
7438 size: None,
7439 base64_key: false
7440 }
7441 );
7442
7443 let mut c = Cursor::new(
7444 b"ms 44OG44K544OI 2 b c C0 E0 F0 I k Oopaque s T0 ME N0\r\nhi\r\nNS\r\n".to_vec(),
7445 );
7446 assert_eq!(
7447 ms_cmd(
7448 &mut c,
7449 b"44OG44K544OI",
7450 &[
7451 MsFlag::Base64Key,
7452 MsFlag::ReturnCas,
7453 MsFlag::CompareCas(0),
7454 MsFlag::NewCas(0),
7455 MsFlag::SetFlags(0),
7456 MsFlag::Invalidate,
7457 MsFlag::ReturnKey,
7458 MsFlag::Opaque("opaque".to_string()),
7459 MsFlag::ReturnSize,
7460 MsFlag::Ttl(0),
7461 MsFlag::Mode(MsMode::Add),
7462 MsFlag::Autovivify(0)
7463 ],
7464 b"hi"
7465 )
7466 .await
7467 .unwrap(),
7468 MsItem {
7469 success: false,
7470 cas: None,
7471 key: None,
7472 opaque: None,
7473 size: None,
7474 base64_key: false
7475 }
7476 );
7477
7478 let mut c = Cursor::new(
7479 b"ms 44OG44K544OI 2 b c C0 E0 F0 I k Oopaque s T0 ME N0\r\nhi\r\nERROR\r\n"
7480 .to_vec(),
7481 );
7482 assert!(
7483 ms_cmd(
7484 &mut c,
7485 b"44OG44K544OI",
7486 &[
7487 MsFlag::Base64Key,
7488 MsFlag::ReturnCas,
7489 MsFlag::CompareCas(0),
7490 MsFlag::NewCas(0),
7491 MsFlag::SetFlags(0),
7492 MsFlag::Invalidate,
7493 MsFlag::ReturnKey,
7494 MsFlag::Opaque("opaque".to_string()),
7495 MsFlag::ReturnSize,
7496 MsFlag::Ttl(0),
7497 MsFlag::Mode(MsMode::Append),
7498 MsFlag::Autovivify(0)
7499 ],
7500 b"hi"
7501 )
7502 .await
7503 .is_err()
7504 );
7505
7506 let mut c = Cursor::new(
7507 b"ms 44OG44K544OI 2 b c C0 E0 F0 I k Oopaque s T0 MS N0\r\nhi\r\nHD b c0 k44OG44K544OI Oopaque s0\r\n".to_vec(),
7508 );
7509 assert_eq!(
7510 ms_cmd(
7511 &mut c,
7512 b"44OG44K544OI",
7513 &[
7514 MsFlag::Base64Key,
7515 MsFlag::ReturnCas,
7516 MsFlag::CompareCas(0),
7517 MsFlag::NewCas(0),
7518 MsFlag::SetFlags(0),
7519 MsFlag::Invalidate,
7520 MsFlag::ReturnKey,
7521 MsFlag::Opaque("opaque".to_string()),
7522 MsFlag::ReturnSize,
7523 MsFlag::Ttl(0),
7524 MsFlag::Mode(MsMode::Set),
7525 MsFlag::Autovivify(0)
7526 ],
7527 b"hi"
7528 )
7529 .await
7530 .unwrap(),
7531 MsItem {
7532 success: true,
7533 cas: Some(0),
7534 key: Some("44OG44K544OI".to_string()),
7535 opaque: Some("opaque".to_string()),
7536 size: Some(0),
7537 base64_key: true
7538 }
7539 );
7540 })
7541 }
7542
7543 #[test]
7544 fn test_md() {
7545 block_on(async {
7546 let mut c = Cursor::new(b"md 44OG44K544OI b C0 E0 I k Oopaque T0 x\r\nNF\r\n".to_vec());
7547 assert_eq!(
7548 md_cmd(
7549 &mut c,
7550 b"44OG44K544OI",
7551 &[
7552 MdFlag::Base64Key,
7553 MdFlag::CompareCas(0),
7554 MdFlag::NewCas(0),
7555 MdFlag::Invalidate,
7556 MdFlag::ReturnKey,
7557 MdFlag::Opaque("opaque".to_string()),
7558 MdFlag::UpdateTtl(0),
7559 MdFlag::LeaveKey,
7560 ]
7561 )
7562 .await
7563 .unwrap(),
7564 MdItem {
7565 success: false,
7566 key: None,
7567 opaque: None,
7568 base64_key: false,
7569 }
7570 );
7571
7572 let mut c = Cursor::new(b"md 44OG44K544OI\r\nEX\r\n".to_vec());
7573 assert_eq!(
7574 md_cmd(&mut c, b"44OG44K544OI", &[]).await.unwrap(),
7575 MdItem {
7576 success: false,
7577 key: None,
7578 opaque: None,
7579 base64_key: false,
7580 }
7581 );
7582
7583 let mut c = Cursor::new(
7584 b"md 44OG44K544OI b C0 E0 I k Oopaque T0 x\r\nHD k44OG44K544OI Oopaque b\r\n"
7585 .to_vec(),
7586 );
7587 assert_eq!(
7588 md_cmd(
7589 &mut c,
7590 b"44OG44K544OI",
7591 &[
7592 MdFlag::Base64Key,
7593 MdFlag::CompareCas(0),
7594 MdFlag::NewCas(0),
7595 MdFlag::Invalidate,
7596 MdFlag::ReturnKey,
7597 MdFlag::Opaque("opaque".to_string()),
7598 MdFlag::UpdateTtl(0),
7599 MdFlag::LeaveKey,
7600 ]
7601 )
7602 .await
7603 .unwrap(),
7604 MdItem {
7605 success: true,
7606 key: Some("44OG44K544OI".to_string()),
7607 opaque: Some("opaque".to_string()),
7608 base64_key: true
7609 }
7610 );
7611
7612 let mut c =
7613 Cursor::new(b"md 44OG44K544OI b C0 E0 I k Oopaque T0 x\r\nERROR\r\n".to_vec());
7614 assert!(
7615 md_cmd(
7616 &mut c,
7617 b"44OG44K544OI",
7618 &[
7619 MdFlag::Base64Key,
7620 MdFlag::CompareCas(0),
7621 MdFlag::NewCas(0),
7622 MdFlag::Invalidate,
7623 MdFlag::ReturnKey,
7624 MdFlag::Opaque("opaque".to_string()),
7625 MdFlag::UpdateTtl(0),
7626 MdFlag::LeaveKey,
7627 ]
7628 )
7629 .await
7630 .is_err(),
7631 )
7632 })
7633 }
7634
7635 #[test]
7636 fn test_ma() {
7637 block_on(async {
7638 let mut c = Cursor::new(
7639 b"ma 44OG44K544OI b C0 E0 N0 J0 D0 T0 M+ Oopaque t c v k\r\nNF\r\n".to_vec(),
7640 );
7641 assert_eq!(
7642 ma_cmd(
7643 &mut c,
7644 b"44OG44K544OI",
7645 &[
7646 MaFlag::Base64Key,
7647 MaFlag::CompareCas(0),
7648 MaFlag::NewCas(0),
7649 MaFlag::AutoCreate(0),
7650 MaFlag::InitValue(0),
7651 MaFlag::DeltaApply(0),
7652 MaFlag::UpdateTtl(0),
7653 MaFlag::Mode(MaMode::Incr),
7654 MaFlag::Opaque("opaque".to_string()),
7655 MaFlag::ReturnTtl,
7656 MaFlag::ReturnCas,
7657 MaFlag::ReturnValue,
7658 MaFlag::ReturnKey,
7659 ],
7660 )
7661 .await
7662 .unwrap(),
7663 MaItem {
7664 success: false,
7665 opaque: None,
7666 ttl: None,
7667 cas: None,
7668 number: None,
7669 key: None,
7670 base64_key: false,
7671 }
7672 );
7673
7674 let mut c = Cursor::new(
7675 b"ma 44OG44K544OI b C0 E0 N0 J0 D0 T0 M+ Oopaque t c v k\r\nNS Oopaque t0 c0 k44OG44K544OI b\r\n"
7676 .to_vec(),
7677 );
7678 assert_eq!(
7679 ma_cmd(
7680 &mut c,
7681 b"44OG44K544OI",
7682 &[
7683 MaFlag::Base64Key,
7684 MaFlag::CompareCas(0),
7685 MaFlag::NewCas(0),
7686 MaFlag::AutoCreate(0),
7687 MaFlag::InitValue(0),
7688 MaFlag::DeltaApply(0),
7689 MaFlag::UpdateTtl(0),
7690 MaFlag::Mode(MaMode::Incr),
7691 MaFlag::Opaque("opaque".to_string()),
7692 MaFlag::ReturnTtl,
7693 MaFlag::ReturnCas,
7694 MaFlag::ReturnValue,
7695 MaFlag::ReturnKey,
7696 ],
7697 )
7698 .await
7699 .unwrap(),
7700 MaItem {
7701 success: false,
7702 opaque: Some("opaque".to_string()),
7703 ttl: Some(0),
7704 cas: Some(0),
7705 number: None,
7706 key: Some("44OG44K544OI".to_string()),
7707 base64_key: true,
7708 }
7709 );
7710
7711 let mut c = Cursor::new(b"ma 44OG44K544OI\r\nEX\r\n".to_vec());
7712 assert_eq!(
7713 ma_cmd(&mut c, b"44OG44K544OI", &[],).await.unwrap(),
7714 MaItem {
7715 success: false,
7716 opaque: None,
7717 ttl: None,
7718 cas: None,
7719 number: None,
7720 key: None,
7721 base64_key: false,
7722 }
7723 );
7724 let mut c = Cursor::new(b"ma 44OG44K544OI\r\nHD\r\n".to_vec());
7725 assert_eq!(
7726 ma_cmd(&mut c, b"44OG44K544OI", &[],).await.unwrap(),
7727 MaItem {
7728 success: true,
7729 opaque: None,
7730 ttl: None,
7731 cas: None,
7732 number: None,
7733 key: None,
7734 base64_key: false,
7735 }
7736 );
7737
7738 let mut c = Cursor::new(
7739 b"ma 44OG44K544OI b C0 E0 N0 J0 D0 T0 M+ Oopaque t c v k\r\nVA 2 Oopaque t0 c0 k44OG44K544OI b\r\n10\r\n"
7740 .to_vec(),
7741 );
7742 assert_eq!(
7743 ma_cmd(
7744 &mut c,
7745 b"44OG44K544OI",
7746 &[
7747 MaFlag::Base64Key,
7748 MaFlag::CompareCas(0),
7749 MaFlag::NewCas(0),
7750 MaFlag::AutoCreate(0),
7751 MaFlag::InitValue(0),
7752 MaFlag::DeltaApply(0),
7753 MaFlag::UpdateTtl(0),
7754 MaFlag::Mode(MaMode::Incr),
7755 MaFlag::Opaque("opaque".to_string()),
7756 MaFlag::ReturnTtl,
7757 MaFlag::ReturnCas,
7758 MaFlag::ReturnValue,
7759 MaFlag::ReturnKey,
7760 ],
7761 )
7762 .await
7763 .unwrap(),
7764 MaItem {
7765 success: true,
7766 opaque: Some("opaque".to_string()),
7767 ttl: Some(0),
7768 cas: Some(0),
7769 number: Some(10),
7770 key: Some("44OG44K544OI".to_string()),
7771 base64_key: true,
7772 }
7773 );
7774
7775 let mut c = Cursor::new(
7776 b"ma 44OG44K544OI b C0 E0 N0 J0 D0 T0 M+ Oopaque t c v k\r\nERROR\r\n".to_vec(),
7777 );
7778 assert!(
7779 ma_cmd(
7780 &mut c,
7781 b"44OG44K544OI",
7782 &[
7783 MaFlag::Base64Key,
7784 MaFlag::CompareCas(0),
7785 MaFlag::NewCas(0),
7786 MaFlag::AutoCreate(0),
7787 MaFlag::InitValue(0),
7788 MaFlag::DeltaApply(0),
7789 MaFlag::UpdateTtl(0),
7790 MaFlag::Mode(MaMode::Decr),
7791 MaFlag::Opaque("opaque".to_string()),
7792 MaFlag::ReturnTtl,
7793 MaFlag::ReturnCas,
7794 MaFlag::ReturnValue,
7795 MaFlag::ReturnKey,
7796 ],
7797 )
7798 .await
7799 .is_err()
7800 )
7801 })
7802 }
7803
7804 #[test]
7805 fn test_lru() {
7806 block_on(async {
7807 let mut c = Cursor::new(b"lru mode flat\r\nERROR\r\n".to_vec());
7808 assert!(lru_cmd(&mut c, LruArg::Mode(LruMode::Flat)).await.is_err());
7809
7810 let mut c = Cursor::new(b"lru mode segmented\r\nOK\r\n".to_vec());
7811 assert!(
7812 lru_cmd(&mut c, LruArg::Mode(LruMode::Segmented))
7813 .await
7814 .is_ok()
7815 );
7816
7817 let mut c = Cursor::new(b"lru tune 10 25 0.1 2\r\nOK\r\n".to_vec());
7818 assert!(
7819 lru_cmd(
7820 &mut c,
7821 LruArg::Tune {
7822 percent_hot: 10,
7823 percent_warm: 25,
7824 max_hot_factor: 0.1,
7825 max_warm_factor: 2.0
7826 }
7827 )
7828 .await
7829 .is_ok()
7830 );
7831
7832 let mut c = Cursor::new(b"lru temp_ttl 0\r\nOK\r\n".to_vec());
7833 assert!(lru_cmd(&mut c, LruArg::TempTtl(0)).await.is_ok())
7834 })
7835 }
7836}