iso3166_1/
lib.rs

1// ISC License (ISC)
2//
3// Copyright (c) 2016, Austin Hellyer <hello@austinhellyer.me>
4//
5// Permission to use, copy, modify, and/or distribute this software for any
6// purpose with or without fee is hereby granted, provided that the above
7// copyright notice and this permission notice appear in all copies.
8//
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
12// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
13// RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
14// CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
15// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16//
17// What is ISO 3166-1?
18//
19// | ISO 3166-1 is part of the ISO 3166 standard published by the International
20// | Organization for Standardization (ISO), and defines codes for the names of
21// | countries, dependent territories, and special areas of geographical
22// | interest.
23// |
24// | - [Wikipedia](http://en.wikipedia.org/wiki/ISO_3166-1)
25//
26// Originally by taiyaeix on GitHub.
27
28mod codes;
29
30pub use codes::all;
31
32/// Struct that contains the data for each Country Code defined by ISO 3166-1,
33/// including the following pieces of information:
34///
35/// - `alpha2` - Two-character Alpha-2 code.
36/// - `alpha3` - Three-character Alpha-3 code.
37/// - `name` - English short name of country.
38/// - `num` - Numeric code of country.
39///
40/// Derives from Clone and Debug.
41#[derive(Clone, Debug)]
42pub struct CountryCode<'a> {
43    pub alpha2: &'a str,
44    pub alpha3: &'a str,
45    pub name: &'a str,
46    pub num: &'a str,
47}
48
49/// Returns an `Option` of a `CountryCode` with the given alpha2 code.
50///
51/// # Examples
52///
53/// ```rust
54/// let country = iso3166_1::alpha2("AF").unwrap();
55/// ```
56pub fn alpha2<'a>(alpha2: &str) -> Option<CountryCode<'a>> {
57    let mut code_ret: Option<CountryCode> = None;
58
59    for code in all() {
60        if code.alpha2 == alpha2 {
61            code_ret = Some(code.clone());
62
63            break;
64        }
65    }
66
67    code_ret
68}
69
70/// Returns an `Option` of a `CountryCode` with the given alpha3 code.
71///
72/// # Examples
73///
74/// ```rust
75/// let country = iso3166_1::alpha3("ATA").unwrap();
76/// ```
77pub fn alpha3<'a>(alpha3: &str) -> Option<CountryCode<'a>> {
78    let mut code_ret: Option<CountryCode> = None;
79
80    for code in all() {
81        if code.alpha3 == alpha3 {
82            code_ret = Some(code.clone());
83
84            break;
85        }
86    }
87
88    code_ret
89}
90
91/// Returns an `Option` of a `CountryCode` with the given name.
92///
93/// # Examples
94///
95/// ```rust
96/// let country = iso3166_1::name("Angola").unwrap();
97/// ```
98pub fn name<'a>(name: &str) -> Option<CountryCode<'a>> {
99    let mut code_ret: Option<CountryCode> = None;
100
101    for code in all() {
102        if code.name == name {
103            code_ret = Some(code.clone());
104
105            break;
106        }
107    }
108
109    code_ret
110}
111
112/// Returns an `Option` of a `CountryCode` with the given numeric value.
113///
114/// # Examples
115///
116/// ```rust
117/// let country = iso3166_1::num("016").unwrap();
118/// ```
119pub fn num<'a>(num: &str) -> Option<CountryCode<'a>> {
120    let mut code_ret: Option<CountryCode> = None;
121
122    for code in all() {
123        if code.num == num {
124            code_ret = Some(code.clone());
125
126            break;
127        }
128    }
129
130    code_ret
131}
132
133/// Returns a `Vec` of `CountryCode`s that have a numeric value within the range
134/// of the `from` and `to` given. The from and to are optional, and can either
135/// be `None` or `Some(&str)` for variations of the range wanted.
136///
137/// # Examples
138///
139/// Getting all values between `100` and `300`:
140///
141/// ```rust
142/// let countries = iso3166_1::num_range(Some("100"), Some("300"));
143/// ```
144///
145/// Getting all values from `400` and beyond:
146///
147/// ```rust
148/// let countries = iso3166_1::num_range(Some("400"), None);
149/// ```
150///
151/// Getting all values up to `500`:
152///
153/// ```rust
154/// let countries = iso3166_1::num_range(None, Some("500"));
155/// ```
156///
157/// Getting no values, if that's your thing:
158///
159/// ```
160/// let countries = iso3166_1::num_range(None, None);
161/// ```
162pub fn num_range<'a>(from: Option<&str>,
163                     to: Option<&str>) -> Vec<CountryCode<'a>> {
164    let mut codes: Vec<CountryCode> = vec![];
165
166    let from_do: bool = from.is_some();
167    let to_do: bool = to.is_some();
168
169    let from_val: i16 = if from_do {
170        from.unwrap().parse::<i16>().unwrap()
171    } else {
172        0
173    };
174    let to_val: i16 = if to_do {
175        to.unwrap().parse::<i16>().unwrap()
176    } else {
177        0
178    };
179
180    for code in all() {
181        let num_as_int: i16 = code.num.parse::<i16>().unwrap();
182
183        let gte: bool = num_as_int >= from_val;
184        let lte: bool = num_as_int <= to_val;
185
186        let matches: bool = if from_do && to_do {
187            gte && lte
188        } else if from_do {
189            gte
190        } else if to_do {
191            lte
192        } else {
193            false
194        };
195
196        if matches {
197            codes.push(code.clone());
198        }
199    }
200
201    codes
202}