use std::fmt;
use crate::{Html, RenderEscaped, ToHtml};
pub struct HtmlFragment<F>
where
F: Fn(&mut (dyn fmt::Write + '_)) -> fmt::Result,
{
f: F,
size_hint: usize,
}
impl<F> HtmlFragment<F>
where
F: Fn(&mut (dyn fmt::Write + '_)) -> fmt::Result,
{
#[doc(hidden)]
pub fn new(f: F, size_hint: usize) -> Self {
HtmlFragment { f, size_hint }
}
}
impl<F> RenderEscaped for HtmlFragment<F>
where
F: Fn(&mut (dyn fmt::Write + '_)) -> fmt::Result,
{
fn render_escaped(&self, f: &mut (dyn fmt::Write + '_)) -> fmt::Result {
(self.f)(f)
}
}
impl<F> ToHtml for HtmlFragment<F>
where
F: Fn(&mut (dyn fmt::Write + '_)) -> fmt::Result,
{
fn to_html(&self) -> Html {
let mut buffer = String::with_capacity(self.size_hint);
(self.f)(&mut buffer).unwrap();
Html::new_unchecked(buffer)
}
}
#[cfg(feature = "actix-web")]
mod actix_web {
use ::actix_web::{HttpRequest, HttpResponse, Responder};
use super::*;
#[cfg_attr(docsrs, doc(cfg(feature = "actix-web")))]
impl<F> Responder for HtmlFragment<F>
where
F: Fn(&mut (dyn fmt::Write + '_)) -> fmt::Result,
{
type Body = String;
fn respond_to(self, req: &HttpRequest) -> HttpResponse<Self::Body> {
self.to_html().respond_to(req)
}
}
}
#[cfg(feature = "axum")]
mod axum {
use ::axum::response::{IntoResponse, Response};
use super::*;
#[cfg_attr(docsrs, doc(cfg(feature = "axum")))]
impl<F> IntoResponse for HtmlFragment<F>
where
F: Fn(&mut (dyn fmt::Write + '_)) -> fmt::Result,
{
fn into_response(self) -> Response {
self.to_html().into_response()
}
}
}
#[cfg(feature = "rocket")]
mod rocket {
use ::rocket::{
Request,
response::{Responder, Result},
};
use super::*;
#[cfg_attr(docsrs, doc(cfg(feature = "rocket")))]
impl<'r, 'o: 'r, F> Responder<'r, 'o> for HtmlFragment<F>
where
F: Fn(&mut (dyn fmt::Write + '_)) -> fmt::Result,
{
fn respond_to(self, request: &'r Request<'_>) -> Result<'o> {
self.to_html().respond_to(request)
}
}
}
pub trait PartialHtml: RenderEscaped {}
impl<F> PartialHtml for HtmlFragment<F> where F: Fn(&mut (dyn fmt::Write + '_)) -> fmt::Result {}