Skip to main content

rumtk_web/utils/
render.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.
5 * Copyright (C) 2025  Nick Stephenson
6 * Copyright (C) 2025  Ethan Dixon
7 * Copyright (C) 2025  MedicalMasses L.L.C.
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22 */
23use crate::types::HTMLResult;
24use crate::{RUMWebRedirect, RUMWebTemplate};
25use askama::Template;
26use rumtk_core::strings::{rumtk_format, RUMString};
27
28#[derive(RUMWebTemplate)]
29#[template(
30    source = "
31        {% for element in elements %}
32           {{ element|safe }}
33        {% endfor %}
34    ",
35    ext = "html"
36)]
37struct ContentBlock<'a> {
38    elements: &'a [RUMString],
39}
40
41pub fn rumtk_web_render_html<T: askama::Template>(template: T, url: RUMWebRedirect) -> HTMLResult {
42    let result = template.render();
43    match result {
44        Ok(html) => Ok(url.into_web_response(Some(html))),
45        Err(e) => {
46            let tn = std::any::type_name::<T>();
47            Err(rumtk_format!("Template {tn} render failed: {e:?}"))
48        }
49    }
50}
51
52pub fn rumtk_web_render_contents(elements: &[RUMString]) -> HTMLResult {
53    rumtk_web_render_html(ContentBlock { elements }, RUMWebRedirect::None)
54}
55
56pub fn rumtk_web_redirect(url: RUMWebRedirect) -> HTMLResult {
57    Ok(url.into_web_response(Some(String::default())))
58}
59
60#[macro_export]
61macro_rules! rumtk_web_render_component {
62    ( $component_fxn:expr ) => {{
63        use rumtk_core::strings::{RUMString, RUMStringConversions};
64        match $component_fxn() {
65            Ok(x) => x.to_rumstring(),
66            _ => RUMString::default(),
67        }
68    }};
69    ( $component_fxn:expr, $app_state:expr ) => {{
70        use rumtk_core::strings::{RUMString, RUMStringConversions};
71        match $component_fxn($app_state.clone()) {
72            Ok(x) => x.to_rumstring(),
73            _ => RUMString::default(),
74        }
75    }};
76    ( $component:expr, $params:expr, $app_state:expr ) => {{
77        use rumtk_core::strings::{RUMString, RUMStringConversions};
78        use $crate::{rumtk_web_get_component, rumtk_web_params_map};
79
80        let component = rumtk_web_get_component!($component);
81
82        match component(&[""], &rumtk_web_params_map!($params), $app_state.clone()) {
83            Ok(x) => x.to_rumstring(),
84            _ => RUMString::default(),
85        }
86    }};
87}
88
89#[macro_export]
90macro_rules! rumtk_web_render_html {
91    ( $page:expr ) => {{
92        use $crate::utils::{rumtk_web_render_html, RUMWebRedirect};
93
94        rumtk_web_render_html($page, RUMWebRedirect::None)
95    }};
96    ( $page:expr, $redirect_url:expr ) => {{
97        use $crate::utils::rumtk_web_render_html;
98
99        rumtk_web_render_html($page, $redirect_url)
100    }};
101}
102
103#[macro_export]
104macro_rules! rumtk_web_render_page_contents {
105    ( $page_elements:expr ) => {{
106        use $crate::utils::rumtk_web_render_contents;
107
108        rumtk_web_render_contents($page_elements)
109    }};
110}
111
112#[macro_export]
113macro_rules! rumtk_web_render_redirect {
114    ( $url:expr ) => {{
115        use $crate::utils::rumtk_web_redirect;
116
117        rumtk_web_redirect($url)
118    }};
119}
120
121///
122///
123/// If using raw strings, do not leave an extra line. The first input must have characters or you will get <pre><code> blocks regardless of what you do.
124///
125#[macro_export]
126macro_rules! rumtk_web_render_markdown {
127    ( $md:expr ) => {{
128        use pulldown_cmark::{Options, Parser};
129        use rumtk_core::strings::RUMStringConversions;
130
131        let mut options = Options::empty();
132        options.insert(Options::ENABLE_STRIKETHROUGH);
133        options.insert(Options::ENABLE_TASKLISTS);
134        options.insert(Options::ENABLE_MATH);
135        options.insert(Options::ENABLE_TABLES);
136        options.insert(Options::ENABLE_WIKILINKS);
137
138        let input = String::from($md);
139        let parser = Parser::new_ext(&input, options);
140        let mut html_output = String::new();
141        pulldown_cmark::html::push_html(&mut html_output, parser);
142        println!("{}", &html_output);
143
144        html_output.to_rumstring()
145    }};
146}