#![warn(missing_docs)]
#[cfg(all(feature = "postgres", feature = "sqlite", not(docsrs)))]
compile_error!("Enable exactly one database backend: `postgres` or `sqlite`, not both.");
#[cfg(not(any(feature = "postgres", feature = "sqlite")))]
compile_error!("Enable at least one database backend feature: `postgres` or `sqlite`.");
pub mod app;
pub mod auth;
pub mod cache;
pub mod config;
pub mod context;
pub mod datastar;
pub mod db;
pub mod error;
pub mod flash;
pub mod form;
pub mod health;
pub mod jobs;
pub mod logging;
pub mod mailer;
pub mod middleware;
pub mod paginate;
pub mod redact;
pub mod storage;
pub mod upload;
pub mod validate;
#[cfg(feature = "test-helpers")]
pub mod testing;
#[cfg(test)]
pub(crate) mod test_helpers;
#[macro_export]
macro_rules! render {
($template:expr) => {{
let __blixt_html = $template
.render()
.map_err(|e| $crate::error::Error::Internal(e.to_string()))?;
Ok($crate::prelude::Html(__blixt_html))
}};
}
pub mod prelude {
pub use crate::app::App;
pub use crate::auth::cookie as auth_cookie;
pub use crate::auth::{AuthUser, Claims, OptionalAuth};
pub use crate::cache::Cache;
pub use crate::config::{Config, Environment};
pub use crate::context::AppContext;
pub use crate::datastar::{
DatastarSignals, Signals, SseFragment, SseResponse, SseSignals, SseStream,
};
pub use crate::db::DbPool;
pub use crate::db::builder::{Delete, Insert, Order, Select, Update, Value};
pub use crate::error::{Error, Result};
pub use crate::flash::{Flash, Redirect};
pub use crate::form::{CsrfToken, Form};
pub use crate::jobs::{Queue, Worker};
pub use crate::logging::init_tracing;
pub use crate::mailer::{Mailer, MailerConfig};
pub use crate::paginate::{Paginated, PaginationParams};
pub use crate::redact::Redact;
pub use crate::storage::{Storage, WriteResult};
pub use crate::upload::{MultipartForm, UploadedFile};
pub use crate::validate::Validator;
pub use askama::Template;
pub use axum::{
Router,
extract::{Path, Query, State},
response::{Html, IntoResponse},
routing::{delete, get, post, put},
};
pub use serde::{Deserialize, Serialize};
pub use sqlx::FromRow;
pub use tracing::{debug, error, info, warn};
pub use crate::{query, query_as, query_scalar, render};
}
#[cfg(test)]
mod render_tests {
use crate::prelude::*;
#[derive(askama::Template)]
#[template(source = "<h1>{{ title }}</h1>", ext = "html")]
struct TestTemplate {
title: String,
}
#[test]
fn render_macro_produces_html_response() {
fn handler() -> Result<Html<String>> {
render!(TestTemplate {
title: "Hello".to_string()
})
}
let result = handler();
assert!(result.is_ok());
assert!(result.unwrap().0.contains("<h1>Hello</h1>"));
}
#[derive(askama::Template)]
#[template(source = "{{ value }}", ext = "html")]
struct EscapeTemplate {
value: String,
}
#[test]
fn render_macro_escapes_html() {
fn handler() -> Result<Html<String>> {
render!(EscapeTemplate {
value: "<script>alert('xss')</script>".to_string()
})
}
let html = handler().unwrap().0;
assert!(!html.contains("<script>"));
}
}