use crate::config::ShellConfig;
use core::marker::PhantomData;
#[derive(Debug, Clone, PartialEq)]
pub struct Response<C: ShellConfig> {
pub message: heapless::String<256>,
pub inline_message: bool,
pub prefix_newline: bool,
pub indent_message: bool,
pub postfix_newline: bool,
pub show_prompt: bool,
#[cfg(feature = "history")]
pub exclude_from_history: bool,
_phantom: PhantomData<C>,
}
impl<C: ShellConfig> Response<C> {
pub fn success(message: &str) -> Self {
let mut msg = heapless::String::new();
let _ = msg.push_str(message);
Self {
message: msg,
inline_message: false,
prefix_newline: false,
indent_message: false,
postfix_newline: true,
show_prompt: true,
#[cfg(feature = "history")]
exclude_from_history: false,
_phantom: PhantomData,
}
}
#[cfg(feature = "history")]
pub fn success_no_history(message: &str) -> Self {
let mut response = Self::success(message);
response.exclude_from_history = true;
response
}
#[cfg(feature = "history")]
pub fn without_history(mut self) -> Self {
self.exclude_from_history = true;
self
}
pub fn inline(mut self) -> Self {
self.inline_message = true;
self
}
pub fn with_prefix_newline(mut self) -> Self {
self.prefix_newline = true;
self
}
pub fn indented(mut self) -> Self {
self.indent_message = true;
self
}
pub fn without_postfix_newline(mut self) -> Self {
self.postfix_newline = false;
self
}
pub fn without_prompt(mut self) -> Self {
self.show_prompt = false;
self
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::config::DefaultConfig;
#[test]
fn test_success_response() {
let response = Response::<DefaultConfig>::success("OK");
assert_eq!(response.message.as_str(), "OK");
assert!(!response.inline_message);
assert!(!response.prefix_newline);
assert!(!response.indent_message);
assert!(response.postfix_newline);
assert!(response.show_prompt);
#[cfg(feature = "history")]
assert!(!response.exclude_from_history);
}
#[test]
fn test_response_empty_message() {
let response = Response::<DefaultConfig>::success("");
assert_eq!(response.message.as_str(), "");
}
#[test]
fn test_response_long_message() {
let long_msg = "A".repeat(250);
let response = Response::<DefaultConfig>::success(&long_msg);
assert_eq!(
response.message.len(),
250,
"Message within capacity should be preserved"
);
let too_long_msg = "B".repeat(300);
let response = Response::<DefaultConfig>::success(&too_long_msg);
assert_eq!(
response.message.len(),
0,
"Message exceeding capacity results in empty message (heapless limitation)"
);
}
#[test]
fn test_builder_chaining() {
let response = Response::<DefaultConfig>::success("OK")
.inline()
.with_prefix_newline()
.indented()
.without_postfix_newline()
.without_prompt();
assert_eq!(response.message.as_str(), "OK");
assert!(response.inline_message);
assert!(response.prefix_newline);
assert!(response.indent_message);
assert!(!response.postfix_newline);
assert!(!response.show_prompt);
}
#[test]
#[cfg(feature = "history")]
fn test_response_exclude_from_history_default() {
let response = Response::<DefaultConfig>::success("Test");
assert!(!response.exclude_from_history);
}
#[test]
#[cfg(feature = "history")]
fn test_response_success_no_history() {
let response = Response::<DefaultConfig>::success_no_history("Sensitive data");
assert!(response.exclude_from_history);
assert_eq!(response.message.as_str(), "Sensitive data");
}
#[test]
#[cfg(feature = "history")]
fn test_response_without_history_builder() {
let response = Response::<DefaultConfig>::success("Password set").without_history();
assert!(response.exclude_from_history);
}
#[test]
#[cfg(feature = "history")]
fn test_builder_chaining_with_history() {
let response = Response::<DefaultConfig>::success("OK")
.inline()
.with_prefix_newline()
.indented()
.without_postfix_newline()
.without_prompt()
.without_history();
assert_eq!(response.message.as_str(), "OK");
assert!(response.inline_message);
assert!(response.prefix_newline);
assert!(response.indent_message);
assert!(!response.postfix_newline);
assert!(!response.show_prompt);
assert!(response.exclude_from_history);
}
}