1#![forbid(unsafe_code)]
10#![warn(missing_docs)]
11
12pub use kevy_resp::Reply;
13
14pub mod backup;
17
18pub mod migrate;
21
22pub const DEFAULT_HOST: &str = "127.0.0.1";
26pub const DEFAULT_PORT: u16 = 6379;
28
29pub mod bulk;
32
33pub mod shadow;
36
37pub mod backfill_keys;
40pub(crate) mod collections;
41pub mod doctor;
42pub mod lint;
43
44pub fn route_tool(args: &[String]) -> Option<std::process::ExitCode> {
48 let rest = args.get(1..).unwrap_or(&[]);
49 match args.first().map(String::as_str)? {
50 "doctor" => Some(doctor::run_doctor_cli(rest)),
51 "shadow" => Some(shadow::run_shadow_cli(rest)),
52 "lint" => Some(lint::run_lint_cli(rest)),
53 "backfill-keys" => Some(backfill_keys::run_backfill_keys_cli(rest)),
54 _ => None,
55 }
56}
57
58pub fn format_reply(reply: &Reply, indent: usize) -> String {
61 match reply {
62 Reply::Simple(s) => String::from_utf8_lossy(s).into_owned(),
63 Reply::Error(s) | Reply::BlobError(s) => {
64 format!("(error) {}", String::from_utf8_lossy(s))
65 }
66 Reply::Int(n) => format!("(integer) {n}"),
67 Reply::Bulk(b) => format!("\"{}\"", String::from_utf8_lossy(b)),
68 Reply::Nil | Reply::Null => "(nil)".to_string(),
69 Reply::Array(items) if items.is_empty() => "(empty array)".to_string(),
70 Reply::Array(items) | Reply::Set(items) | Reply::Push(items) => {
71 let pad = " ".repeat(indent);
72 items
73 .iter()
74 .enumerate()
75 .map(|(i, it)| format!("{pad}{}) {}", i + 1, format_reply(it, indent + 1)))
76 .collect::<Vec<_>>()
77 .join("\n")
78 }
79 Reply::Map(pairs) if pairs.is_empty() => "(empty map)".to_string(),
81 Reply::Map(pairs) => {
82 let pad = " ".repeat(indent);
83 pairs
84 .iter()
85 .enumerate()
86 .map(|(i, (k, v))| {
87 format!(
88 "{pad}{}) {} => {}",
89 i + 1,
90 format_reply(k, indent + 1),
91 format_reply(v, indent + 1)
92 )
93 })
94 .collect::<Vec<_>>()
95 .join("\n")
96 }
97 Reply::Double(v) => format!("(double) {v}"),
98 Reply::Boolean(b) => format!("(boolean) {}", if *b { "t" } else { "f" }),
99 Reply::Verbatim { fmt, data } => format!(
100 "(verbatim/{}) \"{}\"",
101 String::from_utf8_lossy(fmt),
102 String::from_utf8_lossy(data)
103 ),
104 Reply::BigNumber(s) => format!("(bignum) {}", String::from_utf8_lossy(s)),
105 }
106}