This only runs cargo metadata for now, but already in a better way than Nix
LQBZJUGCEIU56WBYBLE757W2DHPZWJ4JNG3ILB52RDXMXUYAPZCQC open Derivationopen Lwt.Syntaxlet fetch_crate source checksum crate version =let registry_dl =if source = "registry+https://github.com/rust-lang/crates.io-index" then"https://crates.io/api/v1/crates"else failwith "Not implemented"inhttp~url:(registry_dl ^ "/" ^ crate ^ "/" ^ version ^ "/download")~hash_algorithm:Elpegrpc.Elpe.Hash.Sha256~hash:(Hex.to_bytes (`Hex checksum))let str_from_toml_table k toml =match Toml.Types.Table.find (Toml.Types.Table.Key.of_string k) toml with| Toml.Types.TString s -> s| _ -> raise Not_foundlet unzip pkg =object (self)inherit std_derivationmethod name = "rust"method! unpack_phase = Lwt.return ""method! build_inputs =Lwt.return[(ubuntu "libc6-dev" :> derivation);(ubuntu "coreutils" :> derivation);(ubuntu "tar" :> derivation);(ubuntu "gzip" :> derivation);]method! build_phase =let* zipped = self#derivation pkg inLwt.return("mkdir -p $DESTDIR; tar -xf " ^ List.hd zipped.destdir ^ " -C $DESTDIR")endlet rust ?(version = "1.84") src =object (self)inherit std_derivationmethod name = "rust"method! src = Lwt.return srcmethod! build_inputs = Lwt.return [ (ubuntu "coreutils" :> derivation) ]method packages toml =let packages =matchToml.Types.Table.find (Toml.Types.Table.Key.of_string "package") tomlwith| Toml.Types.TArray (Toml.Types.NodeTable arr) -> arr| _ -> failwith "Unexpected type"inlet* packages =Lwt.all(List.map(fun pkg ->trylet source = str_from_toml_table "source" pkg inlet checksum = str_from_toml_table "checksum" pkg inlet name = str_from_toml_table "name" pkg inlet version = str_from_toml_table "version" pkg inlet h = fetch_crate source checksum name version inlet* drv = self#derivation (unzip h :> derivation) inLwt.return (Some (name, version, h, drv))with Not_found -> Lwt.return None)packages)inlet h = Hashtbl.create 16 inLwt.return(List.fold_left(fun acc x ->match x with| Some (crate_name, version, _, drv) ->let target =if Hashtbl.find_opt h crate_name = None thenlet _ = Hashtbl.add h crate_name () incrate_name ^ "-" ^ versionelse crate_nameinacc ^ "ln -s " ^ List.hd drv.destdir ^ "/" ^ crate_name ^ "-"^ version ^ " vendor/" ^ target ^ "\n"| None -> acc)"" packages)method! build_phase =let* src = self#src inlet* src_built = src#build inlet lock =Stdlib.open_in(Filename.concat (List.hd src_built.destdir) "Cargo.lock")inlet parsed =match Toml.Parser.from_channel lock with| `Ok toml -> toml| `Error (err, _) -> failwith ("Error: " ^ err)inlet* packages = self#packages parsed inlet metadata =object (self)inherit std_derivationmethod name = "test"method! src = Lwt.return srcmethod! build_phase =let* rustc = self#derivation (ubuntu ("rustc-" ^ version)) inlet rustc = List.hd rustc.destdir inlet* cargo = self#derivation (ubuntu ("cargo-" ^ version)) inlet cargo = List.hd cargo.destdir inlet setup ="export HOME=/home/me\nmkdir -p $HOME\nexport PATH=" ^ rustc^ "/usr/lib/rust-" ^ version ^ "/bin:" ^ cargo ^ "/usr/lib/rust-"^ version ^ "/bin:$PATH\nmkdir -p vendor .cargo\n" ^ packages^ "\n\cat <<EOF >> .cargo/config.toml\n\[source.crates-io]\n\replace-with = \"vendored-sources\"\n\n\[source.vendored-sources]\n\directory = \"vendor\"\n\EOF\n\cargo metadata --offline --format-version 1"inLwt.return setupmethod! build_inputs =Lwt.return [ (ubuntu "coreutils" :> derivation) ]endinlet buf = metadata#set_stdout inlet* _ = metadata#build inlet meta_json = Yojson.Basic.from_string (Buffer.contents buf) inlet open Yojson.Basic.Util inlet members =meta_json |> member "workspace_members" |> to_list |> filter_stringinlet _ = List.map (fun x -> print_endline x) members inLwt.return ""end