The process of creating Rust actions is similar to that of other actions. The following sections guide you through creating and invoking a single Rust action, and demonstrate how to bundle multiple Rust files and third party dependencies.
An example action Rust action is simply a top-level function.
For example, create a file called hello.rs
with the following source code:
extern crate serde_json;
use serde_derive::{Deserialize, Serialize};
use serde_json::{Error, Value};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
struct Input {
#[serde(default = "stranger")]
name: String,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
struct Output {
greeting: String,
}
fn stranger() -> String {
"stranger".to_string()
}
pub fn main(args: Value) -> Result<Value, Error> {
let input: Input = serde_json::from_value(args)?;
let output = Output {
greeting: format!("Hello, {}", input.name),
};
serde_json::to_value(output)
}
Rust actions are mainly composed by a main
function that accepts a JSON serdes Value
as input and returns a Result
including a JSON serde Value
.
An action supports not only a JSON object but also a JSON array as a return value.
It would be a simple example that uses an array as a return value:
extern crate serde_json;
use serde_derive::{Deserialize, Serialize};
use serde_json::{Error, Value};
pub fn main(args: Value) -> Result<Value, Error> {
let output = ["a", "b"];
serde_json::to_value(output)
}
You can also create a sequence action with actions accepting an array param and returning an array result.
You can easily figure out the parameters with the following example:
extern crate serde_json;
use serde_derive::{Deserialize, Serialize};
use serde_json::{Error, Value};
pub fn main(args: Value) -> Result<Value, Error> {
let inputParam = args.as_array();
let defaultOutput = ["c", "d"];
match inputParam {
None => serde_json::to_value(defaultOutput),
Some(x) => serde_json::to_value(x),
}
}
The entry method for the action is main
by default but may be specified explicitly when creating
the action with the wsk
CLI using --main
, as with any other action type.
You can create an OpenWhisk action called helloRust
from this function as follows:
wsk action create helloRust --kind rust:1.34 hello.rs
The CLI automatically infers the type of the action from the source file extension.
For .rs
source files, the action runs using a Rust v1.34 runtime.
Action invocation is the same for Rust actions as it is for any other actions:
wsk action invoke --result helloRust --param name World
{
"greeting": "Hello World!"
}
Find out more about parameters in the Working with parameters section.
If your action needs external dependencies, you need to provide a zip file including your source and your cargo file with all your dependencies.
The filename of the source file containing the entry point (e.g., main
) must be lib.rs
.
The folder structure should be as follows:
|- Cargo.toml
|- src
|- lib.rs
Here is an example of a Cargo.toml file
[package]
name = "actions"
version = "0.1.0"
authors = ["John Doe <[email protected]>"]
edition = "2018"
[dependencies]
serde_json = "1.0"
serde = "1.0"
serde_derive = "1.0"
To zip your folder:
zip -r helloRust.zip Cargo.toml src
and then create the action:
wsk action create helloRust --kind rust:1.34 helloRust.zip