RustQ.Meta (rustq v1.0.0-rc.4)

Copy Markdown View Source

Valid-Elixir macro frontend for generating RustQ Rust fragments.

defrust captures a normal Elixir function-shaped body plus its preceding @spec, lowers that quoted Elixir AST to Rust, and exposes generated Rust items through __rustq_items__/0 and __rustq_source__/0.

defrustmod is for RustQ-owned Rust module structure. Prefer its block form when RustQ is generating the Rust module and the nested functions. Do not use it as a hand-written alias for Rust modules/types that are owned by another generator or crate; those callers should derive/render their Rust paths at their own codegen boundary instead of pretending external Rust modules are Elixir modules.

defrustimpl groups defrust declarations into an inherent or trait Rust impl block. The first argument of each method remains valid Elixir and must be typed as R.ref(Target.t()) or R.mut_ref(Target.t()); RustQ renders it as &self or &mut self respectively.

defrustmacro defines a small macro_rules! item from a Rusty-Elixir body. Its arguments are Rust macro fragments (:expr by default, with :ty supported for type arguments) while the body still uses ordinary Rusty-Elixir forms such as calls, decode_as!/2, and inference-backed propagation.

Prefer @spec plus defrust for user-facing Rusty Elixir. Generated or external Rust paths should normally be expressed as ordinary remote types such as GeneratedOpts.OvalOpts.t(R.lifetime(:a)); use RustQ.Type markers such as R.ref/1, R.nif_result/1, R.unit/0, R.slice/1, and R.lifetime/1 only where Elixir typespecs need Rust-specific precision. RustQ.Meta.AST.functions/1 and function!/2 are the public structural bridge for generators that consume compiled defrust functions; they are not the normal function-authoring surface.

Preferred Rusty-Elixir body forms are ordinary Elixir where possible:

  • final :ok under NifResult<()> returns Ok(())
  • name = expression lowers to Rust let name = expression
  • method calls, field access, aliases, and Elixir tuples lower to their Rust equivalents
  • plural alias calls such as Atoms.fill() lower to snake-case Rust module calls such as atoms::fill()
  • ordinary Elixir macros are expanded before lowering, so reusable body fragments can use defmacro, quote, and unquote
  • fallible calls in argument, return, case-scrutinee, some(...), decode_as!, and many local-binding positions can infer Rust ? from type metadata
  • unwrap!(expression) is the explicit spelling for Rust expression?; prefer inference when callable metadata is available
  • ref(expression) / mut_ref(expression) spell explicit Rust borrows; many ordinary calls infer borrows from expected argument types
  • deref(expression) spells Rust dereference and can propagate fallible reference access such as args.first().ok_or(badarg())
  • Option branching should use Elixir case, for example case maybe do {:some, value} -> ...; :none -> ... end; do not introduce Rust-shaped if_let syntax at the authoring layer

Escape hatches such as raw_expr! remain low-level last resorts, not the normal way to reference project-owned Rust modules or types.

Summary

Functions

Declares a public NIF entrypoint generated from a valid Elixir-shaped body.

Groups Rusty-Elixir methods into an inherent or trait Rust impl block.

Declares a private generated Rust helper from a valid Elixir-shaped body.

Functions

defnif(call_ast, list)

(macro)

Declares a public NIF entrypoint generated from a valid Elixir-shaped body.

defrust(call_ast, list)

(macro)

defrustimpl(target_or_trait_ast, opts \\ [], list)

(macro)

Groups Rusty-Elixir methods into an inherent or trait Rust impl block.

The first argument of every nested defrust declaration is the receiver. Its spec must use R.ref(...) for &self or R.mut_ref(...) for &mut self.

defrustimpl Counter, vis: :crate do
  @spec increment(R.mut_ref(R.path(:Counter)), R.i64()) :: R.i64()
  defrust increment(self, amount), do: self.value + amount
end

defrustimpl Display, for: Counter do
  @spec fmt(R.ref(R.path(:Counter)), R.path(:Formatter)) :: R.path(:FmtResult)
  defrust fmt(self, formatter), do: formatter.write_str(self.label.as_str())
end

Supported options are :for, :vis, :attrs, and :lifetimes.

defrustmacro(call_ast, list)

(macro)

defrustmod(alias_ast, opts \\ [])

(macro)

defrustmod(alias_ast, opts, list)

(macro)

defrustp(call_ast, list)

(macro)

Declares a private generated Rust helper from a valid Elixir-shaped body.