use crate::image::Image;
use crate::list::List;
use crate::style::{Align, Border, Color, Common, FontKey, Overflow, TextStyle};
use crate::table::Table;
#[derive(Clone, Debug)]
pub enum Element {
Text(Text),
Row(Row),
Column(Column),
Spacer(Spacer),
Line(Line),
Rect(Rect),
Table(Table),
Image(Image),
List(List),
PageBreak,
}
impl Element {
pub fn common(&self) -> Option<&Common> {
match self {
Element::Text(t) => Some(&t.common),
Element::Row(r) => Some(&r.common),
Element::Column(c) => Some(&c.common),
Element::Line(l) => Some(&l.common),
Element::Rect(r) => Some(&r.common),
Element::Table(t) => Some(&t.common),
Element::Image(i) => Some(&i.common),
Element::List(l) => Some(&l.common),
Element::Spacer(_) | Element::PageBreak => None,
}
}
pub fn common_mut(&mut self) -> Option<&mut Common> {
match self {
Element::Text(t) => Some(&mut t.common),
Element::Row(r) => Some(&mut r.common),
Element::Column(c) => Some(&mut c.common),
Element::Line(l) => Some(&mut l.common),
Element::Rect(r) => Some(&mut r.common),
Element::Table(t) => Some(&mut t.common),
Element::Image(i) => Some(&mut i.common),
Element::List(l) => Some(&mut l.common),
Element::Spacer(_) | Element::PageBreak => None,
}
}
}
macro_rules! common_builder_methods {
() => {
pub fn width(mut self, width: f32) -> Self {
self.common.width = Some(width);
self
}
pub fn height(mut self, height: f32) -> Self {
self.common.height = Some(height);
self
}
pub fn flex(mut self, factor: f32) -> Self {
self.common.flex = Some(factor);
self
}
pub fn padding(mut self, padding: f32) -> Self {
self.common.padding = padding;
self
}
pub fn overflow(mut self, overflow: Overflow) -> Self {
self.common.overflow = overflow;
self
}
pub fn background(mut self, color: Color) -> Self {
self.common.background = Some(color);
self
}
pub fn border(mut self, border: Border) -> Self {
self.common.border = Some(border);
self
}
pub fn keep_with_next(mut self) -> Self {
self.common.keep_with_next = true;
self
}
};
}
#[derive(Clone, Debug, Default)]
pub struct Text {
pub content: String,
pub style: TextStyle,
pub common: Common,
}
impl Text {
pub fn new(content: impl Into<String>) -> Self {
Text {
content: content.into(),
style: TextStyle::default(),
common: Common::default(),
}
}
pub fn size(mut self, size: f32) -> Self {
self.style.size = size;
self
}
pub fn bold(mut self) -> Self {
self.style.font = FontKey::SANS_BOLD;
self
}
pub fn font(mut self, font: FontKey) -> Self {
self.style.font = font;
self
}
pub fn color(mut self, color: Color) -> Self {
self.style.color = color;
self
}
pub fn align(mut self, align: Align) -> Self {
self.style.align = align;
self
}
pub fn line_height(mut self, line_height: f32) -> Self {
self.style.line_height = line_height;
self
}
pub fn heading1(self) -> Self {
self.size(24.0).bold().keep_with_next()
}
pub fn heading2(self) -> Self {
self.size(18.0).bold().keep_with_next()
}
pub fn heading3(self) -> Self {
self.size(14.0).bold().keep_with_next()
}
common_builder_methods!();
}
impl From<&str> for Text {
fn from(value: &str) -> Self {
Text::new(value)
}
}
impl From<String> for Text {
fn from(value: String) -> Self {
Text::new(value)
}
}
#[derive(Clone, Debug, Default)]
pub struct Row {
pub children: Vec<Element>,
pub gap: f32,
pub align: Align,
pub common: Common,
}
#[derive(Clone, Debug, Default)]
pub struct Column {
pub children: Vec<Element>,
pub gap: f32,
pub align: Align,
pub common: Common,
}
macro_rules! container_impl {
($ty:ident) => {
impl $ty {
pub fn new() -> Self {
Self::default()
}
pub fn child(mut self, child: impl Into<Element>) -> Self {
self.children.push(child.into());
self
}
pub fn children(mut self, children: impl IntoIterator<Item = impl Into<Element>>) -> Self {
self.children.extend(children.into_iter().map(Into::into));
self
}
pub fn gap(mut self, gap: f32) -> Self {
self.gap = gap;
self
}
pub fn align(mut self, align: Align) -> Self {
self.align = align;
self
}
common_builder_methods!();
}
};
}
container_impl!(Row);
container_impl!(Column);
#[derive(Clone, Copy, Debug)]
pub struct Spacer {
pub size: f32,
}
impl Spacer {
pub fn new(size: f32) -> Self {
Spacer { size }
}
}
#[derive(Clone, Debug)]
pub struct Line {
pub thickness: f32,
pub color: Color,
pub common: Common,
}
impl Default for Line {
fn default() -> Self {
Line {
thickness: 1.0,
color: Color::BLACK,
common: Common::default(),
}
}
}
impl Line {
pub fn new() -> Self {
Self::default()
}
pub fn thickness(mut self, thickness: f32) -> Self {
self.thickness = thickness;
self
}
pub fn color(mut self, color: Color) -> Self {
self.color = color;
self
}
common_builder_methods!();
}
#[derive(Clone, Debug, Default)]
pub struct Rect {
pub common: Common,
}
impl Rect {
pub fn new() -> Self {
Self::default()
}
common_builder_methods!();
}
macro_rules! element_from {
($ty:ident) => {
impl From<$ty> for Element {
fn from(value: $ty) -> Self {
Element::$ty(value)
}
}
};
}
element_from!(Text);
element_from!(Row);
element_from!(Column);
element_from!(Spacer);
element_from!(Line);
element_from!(Rect);
element_from!(Table);
element_from!(Image);
element_from!(List);
impl From<&str> for Element {
fn from(value: &str) -> Self {
Element::Text(Text::new(value))
}
}
impl From<String> for Element {
fn from(value: String) -> Self {
Element::Text(Text::new(value))
}
}