Gnosco is a Rust-based escrow and badging application that integrates with the AT Protocol ecosystem..
1//! HTTP utility functions for query strings and error responses.
2//!
3//! Helper functions for template path selection, query parameter formatting,
4//! and contextual error response generation with internationalization.
5
6use axum::{http, response::IntoResponse};
7use axum_template::RenderHtml;
8use minijinja::Value;
9use std::fmt::Display;
10use unic_langid::LanguageIdentifier;
11
12use super::{context::WebContext, errors::WebError};
13
14pub(super) type QueryParam<'a> = (&'a str, &'a str);
15pub(super) type QueryParams<'a> = Vec<QueryParam<'a>>;
16
17pub(super) fn build_querystring(query: QueryParams) -> String {
18 query.iter().fold(String::new(), |acc, &tuple| {
19 acc + tuple.0 + "=" + tuple.1 + "&"
20 })
21}
22
23/// Helper function to select the appropriate template path based on request type
24pub(super) fn select_template_path(
25 template_name: &str,
26 hxboosted: bool,
27 hxrequest: bool,
28 language: &LanguageIdentifier,
29) -> String {
30 let language_str = language.to_string().to_lowercase();
31 if hxboosted {
32 format!("{}/{}.bare.html", language_str, template_name)
33 } else if hxrequest {
34 format!("{}/{}.partial.html", language_str, template_name)
35 } else {
36 format!("{}/{}.html", language_str, template_name)
37 }
38}
39
40/// Helper function to select template with default "alert" name
41pub(super) fn select_alert_template(
42 hxboosted: bool,
43 hxrequest: bool,
44 language: &LanguageIdentifier,
45) -> String {
46 select_template_path("alert", hxboosted, hxrequest, language)
47}
48
49/// Helper function to create contextual error responses
50pub(super) fn contextual_error_response<E: Display>(
51 web_context: &WebContext,
52 language: &LanguageIdentifier,
53 template: &str,
54 template_context: Value,
55 error: E,
56 status_code: Option<http::StatusCode>,
57) -> Result<axum::response::Response, WebError> {
58 let (err_bare, err_partial) = crate::errors::expand_error(error.to_string());
59 tracing::warn!(error = %error, "encountered error");
60
61 let error_message =
62 web_context
63 .i18n_context
64 .locales
65 .format_error(language, &err_bare, &err_partial);
66
67 let status = status_code.unwrap_or(http::StatusCode::OK);
68
69 let context = minijinja::context! { ..template_context, ..minijinja::context! {
70 message => error_message,
71 }};
72
73 Ok((
74 status,
75 RenderHtml(template, web_context.engine.clone(), context),
76 )
77 .into_response())
78}