1
0
Fork 0
mirror of https://github.com/nix-community/home-manager.git synced 2025-11-08 19:46:05 +01:00
home-manager/modules/lib/strings.nix
Austin Horstman f62e9a8114 lib/strings: add extra string matching predicates
Centralize logic to avoid needing to rewrite it elsewhere.

Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2025-07-05 00:26:25 -05:00

91 lines
2.8 KiB
Nix

{ lib }:
let
inherit (lib)
genList
length
lowerChars
replaceStrings
stringToCharacters
upperChars
;
in
rec {
# Figures out a valid Nix store name for the given path.
storeFileName =
path:
let
# All characters that are considered safe. Note "-" is not
# included to avoid "-" followed by digit being interpreted as a
# version.
safeChars =
[
"+"
"."
"_"
"?"
"="
]
++ lowerChars
++ upperChars
++ stringToCharacters "0123456789";
empties = l: genList (x: "") (length l);
unsafeInName = stringToCharacters (replaceStrings safeChars (empties safeChars) path);
safeName = replaceStrings unsafeInName (empties unsafeInName) path;
in
"hm_" + safeName;
/*
Convert a string from camelCase or PascalCase to another case format using a separator
Type: string -> string -> string
*/
toCaseWithSeparator =
separator: string:
let
splitByWords = builtins.split "([A-Z])";
processWord = s: if lib.isString s then s else separator + lib.toLower (lib.elemAt s 0);
words = splitByWords string;
converted = lib.concatStrings (map processWord words);
in
lib.removePrefix separator converted;
/*
Convert a string from camelCase or PascalCase to snake_case
Type: string -> string
*/
toSnakeCase = toCaseWithSeparator "_";
/*
Convert a string from camelCase or PascalCase to kebab-case
Type: string -> string
*/
toKebabCase = toCaseWithSeparator "-";
# A predicate that returns true only for camelCase.
isCamelCase =
str:
# This regex enforces the entire structure:
# - Must start with one or more lowercase letters.
# - Must be followed by one or more "humps" of an uppercase letter
# and then subsequent lowercase letters/numbers.
builtins.match "^[a-z]+([A-Z][a-z0-9]*)+$" str != null;
# Returns true for strings like `PascalCase`, `Application`, `URLShortener`.
# Must start with an uppercase letter.
isPascalCase = str: builtins.match "^[A-Z][a-z0-9]*([A-Z][a-z0-9]*)*$" str != null;
# Returns true for strings like `snake_case`, `a_longer_variable`, `var1`.
# Must be all lowercase letters/numbers, with words separated by single underscores.
isSnakeCase = str: builtins.match "^[a-z0-9]+(_[a-z0-9]+)*$" str != null;
# Returns true for strings like `kebab-case`, `a-css-class-name`.
# Must be all lowercase letters/numbers, with words separated by single hyphens.
isKebabCase = str: builtins.match "^[a-z0-9]+(-[a-z0-9]+)*$" str != null;
# Returns true for strings like `SCREAMING_SNAKE_CASE`, `SOME_CONSTANT`.
# Must be all uppercase letters/numbers, with words separated by single underscores.
isScreamingSnakeCase = str: builtins.match "^[A-Z0-9]+(_[A-Z0-9]+)*$" str != null;
}