use std::rc::Rc;
use crate::base::Rect;
use crate::render::RichText;
use crate::ui::StyledCanvas;
pub enum FeedBlock {
Text(String),
Markdown(String),
Code {
lang: String,
source: String,
},
Custom(CustomBlock),
}
pub(super) type SharedDrawFn = Rc<dyn Fn(&mut dyn StyledCanvas, Rect)>;
pub struct CustomBlock {
pub(super) height: Box<dyn Fn(i32) -> i32>,
pub(super) draw: SharedDrawFn,
}
impl CustomBlock {
pub fn new(
height: impl Fn(i32) -> i32 + 'static,
draw: impl Fn(&mut dyn StyledCanvas, Rect) + 'static,
) -> CustomBlock {
CustomBlock {
height: Box::new(height),
draw: Rc::new(draw),
}
}
}
pub(super) enum ItemBlock {
Text(String),
Markdown(String),
Code {
lang: String,
source: String,
},
Custom(CustomBlock),
Rich(RichText),
}
impl From<FeedBlock> for ItemBlock {
fn from(b: FeedBlock) -> ItemBlock {
match b {
FeedBlock::Text(s) => ItemBlock::Text(s),
FeedBlock::Markdown(s) => ItemBlock::Markdown(s),
FeedBlock::Code { lang, source } => ItemBlock::Code { lang, source },
FeedBlock::Custom(c) => ItemBlock::Custom(c),
}
}
}
pub struct FeedItem {
pub(super) blocks: Vec<ItemBlock>,
}
impl FeedItem {
pub fn new() -> FeedItem {
FeedItem { blocks: Vec::new() }
}
pub fn markdown(src: impl Into<String>) -> FeedItem {
FeedItem::new().block(FeedBlock::Markdown(src.into()))
}
pub fn text(s: impl Into<String>) -> FeedItem {
FeedItem::new().block(FeedBlock::Text(s.into()))
}
pub fn code(lang: impl Into<String>, source: impl Into<String>) -> FeedItem {
FeedItem::new().block(FeedBlock::Code {
lang: lang.into(),
source: source.into(),
})
}
pub fn rich(text: RichText) -> FeedItem {
FeedItem::new().rich_block(text)
}
pub fn rich_lines(lines: Vec<crate::render::RichLine>) -> FeedItem {
FeedItem::rich(RichText::from_lines(lines))
}
pub fn rich_block(mut self, text: RichText) -> FeedItem {
self.blocks.push(ItemBlock::Rich(text));
self
}
pub fn block(mut self, b: FeedBlock) -> FeedItem {
self.blocks.push(b.into());
self
}
}
impl Default for FeedItem {
fn default() -> Self {
FeedItem::new()
}
}