is_rust/lib.rs
1//! # is-rust
2//!
3//! Have you ever wanted to know if a value is rust, or at least rusty?
4//!
5//! Maybe you're doing form validation for a Rust position at your company, and
6//! you want to make sure that someone only inputs Rust-acceptable values. Say
7//! that your form looks like this:
8//!
9//! ```ignore
10//! 1: "What is your favourite programming language?"
11//!
12//! <answer>
13//!
14//! 2: "What language runs blazingly fast, prevents segfaults, and guarentees
15//! thread safety?"
16//!
17//! <answer>
18//!
19//! 3: "What is your favourite colour defined in HEX?"
20//!
21//! <answer>
22//!
23//! 4: "When someone hasn't practiced something for a while, what would you call
24//! them?"
25//!
26//! <answer>
27//! ```
28//!
29//! Using typical form validation, you would have to define acceptable answers
30//! yourself. Using this library, you can simply use the function `is_rust`
31//! or `is_at_least_rusty` for all inputs.
32//!
33//! ### Examples
34//!
35//! For example, rust is rust:
36//!
37//! ```rust
38//! extern crate is_rust;
39//!
40//! assert!(is_rust::is_rust("rust")); // this is rust
41//! ```
42//!
43//! Similarly, Rust is rust:
44//!
45//! ```rust
46//! extern crate is_rust;
47//!
48//! assert!(is_rust::is_rust("Rust")); // this is rust
49//! ```
50//!
51//! It's all rust, except for strings that are not "rust", "b7410e", or the RGB
52//! value `173, 65, 14`. Other than that, it's Rust. You can confirm this due to
53//! the fact that Python is not Rust:
54//!
55//! ```rust
56//! extern crate is_rust;
57//!
58//! assert!(!is_rust::is_rust("python")); // python is obviously not rust
59//! ```
60//!
61//! Additionally you can check that something is rusty:
62//!
63//! ```rust
64//! extern crate is_rust;
65//!
66//! assert!(is_rust::is_rusty("rusty"));
67//! ```
68//!
69//! Something can be at least rusty, or rust itself:
70//!
71//! ```rust
72//! extern crate is_rust;
73//!
74//! assert!(is_rust::is_at_least_rusty("rusty"));
75//! assert!(is_rust::is_at_least_rusty("rust"));
76//! ```
77//!
78//! You can check that a set of input is very rusty, ensuring that all input values
79//! are rust:
80//!
81//! ```rust
82//! extern crate is_rust;
83//!
84//! assert!(is_rust::is_very_rusty(&["rust", "Rust", "RUST", "b7410e"]));
85//! ```
86//!
87//! Lastly, you can check that something is not rust, because booleans are hard:
88//!
89//! ```
90//! extern crate is_rust;
91//!
92//! assert!(is_rust::is_not_rust("Python"));
93//! ```
94//!
95//! At this point, Rust should no longer sound like a word.
96//!
97//! ### Installation
98//!
99//! To install this library to check whether values are Rust, you can use Rust's
100//! Cargo. Add the following to your Rust project's `Cargo.toml`:
101//!
102//! ```toml
103//! [dependencies]
104//! is-rust = "https://github.com/zeyla/is-rust"
105//! ```
106//!
107//! ### License
108//!
109//! ISC.
110
111use std::fmt::Display;
112
113const NAME: &str = "rust";
114const HEX: &str = "b7410e";
115const HEX2: &str = "#b7410e";
116const RGB: [&str; 3] = ["173", "65", "14"];
117
118/// Returns whether a value is rust.
119///
120/// This returns true if the value is `"rust"`, the hex value `"b7410e"`, or the
121/// RGB value `173, 65, 14`.
122///
123/// # Examples
124///
125/// Rust should be rust:
126///
127/// ```rust
128/// assert!(is_rust::is_rust("rust")); // is rust even a word anymore?
129/// assert!(is_rust::is_rust("#b7410e"));
130/// assert!(is_rust::is_rust("rgb(173, 65, 14)"));
131/// ```
132///
133/// Python and Ruby are not rust:
134///
135/// ```rust
136/// assert!(!is_rust::is_rust("python"));
137/// assert!(!is_rust::is_rust("ruby"));
138/// ```
139pub fn is_rust<D: Display>(string: D) -> bool {
140 let content = string.to_string().to_lowercase();
141
142 str_is_rust(&content)
143}
144
145/// Returns whether the given value is equal to `"rusty"`.
146///
147/// This returns false if the value _is_ rust, because it's not "rust-y", it is
148/// rust itself.
149///
150/// This does _not_ accept hex or RGB values _similar_ to rust's colour, because
151/// then we might be getting too close to the colours of other languages, and
152/// that's just not rusty.
153///
154/// # Examples
155///
156/// "rusty" is rusty:
157///
158/// ```rust
159/// assert!(is_rust::is_rusty("rusty"));
160/// ```
161///
162/// "rust" is not rusty:
163///
164/// ```rust
165/// assert!(!is_rust::is_rusty("rust"));
166/// ```
167pub fn is_rusty<D: Display>(string: D) -> bool {
168 string.to_string() == "rusty"
169}
170
171/// Returns whether a value is `"rusty"` or rust itself, meaning it is at least
172/// rusty.
173///
174/// Refer to [`is_rust`] and [`is_rusty`].
175///
176/// # Examples
177///
178/// Rust and rusty values are both accepted:
179///
180/// ```rust
181/// assert!(is_rust::is_at_least_rusty("rust"));
182/// assert!(is_rust::is_at_least_rusty("rusty"));
183/// ```
184pub fn is_at_least_rusty<D: Display>(string: D) -> bool {
185 let string = string.to_string();
186
187 is_rust(&string) || is_rusty(&string)
188}
189
190/// Returns whether all of the given values are rust.
191///
192/// Refer to [`is_rust`].
193///
194/// This function, despite the "rusty" suffix, is not related to [`is_rusty`].
195///
196/// # Examples
197///
198/// "rust", "Rust", "RUST", and "b7410e" are a very rusty combination:
199///
200/// ```rust
201/// assert!(is_rust::is_very_rusty(&["rust", "Rust", "RUST", "b7410e"]));
202/// ```
203pub fn is_very_rusty<D: Display>(values: &[D]) -> bool {
204 values.iter().all(|value| is_rust(value.to_string()))
205}
206
207/// Booleans are hard, so we provide a function to check that something is _not_
208/// rust.
209///
210/// Refer to [`is_rust`] for how this function does _not_ work.
211///
212/// # Examples
213///
214/// C is not Rust:
215///
216/// ```rust
217/// extern crate is_rust;
218///
219/// assert!(is_rust::is_not_rust("Python"));
220/// ```
221pub fn is_not_rust<D: Display>(string: D) -> bool {
222 !is_rust(string.to_string())
223}
224
225fn str_is_rust(mut s: &str) -> bool {
226 if s == NAME || s == HEX || s == HEX2 {
227 return true;
228 }
229
230 if let Some(pos) = s.find('(') {
231 s = &s[pos + 1..];
232 }
233
234 if let Some(pos) = s.find(')') {
235 s = &s[..pos];
236 }
237
238 let string = s.replace(' ', "");
239
240 let parts = string.split(',').collect::<Vec<_>>();
241 let part_count = parts.len();
242
243 let mut cur = parts[0] == RGB[0] && parts[1] == RGB[1] && parts[2] == RGB[2];
244
245 if part_count == 4 {
246 cur = cur && parts[3].starts_with("1")
247 }
248
249 cur
250}