65 lines
1.9 KiB
Nix
65 lines
1.9 KiB
Nix
{lib, ...}: let
|
|
inherit (lib) toInt all min max;
|
|
inherit (builtins) isInt isFloat match getAttr hasAttr;
|
|
|
|
# basic checks
|
|
range = a: b: v: (v <= max a b) && (v >= min a b);
|
|
number = v: isInt v || isFloat v;
|
|
unary = range 0.0 1.0;
|
|
hue = range 0.0 360.0;
|
|
|
|
# type checking
|
|
hex = {
|
|
string = color: let
|
|
hexPatternWithHash = match "#[[:xdigit:]]{6}" color;
|
|
hexPatternNoHash = match "[[:xdigit:]]{6}" color;
|
|
isValid = hexPatternWithHash != null || hexPatternNoHash != null;
|
|
in
|
|
assert isValid || throw "Invalid hex color format: ${color}";
|
|
hexPatternWithHash != null || hexPatternNoHash != null;
|
|
set = color: let
|
|
hasAttributes = all (k: hasAttr k color) ["r" "g" "b"];
|
|
validPattern = all (k: let
|
|
v = getAttr k color;
|
|
in
|
|
match "[[:xdigit:]]{2}" v != null) ["r" "g" "b"];
|
|
in
|
|
hasAttributes && validPattern;
|
|
};
|
|
|
|
rgb = {
|
|
string = color: let
|
|
rgbPattern = match "([0-9]{1,3}),([0-9]{1,3}),([0-9]{1,3})" color;
|
|
toNum = str: let
|
|
num = toInt str;
|
|
in
|
|
num != null && range 0 255 num;
|
|
isValid = rgbPattern != null && all toNum rgbPattern;
|
|
in
|
|
isValid;
|
|
set = color: let
|
|
hasAttributes = all (k: hasAttr k color) ["r" "g" "b"];
|
|
validRanges = all (
|
|
k: let
|
|
v = getAttr k color;
|
|
in
|
|
number v && range 0 255 v
|
|
) ["r" "g" "b"];
|
|
in
|
|
hasAttributes && validRanges;
|
|
};
|
|
|
|
hsl = {
|
|
# TODO: add range checks
|
|
string = color: let
|
|
hslPattern = match "([0-9]{1,3}),[ ]*([0-9]{1,3})%,[ ]*([0-9]{1,3})%" color;
|
|
in
|
|
hslPattern != null;
|
|
|
|
set = color: let
|
|
hasAttributes = all (k: hasAttr k color) ["h" "s" "l"];
|
|
validRanges = hue color.h && all (k: unary (getAttr k color)) ["s" "l"];
|
|
in
|
|
hasAttributes && validRanges;
|
|
};
|
|
in {inherit range number unary hue hex rgb hsl;}
|