The Evolution of a Rust Programmer

Freshman Rust Programmer

fn main() {
    let mut line = String::new();
    std::io::stdin().read_line(&mut line).unwrap();
    let mut sum = 0;
    for word in line.split_whitespace() {
        let num = word.parse::<i64>().unwrap();
        sum += num;
    }
    println!("Sum: {}", sum);
}

Sophomore Rust Programmer

(studied C as a freshman)

extern crate libc;

use libc::{c_char, printf, scanf, EOF};

fn main() {
    unsafe {
        let mut num = 0;
        let mut sum = 0;
        while(scanf(b"%d\0" as *const u8 as *const c_char, &mut num) != EOF) {
            sum += num;
        }
        printf(b"Sum: %d\n\0" as *const u8 as *const c_char, sum);
    }
}

Junior Rust Programmer

(read that unwrap() foils rust’s error management philosophy and joined the "It should be removed in favor of expect() "-movement)

fn main() {
    let mut line = String::new();
    std::io::stdin().read_line(&mut line).expect("read line");
    let mut sum = 0;
    for word in line.split_whitespace() {
        let num = word.parse::<i64>().expect("parse");
        sum += num;
    }
    println!("Sum: {}", sum);
}

Senior Rust Programmer

(learned proper error management)

use std::error;
use std::fmt::{self, Display, Formatter};
use std::io;
use std::num::ParseIntError;
use std::result;

#[derive(Debug)]
enum Error {
    Io(io::Error),
    Parse(ParseIntError),
}

impl Display for Error {
    fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
        match *self {
            Error::Io(ref error) => error.fmt(formatter),
            Error::Parse(ref error) => error.fmt(formatter),
        }
    }
}

impl error::Error for Error {
}

impl From<io::Error> for Error {
    fn from(error: io::Error) -> Self {
        Error::Io(error)
    }
}

impl From<ParseIntError> for Error {
    fn from(error: ParseIntError) -> Self {
        Error::Parse(error)
    }
}

type Result<T> = result::Result<T, Error>;

fn main() -> Result<()> {
    let mut line = String::new();
    std::io::stdin().read_line(&mut line)?;
    let mut sum = 0;
    for word in line.split_whitespace() {
        let num = word.parse::<i64>()?;
        sum += num;
    }
    println!("Sum: {}", sum);
    Ok(())
}

Functional Rust Programmer

(studied Haskell as a freshman and loathes mutability)

use std::io::BufRead;

fn main() {
    let stdin = std::io::stdin();
    let line = stdin.lock().lines().next().unwrap().unwrap();
    let sum: i64 =
        line.split_whitespace()
            .map(|word| word.parse::<i64>().unwrap())
            .sum();
    println!("Sum: {}", sum);
}

Object-oriented Programmer

(studied Java as a freshman)

use std::ops::Deref;

struct Nums {
    vector: Vec<i64>,
}

impl Nums {
    fn new() -> Self {
        Nums {
            vector: Vec::new(),
        }
    }

    fn add(&mut self, num: i64) {
        self.vector.push(num);
    }

    fn get_sum(&self) -> i64 {
        (*self).iter().sum()
    }
}

impl Deref for Nums {
    type Target = Vec<i64>;

    fn deref(&self) -> &Self::Target {
        &self.vector
    }
}

fn main() {
    let mut line = String::new();
    std::io::stdin().read_line(&mut line).unwrap();
    let mut nums = Nums::new();
    for word in line.split_whitespace() {
        let num = word.parse::<i64>().unwrap();
        nums.add(num);
    }
    println!("Sum: {}", nums.get_sum());
}

Macro-man

(misses Lisp macros)

use std::fmt::{self, Display, Formatter};
use std::io;
use std::num::ParseIntError;
use std::result;

macro_rules! from {
    ($from:ty, $typ:ty, $result:expr) => {
        impl From<$from> for $typ {
            fn from(error: $from) -> Self {
                $result(error)
            }
        }
    };
}

macro_rules! display {
    ($typ:ty, [$($patterns:path),*]) => {
        impl Display for $typ {
            fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
                match *self {
                    $($patterns(ref error) => error.fmt(formatter)),*
                }
            }
        }
    };
}

macro_rules! error {
    ($typ:ty) => {
        impl ::std::error::Error for $typ {
        }
    };
}

#[derive(Debug)]
enum Error {
    Io(io::Error),
    Parse(ParseIntError),
}

