viewpoint_js/
lib.rs

1//! Compile-time validated JavaScript macro for Viewpoint.
2//!
3//! This crate provides a `js!` macro that validates JavaScript syntax at compile time,
4//! similar to how `serde_json::json!` validates JSON. This catches JavaScript syntax
5//! errors early, before they reach the browser.
6//!
7//! # Features
8//!
9//! - **Compile-time validation**: JavaScript syntax errors are caught during compilation
10//! - **Rust variable interpolation**: Embed Rust expressions using `#{expr}` syntax
11//! - **Zero runtime overhead**: Static strings when no interpolation is used
12//! - **Clear error messages**: Points to the exact location of syntax errors
13//!
14//! # Usage
15//!
16//! ```rust,ignore
17//! use viewpoint_js::js;
18//! use viewpoint_js_core::ToJsValue; // Needed for interpolation
19//!
20//! // Simple expression - produces &'static str
21//! let code = js!{ 1 + 2 };
22//!
23//! // Arrow function
24//! let code = js!{ () => window.innerWidth };
25//!
26//! // With Rust variable interpolation (requires ToJsValue in scope)
27//! let selector = ".my-class";
28//! let code = js!{ document.querySelector(#{selector}) };
29//!
30//! // Multi-line function
31//! let code = js!{
32//!     (() => {
33//!         const items = document.querySelectorAll('li');
34//!         return items.length;
35//!     })()
36//! };
37//! ```
38//!
39//! # Interpolation
40//!
41//! Use `#{expr}` to embed Rust expressions into JavaScript. Values are automatically
42//! converted to JavaScript representations via the [`ToJsValue`] trait:
43//!
44//! - Strings are quoted and escaped
45//! - Numbers are inserted as-is
46//! - Booleans become `true` or `false`
47//! - `Option::None` becomes `null`
48//!
49//! [`ToJsValue`]: viewpoint_js_core::ToJsValue
50
51use proc_macro::TokenStream;
52
53mod interpolation;
54mod js_macro;
55mod parser;
56
57/// A macro that validates JavaScript syntax at compile time.
58///
59/// This macro accepts JavaScript code and validates its syntax during compilation.
60/// If the JavaScript is invalid, a compile-time error is produced with details
61/// about the syntax error.
62///
63/// # Output Type
64///
65/// - Without interpolation: Returns `&'static str`
66/// - With interpolation: Returns `String`
67///
68/// # Examples
69///
70/// ## Simple Expression
71///
72/// ```rust,ignore
73/// use viewpoint_js::js;
74///
75/// let code: &str = js!{ 1 + 2 };
76/// assert_eq!(code, "1 + 2");
77/// ```
78///
79/// ## Arrow Function
80///
81/// ```rust,ignore
82/// use viewpoint_js::js;
83///
84/// let code = js!{ () => window.innerWidth };
85/// ```
86///
87/// ## With Interpolation
88///
89/// ```rust,ignore
90/// use viewpoint_js::js;
91/// use viewpoint_js_core::ToJsValue;
92///
93/// let selector = ".my-class";
94/// let code: String = js!{ document.querySelector(#{selector}) };
95/// ```
96///
97/// ## Invalid JavaScript (Compile Error)
98///
99/// ```rust,ignore,compile_fail
100/// use viewpoint_js::js;
101///
102/// // This will produce a compile-time error because the JavaScript is invalid
103/// let code = js!{ function( };
104/// ```
105#[proc_macro]
106pub fn js(input: TokenStream) -> TokenStream {
107    js_macro::js_impl(input)
108}