use crate::core::geometry::Rect;
use crate::core::event::Event;
use crate::core::palette::colors;
use crate::core::draw::DrawBuffer;
use crate::terminal::Terminal;
use super::view::{View, write_line_to_terminal};
pub struct ParamText {
bounds: Rect,
template: String,
text: String,
}
impl ParamText {
pub fn new(bounds: Rect, template: &str) -> Self {
Self {
bounds,
template: template.to_string(),
text: template.to_string(),
}
}
pub fn set_template(&mut self, template: &str) {
self.template = template.to_string();
self.text = template.to_string();
}
pub fn set_param_str(&mut self, value: &str) {
self.text = self.template.replacen("%s", value, 1);
}
pub fn set_params_str(&mut self, values: &[&str]) {
let mut result = self.template.clone();
for value in values {
result = result.replacen("%s", value, 1);
}
self.text = result;
}
pub fn set_param_num(&mut self, value: i64) {
let value_str = value.to_string();
self.text = self.template.replacen("%d", &value_str, 1);
}
pub fn set_params(&mut self, str_params: &[&str], num_params: &[i64]) {
let mut result = self.template.clone();
for value in str_params {
result = result.replacen("%s", value, 1);
}
for value in num_params {
let value_str = value.to_string();
result = result.replacen("%d", &value_str, 1);
}
result = result.replace("%%", "%");
self.text = result;
}
pub fn get_text(&self) -> &str {
&self.text
}
pub fn get_template(&self) -> &str {
&self.template
}
}
impl View for ParamText {
fn bounds(&self) -> Rect {
self.bounds
}
fn set_bounds(&mut self, bounds: Rect) {
self.bounds = bounds;
}
fn draw(&mut self, terminal: &mut Terminal) {
let width = self.bounds.width() as usize;
let height = self.bounds.height() as usize;
let lines: Vec<&str> = self.text.lines().collect();
for (i, line) in lines.iter().enumerate() {
if i >= height {
break;
}
let mut buf = DrawBuffer::new(width);
buf.move_char(0, ' ', colors::DIALOG_NORMAL, width);
let display_text = if line.len() > width {
&line[..width]
} else {
line
};
buf.move_str(0, display_text, colors::DIALOG_NORMAL);
write_line_to_terminal(terminal, self.bounds.a.x, self.bounds.a.y + i as i16, &buf);
}
for i in lines.len()..height {
let mut buf = DrawBuffer::new(width);
buf.move_char(0, ' ', colors::DIALOG_NORMAL, width);
write_line_to_terminal(terminal, self.bounds.a.x, self.bounds.a.y + i as i16, &buf);
}
}
fn handle_event(&mut self, _event: &mut Event) {
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_paramtext_creation() {
let param_text = ParamText::new(Rect::new(0, 0, 20, 1), "Hello %s");
assert_eq!(param_text.get_template(), "Hello %s");
assert_eq!(param_text.get_text(), "Hello %s");
}
#[test]
fn test_paramtext_set_param_str() {
let mut param_text = ParamText::new(Rect::new(0, 0, 20, 1), "Hello %s");
param_text.set_param_str("World");
assert_eq!(param_text.get_text(), "Hello World");
}
#[test]
fn test_paramtext_set_param_num() {
let mut param_text = ParamText::new(Rect::new(0, 0, 20, 1), "Count: %d");
param_text.set_param_num(42);
assert_eq!(param_text.get_text(), "Count: 42");
}
#[test]
fn test_paramtext_multiple_params() {
let mut param_text = ParamText::new(
Rect::new(0, 0, 40, 1),
"File: %s, Size: %d bytes"
);
param_text.set_params(&["test.txt"], &[1024]);
assert_eq!(param_text.get_text(), "File: test.txt, Size: 1024 bytes");
}
#[test]
fn test_paramtext_multiple_strings() {
let mut param_text = ParamText::new(
Rect::new(0, 0, 40, 1),
"From %s to %s"
);
param_text.set_params_str(&["Alice", "Bob"]);
assert_eq!(param_text.get_text(), "From Alice to Bob");
}
#[test]
fn test_paramtext_escape_percent() {
let mut param_text = ParamText::new(
Rect::new(0, 0, 30, 1),
"Progress: %d%%"
);
param_text.set_params(&[], &[75]);
assert_eq!(param_text.get_text(), "Progress: 75%");
}
#[test]
fn test_paramtext_set_template() {
let mut param_text = ParamText::new(Rect::new(0, 0, 20, 1), "Hello %s");
param_text.set_param_str("World");
assert_eq!(param_text.get_text(), "Hello World");
param_text.set_template("Goodbye %s");
param_text.set_param_str("Moon");
assert_eq!(param_text.get_text(), "Goodbye Moon");
}
#[test]
fn test_paramtext_complex() {
let mut param_text = ParamText::new(
Rect::new(0, 0, 60, 1),
"User: %s, Files: %d, Size: %d MB (%d%%)"
);
param_text.set_params(&["admin"], &[150, 2048, 95]);
assert_eq!(param_text.get_text(), "User: admin, Files: 150, Size: 2048 MB (95%)");
}
}