1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
//! Rustagram - Apply instagram filters to your photos.
//!
//! ## Example
//!
//! ```rust,no_run
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! use rustagram::{RustagramFilter, FilterType};
//!
//! let img = image::open("myimage.png")?;
//! let modified = img.to_rgba8().apply_filter(FilterType::Valencia);
//! # Ok(())
//! # }
//! ```

use std::fmt;
use std::{fmt::Display, str::FromStr};

/// Re-export of the `image` crate.
pub use image;

pub use filters::{FilterType, RustagramFilter};

mod filters;
mod rustaops;

/// Failed to parse a valid filter from the given name.
#[derive(Debug)]
pub struct InvalidFilterName;

impl Display for InvalidFilterName {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
        write!(f, "{:?}", self)
    }
}

impl FromStr for FilterType {
    type Err = InvalidFilterName;

    fn from_str(filter: &str) -> Result<Self, Self::Err> {
        let search_result = AVAILABLE_FILTERS.iter().find(|f| f.0 == filter);
        match search_result {
            Some((_, filter)) => Ok(*filter),
            None => Err(InvalidFilterName),
        }
    }
}

const AVAILABLE_FILTERS: &[(&str, FilterType)] = &[
    ("1977", FilterType::NineTeenSeventySeven),
    ("aden", FilterType::Aden),
    ("brannan", FilterType::Brannan),
    ("brooklyn", FilterType::Brooklyn),
    ("clarendon", FilterType::Clarendon),
    ("earlybird", FilterType::Earlybird),
    ("gingham", FilterType::Gingham),
    ("hudson", FilterType::Hudson),
    ("inkwell", FilterType::Inkwell),
    ("kelvin", FilterType::Kelvin),
    ("lark", FilterType::Lark),
    ("lofi", FilterType::Lofi),
    ("maven", FilterType::Maven),
    ("mayfair", FilterType::Mayfair),
    ("moon", FilterType::Moon),
    ("nashville", FilterType::Nashville),
    ("reyes", FilterType::Reyes),
    ("rise", FilterType::Rise),
    ("slumber", FilterType::Slumber),
    ("stinson", FilterType::Stinson),
    ("toaster", FilterType::Toaster),
    ("valencia", FilterType::Valencia),
    ("walden", FilterType::Walden),
];