msg: { actual, expected, asString ? false, asJSON ? false, removeDunders ? false , safeToPrint ? true }: let preProcess = v: if removeDunders then undunder v else if asString then toString v else if asJSON then builtins.toJSON v else v; a = preProcess actual; e = preProcess expected; undunder = v: if builtins.isAttrs v then builtins.removeAttrs v [ "__toString" "__functor" ] else v; out = (if safeToPrint then builtins.toJSON (undunder actual) else ''{"msg": "refusing to print"}''); in if (a == e) then '' echo 'it ${msg}' '' else builtins.trace "FAILED ${msg}" '' echo FAILED ${msg} echo '${out}' | jq '.' ''