edit in src/mount.rs at line 5
+ /// A mounted directory.
edit in src/mount.rs at line 11
+ /// Mount the existing mounted root private to the current namespace,
+ /// i.e. stop propagating mount events with the parent namespace.
edit in src/mount.rs at line 31
+ /// Create a bind mount, i.e. a directory into another one.
edit in src/mount.rs at line 57
+ /// Create ramfs mounted onto `target`.
edit in src/main.rs at line 1
replacement in src/main.rs at line 4
[2.1524]→[2.1524:1556](∅→∅) − use std::path::{Path, PathBuf};
+ use serde_derive::*;
+ use std::path::PathBuf;
replacement in src/main.rs at line 32
[2.2075]→[2.2075:2127](∅→∅) − let ref store = self.deb_client.store_path;
+ let ref store = self.deb_client.store_path();
edit in src/main.rs at line 180
+ }
+
+ #[derive(Deserialize)]
+ pub struct Config {
+ pgp_home: PathBuf,
+ store_path: PathBuf,
+ package_index: String,
+ user: String,
edit in src/main.rs at line 190
+ /// Elpe
+ #[derive(Parser, Debug)]
+ #[command(version, about, long_about = None)]
+ struct Args {
+ /// Path to the configuration file
+ #[arg(short, long)]
+ config: PathBuf,
+ }
+
replacement in src/main.rs at line 208
[3.8288]→[2.6695:6806](∅→∅) − let store_path = Path::new("/home/pe/Projets/frix/store");
− let user = "pe";
− let home = "/home/pe";
+ let args = Args::parse();
replacement in src/main.rs at line 210
[2.6807]→[2.6807:6878](∅→∅) − let container_channel = crate::container::serve(user, store_path);
+ let config: Config = toml::from_str(&std::fs::read_to_string(&args.config).unwrap()).unwrap();
+
+ let container_channel = crate::container::serve(&config.user, &config.store_path);
replacement in src/main.rs at line 216
[2.6962]→[2.6962:7101](∅→∅) − privdrop::PrivDrop::default().user(user).apply().unwrap();
− unsafe {
− std::env::set_var("HOME", home);
− }
+ privdrop::PrivDrop::default()
+ .user(&config.user)
+ .apply()
+ .unwrap();
+
replacement in src/main.rs at line 229
[2.7414]→[2.7414:7502](∅→∅) − deb_client: Client::new(store_path, "http://fr.archive.ubuntu.com/ubuntu"),
+ deb_client: Client::new(&config.pgp_home, &config.store_path, &config.package_index),
edit in src/main.rs at line 233
[3.9064]→[2.7534:7695](∅→∅),
[2.7695]→[3.9131:9174](∅→∅),
[3.9131]→[3.9131:9174](∅→∅),
[3.9174]→[2.7696:7738](∅→∅),
[2.7738]→[3.9218:9219](∅→∅),
[3.9218]→[3.9218:9219](∅→∅) − /*
− let x = elpe
− .deb_client
− .command("noble", "qemu-utils", "usr/bin/qemu-nbd")
− .await
− .output()
− .await
− .unwrap();
−
− panic!("x = {:?}", x);
− */
−
replacement in src/lib.rs at line 66
[2.9251]→[2.9251:9271](∅→∅) replacement in src/lib.rs at line 81
[2.9742]→[2.9742:9763](∅→∅) replacement in src/lib.rs at line 91
[2.10076]→[2.10076:10096](∅→∅) edit in src/lib.rs at line 99
replacement in src/lib.rs at line 134
[3.11601]→[2.10904:10909](∅→∅) + /// Root file of a package index, containing the signed hashes of the package list.
replacement in src/lib.rs at line 160
[3.12128]→[2.10954:11035](∅→∅) − pub fn new<P: AsRef<std::path::Path>>(store_path: P, mirror: &str) -> Self {
+ /// Create a client.
+ pub fn new<P: AsRef<std::path::Path>, Q: AsRef<std::path::Path>>(
+ pgp_home: P,
+ store_path: Q,
+ mirror: &str,
+ ) -> Self {
edit in src/lib.rs at line 174
+ pgp_home: pgp_home.as_ref().to_path_buf(),
edit in src/lib.rs at line 176
+ }
+
+ /// Retrieve the store path this client was created with.
+ pub fn store_path(&self) -> &std::path::Path {
+ &self.store_path
replacement in src/lib.rs at line 184
[3.12172]→[2.11461:11637](∅→∅) − self.c.get_or_create(|| reqwest::ClientBuilder::new()
− .read_timeout(self.timeout)
− .build().unwrap()
− )
+ self.c.get_or_create(|| {
+ reqwest::ClientBuilder::new()
+ .read_timeout(self.timeout)
+ .build()
+ .unwrap()
+ })
edit in src/lib.rs at line 192
+ /// Like `tokio::process::Command::new`, but where `cmd` is taken
+ /// from inside the supplied package. This decompresses the
+ /// package.
edit in src/lib.rs at line 207
[2.12053]→[2.12053:12054](∅→∅) edit in src/lib.rs at line 227
+ /// This locks a store path in order to avoid races to write to
+ /// the same store path.
+ ///
+ /// For performance and portability reasons, this is implemented
+ /// using in-memory Mutexes rather than using filesystem
+ /// locks. This process is the only one allowed to write to the
+ /// store anyway.
edit in src/lib.rs at line 253
+ /// Download a list of packages.
edit in src/lib.rs at line 260
[3.12388]→[3.12388:12467](∅→∅) − let ref m = self.mirror;
− let ref release = in_release.release;
edit in src/lib.rs at line 276
+ let ref m = self.mirror;
+ let ref release = in_release.release;
edit in src/lib.rs at line 340
+ /// Download the "InRelease" file of the index, and verify the signatures.
edit in src/lib.rs at line 372
+ // Sequoia wants to extract the verification code from
+ // their binary and make it available as a lib, but
+ // haven't done so as of June 2025.
edit in src/lib.rs at line 376
+ .env("HOME", &self.pgp_home)
edit in src/lib.rs at line 409
+ /// Read an already downloaded InRelease file, without re-checking
+ /// the signatures.
replacement in src/lib.rs at line 481
[2.14890]→[2.14890:14996](∅→∅) − let r = self
− .client()
− .get(url)
− .send()
− .await?;
+ let r = self.client().get(url).send().await?;
edit in src/find_files.rs at line 4
+ /// Recursively list all files inside a directory.
edit in src/find_files.rs at line 13
+ /// An iterator recursively listing all files inside a directory.
edit in src/find_files.rs at line 41
+ /// Recursively list all directories inside a directory.
edit in src/find_files.rs at line 50
+ /// An iterator recursively listing all directories inside a directory.
replacement in src/extract.rs at line 16
[2.17433]→[2.17433:17479](∅→∅) − /// the root (i.e. the root is the last).
+ /// the root (i.e. the root is the last element).
edit in src/extract.rs at line 23
+ /// Download a Debian package and its dependency DAG from package
+ /// indices and the package's name.
replacement in src/extract.rs at line 70
[2.18563]→[2.18563:18665](∅→∅) − debug!("adding transitive dep: {:?} -> {:?}", last.package.package, dep);
+ debug!(
+ "adding transitive dep: {:?} -> {:?}",
+ last.package.package, dep
+ );
replacement in src/extract.rs at line 87
[3.21720]→[2.18953:19023](∅→∅) − elt.spawn_extract(client.clone())
− .await;
+ elt.spawn_extract(client.clone()).await;
replacement in src/extract.rs at line 113
[3.23635]→[2.19730:19756](∅→∅) − pub async fn hash_reader(
replacement in src/extract.rs at line 470
[2.26109]→[2.26109:26203](∅→∅) − debug!("adding transitive dep: {:?} -> {:?}", last.package.package, dep);
+ debug!(
+ "adding transitive dep: {:?} -> {:?}",
+ last.package.package, dep
+ );
replacement in src/extract.rs at line 487
[3.36233]→[2.26460:26539](∅→∅) − async fn spawn_extract(
− &mut self,
− client: Client,
− ) {
+ async fn spawn_extract(&mut self, client: Client) {
edit in src/deb.rs at line 24
edit in src/deb.rs at line 26
edit in src/deb.rs at line 28
edit in src/deb.rs at line 30
edit in src/deb.rs at line 32
edit in src/deb.rs at line 34
edit in src/deb.rs at line 36
+ /// Path of the .deb file inside an index.
edit in src/deb.rs at line 44
+ /// A simple dependency.
replacement in src/deb.rs at line 46
[3.38801]→[3.38801:38847](∅→∅) − Alternatives { alt: Vec<SimpleDep<'a>> },
+ /// A dependency that can be supplied by multiple packages. This
+ /// is an alternative mechanism to virtual packages.
+ Alternatives {
+ #[allow(missing_docs)]
+ alt: Vec<SimpleDep<'a>>,
+ },
edit in src/deb.rs at line 57
+ /// Name of the dependency.
edit in src/deb.rs at line 59
+ /// Whether this dependency can have any version.
edit in src/deb.rs at line 61
+ /// Constraints on dependencies.
edit in src/deb.rs at line 63
[3.39018]→[2.35159:35471](∅→∅) − }
− /*
− impl<'a> From<Dep<'a>> for OwnedDep {
− fn from(e: Dep<'a>) -> Self {
− match e {
− Dep::Simple(s) => OwnedDep::Simple(s.to_owned()),
− Dep::Alternatives { alt } => OwnedDep::Alternatives {
− alt: alt.iter().map(From::from).collect()
− },
− }
− }
edit in src/deb.rs at line 65
[2.35474]→[2.35474:35852](∅→∅),
[2.35852]→[3.39018:39021](∅→∅),
[3.39018]→[3.39018:39021](∅→∅),
[3.39021]→[2.35853:36145](∅→∅) − /// A dependency, which is either a "simple" dependency, or a list of
− /// alternatives.
− #[derive(Debug, Clone)]
− pub enum OwnedDep {
− Simple(OwnedSimpleDep),
− Alternatives { alt: Vec<OwnedSimpleDep> },
− }
−
− /// A single dependency.
− #[derive(Debug, Clone)]
− pub struct OwnedSimpleDep {
− pub name: String,
− pub any: bool,
− pub constraints: Vec<(String, OwnedVersion)>,
− }
−
− impl<'a> From<SimpleDep<'a>> for OwnedSimpleDep {
− fn from(e: SimpleDep<'a>) -> Self {
− OwnedSimpleDep {
− name: e.name.to_string(),
− any: e.any,
− constraints: e.constraints.iter().map(|(a, b)| (a.into(), b.into())).collect(),
− }
− }
− }
− */
−
replacement in src/deb.rs at line 115
[2.36590]→[2.36590:36611](∅→∅) + .try_init()
+ .unwrap();
replacement in src/deb.rs at line 122
[2.39017]→[2.39017:39036](∅→∅) edit in src/deb.rs at line 129
[3.40466]→[3.40466:40644](∅→∅) − ///
− /// Debian versions have mechanisms to override upstream ones, such as
− /// the "epoch" prefix to reorder versions if necessary, and the
− /// "debian" suffix to add specifics.
edit in src/deb.rs at line 131
+ /// Epoch, i.e. a Debian mechanism to reorder upstream versions if
+ /// necessary, for example if the upstream versioning scheme
+ /// changes.
edit in src/deb.rs at line 135
edit in src/deb.rs at line 137
+ /// Debian-specific suffix to distinguish between patches.
edit in src/deb.rs at line 141
[3.40789]→[2.39079:39225](∅→∅) − #[derive(Debug, Clone)]
− pub struct OwnedVersion {
− pub epoch: u32,
− pub upstream_version: OwnedUpstream,
− pub debian: Option<String>,
− }
−
replacement in src/deb.rs at line 278
[3.44464]→[3.44464:44488](∅→∅) − #[derive(Debug, Clone)]
+ #[derive(Debug, Clone, PartialEq, Eq)]
edit in src/deb.rs at line 280
+
+ impl<'a> std::ops::Deref for Upstream<'a> {
+ type Target = str;
+ fn deref(&self) -> &str {
+ self.0
+ }
+ }
replacement in src/deb.rs at line 288
[3.44523]→[2.39570:39628](∅→∅) − #[derive(Debug, Clone)]
− pub struct OwnedUpstream(String);
+ impl<'a> PartialOrd for Upstream<'a> {
+ /// Following the algorithm described here:
+ /// https://www.debian.org/doc/debian-policy/ch-controlfields.html#version
+ fn partial_cmp(&self, b: &Upstream<'a>) -> Option<std::cmp::Ordering> {
+ fn split_initial(s: &str) -> (&str, &str, &str) {
+ // Find `u`, the first digit, and `v > u`, the first non-digit after `u`.
+ let mut u = s.len();
+ let mut v = s.len();
+ for (n, &b) in s.as_bytes().iter().enumerate() {
+ if u == s.len() {
+ if b >= b'0' && b <= b'9' {
+ u = n
+ }
+ } else if b < b'0' || b > b'9' {
+ v = n;
+ break;
+ }
+ }
+ let (ab, c) = s.split_at(v);
+ let (a, b) = ab.split_at(u);
+ (a, b, c)
+ }
+ let mut a = self.0;
+ let mut b = b.0;
+ use std::cmp::Ordering;
+ loop {
+ let (a0, a1, a_) = split_initial(a);
+ let (b0, b1, b_) = split_initial(b);
+ // Compare a0 / b0 using the modified ASCII ordering described in the Debian manual.
+ let mut a0i = a0.as_bytes().iter();
+ let mut b0i = b0.as_bytes().iter();
+ loop {
+ match (a0i.next(), b0i.next()) {
+ (None, None) => break,
+ (Some(c), Some(d)) if c == d => continue,
+ (Some(b'~'), _) => return Some(Ordering::Less),
+ (_, Some(b'~')) => return Some(Ordering::Greater),
+ (Some(c), Some(d)) if c.is_ascii_alphabetic() && !d.is_ascii_alphabetic() => {
+ return Some(Ordering::Less);
+ }
+ (Some(c), Some(d)) if d.is_ascii_alphabetic() && !c.is_ascii_alphabetic() => {
+ return Some(Ordering::Greater);
+ }
+ (c, d) => return Some(c.cmp(&d)),
+ }
+ }
+ // If we haven't returned, a0 == b0. Compare the digits part.
+ let a1 = if a1.is_empty() {
+ 0
+ } else {
+ a1.parse::<u64>().unwrap()
+ };
+ let b1 = if b1.is_empty() {
+ 0
+ } else {
+ b1.parse::<u64>().unwrap()
+ };
+ let cmp1 = a1.cmp(&b1);
+ if let Ordering::Equal = cmp1 {
+ a = a_;
+ b = b_;
+ } else {
+ return Some(cmp1);
+ }
+ }
+ }
+ }
edit in src/deb.rs at line 356
+ impl<'a> Ord for Upstream<'a> {
+ fn cmp(&self, b: &Upstream<'a>) -> std::cmp::Ordering {
+ self.partial_cmp(b).unwrap()
+ }
+ }
+
+ #[test]
+ fn test_upstream_ordering() {
+ let mut x = [
+ Upstream("~~"),
+ Upstream("~~a"),
+ Upstream("~"),
+ Upstream(""),
+ Upstream("a"),
+ ];
+ let y = x.clone();
+ x.sort();
+ assert_eq!(x, y,);
+ }
+
edit in src/deb.rs at line 446
edit in src/deb.rs at line 457
edit in src/deb.rs at line 512
+ /// Parse the control part, containing the description (stanza) of this package.
edit in src/deb.rs at line 521
+ /// Return the md5sums of each file.
edit in src/deb.rs at line 526
+ /// Decompress the data part of the deb file into a directory.
edit in src/deb.rs at line 568
+ /// Parse a `.deb` file from a buffered reader.
edit in src/deb/index.rs at line 6
+ struct Index_ {
+ map: memmap::Mmap,
+ lru: Mutex<lru::LruCache<String, Option<(usize, usize)>>>,
+ }
+
edit in src/deb/index.rs at line 16
[3.52192]→[2.41793:41809](∅→∅),
[2.41809]→[3.52211:52234](∅→∅),
[3.52211]→[3.52211:52234](∅→∅),
[3.52234]→[2.41810:41873](∅→∅),
[2.41873]→[3.52302:52305](∅→∅),
[3.52302]→[3.52302:52305](∅→∅) − struct Index_ {
− map: memmap::Mmap,
− lru: Mutex<lru::LruCache<String, Option<(usize, usize)>>>,
− }
−
edit in src/deb/index.rs at line 20
+ /// Open an index file.
edit in src/deb/index.rs at line 30
+ /// Looks a package up by name. This async version uses
+ /// `spawn_blocking` since the process uses mmap and hence does
+ /// blocking IO.
+ ///
+ /// This implementation assumes the packages are in
+ /// lexicographical order of their name and uses a binary search.
edit in src/deb/index.rs at line 49
+ /// Look virtual packages up by name. This runs a simple regular
+ /// expression on the entire index, and hence may be costly both
+ /// in complexity and in IO.
edit in src/deb/index.rs at line 74
+ /// Blocking package lookup by name.
edit in src/deb/index.rs at line 83
+ /// Given a range of bytes `a` (inclusive) to `b` (exclusive)
+ /// inside the file, as well as a middle point, find the stanza
+ /// containing byte number `m1` in the file.
+ ///
+ /// This assums a..b is large enough to contain the entire stanza
+ /// around m1.
edit in src/deb/index.rs at line 106
+ /// Do the actual binay search.
edit in src/deb/index.rs at line 125
[3.53277]→[3.53277:53549](∅→∅),
[3.53904]→[3.53904:53905](∅→∅) − debug!(
− "a = {:?}",
− std::str::from_utf8(&s[a..s.len().min(a + 30)]).unwrap()
− );
− debug!(
− "b = {:?}",
− std::str::from_utf8(&s[b..s.len().min(b + 30)]).unwrap()
− );
−
edit in src/deb/index.rs at line 130
[3.54060]→[3.54060:54112](∅→∅) − debug!("not found: {:?}", package);
edit in src/deb/index.rs at line 133
[3.54228]→[3.54228:54267](∅→∅) − debug!("line {:?}", line);
edit in src/deb/index.rs at line 134
[3.54322]→[3.54322:54375](∅→∅) − debug!("package: {:?}", st.package);
edit in src/deb/index.rs at line 135
[3.54418]→[3.54418:54469](∅→∅) − debug!("found {:?}", package);
edit in src/deb/index.rs at line 142
[3.54642]→[3.54642:54681](∅→∅) edit in src/deb/index.rs at line 144
[3.54733]→[3.54733:54772](∅→∅) edit in src/deb/index.rs at line 150
[3.54920]→[3.54920:55236](∅→∅) − debug!(
− "break a = {:?}",
− std::str::from_utf8(&s[a..s.len().min(a + 30)]).unwrap()
− );
− debug!(
− "break b = {:?}",
− std::str::from_utf8(&s[b..s.len().min(b + 30)]).unwrap()
− );
edit in src/container.rs at line 13
+ /// Name of the package, to be appended to the hash to form a store path.
edit in src/container.rs at line 15
+ /// Store paths to mount into the build environment.
edit in src/container.rs at line 17
+ /// Build script to run inside the build environment.
edit in src/container.rs at line 19
replacement in src/container.rs at line 212
[2.52093]→[2.52093:52204](∅→∅) − inner_process(
− user, &r, &tmp_dir, &dest, &store, &tmp_store, &name,
− )
+ inner_process(user, &r, &tmp_dir, &dest, &store, &tmp_store, &name)
edit in default.nix at line 2
[3.64959]→[3.64959:65801](∅→∅) −
− let luau = stdenv.mkDerivation rec {
− pname = "luau";
− version = "0.621";
−
− src = fetchFromGitHub {
− owner = "luau-lang";
− repo = "luau";
− rev = version;
− hash = "sha256-bkuYYGYcnMwQDK81ZH+74hA4XaQfVFMWvAKpy+ODCak=";
− };
−
− nativeBuildInputs = [ cmake pkg-config ];
−
− buildInputs = lib.optionals stdenv.cc.isClang [ llvmPackages.libunwind ];
−
− installPhase = ''
− runHook preInstall
−
− install -Dm755 -t $out/bin luau
− install -Dm755 -t $out/bin luau-analyze
− install -Dm755 -t $out/bin luau-compile
− install -Dm755 -t $out/lib lib*
− runHook postInstall
− '';
−
− # doCheck = true;
−
− # checkPhase = ''
− # runHook preCheck
−
− # ./Luau.UnitTest
− # ./Luau.Conformance
−
− # runHook postCheck
− # '';
−
− # passthru.updateScript = gitUpdater { };
replacement in default.nix at line 3
[3.65802]→[3.65802:66725](∅→∅) − meta = with lib; {
− description = "Fast, small, safe, gradually typed embeddable scripting language derived from Lua";
− homepage = "https://luau-lang.org/";
− changelog = "https://github.com/luau-lang/luau/releases/tag/${version}";
− license = licenses.mit;
− platforms = platforms.all;
− maintainers = [ ];
− mainProgram = "luau";
− };
− };
−
− # grpc-async = ocamlPackages.buildDunePackage rec {
− # pname = "gprc-async";
− # version = "0.2.0";
− # src = builtins.fetchurl {
− # url = "https://github.com/emilpriver/jsoo-code-mirror/archive/refs/tags/v0.0.1.tar.gz";
− # sha256 = "sha256:0rby6kd9973icp72fj8i07awibamwsi3afy71dhrbq771dgz16cq";
− # };
− # propagatedBuildInputs = with pkgs; [
− # ocamlPackages.brr
− # ocamlPackages.js_of_ocaml
− # ];
− # };
−
− gluten-async = ocamlPackages.buildDunePackage rec {
+ let gluten-async = ocamlPackages.buildDunePackage rec {
edit in default.nix at line 69
[2.77169]→[2.77169:77405](∅→∅) −
− # grpc-src = pkgs.fetchFromGitHub {
− # owner = "dialohq";
− # repo = "ocaml-grpc";
− # rev = "b71fba7067bad2cad62df9abd8b4e190e3c4fc94";
− # sha256 = "sha256-NtNU0ANMLRFFLoGtHMB0ynHbyh8YTfRF+PttJi9pYHU=";
− # };
edit in default.nix at line 154
[3.70205]→[3.70205:70216](∅→∅) replacement in default.nix at line 168
[3.70431]→[2.78673:78684](∅→∅) edit in Cargo.toml at line 49
+ toml = "0.8.23"
+ clap = { version = "4.5.39", features = ["derive"] }
replacement in Cargo.lock at line 317
[2.81327]→[2.81327:81346](∅→∅) replacement in Cargo.lock at line 319
[2.81411]→[2.81411:81489](∅→∅) − checksum = "ed93b9805f8ba930df42c2590f05453d5ec36cbb85d018868a5b24d31f6ac000"
+ checksum = "fd60e63e9be68e5fb56422e397cf9baddded06dae1d2e523401542383bc72a9f"
edit in Cargo.lock at line 322
replacement in Cargo.lock at line 327
[2.81560]→[2.81560:81579](∅→∅) replacement in Cargo.lock at line 329
[2.81644]→[2.81644:81722](∅→∅) − checksum = "379026ff283facf611b0ea629334361c4211d1b12ee01024eec1591133b04120"
+ checksum = "89cc6392a1f72bbeb820d71f32108f61fdaf18bc526e1d23954168a67759ef51"
edit in Cargo.lock at line 338
+ name = "clap_derive"
+ version = "4.5.32"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+ checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7"
+ dependencies = [
+ "heck",
+ "proc-macro2",
+ "quote",
+ "syn",
+ ]
+
+ [[package]]
edit in Cargo.lock at line 461
edit in Cargo.lock at line 486
edit in Cargo.lock at line 1737
+ "serde",
+ ]
+
+ [[package]]
+ name = "serde_spanned"
+ version = "0.6.9"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+ checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3"
+ dependencies = [
edit in Cargo.lock at line 2059
+ ]
+
+ [[package]]
+ name = "toml"
+ version = "0.8.23"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+ checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362"
+ dependencies = [
+ "serde",
+ "serde_spanned",
+ "toml_datetime",
+ "toml_edit",
edit in Cargo.lock at line 2074
+ name = "toml_datetime"
+ version = "0.6.11"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+ checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c"
+ dependencies = [
+ "serde",
+ ]
+
+ [[package]]
+ name = "toml_edit"
+ version = "0.22.27"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+ checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a"
+ dependencies = [
+ "indexmap",
+ "serde",
+ "serde_spanned",
+ "toml_datetime",
+ "toml_write",
+ "winnow",
+ ]
+
+ [[package]]
+ name = "toml_write"
+ version = "0.1.2"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+ checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801"
+
+ [[package]]
edit in Cargo.lock at line 2571
+
+ [[package]]
+ name = "winnow"
+ version = "0.7.10"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+ checksum = "c06928c8748d81b05c9be96aad92e1b6ff01833332f281e8cfca3be4b35fc9ec"
+ dependencies = [
+ "memchr",
+ ]