Skip to main content
Glama
utils.nix4.03 kB
# Utility functions library { lib }: rec { # Math utilities math = { # Calculate factorial factorial = n: if n == 0 then 1 else n * factorial (n - 1); # Calculate fibonacci number fibonacci = n: if n <= 1 then n else (fibonacci (n - 1)) + (fibonacci (n - 2)); # Check if number is prime isPrime = n: let checkDivisible = i: if i * i > n then true else if lib.mod n i == 0 then false else checkDivisible (i + 1); in if n <= 1 then false else if n <= 3 then true else checkDivisible 2; # Greatest common divisor gcd = a: b: if b == 0 then a else gcd b (lib.mod a b); }; # String manipulation strings = { # Reverse a string reverse = str: let len = lib.stringLength str; chars = lib.genList (i: lib.substring (len - i - 1) 1 str) len; in lib.concatStrings chars; # Check if string is palindrome isPalindrome = str: str == strings.reverse str; # Convert to camelCase toCamelCase = str: let words = lib.splitString "-" str; capitalize = w: if w == "" then "" else (lib.toUpper (lib.substring 0 1 w)) + (lib.substring 1 (-1) w); capitalizedWords = lib.tail (map capitalize words); in (lib.head words) + (lib.concatStrings capitalizedWords); # Convert to snake_case toSnakeCase = str: lib.replaceStrings ["-"] ["_"] (lib.toLower str); }; # List operations lists = { # Get unique elements unique = list: lib.foldl' (acc: x: if lib.elem x acc then acc else acc ++ [x] ) [] list; # Zip two lists zip = list1: list2: let len1 = lib.length list1; len2 = lib.length list2; minLen = if len1 < len2 then len1 else len2; in lib.genList (i: { fst = lib.elemAt list1 i; snd = lib.elemAt list2 i; }) minLen; # Flatten nested list flatten = list: lib.foldl' (acc: x: if builtins.isList x then acc ++ (flatten x) else acc ++ [x] ) [] list; # Partition list by predicate partition = pred: list: lib.foldl' (acc: x: if pred x then { yes = acc.yes ++ [x]; no = acc.no; } else { yes = acc.yes; no = acc.no ++ [x]; } ) { yes = []; no = []; } list; }; # Attribute set operations attrs = { # Deep merge two attribute sets deepMerge = attr1: attr2: lib.recursiveUpdate attr1 attr2; # Filter attributes by predicate filterAttrs = pred: attrs: lib.filterAttrs pred attrs; # Map over attribute values mapValues = f: attrs: lib.mapAttrs (name: value: f value) attrs; # Get nested attribute safely getAttrPath = path: default: attrs: lib.attrByPath path default attrs; }; # File system utilities files = { # Read JSON file readJSON = path: builtins.fromJSON (builtins.readFile path); # Read TOML file readTOML = path: builtins.fromTOML (builtins.readFile path); # Check if path exists pathExists = path: builtins.pathExists path; # Get file type getFileType = path: let type = builtins.readFileType path; in if type == "directory" then "dir" else if type == "regular" then "file" else if type == "symlink" then "link" else "unknown"; }; # Validation utilities validate = { # Check if value is email isEmail = str: builtins.match "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$" str != null; # Check if value is URL isURL = str: builtins.match "^https?://[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}" str != null; # Check if value is valid version isVersion = str: builtins.match "^[0-9]+\\.[0-9]+\\.[0-9]+$" str != null; }; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ryota-murakami/serena'

If you have feedback or need assistance with the MCP directory API, please join our Discord server