{{
    const champions = require('./.champion.json')
        .filter(({ id }) => id > 0)
        .sort(({ name: a }, { name: b }) => a > b ? 1 : -1);
    const hashFactor = 256;
    const enumName = name => name.replace(/[^a-z]+/i, '');
    const strHash = function(str) {
        let h = 0;
        for (let c of str)
            h = hashFactor * h + c.charCodeAt(0);
        return h;
    };
    const padId = function(id) { return ('' + id).padEnd(3); };
}}
// This file is automatically generated.
// Do not directly edit.
// Generated on {{= (new Date).toISOString() }}

use std::fmt;
use num_derive;

#[derive(fmt::Debug, Copy, Clone)]
#[derive(num_derive::FromPrimitive, num_derive::ToPrimitive)]
pub enum Champion {
{{
    for (let { id, name } of champions) {
}}
    {{= enumName(name).padEnd(12) }} = {{= id }},
{{
    }
}}
    }

impl Champion {
    pub fn name(self) -> &'static str {
        match self {
{{
    for (let { id, name } of champions) {
}}
            Self::{{= enumName(name).padEnd(12) }} => "{{= name }}",
{{
    }
}}
        }
    }

    pub fn identifier(self) -> &'static str {
        match self {
{{
    for (let { name, alias } of champions) {
}}
            Self::{{= enumName(name).padEnd(12) }} => "{{= alias }}",
{{
    }
}}
        }
    }
}

impl std::str::FromStr for Champion {
    type Err = ();

    fn from_str(val: &str) -> Result<Self, Self::Err> {
        // 4 characters encoded as an int.
        match val.chars()
            .filter(|c| c.is_ascii_alphabetic())
            .take(4)
            .map(|c| c.to_ascii_uppercase() as u32)
            .fold(0u32, |hash, next| hash * {{= hashFactor }} + next)
        {
{{
    let keyStrings = (name, alias) => new Set([].concat(...[ name, alias ].map(s => s.toUpperCase())
        .map(s => [
            s.replace(/[^A-Z]+/, '').substring(0, 4),
            s.split(/[^A-Z]/, 1)[0].substring(0, 4)
        ])));
    for (let { id, alias, name } of champions) {
        for (let prefix of keyStrings(name, alias)) {
}}
            {{= ('' + strHash(prefix)).padEnd(10) }} /* {{= prefix.padEnd(4) }} */ => Ok(Self::{{= enumName(name) }}),
{{
        }
    }
}}
            _ => Err(()),
        }
    }
}

impl fmt::Display for Champion {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:?}", self)
    }
}