display!(Error, [Error::Io, Error::Parse]);
error!(Error);
from!(io::Error, Error, Error::Io);
from!(ParseIntError, Error, Error::Parse);

type Result<T> = result::Result<T, Error>;

fn main() -> Result<()> {
    let mut line = String::new();
    std::io::stdin().read_line(&mut line)?;
    let mut sum = 0;
    for word in line.split_whitespace() {
        let num = word.parse::<i64>()?;
        sum += num;
    }
    println!("Sum: {}", sum);
    Ok(())
}

Macroceptor

(watched Inception)

use std::fmt::{self, Display, Formatter};
use std::io;
use std::num::ParseIntError;
use std::result;

macro_rules! display {
    ($typ:ty, [$($patterns:path),*]) => {
        impl Display for $typ {
            fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
                match *self {
                    $($patterns(ref error) => error.fmt(formatter)),*
                }
            }
        }
    };
}

macro_rules! error {
    ($typ:ty) => {
        impl ::std::error::Error for $typ {
        }

        macro_rules! from {
            ($from:ty, $result:expr) => {
                impl From<$from> for $typ {
                    fn from(error: $from) -> Self {
                        $result(error)
                    }
                }
            };
        }
    };
}

#[derive(Debug)]
enum Error {
    Io(io::Error),
    Parse(ParseIntError),
}

display!(Error, [Error::Io, Error::Parse]);
error!(Error);
from!(io::Error, Error::Io);
from!(ParseIntError, Error::Parse);

type Result<T> = result::Result<T, Error>;

fn main() -> Result<()> {
    let mut line = String::new();
    std::io::stdin().read_line(&mut line)?;
    let mut sum = 0;
    for word in line.split_whitespace() {
        let num = word.parse::<i64>()?;
        sum += num;
    }
    println!("Sum: {}", sum);
    Ok(())
}

Procedural Macro God

(needs more power)

main.rs
#![feature(proc_macro_hygiene)]

extern crate lib;

use lib::scanfold;

fn main() {
    let sum = scanfold!("%ld+", |num: i64, acc: i64| num + acc);
    println!("Sum: {}", sum);
}
lib.rs
extern crate proc_macro;
extern crate proc_macro2;
extern crate quote;
extern crate syn;

use proc_macro::TokenStream;
use proc_macro2::Span;
use quote::{quote, quote_spanned};
use syn::{Error, Expr, ExprClosure, LitStr, Token, parse};
use syn::parse::{Parse, ParseStream, Result};
use syn::spanned::Spanned;

struct Parameters {
    format: LitStr,
    closure: ExprClosure,
}

impl Parse for Parameters {
    fn parse(input: ParseStream) -> Result<Self> {
        let format = input.parse()?;
        let _comma: Token![,] = input.parse()?;
        let closure: Expr = input.parse()?;
        match closure {
            Expr::Closure(closure) =>
                Ok(Parameters {
                    format,
                    closure,
                }),
            _ => Err(Error::new(closure.span(), "Argument must be a closure"))
        }
    }
}

#[derive(PartialEq)]
enum Param {
    Unknown,
    Int,
    Long,
    LongInt,
    Repeat(Box<Param>),
}

fn to_code(span: Span, param: &Param, recursive: bool) -> proc_macro2::TokenStream {
    let start =
        if recursive {
            quote! {
            }
        }
        else {
            quote! {
                let word = line.split_whitespace().next().unwrap();
            }
        };
    match param {
        Param::Unknown => quote_spanned! {
            span => compile_error!("invalid format string")
        },
        Param::Int => quote! {{
            #start
            let num = word.parse::<i32>().unwrap();
            closure(num, acc)
        }},
        Param::Long | Param::LongInt => quote! {{
            #start
            let num = word.parse::<i64>().unwrap();
            closure(num, acc)
        }},
        Param::Repeat(ref inner_param) => {
            let inner_code = to_code(span, inner_param, true);
            quote! {{
                for word in line.split_whitespace() {
                    acc = #inner_code;
                }
                acc
            }}
        },
    }
}

