Every email consists of a local name and a domain name, separated by the @ sign.

For example, in `alice@leetcode.com``alice` is the local name, and `leetcode.com` is the domain name.

Besides lowercase letters, these emails may contain `'.'`s or `'+'`s.

If you add periods (`'.'`) between some characters in the local name part of an email address, mail sent there will be forwarded to the same address without dots in the local name.  For example, `"alice.z@leetcode.com"` and `"alicez@leetcode.com"` forward to the same email address.  (Note that this rule does not apply for domain names.)

If you add a plus (`'+'`) in the local name, everything after the first plus sign will be ignored. This allows certain emails to be filtered, for example `m.y+name@email.com` will be forwarded to `my@email.com`.  (Again, this rule does not apply for domain names.)

It is possible to use both of these rules at the same time.

Given a list of `emails`, we send one email to each address in the list.  How many different addresses actually receive mails?

Example 1:

```Input: ["test.email+alex@leetcode.com","test.e.mail+bob.cathy@leetcode.com","testemail+david@lee.tcode.com"]
Output: 2
Explanation: "testemail@leetcode.com" and "testemail@lee.tcode.com" actually receive mails
```

Note:

• `1 <= emails[i].length <= 100`
• `1 <= emails.length <= 100`
• Each `emails[i]` contains exactly one `'@'` character.
• All local and domain names are non-empty.
• Local names do not start with a `'+'` character.

``````struct Solution;

use std::collections::HashSet;

#[derive(PartialEq, Eq, Hash)]
struct Email {
local_name: String,
domain_name: String,
}

impl Email {
fn new(s: String) -> Self {
let mut iter = s.split('@');
let left: String = iter.next().unwrap().to_string();
let domain_name: String = iter.next().unwrap().to_string();
let mut local_name: String = left.split('+').next().unwrap().to_string();
local_name.retain(|c| c != '.');
Email {
local_name,
domain_name,
}
}
}

impl Solution {
fn num_unique_emails(emails: Vec<String>) -> i32 {
let mut hs: HashSet<Email> = HashSet::new();
let emails: Vec<Email> = emails
.iter()
.map(|email| Email::new(email.to_string()))
.collect();
for email in emails {
hs.insert(email);
}
hs.len() as i32
}
}

#[test]
fn test() {
let emails: Vec<String> = vec_string![
"test.email+alex@leetcode.com",
"test.e.mail+bob.cathy@leetcode.com",
"testemail+david@lee.tcode.com"
];
assert_eq!(Solution::num_unique_emails(emails), 2);
}
``````