Bug: Migrate from cargo2nix to rust-flake



Migrate the Nix build/shell system from cargo2nix to rust-flake.

**Parent Issue:** #57  
**Related PR:** #8503

## Acceptance Criteria
- [x] Migrate from cargo2nix to rust-flake
- [x] Verify nix CI/CD compatibility

diff --git a/.gitignore b/.gitignore
index 01f1f2e9007..1f31c3c1525 100644
--- a/.gitignore
+++ b/.gitignore
@@ -270,3 +270,4 @@ creds.json
 
 # Nix services data
 /data
+.pre-commit-config.yaml
diff --git a/flake.lock b/flake.lock
index 36c888e7db1..9b65a841327 100644
--- a/flake.lock
+++ b/flake.lock
@@ -1,102 +1,113 @@
 {
   "nodes": {
-    "cargo2nix": {
+    "crane": {
+      "locked": {
+        "lastModified": 1750266157,
+        "narHash": "sha256-tL42YoNg9y30u7zAqtoGDNdTyXTi8EALDeCB13FtbQA=",
+        "owner": "ipetkov",
+        "repo": "crane",
+        "rev": "e37c943371b73ed87faf33f7583860f81f1d5a48",
+        "type": "github"
+      },
+      "original": {
+        "owner": "ipetkov",
+        "repo": "crane",
+        "type": "github"
+      }
+    },
+    "flake-parts": {
       "inputs": {
-        "flake-compat": "flake-compat",
-        "flake-utils": "flake-utils",
-        "nixpkgs": "nixpkgs",
-        "rust-overlay": "rust-overlay"
+        "nixpkgs-lib": "nixpkgs-lib"
       },
       "locked": {
-        "lastModified": 1742755793,
-        "narHash": "sha256-nz3zSO5a/cB/XPcP4c3cddUceKH9V3LNMuNpfV3TDeE=",
-        "owner": "cargo2nix",
-        "repo": "cargo2nix",
-        "rev": "f7b2c744b1e6ee39c7b4528ea34f06db598266a6",
+        "lastModified": 1751413152,
+        "narHash": "sha256-Tyw1RjYEsp5scoigs1384gIg6e0GoBVjms4aXFfRssQ=",
+        "owner": "hercules-ci",
+        "repo": "flake-parts",
+        "rev": "77826244401ea9de6e3bac47c2db46005e1f30b5",
         "type": "github"
       },
       "original": {
-        "owner": "cargo2nix",
-        "ref": "release-0.11.0",
-        "repo": "cargo2nix",
+        "owner": "hercules-ci",
+        "repo": "flake-parts",
         "type": "github"
       }
     },
-    "flake-compat": {
+    "git-hooks": {
       "flake": false,
       "locked": {
-        "lastModified": 1696426674,
-        "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
-        "owner": "edolstra",
-        "repo": "flake-compat",
-        "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
+        "lastModified": 1750779888,
+        "narHash": "sha256-wibppH3g/E2lxU43ZQHC5yA/7kIKLGxVEnsnVK1BtRg=",
+        "owner": "cachix",
+        "repo": "git-hooks.nix",
+        "rev": "16ec914f6fb6f599ce988427d9d94efddf25fe6d",
         "type": "github"
       },
       "original": {
-        "owner": "edolstra",
-        "repo": "flake-compat",
+        "owner": "cachix",
+        "repo": "git-hooks.nix",
         "type": "github"
       }
     },
-    "flake-parts": {
+    "globset": {
       "inputs": {
-        "nixpkgs-lib": "nixpkgs-lib"
+        "nixpkgs-lib": [
+          "rust-flake",
+          "nixpkgs"
+        ]
       },
       "locked": {
-        "lastModified": 1749398372,
-        "narHash": "sha256-tYBdgS56eXYaWVW3fsnPQ/nFlgWi/Z2Ymhyu21zVM98=",
-        "owner": "hercules-ci",
-        "repo": "flake-parts",
-        "rev": "9305fe4e5c2a6fcf5ba6a3ff155720fbe4076569",
+        "lastModified": 1744379919,
+        "narHash": "sha256-ieaQegt7LdMDFweeHhRaUQFYyF0U3pWD/XiCvq5L5U8=",
+        "owner": "pdtpartners",
+        "repo": "globset",
+        "rev": "4e21c96ab1259b8cd864272f96a8891b589c8eda",
         "type": "github"
       },
       "original": {
-        "owner": "hercules-ci",
-        "repo": "flake-parts",
+        "owner": "pdtpartners",
+        "repo": "globset",
         "type": "github"
       }
     },
-    "flake-utils": {
-      "inputs": {
-        "systems": "systems"
-      },
+    "nixos-unified": {
       "locked": {
-        "lastModified": 1694529238,
-        "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=",
-        "owner": "numtide",
-        "repo": "flake-utils",
-        "rev": "ff7b65b44d01cf9ba6a71320833626af21126384",
+        "lastModified": 1751174231,
+        "narHash": "sha256-OLPo3ZI/gKH0C6P6l2W9RYm1ow/Jl4qBrasQ3rjAA0E=",
+        "owner": "srid",
+        "repo": "nixos-unified",
+        "rev": "05eb3d59d3b48460ea01c419702d4fc0c3210805",
         "type": "github"
       },
       "original": {
-        "owner": "numtide",
-        "repo": "flake-utils",
+        "owner": "srid",
+        "repo": "nixos-unified",
         "type": "github"
       }
     },
     "nixpkgs": {
       "locked": {
-        "lastModified": 1705099185,
-        "narHash": "sha256-SxJenKtvcrKJd0TyJQMO3p6VA7PEp+vmMnmlKFzWMNs=",
-        "owner": "nixos",
+        "lastModified": 1751271578,
+        "narHash": "sha256-P/SQmKDu06x8yv7i0s8bvnnuJYkxVGBWLWHaU+tt4YY=",
+        "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "2bce5ccff0ad7abda23e8bb56434b6877a446694",
+        "rev": "3016b4b15d13f3089db8a41ef937b13a9e33a8df",
         "type": "github"
       },
       "original": {
-        "owner": "nixos",
-        "ref": "release-23.11",
+        "owner": "NixOS",
+        "ref": "nixos-unstable",
         "repo": "nixpkgs",
         "type": "github"
       }
     },
     "nixpkgs-lib": {
       "locked": {
-        "lastModified": 1748740939,
-        "narHash": "sha256-rQaysilft1aVMwF14xIdGS3sj1yHlI6oKQNBRTF40cc=",
+        "lastModified": 1751159883,
+        "narHash": "sha256-urW/Ylk9FIfvXfliA1ywh75yszAbiTEVgpPeinFyVZo=",
         "owner": "nix-community",
         "repo": "nixpkgs.lib",
-        "rev": "656a64127e9d791a334452c6b6606d17539476e2",
+        "rev": "14a40a1d7fb9afa4739275ac642ed7301a9ba1ab",
         "type": "github"
       },
       "original": {
@@ -107,36 +118,20 @@
     },
     "nixpkgs_2": {
       "locked": {
-        "lastModified": 1749285348,
-        "narHash": "sha256-frdhQvPbmDYaScPFiCnfdh3B/Vh81Uuoo0w5TkWmmjU=",
-        "owner": "NixOS",
+        "lastModified": 1751271578,
+        "narHash": "sha256-P/SQmKDu06x8yv7i0s8bvnnuJYkxVGBWLWHaU+tt4YY=",
+        "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "3e3afe5174c561dee0df6f2c2b2236990146329f",
+        "rev": "3016b4b15d13f3089db8a41ef937b13a9e33a8df",
         "type": "github"
       },
       "original": {
-        "owner": "NixOS",
+        "owner": "nixos",
         "ref": "nixos-unstable",
         "repo": "nixpkgs",
         "type": "github"
       }
     },
-    "nixpkgs_3": {
-      "locked": {
-        "lastModified": 1744536153,
-        "narHash": "sha256-awS2zRgF4uTwrOKwwiJcByDzDOdo3Q1rPZbiHQg/N38=",
-        "owner": "NixOS",
-        "repo": "nixpkgs",
-        "rev": "18dd725c29603f582cf1900e0d25f9f1063dbf11",
-        "type": "github"
-      },
-      "original": {
-        "owner": "NixOS",
-        "ref": "nixpkgs-unstable",
-        "repo": "nixpkgs",
-        "type": "github"
-      }
-    },
     "process-compose-flake": {
       "locked": {
         "lastModified": 1749418557,
@@ -154,49 +149,49 @@
     },
     "root": {
       "inputs": {
-        "cargo2nix": "cargo2nix",
         "flake-parts": "flake-parts",
-        "nixpkgs": "nixpkgs_2",
+        "git-hooks": "git-hooks",
+        "nixos-unified": "nixos-unified",
+        "nixpkgs": "nixpkgs",
         "process-compose-flake": "process-compose-flake",
-        "rust-overlay": "rust-overlay_2",
+        "rust-flake": "rust-flake",
         "services-flake": "services-flake"
       }
     },
-    "rust-overlay": {
+    "rust-flake": {
       "inputs": {
-        "flake-utils": [
-          "cargo2nix",
-          "flake-utils"
-        ],
-        "nixpkgs": [
-          "cargo2nix",
-          "nixpkgs"
-        ]
+        "crane": "crane",
+        "globset": "globset",
+        "nixpkgs": "nixpkgs_2",
+        "rust-overlay": "rust-overlay"
       },
       "locked": {
-        "lastModified": 1705112162,
-        "narHash": "sha256-IAM0+Uijh/fwlfoeDrOwau9MxcZW3zeDoUHc6Z3xfqM=",
-        "owner": "oxalica",
-        "repo": "rust-overlay",
-        "rev": "9e0af26ffe52bf955ad5575888f093e41fba0104",
+        "lastModified": 1751562414,
+        "narHash": "sha256-0ohW9/OWtkRHFteFdbhWJPGNHD00UWHjVA/qOTeuNfM=",
+        "owner": "juspay",
+        "repo": "rust-flake",
+        "rev": "a1c9995285b1288b3249a6ee1ac19443535bbb94",
         "type": "github"
       },
       "original": {
-        "owner": "oxalica",
-        "repo": "rust-overlay",
+        "owner": "juspay",
+        "repo": "rust-flake",
         "type": "github"
       }
     },
-    "rust-overlay_2": {
+    "rust-overlay": {
       "inputs": {
-        "nixpkgs": "nixpkgs_3"
+        "nixpkgs": [
+          "rust-flake",
+          "nixpkgs"
+        ]
       },
       "locked": {
-        "lastModified": 1749695868,
-        "narHash": "sha256-debjTLOyqqsYOUuUGQsAHskFXH5+Kx2t3dOo/FCoNRA=",
+        "lastModified": 1751510438,
+        "narHash": "sha256-m8PjOoyyCR4nhqtHEBP1tB/jF+gJYYguSZmUmVTEAQE=",
         "owner": "oxalica",
         "repo": "rust-overlay",
-        "rev": "55f914d5228b5c8120e9e0f9698ed5b7214d09cd",
+        "rev": "7f415261f298656f8164bd636c0dc05af4e95b6b",
         "type": "github"
       },
       "original": {
@@ -207,11 +202,11 @@
     },
     "services-flake": {
       "locked": {
-        "lastModified": 1749343305,
-        "narHash": "sha256-K4bK5OOJJlSWbJB7TbVzZQzJ694Qm7iGxOr0BpbqRpc=",
+        "lastModified": 1751536468,
+        "narHash": "sha256-lgzxvPlpx2uxkMznGBB0ID0byZBlMvcSadotcfnKIbM=",
         "owner": "juspay",
         "repo": "services-flake",
-        "rev": "62ef1d7436e7f07667a9b979c95ac2f706fdf3bb",
+        "rev": "a4c8b34362dc86a2d417aff1d0b87fbfef17a3c7",
         "type": "github"
       },
       "original": {
@@ -219,21 +214,6 @@
         "repo": "services-flake",
         "type": "github"
       }
-    },
-    "systems": {
-      "locked": {
-        "lastModified": 1681028828,
-        "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
-        "owner": "nix-systems",
-        "repo": "default",
-        "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
-        "type": "github"
-      },
-      "original": {
-        "owner": "nix-systems",
-        "repo": "default",
-        "type": "github"
-      }
     }
   },
   "root": "root",
diff --git a/flake.nix b/flake.nix
index 05058a75d9e..a9b99a93d19 100644
--- a/flake.nix
+++ b/flake.nix
@@ -5,110 +5,18 @@
     nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
     flake-parts.url = "github:hercules-ci/flake-parts";
 
-    # TODO: Move away from these to https://github.com/juspay/rust-flake
-    cargo2nix.url = "github:cargo2nix/cargo2nix/release-0.11.0";
-    rust-overlay.url = "github:oxalica/rust-overlay";
+    rust-flake.url = "github:juspay/rust-flake";
+
+    nixos-unified.url = "github:srid/nixos-unified";
+
+    git-hooks.url = "github:cachix/git-hooks.nix";
+    git-hooks.flake = false;
 
     process-compose-flake.url = "github:Platonic-Systems/process-compose-flake";
     services-flake.url = "github:juspay/services-flake";
   };
 
   outputs = inputs:
-    inputs.flake-parts.lib.mkFlake { inherit inputs; } {
-      imports = [ inputs.process-compose-flake.flakeModule ];
-      systems = inputs.nixpkgs.lib.systems.flakeExposed;
-      perSystem = { self', pkgs, lib, system, ... }:
-        let
-          cargoToml = lib.importTOML ./Cargo.toml;
-          rustDevVersion = "1.87.0";
-          rustMsrv = cargoToml.workspace.package.rust-version;
-
-          # Common packages
-          base = with pkgs; [
-            diesel-cli
-            just
-            jq
-            openssl
-            pkg-config
-            postgresql # for libpq
-            protobuf
-          ];
-
-          # Minimal packages for running hyperswitch
-          runPackages = base ++ (with pkgs; [
-            rust-bin.stable.${rustMsrv}.default
-          ]);
-
-          # Development packages
-          devPackages = base ++ (with pkgs; [
-            cargo-watch
-            nixd
-            protobuf
-            rust-bin.stable.${rustDevVersion}.default
-            swagger-cli
-          ]);
-
-          # QA packages
-          qaPackages = devPackages ++ (with pkgs; [
-            cypress
-            nodejs
-            parallel
-          ]);
-
-        in
-        {
-          _module.args.pkgs = import inputs.nixpkgs {
-            inherit system;
-            overlays = [ inputs.cargo2nix.overlays.default (import inputs.rust-overlay) ];
-          };
-
-          # Minimal shell
-          devShells.default = pkgs.mkShell {
-            name = "hyperswitch-shell";
-            packages = base;
-          };
-
-          # Development shell
-          devShells.dev = pkgs.mkShell {
-            name = "hyperswitch-dev-shell";
-            packages = devPackages;
-          };
-
-          # QA development shell
-          devShells.qa = pkgs.mkShell {
-            name = "hyperswitch-qa-shell";
-            packages = qaPackages;
-          };
-
-          /* For running external services
-              - Redis
-              - Postgres
-          */
-          process-compose."ext-services" =
-            let 
-              developmentToml = lib.importTOML ./config/development.toml;
-              databaseName = developmentToml.master_database.dbname;
-              databaseUser = developmentToml.master_database.username;
-              databasePass = developmentToml.master_database.password;
-            in
-            {
-              imports = [ inputs.services-flake.processComposeModules.default ];
-              services.redis."r1".enable = true;
-              /* Postgres
-                  - Create an user and grant all privileges
-                  - Create a database
-              */
-              services.postgres."p1" = {
-                enable = true;
-                initialScript = {
-                  before = "CREATE USER ${databaseUser} WITH PASSWORD '${databasePass}' SUPERUSER CREATEDB CREATEROLE INHERIT LOGIN;";
-                  after = "GRANT ALL PRIVILEGES ON DATABASE ${databaseName} to ${databaseUser};";
-                };
-                initialDatabases = [
-                  { name = databaseName; }
-                ];
-              };
-            };
-        };
-    };
+    inputs.nixos-unified.lib.mkFlake
+      { inherit inputs; root = ./.; };
 }
diff --git a/nix/modules/flake/devshell.nix b/nix/modules/flake/devshell.nix
new file mode 100644
index 00000000000..6df0f5951f1
--- /dev/null
+++ b/nix/modules/flake/devshell.nix
@@ -0,0 +1,52 @@
+{
+  debug = true;
+  perSystem = { config, pkgs, self', ... }:
+    let
+      rustMsrv = config.rust-project.cargoToml.workspace.package.rust-version;
+      rustDevVersion = config.rust-project.toolchain.version;
+    in
+    {
+      devShells = {
+        default =
+          pkgs.mkShell {
+            name = "hyperswitch-shell";
+            meta.description = "Environment for Hyperswitch development";
+            inputsFrom = [ config.pre-commit.devShell ];
+            packages = with pkgs; [
+              diesel-cli
+              just
+              jq
+              openssl
+              pkg-config
+              postgresql # for libpq
+              protobuf
+            ];
+          };
+        dev = pkgs.mkShell {
+          name = "hyperswitch-dev-shell";
+          meta.description = "Environment for Hyperswitch development with additional tools";
+          inputsFrom = [ self'.devShells.default ];
+          packages = with pkgs; [
+            cargo-watch
+            nixd
+            rust-bin.stable.${rustDevVersion}.default
+            swagger-cli
+          ];
+          shellHook = ''
+            echo 1>&2 "Ready to work on hyperswitch!"
+            rustc --version
+          '';
+        };
+        qa = pkgs.mkShell {
+          name = "hyperswitch-qa-shell";
+          meta.description = "Environment for Hyperswitch QA";
+          inputsFrom = [ self'.devShells.dev ];
+          packages = with pkgs; [
+            cypress
+            nodejs
+            parallel
+          ];
+        };
+      };
+    };
+}
diff --git a/nix/modules/flake/git-hooks.nix b/nix/modules/flake/git-hooks.nix
new file mode 100644
index 00000000000..0f658711219
--- /dev/null
+++ b/nix/modules/flake/git-hooks.nix
@@ -0,0 +1,11 @@
+{ inputs, ... }:
+{
+  imports = [
+    (inputs.git-hooks + /flake-module.nix)
+  ];
+  perSystem = { ... }: {
+    pre-commit.settings.hooks = {
+      nixpkgs-fmt.enable = true;
+    };
+  };
+}
diff --git a/nix/modules/flake/rust.nix b/nix/modules/flake/rust.nix
new file mode 100644
index 00000000000..2d71ade0332
--- /dev/null
+++ b/nix/modules/flake/rust.nix
@@ -0,0 +1,12 @@
+{ inputs, ... }:
+{
+  imports = [
+    inputs.rust-flake.flakeModules.default
+    inputs.rust-flake.flakeModules.nixpkgs
+  ];
+  perSystem = { pkgs, ... }: {
+    rust-project.toolchain = pkgs.rust-bin.fromRustupToolchain {
+      channel = "1.88.0";
+    };
+  };
+}
diff --git a/nix/modules/flake/services.nix b/nix/modules/flake/services.nix
new file mode 100644
index 00000000000..39154183af8
--- /dev/null
+++ b/nix/modules/flake/services.nix
@@ -0,0 +1,38 @@
+{ inputs, lib, ... }:
+{
+  imports = [
+    inputs.process-compose-flake.flakeModule
+  ];
+  perSystem = { ... }: {
+    /* For running external services
+        - Redis
+        - Postgres
+    */
+    process-compose."ext-services" =
+      let
+        developmentToml = lib.importTOML (inputs.self + /config/development.toml);
+        databaseName = developmentToml.master_database.dbname;
+        databaseUser = developmentToml.master_database.username;
+        databasePass = developmentToml.master_database.password;
+      in
+      {
+        imports = [ inputs.services-flake.processComposeModules.default ];
+        services.redis."r1".enable = true;
+
+        /* Postgres
+            - Create an user and grant all privileges
+            - Create a database
+        */
+        services.postgres."p1" = {
+          enable = true;
+          initialScript = {
+            before = "CREATE USER ${databaseUser} WITH PASSWORD '${databasePass}' SUPERUSER CREATEDB CREATEROLE INHERIT LOGIN;";
+            after = "GRANT ALL PRIVILEGES ON DATABASE ${databaseName} to ${databaseUser};";
+          };
+          initialDatabases = [
+            { name = databaseName; }
+          ];
+        };
+      };
+  };
+}

# Migrate Nix Configuration to rust-flake

This PR refactors the existing Nix setup by migrating from `cargo2nix` to `rust-flake`.
Resolves: #8538 

## TODO:

- [x] **Initial port** - Port current `flake.nix` functionality using rust-flake
  - [x] @kashif-m The current [`flake.nix`](https://github.com/juspay/hyperswitch/blob/d305fad2e6c403fde11b9eea785fddefbf3477df/flake.nix#L63-L78) has `default`, `dev`, and `qa` shells. Are all three required? Typically we use `default` for development and additional shells for specific purposes. Currently the PR has `default` as development shell and `qa` for QA work.
  https://github.com/juspay/hyperswitch/blob/d305fad2e6c403fde11b9eea785fddefbf3477df/flake.nix#L63-L78

- [x] **Configuration review** - @kashif-m This ports the existing flake.nix structure, but we should discuss additional features needed and fix any broken functionality
  - [x] The [`flake.nix`](https://github.com/juspay/hyperswitch/blob/d305fad2e6c403fde11b9eea785fddefbf3477df/flake.nix#L23-L24) defines two rust versions: `rustDevVersion` and `rustMsrv`. The `rustMsrv` is [defined but unused](https://github.com/juspay/hyperswitch/blob/d305fad2e6c403fde11b9eea785fddefbf3477df/flake.nix#L37-L39). Is `rustDevVersion` supposed to be different from the version in `Cargo.toml`?
  https://github.com/juspay/hyperswitch/blob/d305fad2e6c403fde11b9eea785fddefbf3477df/flake.nix#L23-L24
  - [ ] ~~Nixify Docker images using [`nix2container`](https://github.com/nlewo/nix2container)~~ (To be addressed in different PR)
  - [ ] ~~Additional nix integration items (to be discussed)~~ (To be addressed in different PR)

- [x] **Testing** - Ensure nothing breaks and everything works as expected

- [x] **Approval** - Get approval from @srid and @kashif-m

## Benefits

- Reproducible builds across environments
- Consistent development setup
- Simplified dependency management