Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions crates/ember-cli/src/bench_conn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use ember_protocol::parse::parse_frame;
use ember_protocol::types::Frame;
use tokio::io::{AsyncReadExt, AsyncWriteExt};

use crate::connection::auth_frame;
use crate::tls::{self, MaybeTlsStream, TlsClientConfig};

/// Read buffer size for benchmark connections (256 KiB).
Expand Down Expand Up @@ -49,10 +50,7 @@ impl BenchConnection {

/// Authenticates with the server using AUTH.
pub async fn authenticate(&mut self, password: &str) -> Result<(), String> {
let frame = Frame::Array(vec![
Frame::Bulk(Bytes::from_static(b"AUTH")),
Frame::Bulk(Bytes::from(password.to_string())),
]);
let frame = auth_frame(password);
let mut buf = BytesMut::new();
frame.serialize(&mut buf);

Expand Down
19 changes: 17 additions & 2 deletions crates/ember-cli/src/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,12 @@ impl Connection {

/// Authenticates with the server using the AUTH command.
pub async fn authenticate(&mut self, password: &str) -> Result<(), ConnectionError> {
let tokens = vec!["AUTH".to_string(), password.to_string()];
let response = self.send_command(&tokens).await?;
let frame = auth_frame(password);
self.write_buf.clear();
frame.serialize(&mut self.write_buf);
self.stream.write_all(&self.write_buf).await?;
self.stream.flush().await?;
let response = self.read_response().await?;

match &response {
Frame::Simple(s) if s == "OK" => Ok(()),
Expand Down Expand Up @@ -167,3 +171,14 @@ impl Connection {
}
}
}

/// Builds an AUTH command frame from a password string.
///
/// Shared by the interactive REPL connection and the benchmark connection so
/// the AUTH wire format is defined in exactly one place.
pub fn auth_frame(password: &str) -> Frame {
Frame::Array(vec![
Frame::Bulk(bytes::Bytes::from_static(b"AUTH")),
Frame::Bulk(bytes::Bytes::from(password.to_string())),
])
}
24 changes: 17 additions & 7 deletions crates/ember-cli/src/repl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ use crate::connection::{Connection, ConnectionError};
use crate::format::format_response;
use crate::tls::TlsClientConfig;

// ANSI escape sequences for terminal coloring. Defined as constants so a
// color change requires updating one place rather than grep-and-replace.
const RESET: &str = "\x1b[0m";
const GREEN: &str = "\x1b[32m";
const RED: &str = "\x1b[31m";
const BOLD_CYAN: &str = "\x1b[1;36m";
const DIM: &str = "\x1b[2m";

/// Runs the interactive REPL loop.
///
/// Blocks the calling thread. Uses `tokio::runtime::Runtime` internally
Expand Down Expand Up @@ -449,9 +457,9 @@ impl Highlighter for EmberHelper {
|| LOCAL_COMMANDS.iter().any(|c| c.eq_ignore_ascii_case(first));

let highlighted_cmd = if is_known {
format!("\x1b[1;36m{first}\x1b[0m") // bold cyan
format!("{BOLD_CYAN}{first}{RESET}") // bold cyan
} else {
format!("\x1b[31m{first}\x1b[0m") // red
format!("{RED}{first}{RESET}") // red
};

// highlight quoted strings in rest
Expand All @@ -474,7 +482,7 @@ impl Highlighter for EmberHelper {
}

fn highlight_hint<'h>(&self, hint: &'h str) -> Cow<'h, str> {
Cow::Owned(format!("\x1b[2m{hint}\x1b[0m")) // dim
Cow::Owned(format!("{DIM}{hint}{RESET}")) // dim
}

fn highlight_char(
Expand All @@ -495,7 +503,8 @@ fn highlight_quotes(s: &str) -> String {
while let Some(ch) = chars.next() {
match ch {
'"' => {
out.push_str("\x1b[32m\""); // green
out.push_str(GREEN);
out.push('"');
loop {
match chars.next() {
None => break,
Expand All @@ -512,10 +521,11 @@ fn highlight_quotes(s: &str) -> String {
Some(c) => out.push(c),
}
}
out.push_str("\x1b[0m"); // reset
out.push_str(RESET);
}
'\'' => {
out.push_str("\x1b[32m'"); // green
out.push_str(GREEN);
out.push('\'');
loop {
match chars.next() {
None => break,
Expand All @@ -526,7 +536,7 @@ fn highlight_quotes(s: &str) -> String {
Some(c) => out.push(c),
}
}
out.push_str("\x1b[0m"); // reset
out.push_str(RESET);
}
_ => out.push(ch),
}
Expand Down