<commit_before>---
layout: article
title:  "Rust Algorithm Development"
excerpt: "Build your algorithm in Rust"
date: 2016-05-17  09:50:46
permalink: /algorithm-development/guides/rust-guide
tags: [algo-guide-lang]
show_related: true
author: liz_rush
image:
    teaser: /language_logos/rust.png
---

Algorithmia supports development of algorithms in Rust.

#### Handling Input and Output

Text input is handled implementing `EntryPoint` to override `apply_str`.

{% highlight rust %}
#[derive(Default)]
pub struct Algo;

impl EntryPoint for Algo {
    fn apply_str(&self, input: &str) -> Result<AlgoOutput, Box<std::error::Error>> {
        let msg = format!("Hello {}", input);
        Ok(AlgoOutput::Text(msg))
    }
}
{% endhighlight %}

#### Handle binary input:
Binary input is handled implementing `EntryPoint` to override `apply_bytes`.

{% highlight rust %}
#[derive(Default)]
pub struct Algo;

impl EntryPoint for Algo {
    fn apply_bytes(&self, input: &[u8]) -> Result<AlgoOutput, Box<std::error::Error>> {
       Ok(AlgoOutput::Binary(input.to_owned()))
    }
}
{% endhighlight %}

#### Handle JSON input:
JSON input can be handled by implementing `EntryPoint` to override `apply_bytes`.
This provides the algorithm with the `rustc_serialize` `Json` enum as input.
(See also the alternative ways of handling auto-decoded JSON input.)

{% highlight rust %}
use rustc_serialize::json::Json;

#[derive(Default)]
pub struct Algo;

impl EntryPoint for Algo {
    fn apply_json(&self, input: &Json) -> Result<AlgoOutput, Box<std::error::Error>> {
      Ok(AlgoOutput::Json(input.to_owned()))
    }
}
{% endhighlight %}


#### Auto-decode JSON input:
JSON input can be automatically decoded to type of your choosing.
To do this, implement `DecodedEntryPoint` to override `apply_decoded`.
This also requires defining the trait's associated type named `Input`
to a type that you want input decoded into.

{% highlight rust %}
#[derive(Default)]
pub struct Algo;

impl DecodedEntryPoint for Algo {
    type Input = (String, u32);  // Handles JSON array input structured like: [String, Number]
    fn apply_decoded(&self, input: Self::Input) -> Result<AlgoOutput, Box<std::error::Error>> {
        let msg = format("Received string '{}' and number '{}", input.0, input.1);
        Ok(AlgoOutput::Text(msg))
    }
}
{% endhighlight %}

You can extend this idea to decode more complex, structured input JSON.
This example defines a struct that derives `RustcDecodable` so that input
is automatically decoded into a `TaskDefinition`

{% highlight rust %}
#[derive(Default)]
pub struct Algo;

#[derive(RustcDecodable)]
pub struct TaskDefinition {
  foo: String,
  bar: u64,
}

impl DecodedEntryPoint for Algo {
    type Input = TaskDefinition;
    fn apply_decoded(&self, input: Self::Input) -> Result<AlgoOutput, Box<std::error::Error>> {
        let msg = format("Received string '{}' and number '{}", input.foo, input.bar);
        Ok(AlgoOutput::Text(msg))
    }
}
{% endhighlight %}

