<commit_before># Code for buildRustCrate, a Nix function that builds Rust code, just
# like Cargo, but using Nix instead.
#
# This can be useful for deploying packages with NixOps, and to share
# binary dependencies between projects.

{ lib, stdenv, defaultCrateOverrides, fetchCrate, rustc, rust, cargo, jq }:

let
    # This doesn't appear to be officially documented anywhere yet.
    # See https://github.com/rust-lang-nursery/rust-forge/issues/101.
    target_os = if stdenv.hostPlatform.isDarwin
      then "macos"
      else stdenv.hostPlatform.parsed.kernel.name;

    # Create rustc arguments to link against the given list of dependencies and
    # renames
    mkRustcDepArgs = dependencies: crateRenames:
      lib.concatMapStringsSep " " (dep:
        let
          extern = lib.replaceStrings ["-"] ["_"] dep.libName;
          name = if lib.hasAttr dep.crateName crateRenames then
            lib.strings.replaceStrings ["-"] ["_"] crateRenames.${dep.crateName}
          else
            extern;
        in (if lib.any (x: x == "lib" || x == "rlib") dep.crateType then
           " --extern ${name}=${dep.lib}/lib/lib${extern}-${dep.metadata}.rlib"
         else
           " --extern ${name}=${dep.lib}/lib/lib${extern}-${dep.metadata}${stdenv.hostPlatform.extensions.sharedLibrary}")
      ) dependencies;

   inherit (import ./log.nix { inherit lib; }) noisily echo_colored;

   configureCrate = import ./configure-crate.nix {
     inherit lib stdenv echo_colored noisily mkRustcDepArgs;
   };

   buildCrate = import ./build-crate.nix {
     inherit lib stdenv mkRustcDepArgs rust;
   };

   installCrate = import ./install-crate.nix { inherit stdenv; };
in

crate_: lib.makeOverridable ({ rust, release, verbose, features, buildInputs, crateOverrides,
  dependencies, buildDependencies, crateRenames,
  extraRustcOpts, buildTests,
  preUnpack, postUnpack, prePatch, patches, postPatch,
  preConfigure, postConfigure, preBuild, postBuild, preInstall, postInstall }:

let crate = crate_ // (lib.attrByPath [ crate_.crateName ] (attr: {}) crateOverrides crate_);
    dependencies_ = dependencies;
    buildDependencies_ = buildDependencies;
    processedAttrs = [
      "src" "buildInputs" "crateBin" "crateLib" "libName" "libPath"
      "buildDependencies" "dependencies" "features" "crateRenames"
      "crateName" "version" "build" "authors" "colors" "edition"
      "buildTests"
    ];
    extraDerivationAttrs = builtins.removeAttrs crate processedAttrs;
    buildInputs_ = buildInputs;
    extraRustcOpts_ = extraRustcOpts;
    buildTests_ = buildTests;

    # crate2nix has a hack for the old bash based build script that did split
    # entries at `,`. No we have to work around that hack.
    # https://github.com/kolloch/crate2nix/blame/5b19c1b14e1b0e5522c3e44e300d0b332dc939e7/crate2nix/templates/build.nix.tera#L89
    crateBin = lib.filter (bin: !(bin ? name && bin.name == ",")) (crate.crateBin or []);
    hasCrateBin = crate ? crateBin;
in
stdenv.mkDerivation (rec {

    inherit (crate) crateName;
    inherit
      preUnpack
      postUnpack
      prePatch
      patches
      postPatch
      preConfigure
      postConfigure
      preBuild
      postBuild
      preInstall
      postInstall
      buildTests
    ;

    src = crate.src or (fetchCrate { inherit (crate) crateName version sha256; });
    name = "rust_${crate.crateName}-${crate.version}${lib.optionalString buildTests_ "-test"}";
    depsBuildBuild = [ rust stdenv.cc cargo jq ];
    buildInputs = (crate.buildInputs or []) ++ buildInputs_;
    dependencies = map lib.getLib dependencies_;
    buildDependencies = map lib.getLib buildDependencies_;

    completeDeps = lib.unique (dependencies ++ lib.concatMap (dep: dep.completeDeps) dependencies);
    completeBuildDeps = lib.unique (
      buildDependencies
      ++ lib.concatMap (dep: dep.completeBuildDeps ++ dep.completeDeps) buildDependencies
    );

    crateFeatures = lib.optionalString (crate ? features)
      (lib.concatMapStringsSep " " (f: "--cfg feature=\\\"${f}\\\"") (crate.features ++ features));

    libName = if crate ? libName then crate.libName else crate.crateName;
    libPath = if crate ? libPath then crate.libPath else "";

    # Seed the symbol hashes with something unique every time.
    # https://doc.rust-lang.org/1.0.0/rustc/metadata/loader/index.html#frobbing-symbols
    metadata = let
      depsMetadata = lib.foldl' (str: dep: str + dep.metadata) "" (dependencies ++ buildDependencies);
      hashedMetadata = builtins.hashString "sha256"
        (crateName + "-" + crateVersion + "___" + toString crateFeatures + "___" + depsMetadata);
      in lib.substring 0 10 hashedMetadata;

    build = crate.build or "";
    # Either set to a concrete sub path to the crate root
    # or use `null` for auto-detect.
    workspace_member = crate.workspace_member or ".";
    crateVersion = crate.version;
    crateDescription = crate.description or "";
    crateAuthors = if crate ? authors && lib.isList crate.authors then crate.authors else [];
    crateHomepage = crate.homepage or "";
    crateType =
      if lib.attrByPath ["procMacro"] false crate then ["proc-macro"] else
      if lib.attrByPath ["plugin"] false crate then ["dylib"] else<commit_msg>buildRustCrate: fewer backslashes<commit_after># Code for buildRustCrate, a Nix function that builds Rust code, just
# like Cargo, but using Nix instead.
#
# This can be useful for deploying packages with NixOps, and to share
# binary dependencies between projects.

{ lib, stdenv, defaultCrateOverrides, fetchCrate, rustc, rust, cargo, jq }:

let
    # This doesn't appear to be officially documented anywhere yet.
    # See https://github.com/rust-lang-nursery/rust-forge/issues/101.
    target_os = if stdenv.hostPlatform.isDarwin
      then "macos"
      else stdenv.hostPlatform.parsed.kernel.name;

    # Create rustc arguments to link against the given list of dependencies and
    # renames
    mkRustcDepArgs = dependencies: crateRenames:
      lib.concatMapStringsSep " " (dep:
        let
          extern = lib.replaceStrings ["-"] ["_"] dep.libName;
          name = if lib.hasAttr dep.crateName crateRenames then
            lib.strings.replaceStrings ["-"] ["_"] crateRenames.${dep.crateName}
          else
            extern;
        in (if lib.any (x: x == "lib" || x == "rlib") dep.crateType then
           " --extern ${name}=${dep.lib}/lib/lib${extern}-${dep.metadata}.rlib"
         else
           " --extern ${name}=${dep.lib}/lib/lib${extern}-${dep.metadata}${stdenv.hostPlatform.extensions.sharedLibrary}")
      ) dependencies;

   inherit (import ./log.nix { inherit lib; }) noisily echo_colored;

   configureCrate = import ./configure-crate.nix {
     inherit lib stdenv echo_colored noisily mkRustcDepArgs;
   };

   buildCrate = import ./build-crate.nix {
     inherit lib stdenv mkRustcDepArgs rust;
   };

   installCrate = import ./install-crate.nix { inherit stdenv; };
in

crate_: lib.makeOverridable ({ rust, release, verbose, features, buildInputs, crateOverrides,
  dependencies, buildDependencies, crateRenames,
  extraRustcOpts, buildTests,
  preUnpack, postUnpack, prePatch, patches, postPatch,
  preConfigure, postConfigure, preBuild, postBuild, preInstall, postInstall }:

let crate = crate_ // (lib.attrByPath [ crate_.crateName ] (attr: {}) crateOverrides crate_);
    dependencies_ = dependencies;
    buildDependencies_ = buildDependencies;
    processedAttrs = [
      "src" "buildInputs" "crateBin" "crateLib" "libName" "libPath"
      "buildDependencies" "dependencies" "features" "crateRenames"
      "crateName" "version" "build" "authors" "colors" "edition"
      "buildTests"
    ];
    extraDerivationAttrs = builtins.removeAttrs crate processedAttrs;
    buildInputs_ = buildInputs;
    extraRustcOpts_ = extraRustcOpts;
    buildTests_ = buildTests;

    # crate2nix has a hack for the old bash based build script that did split
    # entries at `,`. No we have to work around that hack.
    # https://github.com/kolloch/crate2nix/blame/5b19c1b14e1b0e5522c3e44e300d0b332dc939e7/crate2nix/templates/build.nix.tera#L89
    crateBin = lib.filter (bin: !(bin ? name && bin.name == ",")) (crate.crateBin or []);
    hasCrateBin = crate ? crateBin;
in
stdenv.mkDerivation (rec {

    inherit (crate) crateName;
    inherit
      preUnpack
      postUnpack
      prePatch
      patches
      postPatch
      preConfigure
      postConfigure
      preBuild
      postBuild
      preInstall
      postInstall
      buildTests
    ;

    src = crate.src or (fetchCrate { inherit (crate) crateName version sha256; });
    name = "rust_${crate.crateName}-${crate.version}${lib.optionalString buildTests_ "-test"}";
    depsBuildBuild = [ rust stdenv.cc cargo jq ];
    buildInputs = (crate.buildInputs or []) ++ buildInputs_;
    dependencies = map lib.getLib dependencies_;
    buildDependencies = map lib.getLib buildDependencies_;

    completeDeps = lib.unique (dependencies ++ lib.concatMap (dep: dep.completeDeps) dependencies);
    completeBuildDeps = lib.unique (
      buildDependencies
      ++ lib.concatMap (dep: dep.completeBuildDeps ++ dep.completeDeps) buildDependencies
    );

    crateFeatures = lib.optionalString (crate ? features)
      (lib.concatMapStringsSep " " (f: ''--cfg feature=\"${f}\"'') (crate.features ++ features));

    libName = if crate ? libName then crate.libName else crate.crateName;
    libPath = if crate ? libPath then crate.libPath else "";

    # Seed the symbol hashes with something unique every time.
    # https://doc.rust-lang.org/1.0.0/rustc/metadata/loader/index.html#frobbing-symbols
    metadata = let
      depsMetadata = lib.foldl' (str: dep: str + dep.metadata) "" (dependencies ++ buildDependencies);
      hashedMetadata = builtins.hashString "sha256"
        (crateName + "-" + crateVersion + "___" + toString crateFeatures + "___" + depsMetadata);
      in lib.substring 0 10 hashedMetadata;

    build = crate.build or "";
    # Either set to a concrete sub path to the crate root
    # or use `null` for auto-detect.
    workspace_member = crate.workspace_member or ".";
    crateVersion = crate.version;
    crateDescription = crate.description or "";
    crateAuthors = if crate ? authors && lib.isList crate.authors then crate.authors else [];
    crateHomepage = crate.homepage or "";
    crateType =
      if lib.attrByPath ["procMacro"] false crate then ["proc-macro"] else
      if lib.attrByPath ["plugin"] false crate then ["dylib"] else
{'fraction_non_alphanumeric': 0.11194740853658537, 'fraction_numerical': 0.008765243902439025, 'mean_word_length': 3.3250927070457355, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 6, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1081401', 'n_tokens_mistral': 3277, 'n_tokens_neox': 3221, 'n_words': 835}