forge-rsx 0.1.0

A Rust macro library for declarative, JSX-like HTML generation. It allows you to write HTML structures with embedded logic, attributes, nested tags, loops, and more, directly in Rust code with a concise syntax.
Documentation
# forge-rsx


`forge-rsx` is a Rust macro library for declarative, JSX-like HTML generation. It allows you to write HTML structures with embedded logic, attributes, nested tags, loops, and more, directly in Rust code with a concise syntax.

---

## Features


- Declarative HTML macro: `rsx!` macro
- Supports nested tags, attributes, loops, and embedded expressions
- Indentation-aware formatting
- String literal and identifier attributes
- Flexible syntax for defining complex HTML structures

---

## Usage


Run the following Cargo `command` in your project directory:

```shell
cargo add forge-rsx
```

Or add `forge-rsx` as a dependency in your `Cargo.toml`:

```toml
[dependencies]
forge-rsx = "MAJOR.MINOR.PATCH" # Replace with the latest version
```

In your Rust code, import the macro:

```rust
use forge_rsx::rsx;
```

---

## Macro Variants


- `lined`: produces HTML without indentation or line breaks (single-line output)
- `btfy0`: uses 0 spaces (no indentation, minified output)
- `btfy2`: Indentation with 2 spaces per level.
- `btfy4`: Indentation with 4 spaces per level.

### Examples:


```rust
rsx!(btfy0, div { "No indentation" });
rsx!(btfy2, div { "Indented with 2 spaces" });
rsx!(btfy4, div { "Indented with 4 spaces" });
```

---

## Examples


### Basic Tag with Content


```rust
let greeting = rsx!(lined, span { "Hello, World!" });
println!("{}", greeting);
```

### Nested Tags


```rust
let nested_html = rsx!(lined, div {
    header {
        span { "Navigation" }
    }
    section {
        p { "Welcome to the forge-rsx template!" }
    }
});
println!("{}", nested_html);
```

### Attributes


```rust
let button_html = rsx!(lined, button {
    class: "btn-primary",
    "data-toggle": "modal",
    "Click me!"
});
println!("{}", button_html);
```

### Loop Example


```rust
let users = vec!["Ahmed", "Mohamed", "Montasir"];

let list_html = rsx!(lined, ul {
    for user in &users => {
        li { { format!("User: {}", user) } }
    }
});
println!("{}", list_html);
```

### Full Complex Example


```rust
use forge_rsx::{rsx, get_char};
fn main() {
    let apple = "🍎 Apple";
    let apple_component = rsx!(lined, span { {&apple} });
    let fruits = vec!["🍇", "mango", "orange"];
    let div = rsx!(btfy4, div { "..." 
        {"<!--  How to use attributes with hyphens, like x-show in Alpine.js -->"}
        span {
            id: "my-id",
            class: "my-class",
            "x-show": "",
            ":class": "p-4",
            "..."
        }
        "..."
    });
    let span = rsx!(btfy0, span { "..." });
    let empty_p = rsx!(btfy2, p { });
    let p = rsx!(btfy2, p {"..."});
    let section = rsx!(btfy4, section { div { ol { 
        for fruit in &fruits => {
            li {
                span {
                    {
                        if fruit == &"🍇" {
                            &format!("{} {}", fruit.to_string(), "Grapes")

                        } else if fruit == &"mango" {
                            &format!("{} {}", "🥭", fruit.to_lowercase())
                        } else {
                            &fruit.to_uppercase()
                        }
                    }
                }
            }
        }
        li { 
            {"<!-- How to join RSX component -->"}
            {&apple_component.to_string()} 
            {
                if get_char(&apple, 1).to_string() == "🍎" {
                    "🍎".to_string()
                } else {
                    apple_component.to_string()
                }
            }
        }
    } } });
    println!(
        "{}\n\n{}\n\n{}\n\n{}\n\n{}", 
        div, span, empty_p, p, section
    );
    // <div>
    //     ...
    //     <!--  How to use attributes with hyphens, like x-show in Alpine.js -->
    //     <span id="my-id" class="my-class" x-show='' :class='p-4'>
    //         ...
    //     </span>
    //     ...
    // </div>
    //
    // <span>
    // ...
    // </span>
    //
    // <p></p>
    //
    // <p>
    //   ...
    // </p>
    //
    // <section>
    //     <div>
    //         <ol>
    //             <li>
    //                 <span>
    //                     🍇 Grapes
    //                 </span>
    //             </li>
    //             <li>
    //                 <span>
    //                     🥭 mango
    //                 </span>
    //             </li>
    //             <li>
    //                 <span>
    //                     ORANGE
    //                 </span>
    //             </li>
    //             <li>
    //                 <!-- How to join RSX component -->
    //                 <span>🍎 Apple</span>
    //                 🍎
    //             </li>
    //         </ol>
    //     </div>
    // </section>
}
```

---

## License


MIT License

---

## Notes


- The macro supports attributes with string literals and identifiers.
- Nested tags are handled with recursive macro calls.
- Looping constructs generate repeated content.
- Content inside braces `{}` can contain any Rust expression that implements `Display`.

---