rustagram/
lib.rs

1//! Rustagram - Apply instagram filters to your photos.
2//!
3//! ## Example
4//!
5//! ```rust,no_run
6//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
7//! use rustagram::{RustagramFilter, FilterType};
8//!
9//! let img = image::open("myimage.png")?;
10//! let modified = img.to_rgba8().apply_filter(FilterType::Valencia);
11//! # Ok(())
12//! # }
13//! ```
14
15use std::fmt;
16use std::{fmt::Display, str::FromStr};
17
18/// Re-export of the `image` crate.
19pub use image;
20
21pub use filters::{FilterType, RustagramFilter};
22
23mod filters;
24mod rustaops;
25
26/// Failed to parse a valid filter from the given name.
27#[derive(Debug)]
28pub struct InvalidFilterName;
29
30impl Display for InvalidFilterName {
31    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
32        write!(f, "{:?}", self)
33    }
34}
35
36impl FromStr for FilterType {
37    type Err = InvalidFilterName;
38
39    fn from_str(filter: &str) -> Result<Self, Self::Err> {
40        let search_result = AVAILABLE_FILTERS
41            .iter()
42            .find(|f| f.0.eq_ignore_ascii_case(filter));
43        match search_result {
44            Some((_, filter)) => Ok(*filter),
45            None => Err(InvalidFilterName),
46        }
47    }
48}
49
50const AVAILABLE_FILTERS: &[(&str, FilterType)] = &[
51    ("1977", FilterType::NineTeenSeventySeven),
52    ("nineteenseventyseven", FilterType::NineTeenSeventySeven),
53    ("aden", FilterType::Aden),
54    ("brannan", FilterType::Brannan),
55    ("brooklyn", FilterType::Brooklyn),
56    ("clarendon", FilterType::Clarendon),
57    ("earlybird", FilterType::Earlybird),
58    ("gingham", FilterType::Gingham),
59    ("hudson", FilterType::Hudson),
60    ("inkwell", FilterType::Inkwell),
61    ("kelvin", FilterType::Kelvin),
62    ("lark", FilterType::Lark),
63    ("lofi", FilterType::Lofi),
64    ("maven", FilterType::Maven),
65    ("mayfair", FilterType::Mayfair),
66    ("moon", FilterType::Moon),
67    ("nashville", FilterType::Nashville),
68    ("reyes", FilterType::Reyes),
69    ("rise", FilterType::Rise),
70    ("slumber", FilterType::Slumber),
71    ("stinson", FilterType::Stinson),
72    ("toaster", FilterType::Toaster),
73    ("valencia", FilterType::Valencia),
74    ("walden", FilterType::Walden),
75];
76
77#[cfg(test)]
78mod test {
79    use super::*;
80
81    #[test]
82    fn parses() {
83        assert_eq!(FilterType::NineTeenSeventySeven, "1977".parse().unwrap());
84        assert_eq!(
85            FilterType::NineTeenSeventySeven,
86            "NineTeenSeventySeven".parse().unwrap()
87        );
88        assert_eq!(
89            FilterType::NineTeenSeventySeven,
90            "nineteenseventyseven".parse().unwrap()
91        );
92    }
93}