#[derive(Clone, Debug, Eq, PartialEq)]
#[non_exhaustive]
pub struct Recipient {
key: String,
email: Option<String>,
}
impl Recipient {
#[must_use]
pub fn new(key: impl Into<String>) -> Self {
Self {
key: key.into(),
email: None,
}
}
#[must_use]
pub fn email(mut self, address: impl Into<String>) -> Self {
self.email = Some(address.into());
self
}
#[must_use]
pub fn key(&self) -> &str {
&self.key
}
#[must_use]
pub fn email_address(&self) -> Option<&str> {
self.email.as_deref()
}
}
pub trait Notifiable {
fn recipient(&self) -> Recipient;
}
impl Notifiable for Recipient {
fn recipient(&self) -> Recipient {
self.clone()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn a_recipient_starts_with_no_channels() {
assert_eq!(Recipient::new("user:1").email_address(), None);
}
#[test]
fn the_last_address_wins() {
let recipient = Recipient::new("user:1")
.email("old@example.com")
.email("new@example.com");
assert_eq!(recipient.email_address(), Some("new@example.com"));
}
#[test]
fn a_recipient_is_notifiable_as_itself() {
let recipient = Recipient::new("user:1").email("a@example.com");
assert_eq!(recipient.recipient(), recipient);
}
}