tachys/
lib.rs

1//! Allows rendering user interfaces based on a statically-typed view tree.
2//!
3//! This view tree is generic over rendering backends, and agnostic about reactivity/change
4//! detection.
5
6// this is specifically used for `unsized_const_params` below
7// this allows us to use const generic &'static str for static text nodes and attributes
8#![allow(incomplete_features)]
9#![cfg_attr(
10    all(feature = "nightly", rustc_nightly),
11    feature(unsized_const_params)
12)]
13// support for const generic &'static str has now moved back and forth between
14// these two features a couple times; we'll just enable both
15#![cfg_attr(all(feature = "nightly", rustc_nightly), feature(adt_const_params))]
16#![deny(missing_docs)]
17
18/// Commonly-used traits.
19pub mod prelude {
20    pub use crate::{
21        html::{
22            attribute::{
23                any_attribute::IntoAnyAttribute,
24                aria::AriaAttributes,
25                custom::CustomAttribute,
26                global::{
27                    ClassAttribute, GlobalAttributes, GlobalOnAttributes,
28                    OnAttribute, OnTargetAttribute, PropAttribute,
29                    StyleAttribute,
30                },
31                IntoAttributeValue,
32            },
33            directive::DirectiveAttribute,
34            element::{ElementChild, ElementExt, InnerHtmlAttribute},
35            node_ref::NodeRefAttribute,
36        },
37        renderer::{dom::Dom, Renderer},
38        view::{
39            add_attr::AddAnyAttr,
40            any_view::{AnyView, IntoAny, IntoMaybeErased},
41            IntoRender, Mountable, Render, RenderHtml,
42        },
43    };
44}
45
46use wasm_bindgen::JsValue;
47use web_sys::Node;
48
49/// Helpers for interacting with the DOM.
50pub mod dom;
51/// Types for building a statically-typed HTML view tree.
52pub mod html;
53/// Supports adding interactivity to HTML.
54pub mod hydration;
55/// Types for MathML.
56pub mod mathml;
57/// Defines various backends that can render views.
58pub mod renderer;
59/// Rendering views to HTML.
60pub mod ssr;
61/// Types for SVG.
62pub mod svg;
63/// Core logic for manipulating views.
64pub mod view;
65
66pub use either_of as either;
67#[cfg(feature = "islands")]
68#[doc(hidden)]
69pub use wasm_bindgen;
70#[cfg(feature = "islands")]
71#[doc(hidden)]
72pub use web_sys;
73
74/// View implementations for the `oco_ref` crate (cheaply-cloned string types).
75#[cfg(feature = "oco")]
76pub mod oco;
77/// View implementations for the `reactive_graph` crate.
78#[cfg(feature = "reactive_graph")]
79pub mod reactive_graph;
80
81/// A type-erased container.
82pub mod erased;
83
84pub(crate) trait UnwrapOrDebug {
85    type Output;
86
87    fn or_debug(self, el: &Node, label: &'static str);
88
89    fn ok_or_debug(
90        self,
91        el: &Node,
92        label: &'static str,
93    ) -> Option<Self::Output>;
94}
95
96impl<T> UnwrapOrDebug for Result<T, JsValue> {
97    type Output = T;
98
99    #[track_caller]
100    fn or_debug(self, el: &Node, name: &'static str) {
101        #[cfg(any(debug_assertions, leptos_debuginfo))]
102        {
103            if let Err(err) = self {
104                let location = std::panic::Location::caller();
105                web_sys::console::warn_3(
106                    &JsValue::from_str(&format!(
107                        "[WARNING] Non-fatal error at {location}, while \
108                         calling {name} on "
109                    )),
110                    el,
111                    &err,
112                );
113            }
114        }
115        #[cfg(not(any(debug_assertions, leptos_debuginfo)))]
116        {
117            _ = self;
118        }
119    }
120
121    #[track_caller]
122    fn ok_or_debug(
123        self,
124        el: &Node,
125        name: &'static str,
126    ) -> Option<Self::Output> {
127        #[cfg(any(debug_assertions, leptos_debuginfo))]
128        {
129            if let Err(err) = &self {
130                let location = std::panic::Location::caller();
131                web_sys::console::warn_3(
132                    &JsValue::from_str(&format!(
133                        "[WARNING] Non-fatal error at {location}, while \
134                         calling {name} on "
135                    )),
136                    el,
137                    err,
138                );
139            }
140            self.ok()
141        }
142        #[cfg(not(any(debug_assertions, leptos_debuginfo)))]
143        {
144            self.ok()
145        }
146    }
147}
148
149#[doc(hidden)]
150#[macro_export]
151macro_rules! or_debug {
152    ($action:expr, $el:expr, $label:literal) => {
153        if cfg!(any(debug_assertions, leptos_debuginfo)) {
154            $crate::UnwrapOrDebug::or_debug($action, $el, $label);
155        } else {
156            _ = $action;
157        }
158    };
159}
160
161#[doc(hidden)]
162#[macro_export]
163macro_rules! ok_or_debug {
164    ($action:expr, $el:expr, $label:literal) => {
165        if cfg!(any(debug_assertions, leptos_debuginfo)) {
166            $crate::UnwrapOrDebug::ok_or_debug($action, $el, $label)
167        } else {
168            $action.ok()
169        }
170    };
171}