Created
January 19, 2026 16:58
-
-
Save itsfolf/ad1624951bf4f79b5c342b2e44b74f82 to your computer and use it in GitHub Desktop.
PoDNS Nix
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # pronouns.nix - query pronouns over DNS | |
| # usage: nix eval --raw --impure --expr 'import ./pronouns.nix { domain = "example.com"; }' | |
| { | |
| pkgs ? import <nixpkgs> { }, | |
| domain ? null, | |
| }: | |
| let | |
| inherit (pkgs) lib; | |
| inherit (lib) strings lists; | |
| stripQuotes = str: strings.removeSuffix "\"" (strings.removePrefix "\"" str); | |
| getComment = | |
| str: | |
| if strings.hasInfix "#" str then | |
| strings.removePrefix "#" (lists.last (strings.splitString "#" str)) | |
| else | |
| ""; | |
| removeComment = str: lists.head (strings.splitString "#" str); | |
| normalize = str: lib.replaceStrings [ " " "\t" "\n" "\r" ] [ "" "" "" "" ] (strings.toLower str); | |
| parseTags = | |
| str: | |
| if !strings.hasInfix ";" str then | |
| [ ] | |
| else | |
| let | |
| afterFirst = strings.concatStringsSep ";" (lists.drop 1 (strings.splitString ";" str)); | |
| rawTags = strings.splitString ";" afterFirst; | |
| in | |
| lists.unique (lists.filter (t: t != "") (map strings.trim rawTags)); | |
| getPronounSet = str: strings.trim (lists.head (strings.splitString ";" str)); | |
| validatePronounSet = | |
| str: | |
| let | |
| parts = strings.splitString "/" str; | |
| count = lists.length parts; | |
| in | |
| count >= 2 && count <= 5 && lists.all (p: builtins.match "[a-z]+" p != null) parts; | |
| convertPronounSet = str: if str == "it/its" then "it/it/its/its/itself" else str; | |
| hasPreferredTag = tags: lists.elem "preferred" tags; | |
| hasPlural = tags: lists.elem "plural" tags; | |
| addImplicitPlural = | |
| pronounSet: tags: | |
| if strings.hasPrefix "they/them" pronounSet && !hasPlural tags then | |
| lists.unique (tags ++ [ "plural" ]) | |
| else | |
| tags; | |
| parseRecord = | |
| raw: | |
| let | |
| stripped = stripQuotes raw; | |
| comment = getComment stripped; | |
| withoutComment = removeComment stripped; | |
| normalized = normalize withoutComment; | |
| in | |
| if normalized == "" && comment != "" then | |
| { | |
| type = "comment"; | |
| inherit comment; | |
| } | |
| else if normalized == "" then | |
| null | |
| else if normalized == "*" then | |
| { | |
| type = "wildcard"; | |
| inherit comment; | |
| } | |
| else if normalized == "!" then | |
| { | |
| type = "none"; | |
| inherit comment; | |
| } | |
| else | |
| let | |
| pronounSet = getPronounSet normalized; | |
| rawTags = parseTags normalized; | |
| converted = convertPronounSet pronounSet; | |
| in | |
| if validatePronounSet converted then | |
| { | |
| type = "pronouns"; | |
| pronounSet = converted; | |
| tags = addImplicitPlural converted rawTags; | |
| inherit comment; | |
| } | |
| else | |
| null; | |
| parseRecords = rawRecords: lists.filter (r: r != null) (map parseRecord rawRecords); | |
| findByType = records: type: lists.filter (r: r.type == type) records; | |
| countNonComments = records: lists.length (lists.filter (r: r.type != "comment") records); | |
| validateNoneAlone = | |
| records: | |
| let | |
| hasNone = lists.length (findByType records "none") > 0; | |
| nonCommentCount = countNonComments records; | |
| in | |
| !hasNone || nonCommentCount == 1; | |
| findPreferred = | |
| records: | |
| let | |
| pronounRecords = findByType records "pronouns"; | |
| preferred = lists.filter (r: hasPreferredTag r.tags) pronounRecords; | |
| in | |
| if lists.length preferred > 0 then lists.head preferred else null; | |
| selectDefault = | |
| records: | |
| let | |
| hasWildcard = lists.length (findByType records "wildcard") > 0; | |
| hasNone = lists.length (findByType records "none") > 0; | |
| pronounRecords = findByType records "pronouns"; | |
| preferred = findPreferred records; | |
| in | |
| if hasNone then | |
| { | |
| type = "none"; | |
| message = "Use name (no pronouns)"; | |
| } | |
| else if hasWildcard then | |
| if preferred != null then | |
| { | |
| type = "any-with-preference"; | |
| pronounSet = preferred.pronounSet; | |
| message = "Any, prefer ${preferred.pronounSet}"; | |
| } | |
| else if lists.length pronounRecords > 0 then | |
| { | |
| type = "any-with-preference"; | |
| pronounSet = (lists.head pronounRecords).pronounSet; | |
| message = "Any, prefer ${(lists.head pronounRecords).pronounSet}"; | |
| } | |
| else | |
| { | |
| type = "any"; | |
| message = "Any, default: they/them"; | |
| } | |
| else if preferred != null then | |
| { | |
| type = "preferred"; | |
| pronounSet = preferred.pronounSet; | |
| message = preferred.pronounSet; | |
| } | |
| else if lists.length pronounRecords > 0 then | |
| { | |
| type = "first"; | |
| pronounSet = (lists.head pronounRecords).pronounSet; | |
| message = "${(lists.head pronounRecords).pronounSet} (first record)"; | |
| } | |
| else | |
| { | |
| type = "none-found"; | |
| message = "No valid records"; | |
| }; | |
| queryDns = | |
| domain: | |
| let | |
| queryDomain = if strings.hasPrefix "pronouns." domain then domain else "pronouns.${domain}"; | |
| url = "https://dns.google/resolve?name=${queryDomain}&type=TXT"; | |
| response = builtins.fetchurl { | |
| url = url; | |
| name = "dns-${builtins.hashString "sha256" queryDomain}.json"; | |
| }; | |
| json = builtins.fromJSON (builtins.readFile response); | |
| records = if json ? Answer then json.Answer else [ ]; | |
| txtRecords = lists.filter (r: r.type == 16) records; | |
| in | |
| map (r: r.data) txtRecords; | |
| lookup = | |
| domain: | |
| let | |
| rawRecords = queryDns domain; | |
| in | |
| if lists.length rawRecords == 0 then | |
| { | |
| success = false; | |
| error = "No pronoun records found"; | |
| records = [ ]; | |
| } | |
| else | |
| let | |
| parsed = parseRecords rawRecords; | |
| in | |
| if lists.length parsed == 0 then | |
| { | |
| success = false; | |
| error = "No valid pronoun records found"; | |
| records = [ ]; | |
| } | |
| else if !validateNoneAlone parsed then | |
| { | |
| success = false; | |
| error = "! record must be alone"; | |
| records = parsed; | |
| } | |
| else | |
| { | |
| success = true; | |
| records = parsed; | |
| default = selectDefault parsed; | |
| }; | |
| parse = | |
| recordStrings: | |
| let | |
| parsed = parseRecords recordStrings; | |
| in | |
| if lists.length parsed == 0 then | |
| { | |
| success = false; | |
| error = "No valid pronoun records"; | |
| records = [ ]; | |
| } | |
| else if !validateNoneAlone parsed then | |
| { | |
| success = false; | |
| error = "! record must be alone"; | |
| records = parsed; | |
| } | |
| else | |
| { | |
| success = true; | |
| records = parsed; | |
| default = selectDefault parsed; | |
| }; | |
| formatRecord = | |
| record: | |
| if record.type == "comment" then | |
| "# ${record.comment}" | |
| else if record.type == "wildcard" then | |
| if record.comment != "" then | |
| "* - Wildcard (any pronouns) # ${record.comment}" | |
| else | |
| "* - Wildcard (any pronouns)" | |
| else if record.type == "none" then | |
| if record.comment != "" then "! - None (use name) # ${record.comment}" else "! - None (use name)" | |
| else | |
| let | |
| tagStr = | |
| if lists.length record.tags > 0 then | |
| " (tags: ${strings.concatStringsSep ", " record.tags})" | |
| else | |
| ""; | |
| commentStr = if record.comment != "" then " # ${record.comment}" else ""; | |
| in | |
| "${record.pronounSet}${tagStr}${commentStr}"; | |
| formatCliOutput = | |
| result: domain: | |
| if !result.success then | |
| "Error: ${result.error}" | |
| else | |
| let | |
| recordLines = map ( | |
| r: | |
| let | |
| base = formatRecord r; | |
| in | |
| if r.type == "pronouns" && hasPreferredTag r.tags then | |
| "✓ ${base} [PREFERRED]" | |
| else if r.type == "comment" then | |
| base | |
| else | |
| "• ${base}" | |
| ) result.records; | |
| recordsStr = strings.concatStringsSep "\n " recordLines; | |
| queryDomain = if strings.hasPrefix "pronouns." domain then domain else "pronouns.${domain}"; | |
| in | |
| '' | |
| Querying: ${queryDomain} | |
| Found ${toString (lists.length result.records)} record(s): | |
| ${recordsStr} | |
| Default: ${result.default.message} | |
| ''; | |
| api = { | |
| inherit | |
| lookup | |
| parse | |
| parseRecord | |
| parseRecords | |
| ; | |
| inherit formatRecord formatCliOutput selectDefault; | |
| inherit | |
| stripQuotes | |
| normalize | |
| parseTags | |
| getPronounSet | |
| ; | |
| inherit validatePronounSet convertPronounSet hasPreferredTag; | |
| }; | |
| in | |
| if domain != null then formatCliOutput (lookup domain) domain else api |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment