mod noun;

#[macro_use]
extern crate criterion;
use criterion::{Criterion};

use verba::noun::{Noun};
use verba::noun as N;

use noun::*;

/// Benchmark the creation of first declension regular nouns.
fn benchmark_create_first_noun(c: &mut Criterion) {
    c.bench_function("create regular first declension noun", |b| b.iter(|| {
        N::Regular::new("porta".to_string(), "portae".to_string(), N::Gender::Feminine)
    }));
}

fn benchmark_create_second_masculine_noun(c: &mut Criterion) {
    c.bench_function("create regular second declension masculine noun", |b| b.iter(|| {
        N::Regular::new("dominus".to_string(), "dominī".to_string(), N::Gender::Masculine)
    }));
}

fn benchmark_create_second_neuter_noun(c: &mut Criterion) {
    c.bench_function("create regular second declension neuter noun", |b| b.iter(|| {
        N::Regular::new("bellum".to_string(), "bellī".to_string(), N::Gender::Masculine)
    }));
}

fn benchmark_first_singular_nominative(c: &mut Criterion) {
    let noun = create_porta_portae();

    c.bench_function("single first declension", move |b| b.iter(|| {
        noun.decline(N::Number::Singular, N::Case::Nominative);
    }));
}

fn benchmark_second_masculine_singular_nominative(c: &mut Criterion) {
    let noun = create_dominus_domini();

    c.bench_function("single second declension masculine", move |b| b.iter(|| {
        noun.decline(N::Number::Singular, N::Case::Nominative)
    }));
}

criterion_group!(create, benchmark_create_first_noun, benchmark_create_second_masculine_noun, benchmark_create_second_neuter_noun);
criterion_group!(singular_nominative, benchmark_first_singular_nominative, benchmark_second_masculine_singular_nominative);
criterion_main!(create, singular_nominative);