Skip to content

Commit 584b6f2

Browse files
committed
Move all application logic into src/lib.rs per standard Rust application layout pattern.
1 parent 896ad9f commit 584b6f2

File tree

2 files changed

+163
-162
lines changed

2 files changed

+163
-162
lines changed

src/lib.rs

Lines changed: 163 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,162 @@ pub struct Cli {
2429
pub debug: bool,
2530
}
2631

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

src/main.rs

Lines changed: 0 additions & 160 deletions
Original file line numberDiff line numberDiff line change
@@ -10,97 +10,11 @@
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();
@@ -111,78 +25,4 @@ fn main() {
11125
}
11226

11327
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-
}
18828
}

0 commit comments

Comments
 (0)