Last active
October 4, 2022 13:30
-
-
Save berkes/551a9b453a6d21f59671a7d17c5d9677 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
mod domain { | |
use std::{fmt::Display, ops::Deref}; | |
#[derive(Debug)] | |
pub enum DomainError { | |
InvalidEmailAddress, | |
InvalidResponseCode, | |
} | |
#[derive(Clone, PartialEq)] | |
pub struct EmailAddress { | |
value: String, | |
} | |
impl EmailAddress { | |
pub fn new(value: String) -> Result<Self, DomainError> { | |
if value.contains("@") { | |
Ok(Self { value }) | |
} else { | |
Err(DomainError::InvalidEmailAddress) | |
} | |
} | |
} | |
impl Deref for EmailAddress { | |
type Target = String; | |
fn deref(&self) -> &Self::Target { | |
&self.value | |
} | |
} | |
#[derive(Clone)] | |
pub struct HttpResponseCode { | |
value: u16, | |
} | |
impl Display for HttpResponseCode { | |
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | |
write!(f, "{}", &self.value) | |
} | |
} | |
impl HttpResponseCode { | |
pub fn new(value: u16) -> Result<Self, DomainError> { | |
if value <= 100 || value >= 511 { | |
Err(DomainError::InvalidResponseCode) | |
} else { | |
Ok(Self { value }) | |
} | |
} | |
pub fn is_error(&self) -> bool { | |
self.value >= 400 | |
} | |
} | |
#[derive(Clone)] | |
pub struct PageSize { | |
value: usize, | |
} | |
impl PageSize { | |
pub fn new_from_kilobytes(value: usize) -> Result<Self, DomainError> { | |
Ok(Self { value }) | |
} | |
pub fn as_kilobytes(&self) -> usize { | |
self.value | |
} | |
} | |
} | |
#[derive(Clone)] | |
pub struct PageRequest { | |
url: String, | |
size: PageSize, | |
response_code: HttpResponseCode, | |
} | |
use domain::*; | |
fn make_and_send_report(to: EmailAddress, pages: Vec<PageRequest>) { | |
if to == EmailAddress::new("john@example.com".to_string()).expect("valid email") { | |
return; | |
} | |
let mut report: Vec<String> = pages | |
.clone() | |
.into_iter() | |
.map(|page| { | |
format!( | |
"- {} {}Kb {}", | |
page.url, | |
page.size.as_kilobytes(), | |
page.response_code | |
) | |
}) | |
.collect(); | |
let error_count = pages | |
.into_iter() | |
.filter(|page| page.response_code.is_error()) | |
.count(); | |
report.push(format!("Amount of error codes: {}", error_count)); | |
println!("{:-^1$}", "Delivering email", 60); | |
println!("to: {}", *to); | |
println!("{:-^1$}", "Body", 60); | |
println!("{}", report.join("\n")); | |
} | |
fn main() -> Result<(), DomainError> { | |
let to = EmailAddress::new("boss@example.com".to_string())?; | |
let pages = vec![ | |
PageRequest { | |
url: "http://example.com/about".to_string(), | |
size: PageSize::new_from_kilobytes(1_337)?, | |
response_code: HttpResponseCode::new(200)?, | |
}, | |
PageRequest { | |
url: "http://example.com/new".to_string(), | |
size: PageSize::new_from_kilobytes(42_000)?, | |
response_code: HttpResponseCode::new(200)?, | |
}, | |
PageRequest { | |
url: "http://example.com/about".to_string(), | |
size: PageSize::new_from_kilobytes(1_337)?, | |
response_code: HttpResponseCode::new(304)?, | |
}, | |
]; | |
make_and_send_report(to, pages); | |
Ok(()) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment