stuff
This commit is contained in:
@@ -211,6 +211,7 @@
|
|||||||
mkPkgs
|
mkPkgs
|
||||||
mkInputs
|
mkInputs
|
||||||
mkNixosConfig
|
mkNixosConfig
|
||||||
|
vaculib
|
||||||
;
|
;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
165
vaculib/ip.nix
165
vaculib/ip.nix
@@ -5,13 +5,14 @@
|
|||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
|
toInt = lib.toIntBase10;
|
||||||
elemAt =
|
elemAt =
|
||||||
list:
|
list:
|
||||||
idx:
|
idx:
|
||||||
let
|
let
|
||||||
positiveIdx = if idx < 0 then (lib.length list) + idx else idx;
|
positiveIdx = if idx < 0 then (lib.length list) + idx else idx;
|
||||||
in
|
in
|
||||||
lib.getElem list positiveIdx;
|
lib.elemAt list positiveIdx;
|
||||||
isDigits =
|
isDigits =
|
||||||
str:
|
str:
|
||||||
(builtins.match ''[0-9]+'' str) != null;
|
(builtins.match ''[0-9]+'' str) != null;
|
||||||
@@ -44,7 +45,7 @@ let
|
|||||||
ipToString =
|
ipToString =
|
||||||
obj:
|
obj:
|
||||||
(ipToStringCore obj)
|
(ipToStringCore obj)
|
||||||
++ lib.optionalString obj.hasPrefix
|
+ lib.optionalString obj.hasPrefix
|
||||||
"/${builtins.toString obj.prefixSize}";
|
"/${builtins.toString obj.prefixSize}";
|
||||||
isIP =
|
isIP =
|
||||||
obj:
|
obj:
|
||||||
@@ -58,11 +59,12 @@ let
|
|||||||
inherit segments;
|
inherit segments;
|
||||||
__toString = this.ipToString;
|
__toString = this.ipToString;
|
||||||
hasPrefix = false;
|
hasPrefix = false;
|
||||||
|
prefixSize = null;
|
||||||
toSubnet = mkIP (args // { prefixSize = this.bitSize; });
|
toSubnet = mkIP (args // { prefixSize = this.bitSize; });
|
||||||
} // lib.optionalAttrs (prefixSize != null) {
|
} // lib.optionalAttrs (prefixSize != null) {
|
||||||
hasPrefix = true;
|
hasPrefix = true;
|
||||||
toSubnet = mkIP args;
|
|
||||||
inherit prefixSize;
|
inherit prefixSize;
|
||||||
|
toSubnet = mkIP args;
|
||||||
subnetMask = mkIP {
|
subnetMask = mkIP {
|
||||||
segments = lib.genList (idx: this.maskBitsToSegment (prefixSize - segmentBitSize*idx)) segmentCount;
|
segments = lib.genList (idx: this.maskBitsToSegment (prefixSize - segmentBitSize*idx)) segmentCount;
|
||||||
};
|
};
|
||||||
@@ -73,7 +75,7 @@ let
|
|||||||
subnetSplit = lib.splitString "/" str;
|
subnetSplit = lib.splitString "/" str;
|
||||||
addrStr = lib.head subnetSplit;
|
addrStr = lib.head subnetSplit;
|
||||||
subnetStr = if (lib.length subnetSplit) == 2 then elemAt subnetSplit 1 else null;
|
subnetStr = if (lib.length subnetSplit) == 2 then elemAt subnetSplit 1 else null;
|
||||||
prefixSize = if subnetStr == null then null else lib.toInt subnetStr;
|
prefixSize = if subnetStr == null then null else toInt subnetStr;
|
||||||
innerParse = innerParseStrCore addrStr;
|
innerParse = innerParseStrCore addrStr;
|
||||||
valid = (subnetStr != null -> (isDigits subnetStr) && prefixSize >= 0 && prefixSize <= this.bitSize) && innerParse.valid;
|
valid = (subnetStr != null -> (isDigits subnetStr) && prefixSize >= 0 && prefixSize <= this.bitSize) && innerParse.valid;
|
||||||
in
|
in
|
||||||
@@ -85,15 +87,16 @@ let
|
|||||||
(this.parseStrCore str).valid;
|
(this.parseStrCore str).valid;
|
||||||
parse =
|
parse =
|
||||||
str:
|
str:
|
||||||
builtins.addErrorContext ''While parsing ${lib.escapeNixString str} as ${this.versionString}''
|
builtins.addErrorContext ''While parsing ${lib.strings.escapeNixString str} as ${this.versionString}''
|
||||||
(let
|
(let
|
||||||
innerParse = this.parseStrCore str;
|
innerParse = this.parseStrCore str;
|
||||||
in
|
in
|
||||||
lib.throwIf (!innerParse.valid) "Invalid ${this.versionString} string"
|
lib.throwIf (!innerParse.valid) "Invalid ${this.versionString} string: ${lib.strings.escapeNixString str}"
|
||||||
mkIP innerParse.mkArgs
|
mkIP innerParse.mkArgs
|
||||||
);
|
);
|
||||||
|
zero = this.mkIP { segments = lib.genList (_: 0) this.segmentCount; };
|
||||||
publicMethods = {
|
publicMethods = {
|
||||||
inherit (this) mkIP isIP isValidStr parse;
|
inherit (this) mkIP isIP isValidStr parse zero;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
in this;
|
in this;
|
||||||
@@ -106,18 +109,18 @@ let
|
|||||||
segmentCount = 4;
|
segmentCount = 4;
|
||||||
segmentBitSize = 8;
|
segmentBitSize = 8;
|
||||||
versionInt = 4;
|
versionInt = 4;
|
||||||
mkIP = args: this.mkIPCore // { zone = null; hasZone = false; };
|
mkIP = args: (this.mkIPCore args) // { zone = null; hasZone = false; };
|
||||||
ipToStringCore =
|
ipToStringCore =
|
||||||
obj:
|
obj:
|
||||||
lib.pipe obj.segments [
|
lib.pipe obj.segments [
|
||||||
(map builtins.toString)
|
(map builtins.toString)
|
||||||
(lib.concatStringSep ".")
|
(lib.concatStringsSep ".")
|
||||||
];
|
];
|
||||||
innerParseStrCore =
|
innerParseStrCore =
|
||||||
addrStr:
|
addrStr:
|
||||||
let
|
let
|
||||||
segmentStrs = lib.splitString "." addrStr;
|
segmentStrs = lib.splitString "." addrStr;
|
||||||
segments = map lib.toInt segmentStrs;
|
segments = map toInt segmentStrs;
|
||||||
valid = (builtins.length segmentStrs) == 4 && (lib.all isDigits segmentStrs) && (lib.all (s: s >= 0 && s <= this.segmentValueMax) segments);
|
valid = (builtins.length segmentStrs) == 4 && (lib.all isDigits segmentStrs) && (lib.all (s: s >= 0 && s <= this.segmentValueMax) segments);
|
||||||
in
|
in
|
||||||
{ inherit valid; } // lib.optionalAttrs valid {
|
{ inherit valid; } // lib.optionalAttrs valid {
|
||||||
@@ -134,15 +137,23 @@ let
|
|||||||
inherit zone;
|
inherit zone;
|
||||||
hasZone = zone != null;
|
hasZone = zone != null;
|
||||||
};
|
};
|
||||||
|
ipToStringCore =
|
||||||
|
obj:
|
||||||
|
(lib.pipe obj.segments [
|
||||||
|
(map nix-colors-lib.decToHex)
|
||||||
|
(lib.concatStringSep ":")
|
||||||
|
])
|
||||||
|
+ lib.optionalString obj.hasZone "%${obj.zone}"
|
||||||
|
;
|
||||||
parseSide =
|
parseSide =
|
||||||
str:
|
str:
|
||||||
let
|
let
|
||||||
segmentStrs = lib.splitString ":" str;
|
segmentStrs = lib.splitString ":" str;
|
||||||
segmentStrs' = if segmentStrs == [ "" ] then [] else segmentStrs;
|
segmentStrs' = if segmentStrs == [ "" ] then [] else segmentStrs;
|
||||||
valid = lib.all isHexDigits segmentStrs;
|
valid = lib.all isHexDigits segmentStrs;
|
||||||
segments = map nix-colors-lib.hexToDec segmentStrs';
|
segments = map nix-colors-lib.conversions.hexToDec segmentStrs';
|
||||||
in
|
in
|
||||||
{ inherit valid; } // lib.optionalAttrs valid { inherit segments; };
|
({ inherit valid; } // lib.optionalAttrs valid { inherit segments; });
|
||||||
parsePlain =
|
parsePlain =
|
||||||
{ str, bitsParsedSeparately ? 0 }:
|
{ str, bitsParsedSeparately ? 0 }:
|
||||||
let
|
let
|
||||||
@@ -150,9 +161,9 @@ let
|
|||||||
sides = lib.splitString "::" str;
|
sides = lib.splitString "::" str;
|
||||||
compressed = lib.length sides == 2;
|
compressed = lib.length sides == 2;
|
||||||
leftResult = parseSide (elemAt sides 0);
|
leftResult = parseSide (elemAt sides 0);
|
||||||
leftSegments = leftResult.segments;
|
leftSegments = leftResult.segments or [];
|
||||||
rightResult = if compressed then parseSide (elemAt sides 1) else { valid = true; segments = []; };
|
rightResult = if compressed then parseSide (elemAt sides 1) else { valid = true; segments = []; };
|
||||||
rightSegments = rightResult.segments;
|
rightSegments = rightResult.segments or [];
|
||||||
segmentCount = (lib.length leftSegments) + (lib.length rightSegments);
|
segmentCount = (lib.length leftSegments) + (lib.length rightSegments);
|
||||||
middleSegments = lib.genList (_: 0) (segmentFullCount - segmentCount);
|
middleSegments = lib.genList (_: 0) (segmentFullCount - segmentCount);
|
||||||
segments = leftSegments ++ middleSegments ++ rightSegments;
|
segments = leftSegments ++ middleSegments ++ rightSegments;
|
||||||
@@ -165,11 +176,11 @@ let
|
|||||||
&& lib.all (s: s >= 0 && s <= this.segmentBitSize) segments
|
&& lib.all (s: s >= 0 && s <= this.segmentBitSize) segments
|
||||||
;
|
;
|
||||||
in
|
in
|
||||||
{ inherit valid; } // lib.optionalAttrs valid { inherit segments; };
|
{ inherit valid; } // lib.optionalAttrs valid { segments = segments; };
|
||||||
innerParseStrCore =
|
innerParseStrCore =
|
||||||
addrStr:
|
addrStr:
|
||||||
let
|
let
|
||||||
ip4Regex = ''([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)'';
|
ip4Regex = ''[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+'';
|
||||||
ip4ToIP6Fragment =
|
ip4ToIP6Fragment =
|
||||||
ip4:
|
ip4:
|
||||||
[
|
[
|
||||||
@@ -180,13 +191,15 @@ let
|
|||||||
(lib.removePrefix "[")
|
(lib.removePrefix "[")
|
||||||
(lib.removeSuffix "]")
|
(lib.removeSuffix "]")
|
||||||
];
|
];
|
||||||
matches = builtins.match ''([0-9a-fA-F:]+)(${ip4Regex})?(%[a-zA-Z0-9_-]+)?'' withoutBrackets;
|
matches = builtins.match ''([0-9a-fA-F:]+)(:${ip4Regex})?(%[a-zA-Z0-9_-]+)?'' withoutBrackets;
|
||||||
|
|
||||||
mainMatch = elemAt matches 0;
|
mainMatchBlegh = elemAt matches 0;
|
||||||
ip4Match = elemAt matches 1;
|
ip4MatchBlegh = elemAt matches 1;
|
||||||
zoneMatch = elemAt matches 2;
|
zoneMatch = elemAt matches 2;
|
||||||
|
|
||||||
hasIP4 = ip4Match != null;
|
hasIP4 = ip4MatchBlegh != null;
|
||||||
|
ip4Match = lib.removePrefix ":" ip4MatchBlegh;
|
||||||
|
mainMatch = if hasIP4 then mainMatchBlegh + ":" else mainMatchBlegh;
|
||||||
ip4Parse = v4Data.innerParseStrCore ip4Match;
|
ip4Parse = v4Data.innerParseStrCore ip4Match;
|
||||||
ip4Segments = ip4Parse.mkArgs.segments;
|
ip4Segments = ip4Parse.mkArgs.segments;
|
||||||
|
|
||||||
@@ -200,22 +213,45 @@ let
|
|||||||
zone = if hasZone then lib.removePrefix "%" zoneMatch else null;
|
zone = if hasZone then lib.removePrefix "%" zoneMatch else null;
|
||||||
|
|
||||||
valid =
|
valid =
|
||||||
(lib.hasPrefix "[" addrStr) <-> (lib.hasSuffix "]" addrStr)
|
(lib.hasPrefix "[" addrStr) == (lib.hasSuffix "]" addrStr)
|
||||||
&& matches != null
|
&& (matches != null)
|
||||||
&& (lib.hasPrefix ":" mainMatch) -> (lib.hasPrefix "::" mainMatch)
|
&& ((lib.hasPrefix ":" mainMatch) -> (lib.hasPrefix "::" mainMatch))
|
||||||
&& (lib.hasSuffix ":" mainMatch) -> ((lib.hasSuffix "::" mainMatch) || hasIP4)
|
&& ((lib.hasSuffix ":" mainMatch) -> ((lib.hasSuffix "::" mainMatch) || hasIP4))
|
||||||
&& hasIP4 -> (lib.hasSuffix ":" mainMatch)
|
&& (hasIP4 -> (lib.hasSuffix ":" mainMatch))
|
||||||
&& hasIP4 -> ip4Parse.valid
|
&& (hasIP4 -> ip4Parse.valid)
|
||||||
&& segmentsResult.valid
|
&& segmentsResult.valid
|
||||||
;
|
;
|
||||||
|
|
||||||
|
# debugData = { inherit mainMatch hasIP4 ip4Match; segmentValid = segmentsResult.valid; };
|
||||||
in
|
in
|
||||||
assert matches != null -> (builtins.length matches) == 3;
|
assert matches != null -> (builtins.length matches) == 3;
|
||||||
|
# builtins.trace (builtins.deepSeq debugData debugData)
|
||||||
{ inherit valid; } // lib.optionalAttrs valid {
|
{ inherit valid; } // lib.optionalAttrs valid {
|
||||||
mkArgs = { inherit segments zone; };
|
mkArgs = { inherit segments zone; };
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
parseIPAny =
|
||||||
|
str:
|
||||||
|
let
|
||||||
|
v4Result = v4Data.parseStrCore str;
|
||||||
|
v6Result = v6Data.parseStrCore str;
|
||||||
|
in
|
||||||
|
lib.throwIf (v4Result.valid && v6Result.valid) "${lib.strings.escapeNixString str} is valid as both IPv4 and IPv6; This shouldn't happen"
|
||||||
|
lib.throwIfNot (v4Result.valid || v6Result.valid) "${lib.strings.escapeNixString str} is not a valid IPv4 or IPv6 address"
|
||||||
|
(if v4Result.valid then v4Data.mkIP v4Result.mkArgs else v6Data.mkIP v6Result.mkArgs);
|
||||||
|
equalIPs =
|
||||||
|
a: b:
|
||||||
|
assert isIPAny a;
|
||||||
|
assert isIPAny b;
|
||||||
|
lib.all (attr: a.${attr} == b.${attr}) [
|
||||||
|
"ipVersion"
|
||||||
|
"segments"
|
||||||
|
"hasPrefix"
|
||||||
|
"prefixSize"
|
||||||
|
"zone"
|
||||||
|
];
|
||||||
methods = {
|
methods = {
|
||||||
inherit isIPAny;
|
inherit isIPAny parseIPAny v4Data v6Data equalIPs;
|
||||||
v4 = v4Data.publicMethods;
|
v4 = v4Data.publicMethods;
|
||||||
v6 = v6Data.publicMethods;
|
v6 = v6Data.publicMethods;
|
||||||
} // lib.pipe [ v4Data v6Data ] [
|
} // lib.pipe [ v4Data v6Data ] [
|
||||||
@@ -224,82 +260,9 @@ let
|
|||||||
"isIP${toString data.versionInt}" = data.isIP;
|
"isIP${toString data.versionInt}" = data.isIP;
|
||||||
"isValidIP${toString data.versionInt}Str" = data.isValidStr;
|
"isValidIP${toString data.versionInt}Str" = data.isValidStr;
|
||||||
"parseIP${toString data.versionInt}" = data.parse;
|
"parseIP${toString data.versionInt}" = data.parse;
|
||||||
|
"zeroIP${toString data.versionInt}" = data.zero;
|
||||||
}))
|
}))
|
||||||
lib.mergeAttrsList
|
lib.mergeAttrsList
|
||||||
];
|
];
|
||||||
in
|
in
|
||||||
{ ip = methods; }
|
{ ip = methods; }
|
||||||
# { ip = {
|
|
||||||
# inherit isIPAny;
|
|
||||||
|
|
||||||
# isIP4 = obj: isIP obj && obj.ipVersion == 4;
|
|
||||||
# isIP6 = obj: isIP obj && obj.ipVersion == 6;
|
|
||||||
#
|
|
||||||
# mkIP4 = { segments, prefixSize ? null }@args:
|
|
||||||
# assert vaculib.isListWhere (seg: lib.isInt seg && seg >= 0 && seg <= 255) segments;
|
|
||||||
# assert prefixSize != null -> (lib.isInt prefixSize && prefixSize >= 0 && prefixSize <= 32);
|
|
||||||
# {
|
|
||||||
# _type = "com.shelvacu.nix.ip";
|
|
||||||
# ipVersion = 4;
|
|
||||||
# inherit segments;
|
|
||||||
# __toString = toStringIP4;
|
|
||||||
# hasPrefix = false;
|
|
||||||
# toSubnet = mkIP4 (args // { prefixSize = 32; });
|
|
||||||
# } // lib.optionalAttrs (prefixSize != null) {
|
|
||||||
# hasPrefix = true;
|
|
||||||
# toSubnet = mkIP4 args;
|
|
||||||
# inherit prefixSize;
|
|
||||||
# subnetMask = mkIP4 {
|
|
||||||
# segments = lib.genList (idx: bitsToIP4Segment (prefixSize - 8*idx)) 4;
|
|
||||||
# };
|
|
||||||
# };
|
|
||||||
#
|
|
||||||
# parseIP4 =
|
|
||||||
# str:
|
|
||||||
# builtins.addErrorContext ''While parsing ${lib.escapeNixString str} as IP4''
|
|
||||||
# (let
|
|
||||||
# m = builtins.match ''${ip4Re}${subnetRe}'' str;
|
|
||||||
# prefixMatch = elemAt m 5;
|
|
||||||
# in
|
|
||||||
# assert m != null;
|
|
||||||
# mkIP4 {
|
|
||||||
# segments = lib.pipe m [
|
|
||||||
# (lib.sublist 0 4)
|
|
||||||
# (map lib.toInt)
|
|
||||||
# ];
|
|
||||||
# prefixSize = if prefixMatch != null then lib.toInt prefixMatch else null;
|
|
||||||
# });
|
|
||||||
#
|
|
||||||
# mkIP6Subnet = { segments, prefixSize, zoneIndex }:
|
|
||||||
# assert vaculib.isListWhere (seg: lib.isInt seg && seg >= 0 && seg <= 256 * 256) segments;
|
|
||||||
# assert lib.isInt prefixSize;
|
|
||||||
# assert prefixSize >= 0;
|
|
||||||
# assert prefixSize <= 128;
|
|
||||||
# assert zoneIndex == null && lib.isString zoneIndex;
|
|
||||||
# {
|
|
||||||
# _type = "com.shelvacu.nix.ip";
|
|
||||||
# ipVersion = 6;
|
|
||||||
# inherit segments;
|
|
||||||
# inherit prefixSize;
|
|
||||||
# inherit zoneIndex;
|
|
||||||
# };
|
|
||||||
#
|
|
||||||
# parseIP6 =
|
|
||||||
# str:
|
|
||||||
# builtins.addErrorContext ''While parsing ${lib.escapeNixString str} as IP6''
|
|
||||||
# (let
|
|
||||||
# segment = ''[0-9a-fA-F]{0,4}'';
|
|
||||||
# scope = ''[0-9a-zA-Z]+'';
|
|
||||||
# m = builtins.match ''((${segment}:)+(${segment}))(%${scope})?${subnetRe}'' str;
|
|
||||||
# mIP4 = builtins.match ''((${segment}:)+)${ip4Re}${subnetRe}'' str;
|
|
||||||
# prefixMatch = if m != null then elemAt m -1 else elemAt mIP4 -1;
|
|
||||||
# ip4Match = elemAt mIP4 -2;
|
|
||||||
# segments = if m != null then parseIP6Plain { str = (lib.head m); } else (parseIP6Plain { str = (lib.head mIP4); aaa = 32; }) ++ ip4ToIP6Fragment (parseIP4 ip4Match);
|
|
||||||
# in
|
|
||||||
# assert m != null || mIP4 != null;
|
|
||||||
# mkIP6Subnet {
|
|
||||||
# inherit segments;
|
|
||||||
# prefixSize = if prefixMatch != null then lib.toInt prefixMatch else 128;
|
|
||||||
# zoneIndex = if m != null then elemAt m -2 else null;
|
|
||||||
# });
|
|
||||||
# }; }
|
|
||||||
|
@@ -35,4 +35,16 @@ rec {
|
|||||||
a:
|
a:
|
||||||
list:
|
list:
|
||||||
mapNamesToAttrs (_: a) list;
|
mapNamesToAttrs (_: a) list;
|
||||||
|
|
||||||
|
/**
|
||||||
|
# Type
|
||||||
|
```
|
||||||
|
isListWhere :: (a -> Bool) -> [a] -> Bool
|
||||||
|
isListWhere :: (a -> Bool) -> b -> Bool
|
||||||
|
```
|
||||||
|
*/
|
||||||
|
isListWhere =
|
||||||
|
f:
|
||||||
|
list:
|
||||||
|
lib.isList list && lib.all f list;
|
||||||
}
|
}
|
||||||
|
17
vaculib/math.nix
Normal file
17
vaculib/math.nix
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
rec {
|
||||||
|
# https://github.com/NixOS/nixpkgs/issues/41251#issuecomment-393660714
|
||||||
|
pow = base: exponent:
|
||||||
|
if exponent > 0 then
|
||||||
|
let
|
||||||
|
and1 = x: (x / 2) * 2 != x;
|
||||||
|
x = pow base (exponent / 2);
|
||||||
|
in
|
||||||
|
x * x * (if and1 exponent then base else 1)
|
||||||
|
else if exponent == 0 then
|
||||||
|
1
|
||||||
|
else
|
||||||
|
throw "undefined";
|
||||||
|
}
|
Reference in New Issue
Block a user