diff --git a/extensions/pagetop-bootsier/src/theme/aux/border.rs b/extensions/pagetop-bootsier/src/theme/aux/border.rs index 44d24b0e..3bd705e7 100644 --- a/extensions/pagetop-bootsier/src/theme/aux/border.rs +++ b/extensions/pagetop-bootsier/src/theme/aux/border.rs @@ -64,6 +64,7 @@ impl BorderColor { /// assert_eq!(BorderColor::Black.to_class(), "border-black"); /// assert_eq!(BorderColor::Default.to_class(), ""); /// ``` + #[inline] pub fn to_class(self) -> String { if let Some(suffix) = self.suffix() { let base_len = match self { diff --git a/extensions/pagetop-bootsier/src/theme/aux/breakpoint.rs b/extensions/pagetop-bootsier/src/theme/aux/breakpoint.rs index 992f8525..ce7998e7 100644 --- a/extensions/pagetop-bootsier/src/theme/aux/breakpoint.rs +++ b/extensions/pagetop-bootsier/src/theme/aux/breakpoint.rs @@ -82,8 +82,8 @@ impl BreakPoint { /// let bp = BreakPoint::LG; /// assert_eq!(bp.class_with("", "3"), ""); /// ``` - #[doc(hidden)] - pub fn class_with(self, prefix: &str, suffix: &str) -> String { + #[inline] + pub(crate) fn class_with(self, prefix: &str, suffix: &str) -> String { if prefix.is_empty() { return String::new(); } diff --git a/extensions/pagetop-bootsier/src/theme/aux/button.rs b/extensions/pagetop-bootsier/src/theme/aux/button.rs index b32bd17d..721c2bec 100644 --- a/extensions/pagetop-bootsier/src/theme/aux/button.rs +++ b/extensions/pagetop-bootsier/src/theme/aux/button.rs @@ -65,6 +65,7 @@ impl ButtonColor { /// assert_eq!(ButtonColor::Link.to_class(), "btn-link"); /// assert_eq!(ButtonColor::Default.to_class(), ""); /// ``` + #[inline] pub fn to_class(self) -> String { match self { Self::Default => String::new(), @@ -131,6 +132,7 @@ impl ButtonSize { /// assert_eq!(ButtonSize::Large.to_class(), "btn-lg"); /// assert_eq!(ButtonSize::Default.to_class(), ""); /// ``` + #[inline] pub fn to_class(self) -> String { match self { Self::Default => String::new(), diff --git a/extensions/pagetop-bootsier/src/theme/aux/color.rs b/extensions/pagetop-bootsier/src/theme/aux/color.rs index f49c36b6..b1372104 100644 --- a/extensions/pagetop-bootsier/src/theme/aux/color.rs +++ b/extensions/pagetop-bootsier/src/theme/aux/color.rs @@ -139,8 +139,8 @@ impl Opacity { /// assert_eq!(Opacity::SemiTransparent.class_with("text"), "text-opacity-25"); /// assert_eq!(Opacity::Default.class_with("bg"), ""); /// ``` - #[doc(hidden)] - pub fn class_with(self, prefix: &str) -> String { + #[inline] + pub(crate) fn class_with(self, prefix: &str) -> String { if let Some(suffix) = self.suffix() { let base_len = if prefix.is_empty() { Self::OPACITY.len() @@ -253,6 +253,7 @@ impl ColorBg { /// assert_eq!(ColorBg::Transparent.to_class(), "bg-transparent"); /// assert_eq!(ColorBg::Default.to_class(), ""); /// ``` + #[inline] pub fn to_class(self) -> String { if let Some(suffix) = self.suffix() { let base_len = match self { @@ -351,6 +352,7 @@ impl ColorText { /// assert_eq!(ColorText::Black.to_class(), "text-black"); /// assert_eq!(ColorText::Default.to_class(), ""); /// ``` + #[inline] pub fn to_class(self) -> String { if let Some(suffix) = self.suffix() { let base_len = match self { diff --git a/extensions/pagetop-bootsier/src/theme/aux/layout.rs b/extensions/pagetop-bootsier/src/theme/aux/layout.rs index a1255dc0..09edbf91 100644 --- a/extensions/pagetop-bootsier/src/theme/aux/layout.rs +++ b/extensions/pagetop-bootsier/src/theme/aux/layout.rs @@ -67,8 +67,8 @@ impl ScaleSize { /// assert_eq!(ScaleSize::Three.class_with("p"), "p-3"); /// assert_eq!(ScaleSize::None.class_with("border"), ""); /// ``` - #[doc(hidden)] - pub fn class_with(self, prefix: &str) -> String { + #[inline] + pub(crate) fn class_with(self, prefix: &str) -> String { if !prefix.is_empty() { if let Some(suffix) = self.suffix() { let mut class = String::with_capacity(prefix.len() + suffix.len()); diff --git a/extensions/pagetop-bootsier/src/theme/aux/rounded.rs b/extensions/pagetop-bootsier/src/theme/aux/rounded.rs index 69976142..adf6c261 100644 --- a/extensions/pagetop-bootsier/src/theme/aux/rounded.rs +++ b/extensions/pagetop-bootsier/src/theme/aux/rounded.rs @@ -78,8 +78,8 @@ impl RoundedRadius { /// assert_eq!(RoundedRadius::Circle.class_with(""), "rounded-circle"); /// assert_eq!(RoundedRadius::None.class_with("rounded-bottom-start"), ""); /// ``` - #[doc(hidden)] - pub fn class_with(self, prefix: &str) -> String { + #[inline] + pub(crate) fn class_with(self, prefix: &str) -> String { if let Some(suffix) = self.suffix() { let base_len = if prefix.is_empty() { Self::ROUNDED.len() diff --git a/extensions/pagetop-bootsier/src/theme/classes/border.rs b/extensions/pagetop-bootsier/src/theme/classes/border.rs index 2da7bfbb..3095498c 100644 --- a/extensions/pagetop-bootsier/src/theme/classes/border.rs +++ b/extensions/pagetop-bootsier/src/theme/classes/border.rs @@ -145,6 +145,7 @@ impl Border { /// `"border border-top-0 border-end-3 border-primary border-opacity-50"`, etc.). /// /// Si no se define ningún tamaño, color ni opacidad, devuelve `""`. + #[inline] pub fn to_class(self) -> String { let mut classes = String::new(); self.push_class(&mut classes); diff --git a/extensions/pagetop-bootsier/src/theme/classes/color.rs b/extensions/pagetop-bootsier/src/theme/classes/color.rs index 4f5b4650..162b7849 100644 --- a/extensions/pagetop-bootsier/src/theme/classes/color.rs +++ b/extensions/pagetop-bootsier/src/theme/classes/color.rs @@ -76,6 +76,7 @@ impl Background { /// Devuelve las clases de fondo como cadena (`"bg-primary"`, `"bg-body-secondary bg-opacity-50"`, etc.). /// /// Si no se define ni color ni opacidad, devuelve `""`. + #[inline] pub fn to_class(self) -> String { let mut classes = String::new(); self.push_class(&mut classes); @@ -188,6 +189,7 @@ impl Text { /// etc.). /// /// Si no se define ni color ni opacidad, devuelve `""`. + #[inline] pub fn to_class(self) -> String { let mut classes = String::new(); self.push_class(&mut classes); diff --git a/extensions/pagetop-bootsier/src/theme/classes/layout.rs b/extensions/pagetop-bootsier/src/theme/classes/layout.rs index 1f388450..adb8c3e4 100644 --- a/extensions/pagetop-bootsier/src/theme/classes/layout.rs +++ b/extensions/pagetop-bootsier/src/theme/classes/layout.rs @@ -94,6 +94,7 @@ impl Margin { /// Devuelve la clase de **margin** como cadena (`"mt-3"`, `"ms-lg-auto"`, etc.). /// /// Si `size` es `ScaleSize::None`, devuelve `""`. + #[inline] pub fn to_class(self) -> String { let Some(size) = self.size_suffix() else { return String::new(); @@ -194,6 +195,7 @@ impl Padding { /// Devuelve la clase de **padding** como cadena (`"px-2"`, `"pe-sm-4"`, etc.). /// /// Si `size` es `ScaleSize::None` o `ScaleSize::Auto`, devuelve `""`. + #[inline] pub fn to_class(self) -> String { let Some(size) = self.suffix() else { return String::new(); diff --git a/extensions/pagetop-bootsier/src/theme/classes/rounded.rs b/extensions/pagetop-bootsier/src/theme/classes/rounded.rs index 077740e1..58d50b86 100644 --- a/extensions/pagetop-bootsier/src/theme/classes/rounded.rs +++ b/extensions/pagetop-bootsier/src/theme/classes/rounded.rs @@ -160,6 +160,7 @@ impl Rounded { /// `"rounded-top rounded-bottom-start-4 rounded-bottom-end-circle"`, etc.). /// /// Si no se define ningún radio, devuelve `""`. + #[inline] pub fn to_class(self) -> String { let mut classes = String::new(); self.push_class(&mut classes); diff --git a/extensions/pagetop-bootsier/src/theme/container/props.rs b/extensions/pagetop-bootsier/src/theme/container/props.rs index 209773b9..2010ba8e 100644 --- a/extensions/pagetop-bootsier/src/theme/container/props.rs +++ b/extensions/pagetop-bootsier/src/theme/container/props.rs @@ -59,6 +59,7 @@ impl Width { } */ /// Devuelve la clase asociada al comportamiento del contenedor según el ajuste de su ancho. + #[inline] pub fn to_class(self) -> String { match self { Self::Default => BreakPoint::None.class_with(Self::CONTAINER, ""), diff --git a/extensions/pagetop-bootsier/src/theme/dropdown/props.rs b/extensions/pagetop-bootsier/src/theme/dropdown/props.rs index fd315508..d88f0929 100644 --- a/extensions/pagetop-bootsier/src/theme/dropdown/props.rs +++ b/extensions/pagetop-bootsier/src/theme/dropdown/props.rs @@ -95,8 +95,8 @@ impl Direction { /// Devuelve la clase asociada a la dirección teniendo en cuenta si se agrupa con otros menús /// [`Dropdown`], o `""` si no corresponde ninguna. - #[doc(hidden)] - pub fn class_with(self, grouped: bool) -> String { + #[inline] + pub(crate) fn class_with(self, grouped: bool) -> String { let mut classes = String::new(); self.push_class(&mut classes, grouped); classes @@ -179,7 +179,8 @@ impl MenuAlign { } /* Devuelve las clases de alineación sin incluir `dropdown-menu` (reservado). - pub fn to_class(self) -> String { + #[inline] + pub(crate) fn to_class(self) -> String { let mut classes = String::new(); self.push_class(&mut classes); classes diff --git a/extensions/pagetop-bootsier/src/theme/image/props.rs b/extensions/pagetop-bootsier/src/theme/image/props.rs index 2041b2fd..f31d74c1 100644 --- a/extensions/pagetop-bootsier/src/theme/image/props.rs +++ b/extensions/pagetop-bootsier/src/theme/image/props.rs @@ -94,7 +94,8 @@ impl Source { } */ /// Devuelve la clase asociada a la imagen según la fuente. - pub fn to_class(&self) -> String { + #[inline] + pub(crate) fn to_class(&self) -> String { let s = self.as_str(); if s.is_empty() { String::new() diff --git a/src/core/theme/definition.rs b/src/core/theme/definition.rs index 81e47756..a0edbd9a 100644 --- a/src/core/theme/definition.rs +++ b/src/core/theme/definition.rs @@ -1,12 +1,10 @@ -use crate::base::component::{Html, Intro, IntroOpening}; -use crate::core::component::{Child, ChildOp, Component, Contextual}; +use crate::core::component::Contextual; use crate::core::extension::Extension; -use crate::core::theme::{DefaultRegion, DefaultTemplate, TemplateRef}; use crate::global; use crate::html::{html, Markup}; use crate::locale::L10n; +use crate::prelude::{DefaultTemplate, TemplateRef}; use crate::response::page::Page; -use crate::service::http::StatusCode; /// Interfaz común que debe implementar cualquier tema de PageTop. /// @@ -157,76 +155,20 @@ pub trait Theme: Extension + Send + Sync { } } - /// Contenido predefinido para la página de error "*403 - Forbidden*" (acceso denegado). + /// Contenido predeterminado para la página de error "*403 - Forbidden*". /// /// Los temas pueden sobrescribir este método para personalizar el diseño y el contenido de la - /// página de error. - fn error_403(&self, page: &mut Page) { - page.alter_title(L10n::l("error403_title")) - .alter_template(&DefaultTemplate::Error) - .alter_child_in( - &DefaultRegion::Content, - ChildOp::Prepend(Child::with(Html::with(move |cx| { - html! { - div { - h1 { (L10n::l("error403_alert").using(cx)) } - p { (L10n::l("error403_help").using(cx)) } - } - } - }))), - ); + /// página de error, manteniendo o no el mensaje de los *textos localizados*. + fn error403(&self, page: &mut Page) -> Markup { + html! { div { h1 { (L10n::l("error403_notice").using(page)) } } } } - /// Contenido predefinido para la página de error "*404 - Not Found*" (recurso no encontrado). + /// Contenido predeterminado para la página de error "*404 - Not Found*". /// /// Los temas pueden sobrescribir este método para personalizar el diseño y el contenido de la - /// página de error. - fn error_404(&self, page: &mut Page) { - page.alter_title(L10n::l("error404_title")) - .alter_template(&DefaultTemplate::Error) - .alter_child_in( - &DefaultRegion::Content, - ChildOp::Prepend(Child::with(Html::with(move |cx| { - html! { - div { - h1 { (L10n::l("error404_alert").using(cx)) } - p { (L10n::l("error404_help").using(cx)) } - } - } - }))), - ); - } - - /// Permite al tema preparar y componer una página de error fatal. - /// - /// Por defecto, asigna el título al documento (`title`) y muestra un componente [`Intro`] con - /// el código HTTP del error (`code`) y los mensajes proporcionados (`alert` y `help`) como - /// descripción del error. - /// - /// Este método no se utiliza en las implementaciones predefinidas de [`Self::error_403()`] ni - /// [`Self::error_404()`], que definen su propio contenido específico. - /// - /// Los temas pueden sobrescribir este método para personalizar el diseño y el contenido de la - /// página de error. - fn error_fatal(&self, page: &mut Page, code: StatusCode, title: L10n, alert: L10n, help: L10n) { - page.alter_title(title) - .alter_template(&DefaultTemplate::Error) - .alter_child_in( - &DefaultRegion::Content, - ChildOp::Prepend(Child::with( - Intro::new() - .with_title(L10n::l("error_code").with_arg("code", code.as_str())) - .with_slogan(L10n::n(code.to_string())) - .with_button(None) - .with_opening(IntroOpening::Custom) - .add_child(Html::with(move |cx| { - html! { - h1 { (alert.using(cx)) } - p { (help.using(cx)) } - } - })), - )), - ); + /// página de error, manteniendo o no el mensaje de los *textos localizados*. + fn error404(&self, page: &mut Page) -> Markup { + html! { div { h1 { (L10n::l("error404_notice").using(page)) } } } } } diff --git a/src/locale/definition.rs b/src/locale/definition.rs index 06a07c49..6349b460 100644 --- a/src/locale/definition.rs +++ b/src/locale/definition.rs @@ -179,7 +179,7 @@ impl Locale { /// Es el idioma garantizado incluso cuando no haya configuración de la aplicación o cuando /// el valor configurado no sea válido. pub fn fallback_langid() -> &'static LanguageIdentifier { - &FALLBACK_LANGID + &*FALLBACK_LANGID } /// Devuelve el identificador de idioma configurado o, en su defecto, el de respaldo. @@ -187,7 +187,7 @@ impl Locale { /// Este es el idioma que utiliza internamente [`Locale::default()`] y resulta útil como idioma /// base cuando no se dispone de un contexto más específico. pub fn default_langid() -> &'static LanguageIdentifier { - (*CONFIG_LANGID).unwrap_or(&FALLBACK_LANGID) + (*CONFIG_LANGID).unwrap_or(&*FALLBACK_LANGID) } } diff --git a/src/locale/en-US/theme.ftl b/src/locale/en-US/theme.ftl index 3f4c0064..f766766d 100644 --- a/src/locale/en-US/theme.ftl +++ b/src/locale/en-US/theme.ftl @@ -3,32 +3,7 @@ region_header = Header region_content = Content region_footer = Footer -# Logo. +error403_notice = FORBIDDEN ACCESS +error404_notice = RESOURCE NOT FOUND + pagetop_logo = PageTop Logo - -# Error Messages. -error_code = Error { $code } - -error400_title = Error BAD REQUEST -error400_alert = The request could not be processed. -error400_help = The server could not understand your request. The address may be incorrect or some required data may be missing. - -error403_title = Error FORBIDDEN -error403_alert = You do not have permission to access this resource. -error403_help = Your account does not have the necessary privileges to view this page. If you believe this is an error, please contact the system administrator. - -error404_title = Error RESOURCE NOT FOUND -error404_alert = The requested page could not be found. -error404_help = The address may be incorrect, or the document may have been moved or deleted. Check the URL or use the navigation links to return to a known place. - -error500_title = Error INTERNAL ERROR -error500_alert = An unexpected error occurred on the server. -error500_help = We could not complete your request due to an internal problem. Please try again in a few minutes. If the error persists, contact the system administrator. - -error503_title = Error SERVICE UNAVAILABLE -error503_alert = The service is temporarily unavailable. -error503_help = The server is currently unable to handle your request due to maintenance or high load. Please try again in a few minutes. If the problem persists, contact the system administrator. - -error504_title = Error GATEWAY TIMEOUT -error504_alert = The server took too long to respond. -error504_help = The service is temporarily unavailable or overloaded. Please try again in a few minutes. If the problem continues, notify the system administrator. diff --git a/src/locale/es-ES/theme.ftl b/src/locale/es-ES/theme.ftl index 7d4abcf6..b8b91449 100644 --- a/src/locale/es-ES/theme.ftl +++ b/src/locale/es-ES/theme.ftl @@ -3,32 +3,7 @@ region_header = Cabecera region_content = Contenido region_footer = Pie de página -# Logo. +error403_notice = ACCESO NO PERMITIDO +error404_notice = RECURSO NO ENCONTRADO + pagetop_logo = Logotipo de PageTop - -# Error Messages. -error_code = Error { $code } - -error400_title = Error PETICIÓN INCORRECTA -error400_alert = No se ha podido procesar la petición. -error400_help = El servidor no ha podido interpretar su petición. Es posible que la dirección sea incorrecta o que falten datos obligatorios. Revise la información introducida e inténtelo de nuevo. - -error403_title = Error ACCESO PROHIBIDO -error403_alert = No dispone de permisos para acceder a este recurso. -error403_help = Su cuenta no tiene los privilegios necesarios para visualizar esta página. Si considera que se trata de un error, póngase en contacto con el administrador del sistema. - -error404_title = Error RECURSO NO ENCONTRADO -error404_alert = No se ha podido encontrar el recurso solicitado. -error404_help = Es posible que la dirección sea incorrecta o que el documento haya sido movido o eliminado. Compruebe la URL o utilice los enlaces de navegación para volver a una ubicación conocida. - -error500_title = Error INTERNO DEL SERVIDOR -error500_alert = Se ha producido un error interno en el servidor. -error500_help = No hemos podido completar su petición debido a un problema interno. Inténtelo de nuevo pasados unos minutos. Si el error persiste, póngase en contacto con el administrador del sistema. - -error503_title = Error SERVICIO NO DISPONIBLE -error503_alert = El servicio no está disponible temporalmente. -error503_help = En este momento el servidor no puede atender su petición debido a tareas de mantenimiento o a una alta carga de trabajo. Inténtelo de nuevo en unos minutos. Si el problema persiste, póngase en contacto con el administrador del sistema. - -error504_title = Error TIEMPO DE ESPERA AGOTADO -error504_alert = El servidor ha tardado demasiado en responder. -error504_help = El servicio no está disponible temporalmente o está experimentando una alta carga. Inténtelo de nuevo en unos minutos. Si el problema continúa, notifique la incidencia al administrador del sistema. diff --git a/src/response/page/error.rs b/src/response/page/error.rs index fd9959c2..7d6cf33b 100644 --- a/src/response/page/error.rs +++ b/src/response/page/error.rs @@ -1,9 +1,10 @@ +use crate::base::component::Html; use crate::core::component::Contextual; +use crate::core::theme::DefaultTemplate; use crate::locale::L10n; use crate::response::ResponseError; use crate::service::http::{header::ContentType, StatusCode}; use crate::service::{HttpRequest, HttpResponse}; -use crate::util; use super::Page; @@ -11,87 +12,71 @@ use std::fmt; /// Página de error asociada a un código de estado HTTP. /// -/// Este enumerado agrupa tipos esenciales de error que pueden devolverse como página HTML completa. -/// Cada variante encapsula la solicitud original ([`HttpRequest`]) y se corresponde con un código -/// de estado concreto. +/// Este enumerado agrupa los distintos tipos de error que pueden devolverse como página HTML +/// completa. Cada variante encapsula la solicitud original ([`HttpRequest`]) y se corresponde con +/// un código de estado concreto. /// -/// Para cada error se construye una [`Page`] usando el tema activo, lo que permite personalizar -/// la plantilla y el contenido del mensaje mediante los métodos específicos del tema -/// (por ejemplo, [`Theme::error_403()`](crate::core::theme::Theme::error_403), -/// [`Theme::error_404()`](crate::core::theme::Theme::error_404) o -/// [`Theme::error_fatal()`](crate::core::theme::Theme::error_fatal)). +/// Para algunos errores (como [`ErrorPage::AccessDenied`] y [`ErrorPage::NotFound`]) se construye +/// una [`Page`] usando la plantilla de error del tema activo ([`DefaultTemplate::Error`]), lo que +/// permite personalizar el contenido del mensaje. En el resto de casos se devuelve un cuerpo HTML +/// mínimo basado en una descripción genérica del error. +/// +/// `ErrorPage` implementa [`ResponseError`], por lo que puede utilizarse directamente como tipo de +/// error en los controladores HTTP. #[derive(Debug)] pub enum ErrorPage { + NotModified(HttpRequest), BadRequest(HttpRequest), AccessDenied(HttpRequest), NotFound(HttpRequest), + PreconditionFailed(HttpRequest), InternalError(HttpRequest), - ServiceUnavailable(HttpRequest), - GatewayTimeout(HttpRequest), -} - -impl ErrorPage { - /// Función auxiliar para renderizar una página de error genérica usando el tema activo. - /// - /// Construye una [`Page`] a partir de la petición y un prefijo de clave basado en el código de - /// estado (`error`), del que se derivan los textos localizados `error_title`, - /// `error_alert` y `error_help`. - /// - /// Si el renderizado falla, escribe en su lugar el texto plano asociado al código de estado. - fn display_error_page(&self, f: &mut fmt::Formatter<'_>, request: &HttpRequest) -> fmt::Result { - let mut page = Page::new(request.clone()); - let code = self.status_code(); - page.theme().error_fatal( - &mut page, - code, - L10n::l(util::join!("error", code.as_str(), "_title")), - L10n::l(util::join!("error", code.as_str(), "_alert")), - L10n::l(util::join!("error", code.as_str(), "_help")), - ); - if let Ok(rendered) = page.render() { - write!(f, "{}", rendered.into_string()) - } else { - f.write_str(&code.to_string()) - } - } + Timeout(HttpRequest), } impl fmt::Display for ErrorPage { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { + // Error 304. + ErrorPage::NotModified(_) => f.write_str("Not Modified"), // Error 400. - Self::BadRequest(request) => self.display_error_page(f, request), - + ErrorPage::BadRequest(_) => f.write_str("Bad Client Data"), // Error 403. - Self::AccessDenied(request) => { - let mut page = Page::new(request.clone()); - page.theme().error_403(&mut page); - if let Ok(rendered) = page.render() { - write!(f, "{}", rendered.into_string()) + ErrorPage::AccessDenied(request) => { + let mut error_page = Page::new(request.clone()); + let error403 = error_page.theme().error403(&mut error_page); + if let Ok(page) = error_page + .with_title(L10n::n("Error FORBIDDEN")) + .with_template(&DefaultTemplate::Error) + .add_child(Html::with(move |_| error403.clone())) + .render() + { + write!(f, "{}", page.into_string()) } else { - f.write_str(&self.status_code().to_string()) + f.write_str("Access Denied") } } - // Error 404. - Self::NotFound(request) => { - let mut page = Page::new(request.clone()); - page.theme().error_404(&mut page); - if let Ok(rendered) = page.render() { - write!(f, "{}", rendered.into_string()) + ErrorPage::NotFound(request) => { + let mut error_page = Page::new(request.clone()); + let error404 = error_page.theme().error404(&mut error_page); + if let Ok(page) = error_page + .with_title(L10n::n("Error RESOURCE NOT FOUND")) + .with_template(&DefaultTemplate::Error) + .add_child(Html::with(move |_| error404.clone())) + .render() + { + write!(f, "{}", page.into_string()) } else { - f.write_str(&self.status_code().to_string()) + f.write_str("Not Found") } } - + // Error 412. + ErrorPage::PreconditionFailed(_) => f.write_str("Precondition Failed"), // Error 500. - Self::InternalError(request) => self.display_error_page(f, request), - - // Error 503. - Self::ServiceUnavailable(request) => self.display_error_page(f, request), - + ErrorPage::InternalError(_) => f.write_str("Internal Error"), // Error 504. - Self::GatewayTimeout(request) => self.display_error_page(f, request), + ErrorPage::Timeout(_) => f.write_str("Timeout"), } } } @@ -106,12 +91,13 @@ impl ResponseError for ErrorPage { #[rustfmt::skip] fn status_code(&self) -> StatusCode { match self { + ErrorPage::NotModified(_) => StatusCode::NOT_MODIFIED, ErrorPage::BadRequest(_) => StatusCode::BAD_REQUEST, ErrorPage::AccessDenied(_) => StatusCode::FORBIDDEN, ErrorPage::NotFound(_) => StatusCode::NOT_FOUND, + ErrorPage::PreconditionFailed(_) => StatusCode::PRECONDITION_FAILED, ErrorPage::InternalError(_) => StatusCode::INTERNAL_SERVER_ERROR, - ErrorPage::ServiceUnavailable(_) => StatusCode::SERVICE_UNAVAILABLE, - ErrorPage::GatewayTimeout(_) => StatusCode::GATEWAY_TIMEOUT, + ErrorPage::Timeout(_) => StatusCode::GATEWAY_TIMEOUT, } } }