Botan 3.13.0
Crypto and TLS for C&
email.h
Go to the documentation of this file.
1/*
2* (C) 2026 Jack Lloyd
3*
4* Botan is released under the Simplified BSD License (see license.txt)
5*/
6
7#ifndef BOTAN_EMAIL_ADDRESS_H_
8#define BOTAN_EMAIL_ADDRESS_H_
9
10#include <botan/dns_name.h>
11#include <botan/types.h>
12#include <optional>
13#include <string>
14#include <string_view>
15
16namespace Botan {
17
18/**
19* A parsed email address in mailbox form: "local-part@domain".
20*
21* This is specifically modeling RFC 5280's rfc822Name GeneralName type.
22* In this type, the local-part of the email address must be an ASCII subset.
23*
24* This type and SmtpUTF8Mailbox are very similar in that both express mailbox
25* names. However they are modeled as distinct and unrelated types, as certain
26* name constraint processing rules are applied differently to the two name
27* forms, so it is important that they not be confusable. In addition, by a
28* strict reading of the RFCs, the names expressed by EmailAddress and by
29* SmtpUTF8Mailbox are completely disjoint; EmailAddress as encoded can only
30* express ASCII local-part names, and SmtpUTF8Mailbox is RFC MUST required to be
31* used only for names with a non-ASCII local-part.
32*/
33class BOTAN_PUBLIC_API(3, 13) EmailAddress final {
34 public:
35 /**
36 * Parse an rfc822Name mailbox
37 * @param addr the address to parse
38 * @return the parsed address, or nullopt if addr is not a valid rfc822Name
39 */
40 static std::optional<EmailAddress> from_string(std::string_view addr);
41
42 /// The local-part, ASCII only
43 const std::string& local_part() const { return m_local_part; }
44
45 /// The domain part of the address
46 /// @return the domain of the address
47 const DNSName& domain() const { return m_domain; }
48
49 /**
50 * Format the address as "local-part@domain"
51 * @return the text form of the address
52 */
53 std::string to_string() const;
54
55 /**
56 * Order two addresses
57 * @return the ordering of this address relative to the other
58 */
59 auto operator<=>(const EmailAddress&) const = default;
60
61 /**
62 * Compare two addresses
63 * @return true if the two addresses are equal
64 */
65 bool operator==(const EmailAddress&) const = default;
66
67 private:
68 EmailAddress(std::string local_part, DNSName domain) :
69 m_local_part(std::move(local_part)), m_domain(std::move(domain)) {}
70
71 std::string m_local_part;
72 DNSName m_domain;
73};
74
75/**
76* A parsed internationalized mailbox (`SmtpUTF8Mailbox`) as defined by RFC 9598.
77*
78* The mailbox is `local-part "@" domain`, where local-part is a UTF-8 string.
79* The RFC specifically requires that this name only be used when the local-part
80* of the name is not representable in ASCII.
81*
82* Prior specifications of this name (RFC 8398) allowed for any internationalized
83* domains be stored as U-label names. However RFC 9598 changes this so that only
84* A-label names are allowed. This restriction is enforced by this type.
85*/
86class BOTAN_PUBLIC_API(3, 13) SmtpUtf8Mailbox final {
87 public:
88 /**
89 * Parse an SmtpUTF8Mailbox
90 * @param addr the address to parse
91 * @return the parsed address, or nullopt if addr is not a valid SmtpUTF8Mailbox
92 */
93 static std::optional<SmtpUtf8Mailbox> from_string(std::string_view addr);
94
95 /// The local-part, UTF-8 encoded, should contain non-ASCII
96 const std::string& local_part() const { return m_local_part; }
97
98 /// The domain, as an LDH host name in A-label form (RFC 9598 Section 3)
99 const DNSName& domain() const { return m_domain; }
100
101 /**
102 * Format the mailbox as "local-part@domain"
103 * @return the text form of the mailbox
104 */
105 std::string to_string() const;
106
107 /**
108 * Order two mailboxes
109 * @return the ordering of this mailbox relative to the other
110 */
111 auto operator<=>(const SmtpUtf8Mailbox&) const = default;
112
113 /**
114 * Compare two mailboxes
115 * @return true if the two mailboxes are equal
116 */
117 bool operator==(const SmtpUtf8Mailbox&) const = default;
118
119 private:
120 SmtpUtf8Mailbox(std::string local_part, DNSName domain) :
121 m_local_part(std::move(local_part)), m_domain(std::move(domain)) {}
122
123 std::string m_local_part;
124 DNSName m_domain;
125};
126
127} // namespace Botan
128
129#endif
#define BOTAN_PUBLIC_API(maj, min)
Definition api.h:21
const DNSName & domain() const
Definition email.h:47
const std::string & local_part() const
The local-part, ASCII only.
Definition email.h:43
auto operator<=>(const EmailAddress &) const =default
static std::optional< EmailAddress > from_string(std::string_view addr)
Definition email.cpp:78
bool operator==(const EmailAddress &) const =default
const std::string & local_part() const
The local-part, UTF-8 encoded, should contain non-ASCII.
Definition email.h:96
static std::optional< SmtpUtf8Mailbox > from_string(std::string_view addr)
Definition email.cpp:99
bool operator==(const SmtpUtf8Mailbox &) const =default
auto operator<=>(const SmtpUtf8Mailbox &) const =default
const DNSName & domain() const
The domain, as an LDH host name in A-label form (RFC 9598 Section 3).
Definition email.h:99
std::string to_string(ErrorType type)
Convert an ErrorType to string.
Definition exceptn.cpp:13