add some logging
[ghsmtp.git] / Mailbox.hpp
blob8a622833be285fd6435cf46bdb4cf7ccfe6b390e
1 #ifndef MAILBOX_DOT_HPP
2 #define MAILBOX_DOT_HPP
4 #include "Domain.hpp"
6 #include <cstdint>
7 #include <optional>
8 #include <ostream>
9 #include <string>
10 #include <utility>
12 class Mailbox {
13 public:
14 Mailbox() = default;
16 // Parse the input string against the RFC-5321 Mailbox grammar, normalize any
17 // Unicode, normalize Quoted-string Local-part.
18 inline Mailbox(std::string_view mailbox);
20 // Accept the Local-part as already validated via some external check.
21 inline Mailbox(std::string_view local_part, Domain domain);
23 inline static bool
24 validate(std::string_view mailbox, std::string& msg, Mailbox& mbx);
26 inline void set_local(std::string_view local_part);
27 inline void set_domain(Domain d);
28 inline void clear();
30 inline std::string const& local_part() const;
31 inline Domain const& domain() const;
33 enum class domain_encoding : bool { ascii, utf8 };
35 size_t length(domain_encoding enc = domain_encoding::utf8) const;
36 inline bool empty() const;
38 std::string as_string(domain_encoding enc = domain_encoding::utf8) const;
39 inline operator std::string() const;
41 inline bool operator==(Mailbox const& rhs) const;
42 inline bool operator!=(Mailbox const& rhs) const;
44 enum class local_types : uint8_t {
45 unknown,
46 dot_string,
47 quoted_string,
50 enum class domain_types : uint8_t {
51 unknown,
52 domain,
53 address_literal, // IP4/IP6 address literal
54 general_address_literal, // some other address literal
57 struct parse_results {
58 std::string_view local;
59 std::string_view domain;
60 std::string_view standardized_tag;
61 local_types local_type = local_types::unknown;
62 domain_types domain_type = domain_types::unknown;
65 static std::optional<parse_results> parse(std::string_view mailbox);
67 private:
68 bool set_(std::string_view mailbox, bool should_throw, std::string& msg);
70 std::string local_part_;
71 Domain domain_;
74 Mailbox::Mailbox(std::string_view mailbox)
76 std::string msg;
77 set_(mailbox, true /* throw */, msg);
80 // Accept the inputs as already validated via some external check.
81 Mailbox::Mailbox(std::string_view local_part, Domain domain)
83 set_local(local_part);
84 set_domain(domain);
87 bool Mailbox::validate(std::string_view mailbox, std::string& msg, Mailbox& mbx)
89 return mbx.set_(mailbox, false /* don't throw */, msg);
92 void Mailbox::set_local(std::string_view local_part)
94 local_part_ = local_part;
97 void Mailbox::set_domain(Domain d) { domain_ = d; }
99 void Mailbox::clear()
101 local_part_.clear();
102 domain_.clear();
105 std::string const& Mailbox::local_part() const { return local_part_; }
106 Domain const& Mailbox::domain() const { return domain_; }
108 bool Mailbox::empty() const { return length() == 0; }
110 Mailbox::operator std::string() const
112 return as_string(domain_encoding::utf8);
115 bool Mailbox::operator==(Mailbox const& rhs) const
117 return (local_part_ == rhs.local_part_) && (domain_ == rhs.domain_);
120 bool Mailbox::operator!=(Mailbox const& rhs) const { return !(*this == rhs); }
122 inline std::ostream& operator<<(std::ostream& s, Mailbox const& mb)
124 return s << static_cast<std::string>(mb);
127 #endif // MAILBOX_DOT_HPP