diff --git a/examples/hello/rust/Cargo.toml b/examples/hello/rust/Cargo.toml new file mode 100644 index 000000000..7c3608e1d --- /dev/null +++ b/examples/hello/rust/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "func" +version = "0.1.0" +authors = ["Seif Lotfy "] + +[dependencies] diff --git a/examples/hello/rust/README.md b/examples/hello/rust/README.md new file mode 100644 index 000000000..1cd547c84 --- /dev/null +++ b/examples/hello/rust/README.md @@ -0,0 +1,30 @@ +# Using rust with functions + +The easiest way to create a iron function in rust is via ***cargo*** and ***fn***. + +## Prerequisites +First create an epty rust project as follows: +```bash +cargo init --name func --bin +``` + +Make sure the project name is ***func*** and is of type ***bin***. Now just edit your code, once done you can create an iron function. + +## Creating an IronFunction +Simply run + +```bash +fn init --runtime=rust / +``` + +This will create the ```func.yaml``` file required by functions, which can be built by running: + +```bash +fn build +``` + +## Testing + +```bash +fn run +``` diff --git a/examples/hello/rust/src/main.rs b/examples/hello/rust/src/main.rs new file mode 100644 index 000000000..020c757b1 --- /dev/null +++ b/examples/hello/rust/src/main.rs @@ -0,0 +1,10 @@ +use std::io; +use std::io::Read; + +fn main() { + let mut buffer = String::new(); + let stdin = io::stdin(); + if stdin.lock().read_to_string(&mut buffer).is_ok() { + println!("Hello {}", buffer.trim()); + } +} diff --git a/fn/common.go b/fn/common.go index ee91b1a77..3aba3b160 100644 --- a/fn/common.go +++ b/fn/common.go @@ -235,6 +235,7 @@ var acceptableFnRuntimes = map[string]string{ "python": "iron/python:2", "ruby": "iron/ruby", "scala": "iron/scala", + "rust": "corey/rust-alpine", } const tplDockerfile = `FROM {{ .BaseImage }} diff --git a/fn/init.go b/fn/init.go index 218eac347..36fcbd143 100644 --- a/fn/init.go +++ b/fn/init.go @@ -27,6 +27,7 @@ var ( ".js": "node", ".rb": "ruby", ".py": "python", + ".rs": "rust", } fnInitRuntimes []string diff --git a/fn/langs/base.go b/fn/langs/base.go index 3edcb1c20..bc0117ffb 100644 --- a/fn/langs/base.go +++ b/fn/langs/base.go @@ -13,6 +13,8 @@ func GetLangHelper(lang string) (LangHelper, error) { return &RubyLangHelper{}, nil case "python": return &PythonHelper{}, nil + case "rust": + return &RustLangHelper{}, nil } return nil, fmt.Errorf("No language helper found for %v", lang) } diff --git a/fn/langs/rust.go b/fn/langs/rust.go new file mode 100644 index 000000000..eb580742d --- /dev/null +++ b/fn/langs/rust.go @@ -0,0 +1,42 @@ +package langs + +import ( + "fmt" + "os" + "os/exec" +) + +type RustLangHelper struct{} + +func (lh *RustLangHelper) Entrypoint() string { + return "/function/target/release/func" +} + +func (lh *RustLangHelper) HasPreBuild() bool { + return true +} + +// PreBuild for rust builds the binary so the final image can be as small as possible +func (lh *RustLangHelper) PreBuild() error { + wd, err := os.Getwd() + if err != nil { + return err + } + + cmd := exec.Command( + "docker", "run", + "--rm", "-v", + wd+":/app", "-w", "/app", "corey/rust-alpine", + "/bin/sh", "-c", "cargo build --release", + ) + cmd.Stderr = os.Stderr + cmd.Stdout = os.Stdout + if err := cmd.Run(); err != nil { + return fmt.Errorf("error running docker build: %v", err) + } + return nil +} + +func (lh *RustLangHelper) AfterBuild() error { + return os.RemoveAll("target") +}