-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathMailbox.hpp
More file actions
139 lines (106 loc) · 3.42 KB
/
Copy pathMailbox.hpp
File metadata and controls
139 lines (106 loc) · 3.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#ifndef MAILBOX_DOT_HPP
#define MAILBOX_DOT_HPP
#include "Domain.hpp"
#include <cstdint>
#include <optional>
#include <ostream>
#include <string>
#include <utility>
class Mailbox {
public:
Mailbox() = default;
// Parse the input string against the RFC-5321 Mailbox grammar, normalize any
// Unicode, normalize Quoted-string Local-part.
inline Mailbox(std::string_view mailbox);
// Accept the Local-part as already validated via some external check.
inline Mailbox(std::string_view local_part, Domain domain);
inline static bool
validate(std::string_view mailbox, std::string& msg, Mailbox& mbx);
inline void set_local(std::string_view local_part);
inline void set_domain(Domain d);
inline void clear();
inline std::string const& local_part() const;
inline Domain const& domain() const;
enum class domain_encoding : bool { ascii, utf8 };
size_t length(domain_encoding enc = domain_encoding::utf8) const;
inline bool empty() const;
std::string as_string(domain_encoding enc = domain_encoding::utf8) const;
inline operator std::string() const;
inline bool operator==(Mailbox const& rhs) const;
inline bool operator!=(Mailbox const& rhs) const;
enum class local_types : uint8_t {
unknown,
dot_string,
quoted_string,
};
enum class domain_types : uint8_t {
unknown,
domain,
address_literal, // IP4/IP6 address literal
general_address_literal, // some other address literal
};
struct parse_results {
std::string_view local;
std::string_view domain;
std::string_view standardized_tag;
local_types local_type = local_types::unknown;
domain_types domain_type = domain_types::unknown;
};
static std::optional<parse_results> parse(std::string_view mailbox);
private:
bool set_(std::string_view mailbox, bool should_throw, std::string& msg);
std::string local_part_;
Domain domain_;
};
Mailbox::Mailbox(std::string_view mailbox)
{
std::string msg;
set_(mailbox, true /* throw */, msg);
}
// Accept the inputs as already validated via some external check.
Mailbox::Mailbox(std::string_view local_part, Domain domain)
{
set_local(local_part);
set_domain(domain);
}
bool Mailbox::validate(std::string_view mailbox, std::string& msg, Mailbox& mbx)
{
return mbx.set_(mailbox, false /* don't throw */, msg);
}
void Mailbox::set_local(std::string_view local_part)
{
local_part_ = local_part;
}
void Mailbox::set_domain(Domain d) { domain_ = d; }
void Mailbox::clear()
{
local_part_.clear();
domain_.clear();
}
std::string const& Mailbox::local_part() const { return local_part_; }
Domain const& Mailbox::domain() const { return domain_; }
bool Mailbox::empty() const { return length() == 0; }
Mailbox::operator std::string() const
{
return as_string(domain_encoding::utf8);
}
bool Mailbox::operator==(Mailbox const& rhs) const
{
return (local_part_ == rhs.local_part_) && (domain_ == rhs.domain_);
}
bool Mailbox::operator!=(Mailbox const& rhs) const { return !(*this == rhs); }
template <>
struct std::formatter<Mailbox> {
constexpr auto parse( format_parse_context& context ) {
return context.begin();
}
inline auto format(const Mailbox& mbox, std::format_context& context) const
{
return std::format_to(context.out(), "{}", static_cast<std::string>(mbox));
}
};
inline std::ostream& operator<<(std::ostream& s, Mailbox const& mb)
{
return s << static_cast<std::string>(mb);
}
#endif // MAILBOX_DOT_HPP