This CL can be used to compare the style of nixpkgs-fmt against other formatters (nixpkgs, alejandra). Change-Id: I87c6abff6bcb546b02ead15ad0405f81e01b6d9e Reviewed-on: https://cl.tvl.fyi/c/depot/+/4397 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org> Reviewed-by: lukegb <lukegb@tvl.fyi> Reviewed-by: wpcarro <wpcarro@gmail.com> Reviewed-by: Profpatsch <mail@profpatsch.de> Reviewed-by: kanepyork <rikingcoding@gmail.com> Reviewed-by: tazjin <tazjin@tvl.su> Reviewed-by: cynthia <cynthia@tvl.fyi> Reviewed-by: edef <edef@edef.eu> Reviewed-by: eta <tvl@eta.st> Reviewed-by: grfn <grfn@gws.fyi>
		
			
				
	
	
		
			99 lines
		
	
	
	
		
			2.4 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
			
		
		
	
	
			99 lines
		
	
	
	
		
			2.4 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
| { depot, lib, pkgs, ... }:
 | |
| 
 | |
| let
 | |
| 
 | |
|   inherit (depot.users.sterni.nix.flow)
 | |
|     cond
 | |
|     ;
 | |
| 
 | |
|   inherit (depot.nix)
 | |
|     yants
 | |
|     ;
 | |
| 
 | |
|   inherit (depot.users.sterni.nix)
 | |
|     string
 | |
|     ;
 | |
| 
 | |
|   # A char is the atomic element of a nix string
 | |
|   # which is essentially an array of arbitrary bytes
 | |
|   # as long as they are not a NUL byte.
 | |
|   #
 | |
|   # A char is neither a byte nor a unicode codepoint!
 | |
|   char = yants.restrict "char" (s: builtins.stringLength s == 1) yants.string;
 | |
| 
 | |
|   # integer representation of char
 | |
|   charval = yants.restrict "charval" (i: i >= 1 && i < 256) yants.int;
 | |
| 
 | |
|   allChars = builtins.readFile ./all-chars.bin;
 | |
| 
 | |
|   # Originally I searched a list for this, but came to the
 | |
|   # conclusion that this can never be fast enough in Nix.
 | |
|   # We therefore use a solution similar to infinisil's.
 | |
|   ordMap = builtins.listToAttrs
 | |
|     (lib.imap1 (i: v: { name = v; value = i; })
 | |
|       (string.toChars allChars));
 | |
| 
 | |
|   # Note on performance:
 | |
|   # chr and ord have been benchmarked using the following cases:
 | |
|   #
 | |
|   #  builtins.map ord (lib.stringToCharacters allChars)
 | |
|   #  builtins.map chr (builtins.genList (int.add 1) 255
 | |
|   #
 | |
|   # The findings are as follows:
 | |
|   # 1. Searching through either strings using recursion is
 | |
|   #    unbearably slow in Nix, leading to evaluation times
 | |
|   #    of up to 3s for the following very small test case.
 | |
|   #    This is why we use the trusty attribute set for ord.
 | |
|   # 2. String indexing is much faster than list indexing which
 | |
|   #    is why we use the former for chr.
 | |
|   ord = c: ordMap."${c}";
 | |
| 
 | |
|   chr = i: string.charAt (i - 1) allChars;
 | |
| 
 | |
|   asciiAlpha = c:
 | |
|     let
 | |
|       v = ord c;
 | |
|     in
 | |
|     (v >= 65 && v <= 90)
 | |
|     || (v >= 97 && v <= 122);
 | |
| 
 | |
|   asciiNum = c:
 | |
|     let
 | |
|       v = ord c;
 | |
|     in
 | |
|     v >= 48 && v <= 57;
 | |
| 
 | |
|   asciiAlphaNum = c: asciiAlpha c || asciiNum c;
 | |
| 
 | |
| in
 | |
| {
 | |
|   inherit
 | |
|     allChars
 | |
|     char
 | |
|     charval
 | |
|     ord
 | |
|     chr
 | |
|     asciiAlpha
 | |
|     asciiNum
 | |
|     asciiAlphaNum
 | |
|     ;
 | |
| 
 | |
|   # originally I generated a nix file containing a list of
 | |
|   # characters, but infinisil uses a better way which I adapt
 | |
|   # which is using builtins.readFile instead of import.
 | |
|   __generateAllChars = pkgs.runCommandCC "generate-all-chars"
 | |
|     {
 | |
|       source = ''
 | |
|         #include <stdio.h>
 | |
| 
 | |
|         int main(void) {
 | |
|           for(int i = 1; i <= 0xff; i++) {
 | |
|             putchar(i);
 | |
|           }
 | |
|         }
 | |
|       '';
 | |
|       passAsFile = [ "source" ];
 | |
|     } ''
 | |
|     $CC -o "$out" -x c "$sourcePath"
 | |
|   '';
 | |
| }
 |