//! Custom Askama filters.

/// Returns `singular` if `count == 1`, otherwise `plural`.
pub fn pluralize(count: &usize, singular: &str, plural: &str) -> askama::Result<String> {
    Ok(if *count == 1 {
        singular.to_string()
    } else {
        plural.to_string()
    })
}

/// Returns the first 8 characters of `s`, or the whole string if shorter.
///
/// Unlike a raw `s[..8]` slice, this never panics on short input, so it is
/// safe to apply to SHAs and refs taken directly from request paths.
fn short_chars(s: &str) -> String {
    s.chars().take(8).collect()
}

/// Askama filter `{{ value|short }}`: the first 8 characters of the input.
#[askama::filter_fn]
pub fn short<T: std::fmt::Display>(s: T, _: &dyn askama::Values) -> askama::Result<String> {
    Ok(short_chars(&s.to_string()))
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn pluralize_singular() {
        assert_eq!(pluralize(&1, "item", "items").unwrap(), "item");
    }

    #[test]
    fn pluralize_zero() {
        assert_eq!(pluralize(&0, "item", "items").unwrap(), "items");
    }

    #[test]
    fn pluralize_multiple() {
        assert_eq!(pluralize(&3, "item", "items").unwrap(), "items");
    }

    #[test]
    fn short_full() {
        assert_eq!(short_chars("0123456789abcdef"), "01234567");
    }

    #[test]
    fn short_abbreviated() {
        assert_eq!(short_chars("863a47b"), "863a47b");
    }

    #[test]
    fn short_branch_name() {
        assert_eq!(short_chars("main"), "main");
    }

    #[test]
    fn short_empty() {
        assert_eq!(short_chars(""), "");
    }
}
