use alloc::string::String;
use super::Widget;
use crate::buffer::Buffer;
use crate::layout::Rect;
use crate::style::Style;
#[instability::unstable(feature = "widget-ref")]
pub trait WidgetRef {
fn render_ref(&self, area: Rect, buf: &mut Buffer);
}
impl<W> WidgetRef for &W
where
for<'a> &'a W: Widget,
{
fn render_ref(&self, area: Rect, buf: &mut Buffer) {
self.render(area, buf);
}
}
impl WidgetRef for &str {
fn render_ref(&self, area: Rect, buf: &mut Buffer) {
buf.set_stringn(area.x, area.y, self, area.width as usize, Style::new());
}
}
impl WidgetRef for String {
fn render_ref(&self, area: Rect, buf: &mut Buffer) {
buf.set_stringn(area.x, area.y, self, area.width as usize, Style::new());
}
}
impl<W: WidgetRef> WidgetRef for Option<W> {
fn render_ref(&self, area: Rect, buf: &mut Buffer) {
if let Some(widget) = self {
widget.render_ref(area, buf);
}
}
}
#[cfg(test)]
mod tests {
use alloc::boxed::Box;
use alloc::vec;
use alloc::vec::Vec;
use rstest::{fixture, rstest};
use super::*;
use crate::buffer::Buffer;
use crate::layout::Rect;
use crate::text::Line;
#[fixture]
fn buf() -> Buffer {
Buffer::empty(Rect::new(0, 0, 20, 1))
}
struct Greeting;
struct Farewell;
impl Widget for &Greeting {
fn render(self, area: Rect, buf: &mut Buffer) {
Line::from("Hello").render(area, buf);
}
}
impl Widget for &Farewell {
fn render(self, area: Rect, buf: &mut Buffer) {
Line::from("Goodbye").right_aligned().render(area, buf);
}
}
#[rstest]
fn render_ref(mut buf: Buffer) {
let widget = &Greeting;
widget.render_ref(buf.area, &mut buf);
assert_eq!(buf, Buffer::with_lines(["Hello "]));
}
#[rstest]
fn render_ref_box(mut buf: Buffer) {
let widget: Box<dyn WidgetRef> = Box::new(&Greeting);
widget.render_ref(buf.area, &mut buf);
assert_eq!(buf, Buffer::with_lines(["Hello "]));
}
#[rstest]
fn render_ref_box_vec(mut buf: Buffer) {
let widgets: Vec<Box<dyn WidgetRef>> = vec![Box::new(&Greeting), Box::new(&Farewell)];
for widget in widgets {
widget.render_ref(buf.area, &mut buf);
}
assert_eq!(buf, Buffer::with_lines(["Hello Goodbye"]));
}
#[rstest]
fn render_ref_some(mut buf: Buffer) {
let widget = Some(&Greeting);
widget.render_ref(buf.area, &mut buf);
assert_eq!(buf, Buffer::with_lines(["Hello "]));
}
#[rstest]
fn render_ref_none(mut buf: Buffer) {
let widget: Option<&Greeting> = None;
widget.render_ref(buf.area, &mut buf);
assert_eq!(buf, Buffer::with_lines([" "]));
}
#[rstest]
fn render_ref_str(mut buf: Buffer) {
"hello world".render_ref(buf.area, &mut buf);
assert_eq!(buf, Buffer::with_lines(["hello world "]));
}
#[rstest]
fn render_ref_option_str(mut buf: Buffer) {
Some("hello world").render_ref(buf.area, &mut buf);
assert_eq!(buf, Buffer::with_lines(["hello world "]));
}
#[rstest]
fn render_ref_string(mut buf: Buffer) {
String::from("hello world").render_ref(buf.area, &mut buf);
assert_eq!(buf, Buffer::with_lines(["hello world "]));
}
#[rstest]
fn render_ref_option_string(mut buf: Buffer) {
Some(String::from("hello world")).render_ref(buf.area, &mut buf);
assert_eq!(buf, Buffer::with_lines(["hello world "]));
}
}