Zum Inhalt

ios/Sources/Hex.swift

import Foundation

/// Hex colour parsing, ported from the web studio. Colours are [r,g,b] 0...255.
enum Hex {
    /// "#rrggbb" / "rrggbb" / "#rgb" / "rgb" → [r,g,b], or nil if invalid.
    static func parse(_ str: String) -> [Int]? {
        var s = str.trimmingCharacters(in: .whitespacesAndNewlines).lowercased()
        if s.hasPrefix("#") { s.removeFirst() }
        if s.count == 3, s.allSatisfy(\.isHexDigit) { s = s.map { "\($0)\($0)" }.joined() }
        guard s.count == 6, s.allSatisfy(\.isHexDigit),
              let r = Int(s.prefix(2), radix: 16),
              let g = Int(s.dropFirst(2).prefix(2), radix: 16),
              let b = Int(s.dropFirst(4), radix: 16) else { return nil }
        return [r, g, b]
    }
    /// [r,g,b] → "#rrggbb".
    static func string(_ rgb: [Int]) -> String {
        let c = rgb.count >= 3 ? rgb : [0, 0, 0]
        return String(format: "#%02x%02x%02x", c[0], c[1], c[2])
    }
    /// Scan free text for hex tokens (palette paste); ignores non-hex.
    static func parseList(_ str: String) -> [[Int]] {
        var out: [[Int]] = []
        let pattern = "#?([0-9a-fA-F]{6}|[0-9a-fA-F]{3})\\b"
        guard let re = try? NSRegularExpression(pattern: pattern) else { return out }
        let ns = str as NSString
        for m in re.matches(in: str, range: NSRange(location: 0, length: ns.length)) {
            if let rgb = parse(ns.substring(with: m.range(at: 1))) { out.append(rgb) }
        }
        return out
    }
}