Rust algorithms are expected to have a public type named `Algo` that implements the [`algorithmia::algo::EntryPoint`](http://algorithmiaio.github.io/algorithmia-rust/algorithmia/algo/trait.EntryPoint.html) trait.
In many cases, you may prefer to implement [`algorithmia::algo::DecodedEntryPoint`](http://algorithmiaio.github.io/algorithmia-rust/algorithmia/algo/trait.DecodedEntryPoint.html) which provides an alternate implementation of `EntryPoint`.

How you implement `EntryPoint` depends entirely on the input you want your algorithm to receive.

- For text input, override [`apply_str`](http://algorithmiaio.github.io/algorithmia-rust/algorithmia/algo/trait.EntryPoint.html#method.apply_str)
- For binary input, override [`apply_bytes`](http://algorithmiaio.github.io/algorithmia-rust/algorithmia/algo/trait.EntryPoint.html#method.apply_bytes)
- For JSON input:
  - Override [`apply_json`](http://algorithmiaio.github.io/algorithmia-rust/algorithmia/algo/trait.EntryPoint.html#method.apply_json) if you want to work with the `rustc_serialize` [`Json` enum](https://doc.rust-lang.org/rustc-serialize/rustc_serialize/json/enum.Json.html) as input
  - Implement `DecodedEntryPoint` and override [`apply_decoded`](http://algorithmiaio.github.io/algorithmia-rust/algorithmia/algo/trait.DecodedEntryPoint.html#tymethod.apply_decoded) if you want to automatically decode the input to a type that you define

In all cases, the output of your algorithm will be `Result`-wrapped [`algorithmia::algo::AlgoOutput`](http://algorithmiaio.github.io/algorithmia-rust/algorithmia/algo/enum.AlgoOutput.html) which can represent text, json, or binary output.
There are several `From` conversions implemented to make it possible to simply `return Ok("Some text".into())`

There are several code snippets on the right to demonstrate the possibilities.

#### Error Handling

All the `apply` method variants return a `Result<AlgoOutput, Box<std::error::Error>>`,
which should make it possible to return almost any `Error` type, including by using the `try!` macro.
For simple algorithms, it may suffice to simply return `Err("some error message".into())`

#### Managing Dependencies
<commit_msg>Reorder rust algodev guide a bit<commit_after>---
layout: article
title:  "Rust Algorithm Development"
excerpt: "Build your algorithm in Rust"
date: 2016-05-17  09:50:46
permalink: /algorithm-development/guides/rust-guide
tags: [algo-guide-lang]
show_related: true
author: liz_rush
image:
    teaser: /language_logos/rust.png
---

Algorithmia supports development of algorithms in Rust.

#### Handling Input and Output

Rust algorithms are expected to have a public type named `Algo` that implements the [`algorithmia::algo::EntryPoint`](http://algorithmiaio.github.io/algorithmia-rust/algorithmia/algo/trait.EntryPoint.html) trait.
In many cases, you may prefer to implement [`algorithmia::algo::DecodedEntryPoint`](http://algorithmiaio.github.io/algorithmia-rust/algorithmia/algo/trait.DecodedEntryPoint.html) which provides an alternate implementation of `EntryPoint`.

How you implement `EntryPoint` depends entirely on the input you want your algorithm to receive.

- For text input, override [`apply_str`](http://algorithmiaio.github.io/algorithmia-rust/algorithmia/algo/trait.EntryPoint.html#method.apply_str)
- For binary input, override [`apply_bytes`](http://algorithmiaio.github.io/algorithmia-rust/algorithmia/algo/trait.EntryPoint.html#method.apply_bytes)
- For JSON input:
  - Override [`apply_json`](http://algorithmiaio.github.io/algorithmia-rust/algorithmia/algo/trait.EntryPoint.html#method.apply_json) if you want to work with the `rustc_serialize` [`Json` enum](https://doc.rust-lang.org/rustc-serialize/rustc_serialize/json/enum.Json.html) as input
  - Implement `DecodedEntryPoint` and override [`apply_decoded`](http://algorithmiaio.github.io/algorithmia-rust/algorithmia/algo/trait.DecodedEntryPoint.html#tymethod.apply_decoded) if you want to automatically decode the input to a type that you define

In all cases, the output of your algorithm will be `Result`-wrapped [`algorithmia::algo::AlgoOutput`](http://algorithmiaio.github.io/algorithmia-rust/algorithmia/algo/enum.AlgoOutput.html) which can represent text, json, or binary output.
There are several `From` conversions implemented to make it possible to simply `return Ok("Some text".into())`

There are several examples below to demonstrate the possibilities.

#### Handle text input:

Text input is handled implementing `EntryPoint` to override `apply_str`.

{% highlight rust %}
#[derive(Default)]
pub struct Algo;

impl EntryPoint for Algo {
    fn apply_str(&self, input: &str) -> Result<AlgoOutput, Box<std::error::Error>> {
        let msg = format!("Hello {}", input);
        Ok(AlgoOutput::Text(msg))
    }
}
{% endhighlight %}

#### Handle binary input:
Binary input is handled implementing `EntryPoint` to override `apply_bytes`.

{% highlight rust %}
#[derive(Default)]
pub struct Algo;

impl EntryPoint for Algo {
    fn apply_bytes(&self, input: &[u8]) -> Result<AlgoOutput, Box<std::error::Error>> {
       Ok(AlgoOutput::Binary(input.to_owned()))
    }
}
{% endhighlight %}

#### Handle JSON input:
JSON input can be handled by implementing `EntryPoint` to override `apply_bytes`.
This provides the algorithm with the `rustc_serialize` `Json` enum as input.
(See also the alternative ways of handling auto-decoded JSON input.)

{% highlight rust %}
use rustc_serialize::json::Json;

#[derive(Default)]
pub struct Algo;

impl EntryPoint for Algo {
    fn apply_json(&self, input: &Json) -> Result<AlgoOutput, Box<std::error::Error>> {
      Ok(AlgoOutput::Json(input.to_owned()))
    }
}
{% endhighlight %}


#### Auto-decode JSON input:
JSON input can be automatically decoded to type of your choosing.
To do this, implement `DecodedEntryPoint` to override `apply_decoded`.
This also requires defining the trait's associated type named `Input`
to a type that you want input decoded into.

{% highlight rust %}
#[derive(Default)]
pub struct Algo;

impl DecodedEntryPoint for Algo {
    type Input = (String, u32);  // Handles JSON array input structured like: [String, Number]
    fn apply_decoded(&self, input: Self::Input) -> Result<AlgoOutput, Box<std::error::Error>> {
        let msg = format("Received string '{}' and number '{}", input.0, input.1);
        Ok(AlgoOutput::Text(msg))
    }
}
{% endhighlight %}

You can extend this idea to decode more complex, structured input JSON.
This example defines a struct that derives `RustcDecodable` so that input
is automatically decoded into a `TaskDefinition`

{% highlight rust %}
#[derive(Default)]
pub struct Algo;

#[derive(RustcDecodable)]
pub struct TaskDefinition {
  foo: String,
  bar: u64,
}

impl DecodedEntryPoint for Algo {
    type Input = TaskDefinition;
    fn apply_decoded(&self, input: Self::Input) -> Result<AlgoOutput, Box<std::error::Error>> {
        let msg = format("Received string '{}' and number '{}", input.foo, input.bar);
        Ok(AlgoOutput::Text(msg))
    }
}
{% endhighlight %}


#### Error Handling

All the `apply` method variants return a `Result<AlgoOutput, Box<std::error::Error>>`,
which should make it possible to return almost any `Error` type, including by using the `try!` macro.
For simple algorithms, it may suffice to simply return `Err("some error message".into())`

#### Managing Dependencies

{'fraction_non_alphanumeric': 0.12288830968240178, 'fraction_numerical': 0.00405444540978859, 'mean_word_length': 5.040816326530612, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 37, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1691406', 'n_tokens_mistral': 3130, 'n_tokens_neox': 3111, 'n_words': 967}