#[proc_macro]
pub fn scanfold(input: TokenStream) -> TokenStream {
    let parameters: Result<Parameters> = parse(input);
    let result =
        match parameters {
            Ok(params) => {
                let format = params.format.value();
                let mut is_param = false;
                let mut param = Param::Unknown;
                for char in format.chars() {
                    if is_param {
                        match char {
                            'd' =>
                                if param == Param::Long {
                                    param = Param::LongInt;
                                }
                                else {
                                    param = Param::Int;
                                },
                            'l' => param = Param::Long,
                            '+' => param = Param::Repeat(Box::new(param)),
                            _ => (),
                        }
                    }
                    else if char == '%' {
                        is_param = true;
                    }
                }
                let code = to_code(params.format.span(), &param, false);
                let closure = params.closure;
                quote! {{
                    let closure = #closure;
                    let mut line = String::new();
                    let mut acc = 0;
                    std::io::stdin().read_line(&mut line).unwrap();
                    #code
                }}
            },
            Err(error) => {
                let msg = error.to_string();
                quote_spanned! { error.span() =>
                    compile_error!(#msg)
                }
            },
        };
    result.into()
}

Another senior Rust programmer

(learned to reduce boilerplate with macros)

extern crate error_chain;

use std::io;
use std::num::ParseIntError;

use error_chain::*;

error_chain! {
    types {
        Error, ErrorKind, ResultExt, Result;
    }

    foreign_links {
        Io(io::Error);
        Parse(ParseIntError);
    }
}

fn main() -> Result<()> {
    let mut line = String::new();
    std::io::stdin().read_line(&mut line)?;
    let mut sum = 0;
    for word in line.split_whitespace() {
        let num = word.parse::<i64>()?;
        sum += num;
    }
    println!("Sum: {}", sum);
    Ok(())
}

Yet another senior Rust programmer

(switched from error-chain to stay up-to-date)

extern crate failure;
extern crate failure_derive;

use std::result;

use failure::bail;
use failure_derive::Fail;

#[derive(Debug, Fail)]
enum Error {
    #[fail(display = "empty string")]
    Empty,
}

type Result<T> = result::Result<T, failure::Error>;

fn main() -> Result<()> {
    let mut line = String::new();
    std::io::stdin().read_line(&mut line)?;
    let mut sum = 0;
    let mut empty = true;
    for word in line.split_whitespace() {
        empty = false;
        let num = word.parse::<i64>()?;
        sum += num;
    }
    if empty {
        bail!(Error::Empty);
    }
    println!("Sum: {}", sum);
    Ok(())
}

Hyper-Functional Rust Programmer

(misses Haskell so much that he needs an additional library for more functional power)

extern crate itertools;

use std::io::BufRead;

use itertools::fold;

fn main() {
    let stdin = std::io::stdin();
    let line = stdin.lock().lines().next().unwrap().unwrap();
    let iter =
        line.split_whitespace()
            .map(|word| word.parse::<i64>().unwrap());
    let sum = fold(iter, 0, |a, b| a + b);
    println!("Sum: {}", sum);
}

Combinative Rust Programmer

(learned that nom is faster than parsec)

extern crate nom;

use std::str::FromStr;

use nom::{call, digit, error_position, many1, map_res, named, recognize, sep, wrap_sep, ws};
use nom::types::CompleteStr;

named!(numbers<CompleteStr, Vec<i64>>,
    many1!(ws!(
        map_res!(recognize!(digit), |complete_str: CompleteStr| i64::from_str(&*complete_str))
    ))
);

fn main() {
    let mut line = String::new();
    std::io::stdin().read_line(&mut line).unwrap();
    line.pop();
    let (_input, nums) = numbers(line.as_str().into()).unwrap();
    let sum: i64 = nums.iter().sum();
    println!("Sum: {}", sum);
}

Rust Fast and Elegant Parser Writer

(learned that pest is faster than nom)

extern crate pest;
#[macro_use]
extern crate pest_derive;

use pest::Parser;

#[derive(Parser)]
#[grammar = "nums.pest"]
struct Nums;

fn main() {
    let mut line = String::new();
    std::io::stdin().read_line(&mut line).unwrap();
    let pairs = Nums::parse(Rule::nums, &line).unwrap();
    let mut sum = 0;
    for pair in pairs {
        for word in pair.into_inner() {
            let num = word.as_str().parse::<i64>().unwrap();
            sum += num;
        }
    }
    println!("Sum: {}", sum);
}

Outdated Rust Programmer

(learned Rust in 2009)

extern crate rustc_serialize;

use std::collections::VecDeque;
use std::num::ParseIntError;

use rustc_serialize::Decodable;

#[derive(RustcDecodable)]
struct Nums {
    nums: Vec<i64>,
}

fn main() {
    let mut line = String::new();
    std::io::stdin().read_line(&mut line).unwrap();
    let nums: Nums = decode(line).unwrap();
    let sum: i64 = nums.nums.iter().sum();
    println!("Sum: {}", sum);
}

struct Decoder {
    nums: VecDeque<i64>,
}

impl Decoder {
    fn new(input: String) -> Result<Self, ParseIntError> {
        let nums: Result<VecDeque<i64>, ParseIntError> = input.split_whitespace().map(|word| word.parse::<i64>())
            .collect();
        Ok(Self {
            nums: nums?,
        })
    }
}

impl rustc_serialize::Decoder for Decoder {
    fn read_i64(&mut self) -> Result<i64, Self::Error> {
        self.nums.pop_front().ok_or(())
    }

    fn read_struct<T, F>(&mut self, _struct_name: &str, _len: usize, f: F) -> Result<T, Self::Error> where F: FnOnce(&mut Self) -> Result<T, Self::Error> {
        f(self)
    }

    fn read_struct_field<T, F>(&mut self, _f_name: &str, _f_idx: usize, f: F) -> Result<T, Self::Error> where F: FnOnce(&mut Self) -> Result<T, Self::Error> {
        f(self)
    }

    fn read_seq<T, F>(&mut self, f: F) -> Result<T, Self::Error> where F: FnOnce(&mut Self, usize) -> Result<T, Self::Error> {
        let len = self.nums.len();
        f(self, len)
    }

    fn read_seq_elt<T, F>(&mut self, _idx: usize, f: F) -> Result<T, Self::Error>
    where
        F: FnOnce(&mut Self) -> Result<T, Self::Error>
    {
        f(self)
    }

    type Error = ();
    fn read_nil(&mut self) -> Result<(), Self::Error> { unimplemented!() }
    fn read_usize(&mut self) -> Result<usize, Self::Error> { unimplemented!() }
    fn read_u64(&mut self) -> Result<u64, Self::Error> { unimplemented!() }
    fn read_u32(&mut self) -> Result<u32, Self::Error> { unimplemented!() }
    fn read_u16(&mut self) -> Result<u16, Self::Error> { unimplemented!() }
    fn read_u8(&mut self) -> Result<u8, Self::Error> { unimplemented!() }
    fn read_isize(&mut self) -> Result<isize, Self::Error> { unimplemented!() }
    fn read_i32(&mut self) -> Result<i32, Self::Error> { unimplemented!() }
    fn read_i16(&mut self) -> Result<i16, Self::Error> { unimplemented!() }
    fn read_i8(&mut self) -> Result<i8, Self::Error> { unimplemented!() }
    fn read_bool(&mut self) -> Result<bool, Self::Error> { unimplemented!() }
    fn read_f64(&mut self) -> Result<f64, Self::Error> { unimplemented!() }
    fn read_f32(&mut self) -> Result<f32, Self::Error> { unimplemented!() }
    fn read_char(&mut self) -> Result<char, Self::Error> { unimplemented!() }
    fn read_str(&mut self) -> Result<String, Self::Error> { unimplemented!() }
    fn read_enum<T, F>(&mut self, _name: &str, _f: F) -> Result<T, Self::Error> where F: FnOnce(&mut Self) -> Result<T, Self::Error> { unimplemented!() }
    fn read_enum_variant<T, F>(&mut self, _names: &[&str], _f: F) -> Result<T, Self::Error> where F: FnMut(&mut Self, usize) -> Result<T, Self::Error> { unimplemented!() }
    fn read_enum_variant_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Self::Error> where F: FnOnce(&mut Self) -> Result<T, Self::Error> { unimplemented!() }
    fn read_enum_struct_variant<T, F>(&mut self, _names: &[&str], _f: F) -> Result<T, Self::Error> where F: FnMut(&mut Self, usize) -> Result<T, Self::Error> { unimplemented!() }
    fn read_enum_struct_variant_field<T, F>(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result<T, Self::Error> where F: FnOnce(&mut Self) -> Result<T, Self::Error> { unimplemented!() }
    fn read_tuple<T, F>(&mut self, _len: usize, _f: F) -> Result<T, Self::Error> where F: FnOnce(&mut Self) -> Result<T, Self::Error> { unimplemented!() }
    fn read_tuple_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Self::Error> where F: FnOnce(&mut Self) -> Result<T, Self::Error> { unimplemented!() }
    fn read_tuple_struct<T, F>(&mut self, _s_name: &str, _len: usize, _f: F) -> Result<T, Self::Error> where F: FnOnce(&mut Self) -> Result<T, Self::Error> { unimplemented!() }
    fn read_tuple_struct_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Self::Error> where F: FnOnce(&mut Self) -> Result<T, Self::Error> { unimplemented!() }
    fn read_option<T, F>(&mut self, _f: F) -> Result<T, Self::Error> where F: FnMut(&mut Self, bool) -> Result<T, Self::Error> { unimplemented!() }
    fn read_map<T, F>(&mut self, _f: F) -> Result<T, Self::Error> where F: FnOnce(&mut Self, usize) -> Result<T, Self::Error> { unimplemented!() }
    fn read_map_elt_key<T, F>(&mut self, _idx: usize, _f: F) -> Result<T, Self::Error> where F: FnOnce(&mut Self) -> Result<T, Self::Error> { unimplemented!() }
    fn read_map_elt_val<T, F>(&mut self, _idx: usize, _f: F) -> Result<T, Self::Error> where F: FnOnce(&mut Self) -> Result<T, Self::Error> { unimplemented!() }
    fn error(&mut self, _err: &str) -> Self::Error { unimplemented!() }
}

fn decode<T: Decodable>(string: String) -> Option<T> {
    let mut decoder = Decoder::new(string).unwrap();
    Decodable::decode(&mut decoder).ok()
}

Hyped Rust Programmer

(learned that serde is the new shiny thing for serialization)

extern crate serde;
extern crate serde_derive;

use std::collections::VecDeque;
use std::num::ParseIntError;

use serde::{Deserialize, Deserializer};
use serde::de::{DeserializeSeed, SeqAccess, Visitor};
use serde::de::value::Error;

pub fn from_str<T>(s: &str) -> Result<T, Error>
where for<'a> T: Deserialize<'a>,
{
    let mut deserializer = Decoder::from_str(s.to_string()).unwrap();
    let t = T::deserialize(&mut deserializer)?;
    if deserializer.nums.is_empty() {
        Ok(t)
    }
    else {
        use serde::de::Error;
        Err(Error::custom("empty input"))
    }
}

fn main() {
    let mut line = String::new();
    std::io::stdin().read_line(&mut line).unwrap();
    let nums: Vec<i64> = from_str(&line).unwrap();
    let sum: i64 = nums.iter().sum();
    println!("Sum: {}", sum);
}

struct Decoder {
    nums: VecDeque<i64>,
}

impl Decoder {
    fn from_str(input: String) -> Result<Self, ParseIntError> {
        let nums: Result<VecDeque<i64>, ParseIntError> = input.split_whitespace().map(|word| word.parse::<i64>())
            .collect();
        Ok(Self {
            nums: nums?,
        })
    }
}

impl<'de, 'a> Deserializer<'de> for &'a mut Decoder {
    type Error = Error;

    fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
    where
        V: Visitor<'de> {
        visitor.visit_i64(self.nums.pop_front().unwrap())
    }

    fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
    where
        V: Visitor<'de> {
        visitor.visit_seq(Struct { de: self })
    }

    fn deserialize_struct<V>(self, _name: &'static str, _fields: &'static [&'static str], _visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_map<V>(self, _visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> { unimplemented!(); }
    fn deserialize_identifier<V>(self, _visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> { unimplemented!(); }
    fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_bool<V>(self, _visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_i8<V>(self, _visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_i16<V>(self, _visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_i32<V>(self, _visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_u8<V>(self, _visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_u16<V>(self, _visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_u32<V>(self, _visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_u64<V>(self, _visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_f32<V>(self, _visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_f64<V>(self, _visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_char<V>(self, _visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_str<V>(self, _visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_string<V>(self, _visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_bytes<V>(self, _visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_byte_buf<V>(self, _visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_option<V>(self, _visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_unit<V>(self, _visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_unit_struct<V>(self, _name: &'static str, _visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_newtype_struct<V>(self, _name: &'static str, _visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_tuple<V>(self, _len: usize, _visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_tuple_struct<V>(self, _name: &'static str, _len: usize, _visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_enum<V>(self, _name: &'static str, _variants: &'static [&'static str], _visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_ignored_any<V>(self, _visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> { unimplemented!() }
}

struct Struct<'a> {
    de: &'a mut Decoder,
}

impl<'de, 'a> SeqAccess<'de> for Struct<'a> {
    type Error = Error;

    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Error>
    where
        T: DeserializeSeed<'de>,
    {
        if self.de.nums.is_empty() {
            return Ok(None);
        }
        seed.deserialize(&mut *self.de).map(Some)
    }
}

Blazingly Concurrent Programmer

(wanted a proof that Rust indeed prevents data races)

extern crate rayon;

use rayon::iter::ParallelIterator;
use rayon::str::ParallelString;

use std::io::BufRead;

fn main() {
    let stdin = std::io::stdin();
    let line = stdin.lock().lines().next().unwrap().unwrap();
    let sum: i64 =
        line.par_split_whitespace()
            .map(|word| word.parse::<i64>().unwrap())
            .sum();
    println!("Sum: {}", sum);
}

Outdated Async Rust Programmer

(learned Rust async library in 2009)

extern crate mio;

use std::io;

use mio::{Events, Poll, Ready, PollOpt, Token};
use mio::unix::EventedFd;

const STDIN_FD: i32 = 0;
const STDIN_TOKEN: Token = Token(0);

fn main() -> io::Result<()> {
    let mut sum = 0;
    let poll = Poll::new()?;
    poll.register(&EventedFd(&STDIN_FD), STDIN_TOKEN, Ready::readable(), PollOpt::edge())?;
    let mut events = Events::with_capacity(1);
    'event_loop:
    loop {
        poll.poll(&mut events, None)?;
        for event in &events {
            match event.token() {
                STDIN_TOKEN => {
                    let mut line = String::new();
                    std::io::stdin().read_line(&mut line).unwrap();
                    for word in line.split_whitespace() {
                        let num = word.parse::<i64>().unwrap();
                        sum += num;
                    }
                    break 'event_loop;
                },
                _ => unreachable!(),
            }
        }
    }
    println!("Sum: {}", sum);
    Ok(())
}

Senior Dependenciely-Typed Rust Programmer

(learned to use all the best crates of the Rust ecosystem)

// High score (total number of dependencies): 99

#![feature(generators, proc_macro_hygiene, try_trait)]

extern crate error_chain;
extern crate futures_await as futures;
extern crate lazy_static;
extern crate rayon;
extern crate serde;
extern crate serde_derive;
extern crate tokio;
extern crate tokio_codec;
extern crate tokio_fs;
extern crate tokio_io;
extern crate tokio_threadpool;

use std::collections::VecDeque;
use std::fmt::Display;
use std::io;
use std::num::ParseIntError;
use std::option::NoneError;
use std::sync::Mutex;

use futures::prelude::{async, await};
use lazy_static::lazy_static;
use rayon::iter::ParallelIterator;
use rayon::str::ParallelString;
use serde::{Deserialize, Deserializer};
use serde::de::{self, DeserializeSeed, SeqAccess, Visitor};
use tokio::prelude::Future;
use tokio_codec::{FramedRead, LinesCodec};
use tokio_fs::{stdin, stdout};
use tokio_io::io::write_all;
use tokio_threadpool::Builder;

use error_chain::*;

lazy_static! {
    static ref NUMS: Mutex<VecDeque<i64>> = Mutex::new(VecDeque::new());
}

error_chain! {
    types {
        Error, ErrorKind, ResultExt, Result;
    }

    foreign_links {
        Io(io::Error);
        Parse(ParseIntError);
    }

    errors {
        Async {
            description("async error")
            display("useful async error")
        }
        EmptyVec {
            description("empty vec")
            display("empty vec")
        }
    }
}

impl From<()> for Error {
    fn from((): ()) -> Self {
        ErrorKind::Async.into()
    }
}

impl From<NoneError> for Error {
    fn from(_: NoneError) -> Self {
        ErrorKind::EmptyVec.into()
    }
}

impl de::Error for Error {
    fn custom<T: Display>(msg: T) -> Self {
        msg.to_string().into()
    }
}

#[async]
fn future() -> Result<()> {
    let stdin = FramedRead::new(stdin(), LinesCodec::new());
    #[async]
    for line in stdin {
        let nums: Vec<i64> = from_str(&line)?;
        let sum: i64 = nums.iter().sum();
        await!(write_all(stdout(), format!("Sum: {}\n", sum).into_bytes()))?;
    }
    Ok(())
}

fn main() -> Result<()> {
    let pool = Builder::new().pool_size(1).build();
    pool.spawn(future().map_err(|_| ()));
    pool.shutdown_on_idle().wait()?;
    Ok(())
}

pub fn from_str<T>(s: &str) -> Result<T>
where for<'a> T: Deserialize<'a>,
{
    let mut deserializer = Decoder::from_str(s.to_string())?;
    let t = T::deserialize(&mut deserializer)?;
    if NUMS.lock().unwrap().is_empty() {
        Ok(t)
    }
    else {
        Err(serde::de::Error::custom("empty input"))
    }
}

struct Decoder {
}

impl Decoder {
    fn from_str(input: String) -> Result<Self> {
        let nums: Result<VecDeque<i64>> = input.par_split_whitespace().map(|word| word.parse::<i64>().map_err(|err| err.into()))
            .collect();
        *NUMS.lock().unwrap() = nums?;
        Ok(Self {
        })
    }
}

impl<'de, 'a> Deserializer<'de> for &'a mut Decoder {
    type Error = Error;

    fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value>
    where
        V: Visitor<'de> {
        visitor.visit_i64(NUMS.lock().unwrap().pop_front()?)
    }

    fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
    where
        V: Visitor<'de> {
        visitor.visit_seq(Struct { de: self })
    }

    fn deserialize_struct<V>(self, _name: &'static str, _fields: &'static [&'static str], _visitor: V) -> Result<V::Value> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_map<V>(self, _visitor: V) -> Result<V::Value> where V: Visitor<'de> { unimplemented!(); }
    fn deserialize_identifier<V>(self, _visitor: V) -> Result<V::Value> where V: Visitor<'de> { unimplemented!(); }
    fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_bool<V>(self, _visitor: V) -> Result<V::Value> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_i8<V>(self, _visitor: V) -> Result<V::Value> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_i16<V>(self, _visitor: V) -> Result<V::Value> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_i32<V>(self, _visitor: V) -> Result<V::Value> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_u8<V>(self, _visitor: V) -> Result<V::Value> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_u16<V>(self, _visitor: V) -> Result<V::Value> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_u32<V>(self, _visitor: V) -> Result<V::Value> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_u64<V>(self, _visitor: V) -> Result<V::Value> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_f32<V>(self, _visitor: V) -> Result<V::Value> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_f64<V>(self, _visitor: V) -> Result<V::Value> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_char<V>(self, _visitor: V) -> Result<V::Value> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_str<V>(self, _visitor: V) -> Result<V::Value> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_string<V>(self, _visitor: V) -> Result<V::Value> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_bytes<V>(self, _visitor: V) -> Result<V::Value> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_byte_buf<V>(self, _visitor: V) -> Result<V::Value> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_option<V>(self, _visitor: V) -> Result<V::Value> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_unit<V>(self, _visitor: V) -> Result<V::Value> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_unit_struct<V>(self, _name: &'static str, _visitor: V) -> Result<V::Value> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_newtype_struct<V>(self, _name: &'static str, _visitor: V) -> Result<V::Value> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_tuple<V>(self, _len: usize, _visitor: V) -> Result<V::Value> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_tuple_struct<V>(self, _name: &'static str, _len: usize, _visitor: V) -> Result<V::Value> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_enum<V>(self, _name: &'static str, _variants: &'static [&'static str], _visitor: V) -> Result<V::Value> where V: Visitor<'de> { unimplemented!() }
    fn deserialize_ignored_any<V>(self, _visitor: V) -> Result<V::Value> where V: Visitor<'de> { unimplemented!() }
}

struct Struct<'a> {
    de: &'a mut Decoder,
}

impl<'de, 'a> SeqAccess<'de> for Struct<'a> {
    type Error = Error;

    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<<T as serde::de::DeserializeSeed<'de>>::Value>>
    where
        T: DeserializeSeed<'de>,
    {
        if NUMS.lock().unwrap().is_empty() {
            return Ok(None);
        }
        seed.deserialize(&mut *self.de).map(Some)
    }
}

Copyright © 2019 Antoni Boucher All rights reserved