Skip to content

Instantly share code, notes, and snippets.

@berkes
Last active October 4, 2022 13:30
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save berkes/551a9b453a6d21f59671a7d17c5d9677 to your computer and use it in GitHub Desktop.
Save berkes/551a9b453a6d21f59671a7d17c5d9677 to your computer and use it in GitHub Desktop.
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