diff --git a/Sources/LibMakeColors/Model/Color.swift b/Sources/LibMakeColors/Model/Color.swift index ef2030e..6e9740d 100644 --- a/Sources/LibMakeColors/Model/Color.swift +++ b/Sources/LibMakeColors/Model/Color.swift @@ -19,6 +19,14 @@ struct Color: CustomStringConvertible, Equatable { alpha = array.count == 4 ? array[3] : 0xFF } + init(white array: [UInt8]) { + precondition(array.count == 1 || array.count == 2) + red = array[0] + green = array[0] + blue = array[0] + alpha = array.count == 2 ? array[1] : 0xFF + } + var description: String { let alphaSuffix = alpha != 0xFF ? String(format: "%02X", alpha) : "" return String(format: "#%02X%02X%02X%@", red, green, blue, alphaSuffix) diff --git a/Sources/LibMakeColors/Model/Scanner+ColorParser.swift b/Sources/LibMakeColors/Model/Scanner+ColorParser.swift index 62904b1..fb0bd1c 100644 --- a/Sources/LibMakeColors/Model/Scanner+ColorParser.swift +++ b/Sources/LibMakeColors/Model/Scanner+ColorParser.swift @@ -27,6 +27,10 @@ extension Scanner { return Color(components) } + if string("white"), let arguments = argumentList(min: 1, max: 2) { + return Color(white: arguments) + } + return nil } @@ -91,6 +95,26 @@ extension Scanner { return result } + // swiftlint:disable:next discouraged_optional_collection + func argumentList(_ count: Int) -> [UInt8]? { + argumentList(min: count, max: count) + } + + // swiftlint:disable:next discouraged_optional_collection + func argumentList(min: Int, max: Int? = nil) -> [UInt8]? { + let max = max ?? Int.max + guard + string("("), + let arguments = commaSeparated(), + string(")"), + (min...max) ~= arguments.count + else { + return nil + } + + return arguments + } + // swiftlint:disable:next discouraged_optional_collection func commaSeparated() -> [UInt8]? { var result: [UInt8] = [] diff --git a/Tests/MakeColorsTests/ColorParserTest.swift b/Tests/MakeColorsTests/ColorParserTest.swift index 4a8a5e5..3db8714 100644 --- a/Tests/MakeColorsTests/ColorParserTest.swift +++ b/Tests/MakeColorsTests/ColorParserTest.swift @@ -43,4 +43,28 @@ final class ColorParserTest: XCTestCase { let color = scanner.color() XCTAssertEqual(Color(red: 1, green: 2, blue: 3, alpha: 4), color) } + + func testScanningWhite() throws { + let scanner = Scanner(string: "white(255)") + let color = scanner.color() + XCTAssertEqual(Color(red: 255, green: 255, blue: 255, alpha: 255), color) + } + + func testScanningWhiteWithAlpha() throws { + let scanner = Scanner(string: "white(255, 128)") + let color = scanner.color() + XCTAssertEqual(Color(red: 255, green: 255, blue: 255, alpha: 128), color) + } + + func testWhiteFailsWithoutArguments() throws { + let scanner = Scanner(string: "white()") + let color = scanner.color() + XCTAssertNil(color) + } + + func testWhiteFailsWith3Arguments() throws { + let scanner = Scanner(string: "white(1,2,3)") + let color = scanner.color() + XCTAssertNil(color) + } }