use std::fmt;
use crate::{Alignment, Block, Inline};
use itemize::IntoItems;
pub fn block(value: impl IntoItems<Block>) -> Block {
Block::BlockList(value.into_items().collect())
}
pub fn p(value: impl IntoItems<Inline>) -> Block {
Block::Paragraph(value.into_items().collect())
}
pub fn h(level: u8, value: impl IntoItems<Inline>) -> Block {
Block::Heading {
level,
content: value.into_items().collect(),
}
}
pub fn h1(value: impl IntoItems<Inline>) -> Block {
h(1, value)
}
pub fn h2(value: impl IntoItems<Inline>) -> Block {
h(2, value)
}
pub fn h3(value: impl IntoItems<Inline>) -> Block {
h(3, value)
}
pub fn h4(value: impl IntoItems<Inline>) -> Block {
h(4, value)
}
pub fn h5(value: impl IntoItems<Inline>) -> Block {
h(5, value)
}
pub fn h6(value: impl IntoItems<Inline>) -> Block {
h(6, value)
}
pub fn code_block(language: impl Into<OptString>, value: impl Into<String>) -> Block {
Block::CodeBlock {
language: language.into().0,
content: value.into(),
}
}
pub fn list(ordered: bool, items: impl IntoItems<Block>) -> Block {
Block::List {
ordered,
items: items.into_items().collect(),
}
}
pub fn ul(items: impl IntoItems<Block>) -> Block {
list(false, items)
}
pub fn ol(items: impl IntoItems<Block>) -> Block {
list(true, items)
}
pub struct TaskItem(bool, Block);
impl<T> From<(bool, T)> for TaskItem
where
T: Into<Block>,
{
fn from(value: (bool, T)) -> Self {
TaskItem(value.0, value.1.into())
}
}
itemize::impl_items!(IntoItems for TaskItem);
pub fn task_list(items: impl IntoItems<TaskItem>) -> Block {
Block::TaskList {
items: items.into_items().map(|item| (item.0, item.1)).collect(),
}
}
pub struct Align(Alignment, Inline);
impl Align {
pub fn left(inline: impl Into<Inline>) -> Self {
Align(Alignment::Left, inline.into())
}
pub fn center(inline: impl Into<Inline>) -> Self {
Align(Alignment::Center, inline.into())
}
pub fn right(inline: impl Into<Inline>) -> Self {
Align(Alignment::Right, inline.into())
}
}
impl<T> From<T> for Align
where
T: Into<Inline>,
{
fn from(value: T) -> Self {
Align::left(value)
}
}
itemize::impl_items!(IntoItems for Align);
pub struct Row(Vec<Inline>);
impl<T: IntoItems<Inline>> From<T> for Row {
fn from(value: T) -> Self {
Row(value.into_items().collect())
}
}
pub fn table(headers: impl IntoItems<Align>, rows: impl IntoItems<Row>) -> Block {
let mut columns = Vec::new();
let mut alignments = Vec::new();
for header in headers.into_items() {
columns.push(header.1);
alignments.push(header.0);
}
Block::Table {
headers: columns,
rows: rows.into_items().map(|row| row.0).collect(),
alignments,
}
}
pub fn hr() -> Block {
Block::HorizontalRule
}
pub fn quote(value: impl IntoItems<Block>) -> Block {
Block::Blockquote(value.into_items().collect())
}
pub fn text(value: impl fmt::Display) -> Inline {
Inline::Text(value.to_string())
}
pub fn bold(value: impl IntoItems<Inline>) -> Inline {
Inline::Bold(value.into_items().collect())
}
pub fn italic(value: impl IntoItems<Inline>) -> Inline {
Inline::Italic(value.into_items().collect())
}
pub fn strikethrough(value: impl IntoItems<Inline>) -> Inline {
Inline::Strikethrough(value.into_items().collect())
}
pub fn code(value: impl Into<String>) -> Inline {
Inline::Code(value.into())
}
pub fn link(text: impl IntoItems<Inline>, url: impl Into<String>) -> Inline {
Inline::Link {
text: text.into_items().collect(),
url: url.into(),
}
}
pub trait BlockExt: Sized + IntoItems<Inline> {
fn h1(self) -> Block {
h1(self)
}
fn h2(self) -> Block {
h2(self)
}
fn h3(self) -> Block {
h3(self)
}
fn h4(self) -> Block {
h4(self)
}
fn h5(self) -> Block {
h5(self)
}
fn h6(self) -> Block {
h6(self)
}
fn p(self) -> Block {
p(self)
}
}
impl<T: IntoItems<Inline>> BlockExt for T {}
pub trait InlineExt: Sized {
fn bold(self) -> Inline
where
Self: IntoItems<Inline>,
{
bold(self)
}
fn italic(self) -> Inline
where
Self: IntoItems<Inline>,
{
italic(self)
}
fn strikethrough(self) -> Inline
where
Self: IntoItems<Inline>,
{
strikethrough(self)
}
fn link<S>(self, url: S) -> Inline
where
Self: IntoItems<Inline>,
S: Into<String>,
{
Inline::Link {
text: self.into_items().collect(),
url: url.into(),
}
}
}
impl<T: IntoItems<Inline>> InlineExt for T {}
pub struct OptString(Option<String>);
impl From<&str> for OptString {
fn from(value: &str) -> Self {
Self(Some(value.to_string()))
}
}
impl From<String> for OptString {
fn from(value: String) -> Self {
Self(Some(value))
}
}
impl From<()> for OptString {
fn from(_: ()) -> Self {
Self(None)
}
}
impl From<Option<String>> for OptString {
fn from(value: Option<String>) -> Self {
Self(value)
}
}