Skip to content

Commit 4b1889b

Browse files
committed
Make use of the debug CLI flag for request response status and error printing
1 parent 896ad9f commit 4b1889b

File tree

2 files changed

+184
-167
lines changed

2 files changed

+184
-167
lines changed

src/lib.rs

Lines changed: 184 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,12 @@
88
//!
99
//! See the `LICENSE` file for Copyright and license details.
1010
//!
11-
//!
11+
12+
use rand::{thread_rng, Rng};
13+
use reqwest::blocking::Client;
14+
use reqwest::header::CONTENT_TYPE;
15+
use serde::{Serialize, Deserialize};
16+
use std::fmt;
1217
use clap::{Parser};
1318

1419
/// Defines the Ambi Mock Client command line interface as a struct
@@ -24,6 +29,183 @@ pub struct Cli {
2429
pub debug: bool,
2530
}
2631

32+
#[derive(Serialize, Deserialize)]
33+
struct Reading {
34+
temperature: String,
35+
humidity: String,
36+
pressure: String,
37+
dust_concentration: String,
38+
air_purity: String
39+
}
40+
41+
impl Reading {
42+
fn new(
43+
temperature: String,
44+
humidity: String,
45+
pressure: String,
46+
dust_concentration: String,
47+
air_purity: String
48+
) -> Reading {
49+
Reading {
50+
temperature,
51+
humidity,
52+
pressure,
53+
dust_concentration,
54+
air_purity
55+
}
56+
}
57+
}
58+
59+
#[derive(Debug, PartialEq)]
60+
enum AirPurity {
61+
Dangerous,
62+
High,
63+
Low,
64+
FreshAir
65+
}
66+
67+
impl AirPurity {
68+
fn from_value(value: u16) -> AirPurity {
69+
match value {
70+
0..=50 => return AirPurity::FreshAir,
71+
51..=100 => return AirPurity::Low,
72+
101..=150 => return AirPurity::High,
73+
151.. => return AirPurity::Dangerous,
74+
};
75+
}
76+
}
77+
78+
// implements fmt::Display for AirPurity so that we can call .to_string() on
79+
// each enum value
80+
impl fmt::Display for AirPurity {
81+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
82+
match self {
83+
AirPurity::Low => write!(f, "Fresh Air"),
84+
AirPurity::High => write!(f, "Low Pollution"),
85+
AirPurity::Dangerous => write!(f, "High Pollution"),
86+
AirPurity::FreshAir => write!(f, "Dangerous Pollution")
87+
}
88+
}
89+
}
90+
91+
fn random_gen_humidity() -> String {
92+
let mut rng = thread_rng();
93+
let value = rng.gen_range(0.0..=100.0);
94+
format!("{:.1}", value)
95+
}
96+
97+
fn random_gen_temperature() -> String {
98+
let mut rng = thread_rng();
99+
let value = rng.gen_range(15.0..=35.0);
100+
format!("{:.1}", value)
101+
}
102+
103+
fn random_gen_pressure() -> String {
104+
let mut rng = thread_rng();
105+
rng.gen_range(900..=1100).to_string()
106+
}
107+
108+
fn random_gen_dust_concentration() -> String {
109+
let mut rng = thread_rng();
110+
rng.gen_range(0..=1000).to_string()
111+
}
112+
27113
pub fn run(cli: &Cli) {
28114
println!("\r\ncli: {:?}\r\n", cli);
29-
}
115+
116+
let dust_concentration = random_gen_dust_concentration();
117+
let air_purity = AirPurity::from_value(dust_concentration.parse::<u16>().unwrap()).to_string();
118+
let reading = Reading::new(
119+
random_gen_temperature(),
120+
random_gen_humidity(),
121+
random_gen_pressure(),
122+
dust_concentration,
123+
air_purity
124+
);
125+
126+
let json = serde_json::to_string(&reading).unwrap();
127+
const URL: &str = "http://localhost:4000/api/readings/add";
128+
129+
println!("Sending POST request to {} as JSON: {}", URL, json);
130+
131+
let client = Client::new();
132+
let res = client
133+
.post(URL)
134+
.header(CONTENT_TYPE, "application/json")
135+
.body(json)
136+
.send();
137+
match res {
138+
Ok(response) => {
139+
match cli.debug {
140+
true => println!("Response from Ambi backend: {:#?}", response),
141+
false => println!("Response from Ambi backend: {:?}", response.status().as_str())
142+
}
143+
}
144+
Err(e) => {
145+
match cli.debug {
146+
// Print out the entire reqwest::Error for verbose debugging
147+
true => eprintln!("Response error from Ambi backend: {:?}", e),
148+
// Keep the error reports more succinct
149+
false => {
150+
if e.is_request() {
151+
eprintln!("Response error from Ambi backend: request error");
152+
} else if e.is_timeout() {
153+
eprintln!("Response error from Ambi backend: request timed out");
154+
} else {
155+
eprintln!("Response error from Ambi backend: specific error type unknown");
156+
}
157+
}
158+
}
159+
}
160+
}
161+
}
162+
163+
#[cfg(test)]
164+
mod tests {
165+
use super::*;
166+
use regex::Regex;
167+
168+
#[test]
169+
fn random_gen_humidity_returns_correctly_formatted_humidity_data() {
170+
let result = random_gen_humidity();
171+
let regex = Regex::new(r"\d{1,2}.\d{1}").unwrap();
172+
173+
assert!(regex.is_match(&result));
174+
}
175+
176+
#[test]
177+
fn random_gen_temperature_returns_correctly_formatted_humidity_data() {
178+
let result = random_gen_temperature();
179+
let regex = Regex::new(r"\d{1,2}.\d{1}").unwrap();
180+
181+
assert!(regex.is_match(&result));
182+
}
183+
184+
#[test]
185+
fn random_gen_pressure_returns_correctly_formatted_pressure_data() {
186+
let result = random_gen_pressure();
187+
let regex = Regex::new(r"\d{3,4}").unwrap();
188+
assert!(regex.is_match(&result));
189+
}
190+
191+
#[test]
192+
fn random_gen_dust_concentration_returns_correctly_formatted_pressure_data() {
193+
let result = random_gen_dust_concentration();
194+
let regex = Regex::new(r"\d{0,4}").unwrap();
195+
assert!(regex.is_match(&result));
196+
}
197+
198+
#[test]
199+
fn air_purity_from_value_returns_correct_enum() {
200+
let mut rng = thread_rng();
201+
let fresh_air = rng.gen_range(0..=50);
202+
let low = rng.gen_range(51..=100);
203+
let high = rng.gen_range(101..=150);
204+
let dangerous = rng.gen_range(151..u16::MAX);
205+
206+
assert_eq!(AirPurity::from_value(fresh_air), AirPurity::FreshAir);
207+
assert_eq!(AirPurity::from_value(low), AirPurity::Low);
208+
assert_eq!(AirPurity::from_value(high), AirPurity::High);
209+
assert_eq!(AirPurity::from_value(dangerous), AirPurity::Dangerous);
210+
}
211+
}

