#![cfg_attr(docsrs, feature(doc_cfg))]
#![deny(missing_docs)]
#![warn(clippy::all)]
#![doc(html_root_url = "https://docs.rs/boxen")]
#![doc(html_logo_url = "https://raw.githubusercontent.com/sabry-awad97/boxen/main/assets/logo.png")]
#![doc(
html_favicon_url = "https://raw.githubusercontent.com/sabry-awad97/boxen/main/assets/favicon.ico"
)]
pub mod borders;
pub mod color;
pub mod error;
pub mod memory;
pub mod options;
pub mod render;
pub mod terminal;
pub mod text;
pub mod validation;
#[cfg(test)]
mod error_tests;
pub use error::{BoxenError, BoxenResult, ErrorRecommendation};
pub use options::{
BorderChars, BorderStyle, BoxenBuilder, BoxenOptions, Color, DimensionConstraints, Float,
FullscreenMode, Height, LayoutDimensions, Spacing, TextAlignment, TitleAlignment, Width,
};
pub use render::boxen;
pub use validation::{
MinimumDimensions, ValidationResult, auto_adjust_options, calculate_minimum_dimensions,
suggest_optimal_dimensions, validate_configuration,
};
pub use terminal::{get_terminal_height, get_terminal_size, get_terminal_width};
#[must_use]
pub fn builder() -> BoxenBuilder {
BoxenBuilder::new()
}
pub fn simple_box<S: AsRef<str>>(text: S) -> String {
let text_ref = text.as_ref();
boxen(text_ref, None).unwrap_or_else(|_| text_ref.to_string())
}
pub fn double_box<S: AsRef<str>>(text: S) -> String {
let text_ref = text.as_ref();
let options = BoxenOptions {
border_style: BorderStyle::Double,
..Default::default()
};
boxen(text_ref, Some(options)).unwrap_or_else(|_| text_ref.to_string())
}
pub fn round_box<S: AsRef<str>>(text: S) -> String {
let text_ref = text.as_ref();
let options = BoxenOptions {
border_style: BorderStyle::Round,
..Default::default()
};
boxen(text_ref, Some(options)).unwrap_or_else(|_| text_ref.to_string())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_basic_boxen() {
let result = boxen("Hello", None);
assert!(result.is_ok());
let box_str = result.unwrap();
assert!(box_str.contains("Hello"));
}
#[test]
fn test_builder_pattern() {
let builder = builder();
assert!(builder.render("Test").is_ok());
}
#[test]
fn test_builder_fluent_interface() {
let result = builder()
.border_style(BorderStyle::Double)
.padding(2)
.margin(1)
.text_alignment(TextAlignment::Center)
.title("Builder Test")
.width(50)
.border_color("blue")
.render("Testing fluent interface");
assert!(result.is_ok());
let output = result.unwrap();
assert!(output.contains("Testing fluent interface"));
assert!(output.contains("Builder Test"));
}
#[test]
fn test_builder_validation() {
let result = builder()
.width(5) .padding(10) .render("Test");
assert!(result.is_err());
}
#[test]
fn test_builder_convenience_methods() {
let result = builder()
.spacing(1) .colors("red", "white") .size(50, 8) .center_all() .title("Convenience Test")
.render("Testing convenience methods");
assert!(result.is_ok());
let output = result.unwrap();
assert!(output.contains("Testing convenience methods"));
assert!(output.contains("Convenience Test"));
}
#[test]
fn test_convenience_functions() {
assert!(simple_box("Test").contains("Test"));
assert!(double_box("Test").contains("Test"));
assert!(round_box("Test").contains("Test"));
}
#[test]
fn test_spacing_from_usize() {
let spacing = Spacing::from(2);
assert_eq!(spacing.top, 2);
assert_eq!(spacing.right, 6); assert_eq!(spacing.bottom, 2);
assert_eq!(spacing.left, 6); }
#[test]
fn test_spacing_from_tuple() {
let spacing = Spacing::from((1, 2, 3, 4));
assert_eq!(spacing.top, 1);
assert_eq!(spacing.right, 2);
assert_eq!(spacing.bottom, 3);
assert_eq!(spacing.left, 4);
}
#[test]
fn test_color_from_string() {
let color = Color::from("red");
matches!(color, Color::Named(_));
let hex_color = Color::from("#ff0000");
matches!(hex_color, Color::Hex(_));
}
#[test]
fn test_color_from_rgb() {
let color = Color::from((255, 0, 0));
matches!(color, Color::Rgb(255, 0, 0));
}
}