Skip to main content

rumtk_web/utils/
matcher.rs

1/*
2 * rumtk attempts to implement HL7 and medical protocols for interoperability in medicine.
3 * This toolkit aims to be reliable, simple, performant, and standards compliant.
4 * Copyright (C) 2025  Luis M. Santos, M.D. <lsantos@medicalmasses.com>
5 * Copyright (C) 2025  Ethan Dixon
6 * Copyright (C) 2025  MedicalMasses L.L.C. <contact@medicalmasses.com>
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20 */
21use crate::components::app::app_shell::app_shell;
22use crate::components::job_loader::job_loader;
23use crate::utils::defaults::DEFAULT_ROBOT_TXT;
24use crate::utils::form_data::compile_form_data;
25use crate::utils::types::SharedAppState;
26use crate::utils::{HTMLResult, RUMString};
27use crate::{rumtk_web_get_api_endpoint, rumtk_web_render_template, RUMWebData, RUMWebResponse, RouterForm};
28use axum::body::Body;
29use axum::http::Response;
30use axum::response::{Html, IntoResponse};
31use rumtk_core::strings::rumtk_format;
32
33pub async fn default_robots_matcher(
34    _path: Vec<RUMString>,
35    _params: RUMWebData,
36    _state: SharedAppState,
37) -> HTMLResult {
38    RUMWebResponse::into_get_response(DEFAULT_ROBOT_TXT).into_html_result()
39}
40
41pub async fn default_page_matcher(
42    path: Vec<RUMString>,
43    params: RUMWebData,
44    state: SharedAppState,
45) -> HTMLResult {
46    let path_components = match path.first() {
47        Some(x) => x.split('/').collect::<Vec<&str>>(),
48        None => Vec::new(),
49    };
50
51    // Do not minify the page. we saved 0.3KB but transfer went from 5ms to 45ms
52    let page = app_shell(&path_components, &params, state)?;
53
54    rumtk_web_render_template!(page)
55}
56
57pub async fn default_job_matcher(
58    path: Vec<RUMString>,
59    params: RUMWebData,
60    state: SharedAppState,
61) -> HTMLResult {
62    let loader = job_loader(&[], &params, state)?;
63
64    rumtk_web_render_template!(loader)
65}
66
67pub async fn default_api_matcher(
68    path: RUMString,
69    params: RUMWebData,
70    mut form: RouterForm,
71    state: SharedAppState,
72) -> HTMLResult {
73    let form_data = compile_form_data(&mut form).await?;
74    let api_endpoint = match rumtk_web_get_api_endpoint!(&path) {
75        Some(endpoint) => endpoint,
76        None => return Err(rumtk_format!("Requested endpoint is not registered!"))
77    };
78    api_endpoint(path, params, form_data, state)
79}
80
81pub fn match_maker(match_response: HTMLResult) -> Response<Body> {
82    match match_response {
83        Ok(res) => res.into_response(),
84        Err(e) => {
85            println!("Error: {}", e);
86            Html(String::default()).into_response()
87        },
88    }
89}
90
91#[macro_export]
92macro_rules! rumtk_web_fetch {
93    ( $matcher:expr ) => {{
94        use axum::extract::{Path, Query, State};
95        use axum::response::{Html, Response};
96        use $crate::matcher::match_maker;
97        use $crate::utils::types::{RouterAppState, RouterComponents, RouterForm, RouterParams};
98
99        async |Path(path_params): RouterComponents,
100               Query(params): RouterParams,
101               State(state): RouterAppState|
102               -> Response {
103            let r = $matcher(path_params, params, state).await;
104            match_maker(r)
105        }
106    }};
107}
108
109#[macro_export]
110macro_rules! rumtk_web_api_process {
111    ( $matcher:expr ) => {{
112        use axum::extract::{Multipart, Path, Query, State};
113        use axum::response::{Html, Response};
114        use $crate::matcher::match_maker;
115        use $crate::utils::types::{RouterAPIPath, RouterAppState, RouterForm, RouterParams};
116
117        async |Path(path_params): RouterAPIPath,
118               Query(params): RouterParams,
119               State(state): RouterAppState,
120               mut form: RouterForm|
121               -> Response {
122            let r = $matcher(path_params, params, form, state).await;
123            match_maker(r)
124        }
125    }};
126}