Module evaluate_wolfram_code_from_rust

Source
Expand description

§How To: Evaluate Wolfram code from Rust

§Generating Wolfram messages from Rust

Suppose you want to generate a Wolfram Message[..] from within Rust.

The easiest way to accomplish this is to construct an appropriate Wolfram expression using the Expr type, and then use the evaluate() function to call back into Wolfram to evaluate that expression.

Rust

use wolfram_library_link::{
    self as wll, export,
    expr::{Expr, Symbol},
};

#[export(wstp)]
fn generate_message(_: Vec<Expr>) {
    // Construct the expression `Message[MySymbol::msg, "..."]`.
    let message = Expr::normal(Symbol::new("System`Message"), vec![
        // MySymbol::msg is MessageName[MySymbol, "msg"]
        Expr::normal(Symbol::new("System`MessageName"), vec![
            Expr::from(Symbol::new("Global`MySymbol")),
            Expr::string("msg"),
        ]),
        Expr::string("a Rust LibraryLink function"),
    ]);

    // Evaluate the message expression.
    let _: Expr = wll::evaluate(&message);
}

Wolfram

MySymbol::msg = "This is a message generated from ``";

(* FIXME: For some reason, the test below fails with the following message unless
	we _save the result_ of calling Links[]:
		LinkObject::linkd: Unable to communicate with closed link LinkObject[...]
	Note that this only happens when running the tests using
	`wolfram-cli paclet test`, so it's likely this is some unknown conflict.
*)
before = Links[];

VerificationTest[
    generateMessage = LibraryFunctionLoad[
        "libwll_docs", "generate_message",
        LinkObject, LinkObject
    ];

    (* Note:
        Set $Context and $ContextPath to force symbols sent
        via WSTP to include their context. *)
    Block[{$Context = "Empty`", $ContextPath = {}},
        generateMessage[]
    ]
    ,
    Null
    ,
    {HoldForm[Message[MySymbol::msg, "a Rust LibraryLink function"]]}
]

§Using Print[..] from Rust

TODO