Skip to content

Instantly share code, notes, and snippets.

@mbernson
Last active December 2, 2024 13:47
Show Gist options
  • Save mbernson/22cf86368602122d8c8c0a3af46f5572 to your computer and use it in GitHub Desktop.
Save mbernson/22cf86368602122d8c8c0a3af46f5572 to your computer and use it in GitHub Desktop.
MACAddress value type in Swift, for storing a MAC address. Its rawValue is of type Data, and it provides serialization and deserialization.
//
// MACAddress.swift
//
//
// Created by Mathijs on 23/01/2024.
//
import Foundation
/// Model for a standard MAC (Media Access Control) address, which consists of 6 bytes
/// and can be represented as 6 hexadecimals separated by a colon. For example: `00:0C:6E:D2:11:E6`.
struct MACAddress: RawRepresentable, CustomStringConvertible, Hashable, Sendable {
let rawValue: Data
init?(rawValue: Data) {
guard rawValue.count == 6 else { return nil }
self.rawValue = rawValue
}
init?(string: String) {
let components = string.split(separator: ":").map { String($0) }
guard components.count == 6 else { return nil }
var bytes = Data()
for component in components {
guard let byte = UInt8(component, radix: 16) else { return nil }
bytes.append(byte)
}
self.init(rawValue: bytes)
}
var description: String {
return rawValue.map { String(format: "%02X", $0) }.joined(separator: ":")
}
}
//
// MACAddressTests.swift
//
//
// Created by Mathijs on 23/01/2024.
//
import Foundation
import Testing
@testable import MACAddress
@Test func testValidMACAddress() {
#expect(MACAddress(string: "00:0C:6E:D2:11:E6") != nil)
#expect(MACAddress(string: "FF:FF:FF:FF:FF:FF") != nil)
}
@Test func testInvalidMACAddress() {
#expect(MACAddress(string: "") == nil)
#expect(MACAddress(string: "00:0C:6E:D2:11:E6:FF") == nil, "Too many bytes")
#expect(MACAddress(string: "00:0C:6E:D2:11") == nil, "Too few bytes")
#expect(MACAddress(rawValue: Data([0x00, 0x1A, 0x2B, 0x3C, 0x4D, 0x5E, 0xFF])) == nil, "Too many bytes")
#expect(MACAddress(rawValue: Data([0x00, 0x1A, 0x2B, 0x3C, 0x4D])) == nil, "Too few bytes")
}
@Test func testByteOrdering() throws {
let macAddress = try #require(MACAddress(rawValue: Data([0x00, 0x1A, 0x2B, 0x3C, 0x4D, 0x5E])))
let macAddressFromString = try #require(MACAddress(string: "00:1A:2B:3C:4D:5E"))
#expect(macAddress == macAddressFromString)
#expect(macAddress.description == "00:1A:2B:3C:4D:5E")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment