use crate::error::WriteResult;
use crate::writer::{CommonMarkWriter, HtmlWriter};
pub trait CommonMarkRenderable: super::core::NodeContent {
fn render_commonmark(&self, writer: &mut CommonMarkWriter) -> WriteResult<()>;
}
pub trait HtmlRenderable: super::core::NodeContent {
fn render_html(&self, writer: &mut HtmlWriter) -> WriteResult<()>;
}
pub trait Format<W> {
fn format(&self, writer: &mut W) -> WriteResult<()>;
}
pub trait ToCommonMark {
fn to_commonmark(&self, writer: &mut CommonMarkWriter) -> WriteResult<()>;
}
pub trait ToHtml {
fn to_html(&self, writer: &mut HtmlWriter) -> WriteResult<()>;
}
impl<T> ToCommonMark for T
where
T: Format<CommonMarkWriter>,
{
fn to_commonmark(&self, writer: &mut CommonMarkWriter) -> WriteResult<()> {
self.format(writer)
}
}
impl<T> ToHtml for T
where
T: Format<HtmlWriter>,
{
fn to_html(&self, writer: &mut HtmlWriter) -> WriteResult<()> {
self.format(writer)
}
}
impl<T> CommonMarkRenderable for T
where
T: ToCommonMark + super::core::NodeContent,
{
fn render_commonmark(&self, writer: &mut CommonMarkWriter) -> WriteResult<()> {
self.to_commonmark(writer)
}
}
impl<T> HtmlRenderable for T
where
T: ToHtml + super::core::NodeContent,
{
fn render_html(&self, writer: &mut HtmlWriter) -> WriteResult<()> {
self.to_html(writer)
}
}
pub trait MultiFormat: ToCommonMark {
fn supports_html(&self) -> bool {
false
}
fn html_format(&self, writer: &mut HtmlWriter) -> WriteResult<()> {
writer
.raw_html(&format!(
"<!-- HTML rendering not implemented for {} -->",
std::any::type_name::<Self>()
))
.map_err(Into::into)
}
fn render_multi<W>(&self, writer: &mut W) -> WriteResult<()>
where
W: std::any::Any + 'static,
{
if let Some(cm_writer) =
(writer as &mut dyn std::any::Any).downcast_mut::<CommonMarkWriter>()
{
self.to_commonmark(cm_writer)
} else if let Some(html_writer) =
(writer as &mut dyn std::any::Any).downcast_mut::<HtmlWriter>()
{
if self.supports_html() {
self.html_format(html_writer)
} else {
Err(crate::error::WriteError::custom(
"HTML format not supported for this node type",
))
}
} else {
Err(crate::error::WriteError::custom("Unsupported writer type"))
}
}
}
impl<T> MultiFormat for T
where
T: ToCommonMark + ToHtml,
{
fn supports_html(&self) -> bool {
true
}
fn html_format(&self, writer: &mut HtmlWriter) -> WriteResult<()> {
self.to_html(writer)
}
}