Added the Utility package (#29)
This PR contains the work done to create the new **Utility** package within the project, and also included in it the `NormalizeEmail` method, as it's not something that belongs to the **Infrastructure** package. Reviewed-on: rock-n-code/loud-amsterdam#29 Co-authored-by: Javier Cicchelli <javier@rock-n-code.com>
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
import Foundation
|
||||
|
||||
/// A validator reducing a submitted email address to its canonical form.
|
||||
///
|
||||
/// Trims surrounding whitespace, lowercases the address (so one mailbox cannot register once per spelling), caps it at the 254 bytes an address can
|
||||
/// be, and checks its shape: something before the `@`, and a domain with a dot. Control characters are rejected separately: the shape only excludes
|
||||
/// whitespace, which would let non-whitespace controls (such as `NUL`) into the stored address.
|
||||
public struct NormalizeEmail: Sendable {
|
||||
|
||||
// MARK: Initializers
|
||||
|
||||
/// Creates an email normalization method.
|
||||
public init() {}
|
||||
|
||||
// MARK: Functions
|
||||
|
||||
/// Validates and normalizes a submitted email address.
|
||||
/// - Parameter email: the submitted email address, if any.
|
||||
/// - Returns: the normalized address, or `nil` when the submission is missing or invalid.
|
||||
public func callAsFunction(
|
||||
_ email: String?
|
||||
) -> String? {
|
||||
guard
|
||||
let email = email?
|
||||
.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
.lowercased(),
|
||||
email.utf8.count <= Constant.Length.maxEmail,
|
||||
!email.unicodeScalars.contains(where: {
|
||||
$0.properties.generalCategory == .control
|
||||
}),
|
||||
email.wholeMatch(of: /[^\s@]+@[^\s@]+\.[^\s@]+/) != nil
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return email
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Constants
|
||||
|
||||
private enum Constant {
|
||||
/// A namespace for the length constants.
|
||||
enum Length {
|
||||
/// The longest an email address can be, in bytes, per RFC 5321's path limit.
|
||||
static let maxEmail = 254
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user