src/main.rs

Lines changed: 0 additions & 165 deletions
Original file line numberDiff line numberDiff line change
@@ -10,179 +10,14 @@
1010
//! See the `LICENSE` file for Copyright and license details.
1111
//!
1212
13-
use rand::{thread_rng, Rng};
14-
use reqwest::blocking::Client;
15-
use reqwest::header::CONTENT_TYPE;
16-
use serde::{Serialize, Deserialize};
17-
use std::fmt;
1813
use clap::{Parser};
1914

2015
// Internal library namespace for separation of app logic
2116
use ambi_mock_client;
2217

23-
#[derive(Serialize, Deserialize)]
24-
struct Reading {
25-
temperature: String,
26-
humidity: String,
27-
pressure: String,
28-
dust_concentration: String,
29-
air_purity: String
30-
}
31-
32-
impl Reading {
33-
fn new(
34-
temperature: String,
35-
humidity: String,
36-
pressure: String,
37-
dust_concentration: String,
38-
air_purity: String
39-
) -> Reading {
40-
Reading {
41-
temperature,
42-
humidity,
43-
pressure,
44-
dust_concentration,
45-
air_purity
46-
}
47-
}
48-
}
49-
50-
#[derive(Debug, PartialEq)]
51-
enum AirPurity {
52-
Dangerous,
53-
High,
54-
Low,
55-
FreshAir
56-
}
57-
58-
impl AirPurity {
59-
fn from_value(value: u16) -> AirPurity {
60-
match value {
61-
0..=50 => return AirPurity::FreshAir,
62-
51..=100 => return AirPurity::Low,
63-
101..=150 => return AirPurity::High,
64-
151.. => return AirPurity::Dangerous,
65-
};
66-
}
67-
}
68-
69-
// implements fmt::Display for AirPurity so that we can call .to_string() on
70-
// each enum value
71-
impl fmt::Display for AirPurity {
72-
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
73-
match self {
74-
AirPurity::Low => write!(f, "Fresh Air"),
75-
AirPurity::High => write!(f, "Low Pollution"),
76-
AirPurity::Dangerous => write!(f, "High Pollution"),
77-
AirPurity::FreshAir => write!(f, "Dangerous Pollution")
78-
}
79-
}
80-
}
81-
82-
fn random_gen_humidity() -> String {
83-
let mut rng = thread_rng();
84-
let value = rng.gen_range(0.0..=100.0);
85-
format!("{:.1}", value)
86-
}
87-
88-
fn random_gen_temperature() -> String {
89-
let mut rng = thread_rng();
90-
let value = rng.gen_range(15.0..=35.0);
91-
format!("{:.1}", value)
92-
}
93-
94-
fn random_gen_pressure() -> String {
95-
let mut rng = thread_rng();
96-
rng.gen_range(900..=1100).to_string()
97-
}
98-
99-
fn random_gen_dust_concentration() -> String {
100-
let mut rng = thread_rng();
101-
rng.gen_range(0..=1000).to_string()
102-
}
103-
10418
fn main() {
10519
// Parses the provided command line interface arguments and flags
10620
let cli = ambi_mock_client::Cli::parse();
10721

108-
match cli.debug {
109-
true => println!("Debug mode is now *on*"),
110-
false => println!("Debug mode is now *off*")
111-
}
112-
11322
ambi_mock_client::run(&cli);
114-
115-
let dust_concentration = random_gen_dust_concentration();
116-
let air_purity = AirPurity::from_value(dust_concentration.parse::<u16>().unwrap()).to_string();
117-
let reading = Reading::new(
118-
random_gen_temperature(),
119-
random_gen_humidity(),
120-
random_gen_pressure(),
121-
dust_concentration,
122-
air_purity
123-
);
124-
125-
let json = serde_json::to_string(&reading).unwrap();
126-
const URL: &str = "http://localhost:4000/api/readings/add";
127-
128-
println!("Sending POST request to {} as JSON: {}", URL, json);
129-
130-
let client = Client::new();
131-
let res = client
132-
.post(URL)
133-
.header(CONTENT_TYPE, "application/json")
134-
.body(json)
135-
.send();
136-
137-
println!("Response: {:#?}", res);
138-
}
139-
140-
#[cfg(test)]
141-
mod tests {
142-
use super::*;
143-
use regex::Regex;
144-
145-
#[test]
146-
fn random_gen_humidity_returns_correctly_formatted_humidity_data() {
147-
let result = random_gen_humidity();
148-
let regex = Regex::new(r"\d{1,2}.\d{1}").unwrap();
149-
150-
assert!(regex.is_match(&result));
151-
}
152-
153-
#[test]
154-
fn random_gen_temperature_returns_correctly_formatted_humidity_data() {
155-
let result = random_gen_temperature();
156-
let regex = Regex::new(r"\d{1,2}.\d{1}").unwrap();
157-
158-
assert!(regex.is_match(&result));
159-
}
160-
161-
#[test]
162-
fn random_gen_pressure_returns_correctly_formatted_pressure_data() {
163-
let result = random_gen_pressure();
164-
let regex = Regex::new(r"\d{3,4}").unwrap();
165-
assert!(regex.is_match(&result));
166-
}
167-
168-
#[test]
169-
fn random_gen_dust_concentration_returns_correctly_formatted_pressure_data() {
170-
let result = random_gen_dust_concentration();
171-
let regex = Regex::new(r"\d{0,4}").unwrap();
172-
assert!(regex.is_match(&result));
173-
}
174-
175-
#[test]
176-
fn air_purity_from_value_returns_correct_enum() {
177-
let mut rng = thread_rng();
178-
let fresh_air = rng.gen_range(0..=50);
179-
let low = rng.gen_range(51..=100);
180-
let high = rng.gen_range(101..=150);
181-
let dangerous = rng.gen_range(151..u16::MAX);
182-
183-
assert_eq!(AirPurity::from_value(fresh_air), AirPurity::FreshAir);
184-
assert_eq!(AirPurity::from_value(low), AirPurity::Low);
185-
assert_eq!(AirPurity::from_value(high), AirPurity::High);
186-
assert_eq!(AirPurity::from_value(dangerous), AirPurity::Dangerous);
187-
}
18823
}

0 commit comments

Comments
 (0)