# `RustQ`
[🔗](https://github.com/dannote/rustq/blob/v0.11.1/lib/rustq.ex#L1)

Rust template quasiquoting and code generation.

RustQ renders real Rust templates from Elixir. Parse a template, bind
placeholder identifiers/expressions, splice Rust fragments, then generate
formatted Rust source.

The most common entry points are:

  * `render!/3` for one-shot rendering from a string template.
  * `render_file!/2` for `.rs` template files.
  * `parse!/2`, `bind/2`, `splice/3`, and `render!/1,2` for pipeline-style generation.
  * `parse_fragment!/2` and `valid_fragment?/2` for validating explicit escapes.

Use `RustQ.Rust.AST` builders for generated structure, the cohesive
`RustQ.Rustler` submodules for Rustler generation, and `RustQ.Config` plus
`mix rustq.gen` for project-level generated files.

# `source`

```elixir
@type source() :: iodata()
```

# `bind`

```elixir
@spec bind(
  RustQ.Template.t(),
  keyword()
) :: RustQ.Template.t()
```

Binds Rust placeholders in a parsed template.

RustQ placeholders use the `__rq_` prefix. Use `__rq_Name` where Rust expects
an identifier/type/lifetime, and `__rq_name!()` where Rust expects an
expression or type macro.

Values may be strings, atoms, `{:literal, value}`, `{:expr, code}`, or
`{:type, type}` where type is accepted by `RustQ.Rust.AST.TypeBuilder.type/1`.

# `parse`

```elixir
@spec parse(source(), String.t()) :: {:ok, RustQ.Template.t()} | {:error, [map()]}
```

Parses and validates a Rust template.

`filename` is used only in error messages; it does not need to exist on disk.

# `parse!`

```elixir
@spec parse!(source(), String.t()) :: RustQ.Template.t()
```

Like `parse/2`, but returns the template directly or raises on errors.

# `parse_file`

```elixir
@spec parse_file(
  Path.t(),
  keyword()
) :: {:ok, RustQ.Template.t()} | {:error, [map()] | File.posix()}
```

Reads and parses a Rust template file.

Template files may include other Rust template files with
`__rq_include!("relative/path.rs");`. Includes are expanded before Rust
parsing and are resolved relative to the including file by default. Pass
`:include_dir` to override the root directory for the initial file.

# `parse_file!`

```elixir
@spec parse_file!(
  Path.t(),
  keyword()
) :: RustQ.Template.t()
```

Like `parse_file/1`, but returns the template directly or raises on errors.

# `parse_fragment`

```elixir
@spec parse_fragment(atom(), term()) ::
  {:ok, RustQ.Rust.Fragment.t()} | {:error, [map()]}
```

Parses and validates a Rust fragment for a specific context.

Supported contexts are `:item`, `:impl_item`, `:field`, `:stmt`, `:arg`,
`:arm`, `:expr`, and `:type`.

# `parse_fragment!`

```elixir
@spec parse_fragment!(atom(), term()) :: RustQ.Rust.Fragment.t()
```

Like `parse_fragment/2`, but returns the fragment directly or raises on errors.

# `render`

```elixir
@spec render(RustQ.Template.t()) :: {:ok, String.t()} | {:error, [map()]}
```

Parses and renders source, or renders an already parsed template.

Options:

  * `:bind` - bindings passed to `bind/2`.
  * `:splice` - splice replacements passed to `splice/3`.
  * `:preamble` - optional text prepended after formatting.

# `render`

```elixir
@spec render(
  RustQ.Template.t(),
  keyword()
) :: {:ok, String.t()} | {:error, [map()]}
@spec render(source(), String.t()) :: {:ok, String.t()} | {:error, [map()]}
```

# `render`

```elixir
@spec render(source(), String.t(), keyword()) :: {:ok, String.t()} | {:error, [map()]}
```

# `render!`

```elixir
@spec render!(RustQ.Template.t()) :: String.t()
```

Like `render/1,2,3`, but raises on errors.

# `render!`

```elixir
@spec render!(
  RustQ.Template.t(),
  keyword()
) :: String.t()
@spec render!(source(), String.t()) :: String.t()
```

# `render!`

```elixir
@spec render!(source(), String.t(), keyword()) :: String.t()
```

# `render_file`

```elixir
@spec render_file(
  Path.t(),
  keyword()
) :: {:ok, String.t()} | {:error, [map()] | File.posix()}
```

Renders a Rust template file.

Accepts the same options as `render/3`.

# `render_file!`

```elixir
@spec render_file!(
  Path.t(),
  keyword()
) :: String.t()
```

Like `render_file/2`, but raises on errors.

# `splice`

```elixir
@spec splice(RustQ.Template.t(), RustQ.Splice.source()) :: RustQ.Template.t()
```

Splices a keyword/map/nested list of splice replacements.

Duplicate names are concatenated, which allows independent generators to
contribute fragments to the same splice point.

# `splice`

```elixir
@spec splice(RustQ.Template.t(), atom(), term() | [term()]) :: RustQ.Template.t()
```

Splices fragments into a parsed template.

The splice name matches placeholders such as `__rq_items!();`,
`__rq_fields: (),`, or `__rq_arms => unreachable!(),`.

# `valid?`

```elixir
@spec valid?(source(), String.t()) :: boolean()
```

Returns true when source is a valid Rust template.

# `valid_fragment?`

```elixir
@spec valid_fragment?(atom(), term()) :: boolean()
```

Returns true when a Rust fragment is valid for the given context.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
