facebook / starlark-rust

A Rust implementation of the Starlark language

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

How to return values from Starlark?

GaryBoone opened this issue · comments

I'm creating my own values and functions and extracting them from Starklark for use in Rust. But what's the right way to return my objects from the Starlark modules? Eg, how should they be returned from something like:

pub fn read_file(fname: &str) -> anyhow::Result<Animal> {...}

The problem that I encountered was that my extracted values were local, so Rust complained about returning local variables. I found a simple solution: don't make the module local: Pass it in and let it contain the resulting value:

pub fn read_file<'a>(module: &'a Module, fname: &str) -> anyhow::Result<&'a Animal> {...}

However, now I'm using the load() Starlark command, following the example here: https://docs.rs/starlark/0.4.0/starlark/#enable-the-load-statement. But in that example, the get_module()` function creates a local module for each load. I'm able to load my object like:

let ab = get_module(fname)?;
let vv = ab.get("puppy").expect("error getting variable");
let val = Animal::from_value(vv.value()).ok_or(anyhow!("error extracting value"));

But trying to return Ok(val) of course results in a "cannot return value referencing local variable". I suppose I could modify get_module() to accept a module to contain the values, as above, or Box it, which would require my object to implement copy, but I wonder if there's a simpler or intended way for starlark-rust?

The easiest way is just to call clone on the Animal - and unless you are doing something which can't be cloned for some reason, or has very tight performance bounds, that will be the easiest thing to do. If you are using FrozenModule you can use an OwnedFrozenValue to pass around the result, but it's more work than a simple Clone.

Success. Animal wasn't Clone. Simple fix.