diff --git a/Cargo.lock b/Cargo.lock index b27fd66..5353dd4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,6 +11,21 @@ dependencies = [ "memchr", ] +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "anes" version = "0.1.6" @@ -23,18 +38,18 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" +[[package]] +name = "anyhow" +version = "1.0.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" + [[package]] name = "autocfg" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" -[[package]] -name = "bitflags" -version = "2.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" - [[package]] name = "bumpalo" version = "3.19.0" @@ -49,9 +64,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.2.30" +version = "1.2.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "deec109607ca693028562ed836a5f1c4b8bd77755c4e132fc5ce11b0b6211ae7" +checksum = "42bc4aea80032b7bf409b0bc7ccad88853858911b7713a8062fdc0623867bedc" dependencies = [ "jobserver", "libc", @@ -60,9 +75,23 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.1" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" +checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" + +[[package]] +name = "chrono" +version = "0.4.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-link", +] [[package]] name = "ciborium" @@ -93,18 +122,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.42" +version = "4.5.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed87a9d530bb41a67537289bafcac159cb3ee28460e0a4571123d2a778a6a882" +checksum = "2c5e4fcf9c21d2e544ca1ee9d8552de13019a42aa7dbf32747fa7aaf1df76e57" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.42" +version = "4.5.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64f4f3f3c77c94aff3c7e9aac9a2ca1974a5adf392a8bb751e827d6d127ab966" +checksum = "fecb53a0e6fcfb055f686001bc2e2592fa527efaf38dbe81a6a9563562e57d41" dependencies = [ "anstyle", "clap_lex", @@ -116,6 +145,12 @@ version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + [[package]] name = "criterion" version = "0.7.0" @@ -188,6 +223,7 @@ dependencies = [ "libc", "serde", "serde_json", + "stdext", "toml-span", "windows-sys", "winresource", @@ -222,6 +258,36 @@ dependencies = [ "crunchy", ] +[[package]] +name = "iana-time-zone" +version = "0.1.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "indoc" +version = "2.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd" + [[package]] name = "itertools" version = "0.13.0" @@ -239,9 +305,9 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "jobserver" -version = "0.1.33" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" dependencies = [ "getrandom", "libc", @@ -259,9 +325,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.174" +version = "0.2.175" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" +checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" [[package]] name = "log" @@ -296,6 +362,12 @@ version = "11.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" +[[package]] +name = "pico-args" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" + [[package]] name = "pkg-config" version = "0.3.32" @@ -332,9 +404,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.95" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" dependencies = [ "unicode-ident", ] @@ -356,9 +428,9 @@ checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" [[package]] name = "rayon" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" dependencies = [ "either", "rayon-core", @@ -366,9 +438,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.12.1" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" dependencies = [ "crossbeam-deque", "crossbeam-utils", @@ -376,9 +448,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.11.1" +version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +checksum = "23d7fd106d8c02486a8d64e778353d1cffe08ce79ac2e82f540c86d0facf6912" dependencies = [ "aho-corasick", "memchr", @@ -388,9 +460,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +checksum = "6b9458fa0bfeeac22b5ca447c63aaf45f28439a709ccd244698632f9aa6394d6" dependencies = [ "aho-corasick", "memchr", @@ -399,15 +471,21 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001" + +[[package]] +name = "roxmltree" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97" [[package]] name = "rustversion" -version = "1.0.21" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "ryu" @@ -446,9 +524,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.141" +version = "1.0.143" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30b9eff21ebe718216c6ec64e1d9ac57087aad11efc64e32002bce4a0d4c03d3" +checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a" dependencies = [ "itoa", "memchr", @@ -468,11 +546,18 @@ version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +[[package]] +name = "stdext" +version = "0.0.0" +dependencies = [ + "libc", +] + [[package]] name = "syn" -version = "2.0.104" +version = "2.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" +checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" dependencies = [ "proc-macro2", "quote", @@ -498,6 +583,18 @@ dependencies = [ "smallvec", ] +[[package]] +name = "unicode-gen" +version = "0.0.0" +dependencies = [ + "anyhow", + "chrono", + "indoc", + "pico-args", + "rayon", + "roxmltree", +] + [[package]] name = "unicode-ident" version = "1.0.18" @@ -522,11 +619,11 @@ dependencies = [ [[package]] name = "wasi" -version = "0.14.2+wasi-0.2.4" +version = "0.14.3+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +checksum = "6a51ae83037bdd272a9e28ce236db8c07016dd0d50c27038b3f407533c030c95" dependencies = [ - "wit-bindgen-rt", + "wit-bindgen", ] [[package]] @@ -599,28 +696,88 @@ dependencies = [ [[package]] name = "winapi-util" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +checksum = "0978bf7171b3d90bac376700cb56d606feb40f251a475a5d6634613564460b22" dependencies = [ "windows-sys", ] [[package]] -name = "windows-sys" -version = "0.59.0" +name = "windows-core" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.59.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + +[[package]] +name = "windows-result" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" dependencies = [ "windows-targets", ] [[package]] name = "windows-targets" -version = "0.52.6" +version = "0.53.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" dependencies = [ + "windows-link", "windows_aarch64_gnullvm", "windows_aarch64_msvc", "windows_i686_gnu", @@ -633,51 +790,51 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.6" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" [[package]] name = "windows_aarch64_msvc" -version = "0.52.6" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" [[package]] name = "windows_i686_gnu" -version = "0.52.6" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" [[package]] name = "windows_i686_gnullvm" -version = "0.52.6" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" [[package]] name = "windows_i686_msvc" -version = "0.52.6" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" [[package]] name = "windows_x86_64_gnu" -version = "0.52.6" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.6" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" [[package]] name = "windows_x86_64_msvc" -version = "0.52.6" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" [[package]] name = "winresource" @@ -689,13 +846,10 @@ dependencies = [ ] [[package]] -name = "wit-bindgen-rt" -version = "0.39.0" +name = "wit-bindgen" +version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" -dependencies = [ - "bitflags", -] +checksum = "052283831dbae3d879dc7f51f3d92703a316ca49f91540417d38591826127814" [[package]] name = "zstd" diff --git a/Cargo.toml b/Cargo.toml index 792aa41..c7c29b4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,21 +1,13 @@ -[package] -name = "edit" -version = "1.2.1" +[workspace] +default-members = ["crates/edit"] +members = ["crates/*"] +resolver = "2" + +[workspace.package] edition = "2024" -rust-version = "1.87" -readme = "README.md" -repository = "https://github.com/microsoft/edit" -homepage = "https://github.com/microsoft/edit" license = "MIT" -categories = ["text-editors"] -build = "build/main.rs" - -[[bench]] -name = "lib" -harness = false - -[features] -debug-latency = [] +repository = "https://github.com/microsoft/edit" +rust-version = "1.88" # We use `opt-level = "s"` as it significantly reduces binary size. # We could then use the `#[optimize(speed)]` attribute for spot optimizations. @@ -34,35 +26,7 @@ incremental = true # Improves re-compile times codegen-units = 16 # Make compiling criterion faster (16 is the default, but profile.release sets it to 1) lto = "thin" # Similarly, speed up linking by a ton -[dependencies] - -[target.'cfg(unix)'.dependencies] -libc = "0.2" - -[build-dependencies] -# The default toml crate bundles its dependencies with bad compile times. Thanks. -# Thankfully toml-span exists. FWIW the alternative is yaml-rust (without the 2 suffix). -toml-span = { version = "0.5", default-features = false } - -[target.'cfg(windows)'.build-dependencies] -winresource = { version = "0.1.22", default-features = false } - -[target.'cfg(windows)'.dependencies.windows-sys] -version = "0.59" -features = [ - "Win32_Globalization", - "Win32_Security", - "Win32_Storage_FileSystem", - "Win32_System_Console", - "Win32_System_Diagnostics_Debug", - "Win32_System_IO", - "Win32_System_LibraryLoader", - "Win32_System_Memory", - "Win32_System_Threading", -] - -[dev-dependencies] -criterion = { version = "0.7", features = ["html_reports"] } -serde = { version = "1.0", features = ["derive"] } -serde_json = { version = "1.0" } -zstd = { version = "0.13", default-features = false } +[workspace.dependencies] +stdext = { path = "./crates/stdext" } +edit = { path = "./crates/edit" } +unicode-gen = { path = "./crates/unicode-gen" } diff --git a/crates/edit/Cargo.toml b/crates/edit/Cargo.toml new file mode 100644 index 0000000..a759aee --- /dev/null +++ b/crates/edit/Cargo.toml @@ -0,0 +1,47 @@ +[package] +name = "edit" +version = "1.2.1" + +edition.workspace = true +license.workspace = true +repository.workspace = true +rust-version.workspace = true + +build = "build/main.rs" +categories = ["text-editors"] + +[features] +debug-latency = [] + +[dependencies] +stdext.workspace = true + +[target.'cfg(unix)'.dependencies] +libc = "0.2" + +[build-dependencies] +# The default toml crate bundles its dependencies with bad compile times. Thanks. +# Thankfully toml-span exists. FWIW the alternative is yaml-rust (without the 2 suffix). +toml-span = { version = "0.5", default-features = false } + +[target.'cfg(windows)'.build-dependencies] +winresource = { version = "0.1.22", default-features = false } + +[target.'cfg(windows)'.dependencies.windows-sys] +version = "0.60" +features = [ + "Win32_Globalization", + "Win32_Security", + "Win32_Storage_FileSystem", + "Win32_System_Console", + "Win32_System_Diagnostics_Debug", + "Win32_System_IO", + "Win32_System_LibraryLoader", + "Win32_System_Threading", +] + +[dev-dependencies] +criterion = { version = "0.7", features = ["html_reports"] } +serde = { version = "1.0", features = ["derive"] } +serde_json = { version = "1.0" } +zstd = { version = "0.13", default-features = false } diff --git a/benches/lib.rs b/crates/edit/benches/lib.rs similarity index 98% rename from benches/lib.rs rename to crates/edit/benches/lib.rs index b06bd06..4c8fcc3 100644 --- a/benches/lib.rs +++ b/crates/edit/benches/lib.rs @@ -8,8 +8,9 @@ use std::{mem, vec}; use criterion::{BenchmarkId, Criterion, Throughput, criterion_group, criterion_main}; use edit::helpers::*; use edit::simd::MemsetSafe; -use edit::{arena, buffer, hash, oklab, simd, unicode}; +use edit::{buffer, hash, oklab, simd, unicode}; use serde::Deserialize; +use stdext::arena; #[derive(Deserialize)] pub struct EditingTracePatch(pub usize, pub usize, pub String); @@ -29,7 +30,7 @@ pub struct EditingTraceData { } fn bench_buffer(c: &mut Criterion) { - let data = include_bytes!("../assets/editing-traces/rustcode.json.zst"); + let data = include_bytes!("../../../assets/editing-traces/rustcode.json.zst"); let data = zstd::decode_all(Cursor::new(data)).unwrap(); let data: EditingTraceData = serde_json::from_slice(&data).unwrap(); let mut patches_with_coords = Vec::new(); diff --git a/build/helpers.rs b/crates/edit/build/helpers.rs similarity index 100% rename from build/helpers.rs rename to crates/edit/build/helpers.rs diff --git a/build/i18n.rs b/crates/edit/build/i18n.rs similarity index 100% rename from build/i18n.rs rename to crates/edit/build/i18n.rs diff --git a/build/main.rs b/crates/edit/build/main.rs similarity index 90% rename from build/main.rs rename to crates/edit/build/main.rs index fb1d8d1..9ebb178 100644 --- a/build/main.rs +++ b/crates/edit/build/main.rs @@ -29,16 +29,16 @@ fn main() { } fn compile_i18n() { - const PATH: &str = "i18n/edit.toml"; + let i18n_path = "../../i18n/edit.toml"; - let i18n = std::fs::read_to_string(PATH).unwrap(); + let i18n = std::fs::read_to_string(i18n_path).unwrap(); let contents = i18n::generate(&i18n); let out_dir = env_opt("OUT_DIR"); let path = format!("{out_dir}/i18n_edit.rs"); - std::fs::write(path, contents).unwrap(); + std::fs::write(&path, contents).unwrap(); println!("cargo::rerun-if-env-changed=EDIT_CFG_LANGUAGES"); - println!("cargo::rerun-if-changed={PATH}"); + println!("cargo::rerun-if-changed={i18n_path}"); } fn configure_icu(target_os: TargetOs) { @@ -111,13 +111,16 @@ fn configure_windows_binary(target_os: TargetOs) { return; } - const PATH: &str = "src/bin/edit/edit.exe.manifest"; - println!("cargo::rerun-if-changed={PATH}"); + let manifest_path = "src/bin/edit/edit.exe.manifest"; + let icon_path = "../../assets/edit.ico"; + winresource::WindowsResource::new() - .set_manifest_file(PATH) + .set_manifest_file(manifest_path) .set("FileDescription", "Microsoft Edit") .set("LegalCopyright", "© Microsoft Corporation. All rights reserved.") - .set_icon("assets/edit.ico") + .set_icon(icon_path) .compile() .unwrap(); + + println!("cargo::rerun-if-changed={manifest_path}"); } diff --git a/src/apperr.rs b/crates/edit/src/apperr.rs similarity index 72% rename from src/apperr.rs rename to crates/edit/src/apperr.rs index faa1aa4..8427f2f 100644 --- a/src/apperr.rs +++ b/crates/edit/src/apperr.rs @@ -3,6 +3,7 @@ //! Provides a transparent error type for edit. +use std::alloc::AllocError; use std::{io, result}; use crate::sys; @@ -40,3 +41,11 @@ impl From for Error { sys::io_error_to_apperr(err) } } + +impl From for Error { + fn from(_: AllocError) -> Self { + // TODO: Technically this breaks if the AllocError isn't recent. By then, the errno may + // have been tained. But the stdlib AllocError is a bad type with no way to carry info. + sys::get_last_error() + } +} diff --git a/src/base64.rs b/crates/edit/src/base64.rs similarity index 98% rename from src/base64.rs rename to crates/edit/src/base64.rs index bce13c6..944e2c8 100644 --- a/src/base64.rs +++ b/crates/edit/src/base64.rs @@ -3,7 +3,7 @@ //! Base64 facilities. -use crate::arena::ArenaString; +use stdext::arena::ArenaString; const CHARSET: [u8; 64] = *b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; @@ -79,8 +79,9 @@ pub fn encode(dst: &mut ArenaString, src: &[u8]) { #[cfg(test)] mod tests { + use stdext::arena::{Arena, ArenaString}; + use super::encode; - use crate::arena::{Arena, ArenaString}; #[test] fn test_basic() { diff --git a/src/bin/edit/documents.rs b/crates/edit/src/bin/edit/documents.rs similarity index 100% rename from src/bin/edit/documents.rs rename to crates/edit/src/bin/edit/documents.rs diff --git a/src/bin/edit/draw_editor.rs b/crates/edit/src/bin/edit/draw_editor.rs similarity index 100% rename from src/bin/edit/draw_editor.rs rename to crates/edit/src/bin/edit/draw_editor.rs diff --git a/src/bin/edit/draw_filepicker.rs b/crates/edit/src/bin/edit/draw_filepicker.rs similarity index 99% rename from src/bin/edit/draw_filepicker.rs rename to crates/edit/src/bin/edit/draw_filepicker.rs index 3fae635..94adb03 100644 --- a/src/bin/edit/draw_filepicker.rs +++ b/crates/edit/src/bin/edit/draw_filepicker.rs @@ -5,12 +5,12 @@ use std::cmp::Ordering; use std::fs; use std::path::{Path, PathBuf}; -use edit::arena::scratch_arena; use edit::framebuffer::IndexedColor; use edit::helpers::*; use edit::input::{kbmod, vk}; use edit::tui::*; use edit::{icu, path}; +use stdext::arena::scratch_arena; use crate::localization::*; use crate::state::*; diff --git a/src/bin/edit/draw_menubar.rs b/crates/edit/src/bin/edit/draw_menubar.rs similarity index 99% rename from src/bin/edit/draw_menubar.rs rename to crates/edit/src/bin/edit/draw_menubar.rs index 9fe8b7c..8f14f70 100644 --- a/src/bin/edit/draw_menubar.rs +++ b/crates/edit/src/bin/edit/draw_menubar.rs @@ -1,10 +1,10 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -use edit::arena_format; use edit::helpers::*; use edit::input::{kbmod, vk}; use edit::tui::*; +use stdext::arena_format; use crate::localization::*; use crate::state::*; diff --git a/src/bin/edit/draw_statusbar.rs b/crates/edit/src/bin/edit/draw_statusbar.rs similarity index 99% rename from src/bin/edit/draw_statusbar.rs rename to crates/edit/src/bin/edit/draw_statusbar.rs index f7a631a..8250e44 100644 --- a/src/bin/edit/draw_statusbar.rs +++ b/crates/edit/src/bin/edit/draw_statusbar.rs @@ -1,13 +1,14 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -use edit::arena::scratch_arena; use edit::framebuffer::{Attributes, IndexedColor}; use edit::fuzzy::score_fuzzy; use edit::helpers::*; +use edit::icu; use edit::input::vk; use edit::tui::*; -use edit::{arena_format, icu}; +use stdext::arena::scratch_arena; +use stdext::arena_format; use crate::localization::*; use crate::state::*; diff --git a/src/bin/edit/edit.exe.manifest b/crates/edit/src/bin/edit/edit.exe.manifest similarity index 100% rename from src/bin/edit/edit.exe.manifest rename to crates/edit/src/bin/edit/edit.exe.manifest diff --git a/src/bin/edit/localization.rs b/crates/edit/src/bin/edit/localization.rs similarity index 95% rename from src/bin/edit/localization.rs rename to crates/edit/src/bin/edit/localization.rs index aeecec7..2e3eed8 100644 --- a/src/bin/edit/localization.rs +++ b/crates/edit/src/bin/edit/localization.rs @@ -1,9 +1,9 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -use edit::arena::scratch_arena; use edit::helpers::AsciiStringHelpers; use edit::sys; +use stdext::arena::scratch_arena; include!(concat!(env!("OUT_DIR"), "/i18n_edit.rs")); diff --git a/src/bin/edit/main.rs b/crates/edit/src/bin/edit/main.rs similarity index 99% rename from src/bin/edit/main.rs rename to crates/edit/src/bin/edit/main.rs index 326c88a..b374e0a 100644 --- a/src/bin/edit/main.rs +++ b/crates/edit/src/bin/edit/main.rs @@ -22,16 +22,17 @@ use draw_editor::*; use draw_filepicker::*; use draw_menubar::*; use draw_statusbar::*; -use edit::arena::{self, Arena, ArenaString, scratch_arena}; use edit::framebuffer::{self, IndexedColor}; use edit::helpers::{CoordType, KIBI, MEBI, MetricFormatter, Rect, Size}; use edit::input::{self, kbmod, vk}; use edit::oklab::StraightRgba; use edit::tui::*; use edit::vt::{self, Token}; -use edit::{apperr, arena_format, base64, path, sys, unicode}; +use edit::{apperr, base64, path, sys, unicode}; use localization::*; use state::*; +use stdext::arena::{self, Arena, ArenaString, scratch_arena}; +use stdext::arena_format; #[cfg(target_pointer_width = "32")] const SCRATCH_ARENA_CAPACITY: usize = 128 * MEBI; diff --git a/src/bin/edit/state.rs b/crates/edit/src/bin/edit/state.rs similarity index 100% rename from src/bin/edit/state.rs rename to crates/edit/src/bin/edit/state.rs diff --git a/src/buffer/gap_buffer.rs b/crates/edit/src/buffer/gap_buffer.rs similarity index 97% rename from src/buffer/gap_buffer.rs rename to crates/edit/src/buffer/gap_buffer.rs index df1e38d..4f84d71 100644 --- a/src/buffer/gap_buffer.rs +++ b/crates/edit/src/buffer/gap_buffer.rs @@ -5,9 +5,11 @@ use std::ops::Range; use std::ptr::{self, NonNull}; use std::slice; +use stdext::sys::{virtual_commit, virtual_release, virtual_reserve}; + +use crate::apperr; use crate::document::{ReadableDocument, WriteableDocument}; use crate::helpers::*; -use crate::{apperr, sys}; #[cfg(target_pointer_width = "32")] const LARGE_CAPACITY: usize = 128 * MEBI; @@ -31,7 +33,7 @@ impl Drop for BackingBuffer { fn drop(&mut self) { unsafe { if let Self::VirtualMemory(ptr, reserve) = *self { - sys::virtual_release(ptr, reserve); + virtual_release(ptr, reserve); } } } @@ -73,7 +75,7 @@ impl GapBuffer { buffer = BackingBuffer::Vec(Vec::new()); } else { reserve = LARGE_CAPACITY; - text = unsafe { sys::virtual_reserve(reserve)? }; + text = unsafe { virtual_reserve(reserve)? }; buffer = BackingBuffer::VirtualMemory(text, reserve); } @@ -195,7 +197,7 @@ impl GapBuffer { match &mut self.buffer { BackingBuffer::VirtualMemory(ptr, _) => unsafe { - if sys::virtual_commit(ptr.add(bytes_old), bytes_new - bytes_old).is_err() { + if virtual_commit(ptr.add(bytes_old), bytes_new - bytes_old).is_err() { return; } }, diff --git a/src/buffer/line_cache.rs b/crates/edit/src/buffer/line_cache.rs similarity index 100% rename from src/buffer/line_cache.rs rename to crates/edit/src/buffer/line_cache.rs diff --git a/src/buffer/mod.rs b/crates/edit/src/buffer/mod.rs similarity index 99% rename from src/buffer/mod.rs rename to crates/edit/src/buffer/mod.rs index 6f0a714..9ea4485 100644 --- a/src/buffer/mod.rs +++ b/crates/edit/src/buffer/mod.rs @@ -35,8 +35,8 @@ use std::rc::Rc; use std::str; pub use gap_buffer::GapBuffer; +use stdext::arena::{Arena, ArenaString, scratch_arena}; -use crate::arena::{Arena, ArenaString, scratch_arena}; use crate::cell::SemiRefCell; use crate::clipboard::Clipboard; use crate::document::{ReadableDocument, WriteableDocument}; diff --git a/src/buffer/navigation.rs b/crates/edit/src/buffer/navigation.rs similarity index 100% rename from src/buffer/navigation.rs rename to crates/edit/src/buffer/navigation.rs diff --git a/src/cell.rs b/crates/edit/src/cell.rs similarity index 100% rename from src/cell.rs rename to crates/edit/src/cell.rs diff --git a/src/clipboard.rs b/crates/edit/src/clipboard.rs similarity index 100% rename from src/clipboard.rs rename to crates/edit/src/clipboard.rs diff --git a/src/document.rs b/crates/edit/src/document.rs similarity index 98% rename from src/document.rs rename to crates/edit/src/document.rs index 697bcea..c7def36 100644 --- a/src/document.rs +++ b/crates/edit/src/document.rs @@ -8,7 +8,8 @@ use std::mem; use std::ops::Range; use std::path::PathBuf; -use crate::arena::{ArenaString, scratch_arena}; +use stdext::arena::{ArenaString, scratch_arena}; + use crate::helpers::ReplaceRange as _; /// An abstraction over reading from text containers. diff --git a/src/framebuffer.rs b/crates/edit/src/framebuffer.rs similarity index 99% rename from src/framebuffer.rs rename to crates/edit/src/framebuffer.rs index b26a715..490f75e 100644 --- a/src/framebuffer.rs +++ b/crates/edit/src/framebuffer.rs @@ -9,7 +9,8 @@ use std::ops::{BitOr, BitXor}; use std::ptr; use std::slice::ChunksExact; -use crate::arena::{Arena, ArenaString}; +use stdext::arena::{Arena, ArenaString}; + use crate::helpers::{CoordType, Point, Rect, Size}; use crate::oklab::StraightRgba; use crate::simd::{MemsetSafe, memset}; diff --git a/src/fuzzy.rs b/crates/edit/src/fuzzy.rs similarity index 99% rename from src/fuzzy.rs rename to crates/edit/src/fuzzy.rs index b3dbf6f..2dc450f 100644 --- a/src/fuzzy.rs +++ b/crates/edit/src/fuzzy.rs @@ -7,7 +7,8 @@ use std::vec; -use crate::arena::{Arena, scratch_arena}; +use stdext::arena::{Arena, scratch_arena}; + use crate::icu; const NO_MATCH: i32 = 0; diff --git a/src/hash.rs b/crates/edit/src/hash.rs similarity index 100% rename from src/hash.rs rename to crates/edit/src/hash.rs diff --git a/src/helpers.rs b/crates/edit/src/helpers.rs similarity index 100% rename from src/helpers.rs rename to crates/edit/src/helpers.rs diff --git a/src/icu.rs b/crates/edit/src/icu.rs similarity index 99% rename from src/icu.rs rename to crates/edit/src/icu.rs index 9687794..1be7960 100644 --- a/src/icu.rs +++ b/crates/edit/src/icu.rs @@ -10,10 +10,12 @@ use std::mem::MaybeUninit; use std::ops::Range; use std::ptr::{null, null_mut}; -use crate::arena::{Arena, ArenaString, scratch_arena}; +use stdext::arena::{Arena, ArenaString, scratch_arena}; +use stdext::arena_format; + use crate::buffer::TextBuffer; use crate::unicode::Utf8Chars; -use crate::{apperr, arena_format, sys}; +use crate::{apperr, sys}; #[derive(Clone, Copy)] pub struct Encoding { diff --git a/src/input.rs b/crates/edit/src/input.rs similarity index 100% rename from src/input.rs rename to crates/edit/src/input.rs diff --git a/src/lib.rs b/crates/edit/src/lib.rs similarity index 96% rename from src/lib.rs rename to crates/edit/src/lib.rs index 4a150da..59e3df0 100644 --- a/src/lib.rs +++ b/crates/edit/src/lib.rs @@ -17,9 +17,6 @@ )] #![allow(clippy::missing_transmute_annotations, clippy::new_without_default, stable_features)] -#[macro_use] -pub mod arena; - pub mod apperr; pub mod base64; pub mod buffer; diff --git a/src/oklab.rs b/crates/edit/src/oklab.rs similarity index 100% rename from src/oklab.rs rename to crates/edit/src/oklab.rs diff --git a/src/path.rs b/crates/edit/src/path.rs similarity index 100% rename from src/path.rs rename to crates/edit/src/path.rs diff --git a/src/simd/lines_bwd.rs b/crates/edit/src/simd/lines_bwd.rs similarity index 100% rename from src/simd/lines_bwd.rs rename to crates/edit/src/simd/lines_bwd.rs diff --git a/src/simd/lines_fwd.rs b/crates/edit/src/simd/lines_fwd.rs similarity index 100% rename from src/simd/lines_fwd.rs rename to crates/edit/src/simd/lines_fwd.rs diff --git a/src/simd/memchr2.rs b/crates/edit/src/simd/memchr2.rs similarity index 98% rename from src/simd/memchr2.rs rename to crates/edit/src/simd/memchr2.rs index 3e1708d..0514da0 100644 --- a/src/simd/memchr2.rs +++ b/crates/edit/src/simd/memchr2.rs @@ -225,8 +225,9 @@ unsafe fn memchr2_neon(needle1: u8, needle2: u8, mut beg: *const u8, end: *const mod tests { use std::slice; + use stdext::sys::{virtual_commit, virtual_reserve}; + use super::*; - use crate::sys; #[test] fn test_empty() { @@ -265,8 +266,8 @@ mod tests { const PAGE_SIZE: usize = 64 * 1024; // 64 KiB to cover many architectures. // 3 pages: uncommitted, committed, uncommitted - let ptr = sys::virtual_reserve(PAGE_SIZE * 3).unwrap(); - sys::virtual_commit(ptr.add(PAGE_SIZE), PAGE_SIZE).unwrap(); + let ptr = virtual_reserve(PAGE_SIZE * 3).unwrap(); + virtual_commit(ptr.add(PAGE_SIZE), PAGE_SIZE).unwrap(); slice::from_raw_parts_mut(ptr.add(PAGE_SIZE).as_ptr(), PAGE_SIZE) }; diff --git a/src/simd/memset.rs b/crates/edit/src/simd/memset.rs similarity index 100% rename from src/simd/memset.rs rename to crates/edit/src/simd/memset.rs diff --git a/src/simd/mod.rs b/crates/edit/src/simd/mod.rs similarity index 100% rename from src/simd/mod.rs rename to crates/edit/src/simd/mod.rs diff --git a/src/sys/mod.rs b/crates/edit/src/sys/mod.rs similarity index 100% rename from src/sys/mod.rs rename to crates/edit/src/sys/mod.rs diff --git a/src/sys/unix.rs b/crates/edit/src/sys/unix.rs similarity index 88% rename from src/sys/unix.rs rename to crates/edit/src/sys/unix.rs index f3b067b..e207812 100644 --- a/src/sys/unix.rs +++ b/crates/edit/src/sys/unix.rs @@ -14,24 +14,11 @@ use std::path::Path; use std::ptr::{self, NonNull, null_mut}; use std::{thread, time}; -use crate::arena::{Arena, ArenaString, scratch_arena}; +use stdext::arena::{Arena, ArenaString, scratch_arena}; +use stdext::arena_format; + +use crate::apperr; use crate::helpers::*; -use crate::{apperr, arena_format}; - -#[cfg(target_os = "netbsd")] -const fn desired_mprotect(flags: c_int) -> c_int { - // NetBSD allows an mmap(2) caller to specify what protection flags they - // will use later via mprotect. It does not allow a caller to move from - // PROT_NONE to PROT_READ | PROT_WRITE. - // - // see PROT_MPROTECT in man 2 mmap - flags << 3 -} - -#[cfg(not(target_os = "netbsd"))] -const fn desired_mprotect(_: c_int) -> c_int { - libc::PROT_NONE -} struct State { stdin: libc::c_int, @@ -379,58 +366,6 @@ pub fn file_id(file: Option<&File>, path: &Path) -> apperr::Result { } } -/// Reserves a virtual memory region of the given size. -/// To commit the memory, use `virtual_commit`. -/// To release the memory, use `virtual_release`. -/// -/// # Safety -/// -/// This function is unsafe because it uses raw pointers. -/// Don't forget to release the memory when you're done with it or you'll leak it. -pub unsafe fn virtual_reserve(size: usize) -> apperr::Result> { - unsafe { - let ptr = libc::mmap( - null_mut(), - size, - desired_mprotect(libc::PROT_READ | libc::PROT_WRITE), - libc::MAP_PRIVATE | libc::MAP_ANONYMOUS, - -1, - 0, - ); - if ptr.is_null() || ptr::eq(ptr, libc::MAP_FAILED) { - Err(errno_to_apperr(libc::ENOMEM)) - } else { - Ok(NonNull::new_unchecked(ptr as *mut u8)) - } - } -} - -/// Releases a virtual memory region of the given size. -/// -/// # Safety -/// -/// This function is unsafe because it uses raw pointers. -/// Make sure to only pass pointers acquired from `virtual_reserve`. -pub unsafe fn virtual_release(base: NonNull, size: usize) { - unsafe { - libc::munmap(base.cast().as_ptr(), size); - } -} - -/// Commits a virtual memory region of the given size. -/// -/// # Safety -/// -/// This function is unsafe because it uses raw pointers. -/// Make sure to only pass pointers acquired from `virtual_reserve` -/// and to pass a size less than or equal to the size passed to `virtual_reserve`. -pub unsafe fn virtual_commit(base: NonNull, size: usize) -> apperr::Result<()> { - unsafe { - let status = libc::mprotect(base.cast().as_ptr(), size, libc::PROT_READ | libc::PROT_WRITE); - if status != 0 { Err(errno_to_apperr(libc::ENOMEM)) } else { Ok(()) } - } -} - unsafe fn load_library(name: *const c_char) -> apperr::Result> { unsafe { NonNull::new(libc::dlopen(name, libc::RTLD_LAZY)) @@ -612,6 +547,11 @@ fn errno() -> i32 { ManuallyDrop::new(std::io::Error::last_os_error()).raw_os_error().unwrap_or(0) } +#[cold] +pub fn get_last_error() -> apperr::Error { + errno_to_apperr(errno()) +} + #[inline] pub(crate) fn io_error_to_apperr(err: std::io::Error) -> apperr::Error { errno_to_apperr(err.raw_os_error().unwrap_or(0)) @@ -640,5 +580,5 @@ const fn errno_to_apperr(no: c_int) -> apperr::Error { } fn check_int_return(ret: libc::c_int) -> apperr::Result { - if ret < 0 { Err(errno_to_apperr(errno())) } else { Ok(ret) } + if ret < 0 { Err(get_last_error()) } else { Ok(ret) } } diff --git a/src/sys/windows.rs b/crates/edit/src/sys/windows.rs similarity index 90% rename from src/sys/windows.rs rename to crates/edit/src/sys/windows.rs index 6ec8f76..03e9ca7 100644 --- a/src/sys/windows.rs +++ b/crates/edit/src/sys/windows.rs @@ -10,15 +10,15 @@ use std::path::{Path, PathBuf}; use std::ptr::{self, NonNull, null, null_mut}; use std::{mem, time}; +use stdext::arena::{Arena, ArenaString, scratch_arena}; use windows_sys::Win32::Foundation::ERROR_INVALID_PARAMETER; use windows_sys::Win32::Storage::FileSystem; use windows_sys::Win32::System::Diagnostics::Debug; -use windows_sys::Win32::System::{Console, IO, LibraryLoader, Memory, Threading}; +use windows_sys::Win32::System::{Console, IO, LibraryLoader, Threading}; use windows_sys::Win32::{Foundation, Globalization}; -use windows_sys::w; +use windows_sys::core::*; use crate::apperr; -use crate::arena::{Arena, ArenaString, scratch_arena}; use crate::helpers::*; macro_rules! w_env { @@ -56,7 +56,7 @@ type ReadConsoleInputExW = unsafe extern "system" fn( n_length: u32, lp_number_of_events_read: *mut u32, w_flags: u16, -) -> Foundation::BOOL; +) -> BOOL; unsafe extern "system" fn read_console_input_ex_placeholder( _: Foundation::HANDLE, @@ -64,7 +64,7 @@ unsafe extern "system" fn read_console_input_ex_placeholder( _: u32, _: *mut u32, _: u16, -) -> Foundation::BOOL { +) -> BOOL { panic!(); } @@ -101,7 +101,7 @@ static mut STATE: State = State { wants_exit: false, }; -extern "system" fn console_ctrl_handler(_ctrl_type: u32) -> Foundation::BOOL { +extern "system" fn console_ctrl_handler(_ctrl_type: u32) -> BOOL { unsafe { STATE.wants_exit = true; IO::CancelIoEx(STATE.stdin, null()); @@ -516,70 +516,6 @@ pub fn canonicalize(path: &Path) -> std::io::Result { Ok(path) } -/// Reserves a virtual memory region of the given size. -/// To commit the memory, use [`virtual_commit`]. -/// To release the memory, use [`virtual_release`]. -/// -/// # Safety -/// -/// This function is unsafe because it uses raw pointers. -/// Don't forget to release the memory when you're done with it or you'll leak it. -pub unsafe fn virtual_reserve(size: usize) -> apperr::Result> { - unsafe { - #[allow(unused_assignments, unused_mut)] - let mut base = null_mut(); - - // In debug builds, we use fixed addresses to aid in debugging. - // Makes it possible to immediately tell which address space a pointer belongs to. - #[cfg(all(debug_assertions, not(target_pointer_width = "32")))] - { - static mut S_BASE_GEN: usize = 0x0000100000000000; // 16 TiB - S_BASE_GEN += 0x0000001000000000; // 64 GiB - base = S_BASE_GEN as *mut _; - } - - check_ptr_return(Memory::VirtualAlloc( - base, - size, - Memory::MEM_RESERVE, - Memory::PAGE_READWRITE, - ) as *mut u8) - } -} - -/// Releases a virtual memory region of the given size. -/// -/// # Safety -/// -/// This function is unsafe because it uses raw pointers. -/// Make sure to only pass pointers acquired from [`virtual_reserve`]. -pub unsafe fn virtual_release(base: NonNull, _size: usize) { - unsafe { - // NOTE: `VirtualFree` fails if the pointer isn't - // a valid base address or if the size isn't zero. - Memory::VirtualFree(base.as_ptr() as *mut _, 0, Memory::MEM_RELEASE); - } -} - -/// Commits a virtual memory region of the given size. -/// -/// # Safety -/// -/// This function is unsafe because it uses raw pointers. -/// Make sure to only pass pointers acquired from [`virtual_reserve`] -/// and to pass a size less than or equal to the size passed to [`virtual_reserve`]. -pub unsafe fn virtual_commit(base: NonNull, size: usize) -> apperr::Result<()> { - unsafe { - check_ptr_return(Memory::VirtualAlloc( - base.as_ptr() as *mut _, - size, - Memory::MEM_COMMIT, - Memory::PAGE_READWRITE, - )) - .map(|_| ()) - } -} - unsafe fn get_module(name: *const u16) -> apperr::Result> { unsafe { check_ptr_return(LibraryLoader::GetModuleHandleW(name)) } } @@ -719,7 +655,7 @@ fn wide_to_utf8<'a>(arena: &'a Arena, wide: &[u16]) -> ArenaString<'a> { } #[cold] -fn get_last_error() -> apperr::Error { +pub fn get_last_error() -> apperr::Error { unsafe { gle_to_apperr(Foundation::GetLastError()) } } @@ -773,7 +709,7 @@ pub fn apperr_is_not_found(err: apperr::Error) -> bool { err == gle_to_apperr(Foundation::ERROR_FILE_NOT_FOUND) } -fn check_bool_return(ret: Foundation::BOOL) -> apperr::Result<()> { +fn check_bool_return(ret: BOOL) -> apperr::Result<()> { if ret == 0 { Err(get_last_error()) } else { Ok(()) } } diff --git a/src/tui.rs b/crates/edit/src/tui.rs similarity index 99% rename from src/tui.rs rename to crates/edit/src/tui.rs index 78308f0..93f42da 100644 --- a/src/tui.rs +++ b/crates/edit/src/tui.rs @@ -92,7 +92,7 @@ //! use edit::helpers::Size; //! use edit::input::Input; //! use edit::tui::*; -//! use edit::{arena, arena_format}; +//! use stdext::{arena, arena_format}; //! //! struct State { //! counter: i32, @@ -149,7 +149,9 @@ use std::collections::HashSet; use std::fmt::Write as _; use std::{iter, mem, ptr, time}; -use crate::arena::{Arena, ArenaString, scratch_arena}; +use stdext::arena::{Arena, ArenaString, scratch_arena}; +use stdext::arena_format; + use crate::buffer::{CursorMovement, MoveLineDirection, RcTextBuffer, TextBuffer, TextBufferCell}; use crate::cell::*; use crate::clipboard::Clipboard; @@ -159,7 +161,7 @@ use crate::hash::*; use crate::helpers::*; use crate::input::{InputKeyMod, kbmod, vk}; use crate::oklab::StraightRgba; -use crate::{apperr, arena_format, input, simd, unicode}; +use crate::{apperr, input, simd, unicode}; const ROOT_ID: u64 = 0x14057B7EF767814F; // Knuth's MMIX constant const SHIFT_TAB: InputKey = vk::TAB.with_modifiers(kbmod::SHIFT); diff --git a/src/unicode/measurement.rs b/crates/edit/src/unicode/measurement.rs similarity index 100% rename from src/unicode/measurement.rs rename to crates/edit/src/unicode/measurement.rs diff --git a/src/unicode/mod.rs b/crates/edit/src/unicode/mod.rs similarity index 100% rename from src/unicode/mod.rs rename to crates/edit/src/unicode/mod.rs diff --git a/src/unicode/tables.rs b/crates/edit/src/unicode/tables.rs similarity index 100% rename from src/unicode/tables.rs rename to crates/edit/src/unicode/tables.rs diff --git a/src/unicode/utf8.rs b/crates/edit/src/unicode/utf8.rs similarity index 100% rename from src/unicode/utf8.rs rename to crates/edit/src/unicode/utf8.rs diff --git a/src/vt.rs b/crates/edit/src/vt.rs similarity index 100% rename from src/vt.rs rename to crates/edit/src/vt.rs diff --git a/crates/stdext/Cargo.toml b/crates/stdext/Cargo.toml new file mode 100644 index 0000000..6291567 --- /dev/null +++ b/crates/stdext/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "stdext" +version = "0.0.0" + +edition.workspace = true +license.workspace = true +repository.workspace = true +rust-version.workspace = true + +[target.'cfg(unix)'.dependencies] +libc = "0.2" diff --git a/src/arena/debug.rs b/crates/stdext/src/arena/debug.rs similarity index 95% rename from src/arena/debug.rs rename to crates/stdext/src/arena/debug.rs index 48083ba..3c9144b 100644 --- a/src/arena/debug.rs +++ b/crates/stdext/src/arena/debug.rs @@ -4,11 +4,10 @@ #![allow(clippy::missing_safety_doc, clippy::mut_from_ref)] use std::alloc::{AllocError, Allocator, Layout}; -use std::mem::{self, MaybeUninit}; +use std::mem::MaybeUninit; use std::ptr::NonNull; use super::release; -use crate::apperr; /// A debug wrapper for [`release::Arena`]. /// @@ -19,7 +18,7 @@ use crate::apperr; /// It is completely valid for the same [`release::Arena`] to be borrowed multiple times at once, /// *as long as* you only use the most recent borrow. Bad example: /// ```should_panic -/// use edit::arena::scratch_arena; +/// use stdext::arena::scratch_arena; /// /// let mut scratch1 = scratch_arena(None); /// let mut scratch2 = scratch_arena(None); @@ -63,14 +62,14 @@ impl Arena { Self::Owned { arena: release::Arena::empty() } } - pub fn new(capacity: usize) -> apperr::Result { + pub fn new(capacity: usize) -> Result { Ok(Self::Owned { arena: release::Arena::new(capacity)? }) } pub(super) fn delegated(delegate: &release::Arena) -> Self { let borrow = delegate.borrows.get() + 1; delegate.borrows.set(borrow); - Self::Delegated { delegate: unsafe { mem::transmute(delegate) }, borrow } + Self::Delegated { delegate: unsafe { &*(delegate as *const _) }, borrow } } #[inline] diff --git a/src/arena/mod.rs b/crates/stdext/src/arena/mod.rs similarity index 100% rename from src/arena/mod.rs rename to crates/stdext/src/arena/mod.rs diff --git a/src/arena/release.rs b/crates/stdext/src/arena/release.rs similarity index 98% rename from src/arena/release.rs rename to crates/stdext/src/arena/release.rs index 7e4ebcf..c1441c2 100644 --- a/src/arena/release.rs +++ b/crates/stdext/src/arena/release.rs @@ -5,15 +5,13 @@ use std::alloc::{AllocError, Allocator, Layout}; use std::cell::Cell; -use std::hint::cold_path; use std::mem::MaybeUninit; use std::ptr::{self, NonNull}; use std::{mem, slice}; -use crate::helpers::*; -use crate::{apperr, sys}; +use crate::{cold_path, sys}; -const ALLOC_CHUNK_SIZE: usize = 64 * KIBI; +const ALLOC_CHUNK_SIZE: usize = 64 * 1024; /// An arena allocator. /// @@ -64,7 +62,7 @@ impl Arena { } } - pub fn new(capacity: usize) -> apperr::Result { + pub fn new(capacity: usize) -> Result { let capacity = (capacity.max(1) + ALLOC_CHUNK_SIZE - 1) & !(ALLOC_CHUNK_SIZE - 1); let base = unsafe { sys::virtual_reserve(capacity)? }; diff --git a/src/arena/scratch.rs b/crates/stdext/src/arena/scratch.rs similarity index 97% rename from src/arena/scratch.rs rename to crates/stdext/src/arena/scratch.rs index d280509..7c519df 100644 --- a/src/arena/scratch.rs +++ b/crates/stdext/src/arena/scratch.rs @@ -1,12 +1,12 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +use std::alloc::AllocError; use std::ops::Deref; #[cfg(debug_assertions)] use super::debug; use super::{Arena, release}; -use crate::apperr; use crate::helpers::*; /// Borrows an [`Arena`] for temporary allocations. @@ -74,7 +74,7 @@ mod single_threaded { /// Initialize the scratch arenas with a given capacity. /// Call this before using [`scratch_arena`]. #[allow(dead_code)] - pub fn init(capacity: usize) -> apperr::Result<()> { + pub fn init(capacity: usize) -> Result<(), AllocError> { unsafe { for s in &mut S_SCRATCH[..] { *s = release::Arena::new(capacity)?; @@ -130,7 +130,7 @@ mod multi_threaded { /// Does nothing. #[allow(dead_code)] - pub fn init(_: usize) -> apperr::Result<()> { + pub fn init(_: usize) -> Result<(), AllocError> { Ok(()) } diff --git a/src/arena/string.rs b/crates/stdext/src/arena/string.rs similarity index 99% rename from src/arena/string.rs rename to crates/stdext/src/arena/string.rs index e2ac650..ed46b89 100644 --- a/src/arena/string.rs +++ b/crates/stdext/src/arena/string.rs @@ -279,7 +279,7 @@ impl fmt::Write for ArenaString<'_> { macro_rules! arena_format { ($arena:expr, $($arg:tt)*) => {{ use std::fmt::Write as _; - let mut output = $crate::arena::ArenaString::new_in($arena); + let mut output = stdext::arena::ArenaString::new_in($arena); output.write_fmt(format_args!($($arg)*)).unwrap(); output }} diff --git a/crates/stdext/src/helpers.rs b/crates/stdext/src/helpers.rs new file mode 100644 index 0000000..556206a --- /dev/null +++ b/crates/stdext/src/helpers.rs @@ -0,0 +1,171 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +//! Random assortment of helpers I didn't know where to put. + +use std::alloc::Allocator; +use std::mem::{self, MaybeUninit}; +use std::ops::{Bound, Range, RangeBounds}; +use std::{fmt, ptr, slice, str}; + +pub const KILO: usize = 1000; +pub const MEGA: usize = 1000 * 1000; +pub const GIGA: usize = 1000 * 1000 * 1000; + +pub const KIBI: usize = 1024; +pub const MEBI: usize = 1024 * 1024; +pub const GIBI: usize = 1024 * 1024 * 1024; + +pub struct MetricFormatter(pub T); + +impl fmt::Display for MetricFormatter { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut value = self.0; + let mut suffix = "B"; + if value >= GIGA { + value /= GIGA; + suffix = "GB"; + } else if value >= MEGA { + value /= MEGA; + suffix = "MB"; + } else if value >= KILO { + value /= KILO; + suffix = "kB"; + } + write!(f, "{value}{suffix}") + } +} + +#[inline(always)] +#[cold] +pub const fn cold_path() {} + +/// [`std::cmp::minmax`] is unstable, as per usual. +pub fn minmax(v1: T, v2: T) -> [T; 2] +where + T: Ord, +{ + if v2 < v1 { [v2, v1] } else { [v1, v2] } +} + +#[inline(always)] +#[allow(clippy::ptr_eq)] +pub fn opt_ptr(a: Option<&T>) -> *const T { + unsafe { mem::transmute(a) } +} + +/// Surprisingly, there's no way in Rust to do a `ptr::eq` on `Option<&T>`. +/// Uses `unsafe` so that the debug performance isn't too bad. +#[inline(always)] +#[allow(clippy::ptr_eq)] +pub fn opt_ptr_eq(a: Option<&T>, b: Option<&T>) -> bool { + opt_ptr(a) == opt_ptr(b) +} + +/// Creates a `&str` from a pointer and a length. +/// Exists, because `std::str::from_raw_parts` is unstable, par for the course. +/// +/// # Safety +/// +/// The given data must be valid UTF-8. +/// The given data must outlive the returned reference. +#[inline] +#[must_use] +pub const unsafe fn str_from_raw_parts<'a>(ptr: *const u8, len: usize) -> &'a str { + unsafe { str::from_utf8_unchecked(slice::from_raw_parts(ptr, len)) } +} + +/// [`<[T]>::copy_from_slice`] panics if the two slices have different lengths. +/// This one just returns the copied amount. +pub fn slice_copy_safe(dst: &mut [T], src: &[T]) -> usize { + let len = src.len().min(dst.len()); + unsafe { ptr::copy_nonoverlapping(src.as_ptr(), dst.as_mut_ptr(), len) }; + len +} + +/// [`Vec::splice`] results in really bad assembly. +/// This doesn't. Don't use [`Vec::splice`]. +pub trait ReplaceRange { + fn replace_range>(&mut self, range: R, src: &[T]); +} + +impl ReplaceRange for Vec { + fn replace_range>(&mut self, range: R, src: &[T]) { + let start = match range.start_bound() { + Bound::Included(&start) => start, + Bound::Excluded(start) => start + 1, + Bound::Unbounded => 0, + }; + let end = match range.end_bound() { + Bound::Included(end) => end + 1, + Bound::Excluded(&end) => end, + Bound::Unbounded => usize::MAX, + }; + vec_replace_impl(self, start..end, src); + } +} + +fn vec_replace_impl(dst: &mut Vec, range: Range, src: &[T]) { + unsafe { + let dst_len = dst.len(); + let src_len = src.len(); + let off = range.start.min(dst_len); + let del_len = range.end.saturating_sub(off).min(dst_len - off); + + if del_len == 0 && src_len == 0 { + return; // nothing to do + } + + let tail_len = dst_len - off - del_len; + let new_len = dst_len - del_len + src_len; + + if src_len > del_len { + dst.reserve(src_len - del_len); + } + + // NOTE: drop_in_place() is not needed here, because T is constrained to Copy. + + // SAFETY: as_mut_ptr() must called after reserve() to ensure that the pointer is valid. + let ptr = dst.as_mut_ptr().add(off); + + // Shift the tail. + if tail_len > 0 && src_len != del_len { + ptr::copy(ptr.add(del_len), ptr.add(src_len), tail_len); + } + + // Copy in the replacement. + ptr::copy_nonoverlapping(src.as_ptr(), ptr, src_len); + dst.set_len(new_len); + } +} + +/// Turns a [`&[u8]`] into a [`&[MaybeUninit]`]. +#[inline(always)] +pub const fn slice_as_uninit_ref(slice: &[T]) -> &[MaybeUninit] { + unsafe { slice::from_raw_parts(slice.as_ptr() as *const MaybeUninit, slice.len()) } +} + +/// Turns a [`&mut [T]`] into a [`&mut [MaybeUninit]`]. +#[inline(always)] +pub const fn slice_as_uninit_mut(slice: &mut [T]) -> &mut [MaybeUninit] { + unsafe { slice::from_raw_parts_mut(slice.as_mut_ptr() as *mut MaybeUninit, slice.len()) } +} + +/// Helpers for ASCII string comparisons. +pub trait AsciiStringHelpers { + /// Tests if a string starts with a given ASCII prefix. + /// + /// This function name really is a mouthful, but it's a combination + /// of [`str::starts_with`] and [`str::eq_ignore_ascii_case`]. + fn starts_with_ignore_ascii_case(&self, prefix: &str) -> bool; +} + +impl AsciiStringHelpers for str { + fn starts_with_ignore_ascii_case(&self, prefix: &str) -> bool { + // Casting to bytes first ensures we skip any UTF8 boundary checks. + // Since the comparison is ASCII, we don't need to worry about that. + let s = self.as_bytes(); + let p = prefix.as_bytes(); + p.len() <= s.len() && s[..p.len()].eq_ignore_ascii_case(p) + } +} diff --git a/crates/stdext/src/lib.rs b/crates/stdext/src/lib.rs new file mode 100644 index 0000000..d7226d7 --- /dev/null +++ b/crates/stdext/src/lib.rs @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +//! Arena allocators. Small and fast. + +#![feature(allocator_api)] + +pub mod arena; +pub mod sys; + +mod helpers; +pub use helpers::*; diff --git a/crates/stdext/src/sys/mod.rs b/crates/stdext/src/sys/mod.rs new file mode 100644 index 0000000..91d5988 --- /dev/null +++ b/crates/stdext/src/sys/mod.rs @@ -0,0 +1,17 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +//! Platform abstractions. + +#[cfg(unix)] +mod unix; +#[cfg(windows)] +mod windows; + +#[cfg(not(windows))] +pub use std::fs::canonicalize; + +#[cfg(unix)] +pub use unix::*; +#[cfg(windows)] +pub use windows::*; diff --git a/crates/stdext/src/sys/unix.rs b/crates/stdext/src/sys/unix.rs new file mode 100644 index 0000000..dd634ca --- /dev/null +++ b/crates/stdext/src/sys/unix.rs @@ -0,0 +1,73 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +use std::alloc::AllocError; +use std::ffi::c_int; +use std::ptr::{self, NonNull, null_mut}; + +/// Reserves a virtual memory region of the given size. +/// To commit the memory, use `virtual_commit`. +/// To release the memory, use `virtual_release`. +/// +/// # Safety +/// +/// This function is unsafe because it uses raw pointers. +/// Don't forget to release the memory when you're done with it or you'll leak it. +pub unsafe fn virtual_reserve(size: usize) -> Result, AllocError> { + unsafe { + let ptr = libc::mmap( + null_mut(), + size, + desired_mprotect(libc::PROT_READ | libc::PROT_WRITE), + libc::MAP_PRIVATE | libc::MAP_ANONYMOUS, + -1, + 0, + ); + if ptr.is_null() || ptr::eq(ptr, libc::MAP_FAILED) { + Err(AllocError) + } else { + Ok(NonNull::new_unchecked(ptr as *mut u8)) + } + } +} + +#[cfg(target_os = "netbsd")] +const fn desired_mprotect(flags: c_int) -> c_int { + // NetBSD allows an mmap(2) caller to specify what protection flags they + // will use later via mprotect. It does not allow a caller to move from + // PROT_NONE to PROT_READ | PROT_WRITE. + // + // see PROT_MPROTECT in man 2 mmap + flags << 3 +} + +#[cfg(not(target_os = "netbsd"))] +const fn desired_mprotect(_: c_int) -> c_int { + libc::PROT_NONE +} + +/// Releases a virtual memory region of the given size. +/// +/// # Safety +/// +/// This function is unsafe because it uses raw pointers. +/// Make sure to only pass pointers acquired from `virtual_reserve`. +pub unsafe fn virtual_release(base: NonNull, size: usize) { + unsafe { + libc::munmap(base.cast().as_ptr(), size); + } +} + +/// Commits a virtual memory region of the given size. +/// +/// # Safety +/// +/// This function is unsafe because it uses raw pointers. +/// Make sure to only pass pointers acquired from `virtual_reserve` +/// and to pass a size less than or equal to the size passed to `virtual_reserve`. +pub unsafe fn virtual_commit(base: NonNull, size: usize) -> Result<(), AllocError> { + unsafe { + let status = libc::mprotect(base.cast().as_ptr(), size, libc::PROT_READ | libc::PROT_WRITE); + if status != 0 { Err(AllocError) } else { Ok(()) } + } +} diff --git a/crates/stdext/src/sys/windows.rs b/crates/stdext/src/sys/windows.rs new file mode 100644 index 0000000..e008814 --- /dev/null +++ b/crates/stdext/src/sys/windows.rs @@ -0,0 +1,63 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +use std::alloc::AllocError; +use std::ptr::{NonNull, null_mut}; + +const MEM_COMMIT: u32 = 0x00001000; +const MEM_RELEASE: u32 = 0x00008000; +const MEM_RESERVE: u32 = 0x00002000; +const PAGE_READWRITE: u32 = 0x04; + +unsafe extern "system" { + fn VirtualAlloc( + lpAddress: *mut u8, + dwSize: usize, + flAllocationType: u32, + flProtect: u32, + ) -> *mut u8; + fn VirtualFree(lpAddress: *mut u8, dwSize: usize, dwFreeType: u32) -> i32; +} + +/// Reserves a virtual memory region of the given size. +/// To commit the memory, use [`virtual_commit`]. +/// To release the memory, use [`virtual_release`]. +/// +/// # Safety +/// +/// This function is unsafe because it uses raw pointers. +/// Don't forget to release the memory when you're done with it or you'll leak it. +pub unsafe fn virtual_reserve(size: usize) -> Result, AllocError> { + unsafe { + let res = VirtualAlloc(null_mut(), size, MEM_RESERVE, PAGE_READWRITE); + if res.is_null() { Err(AllocError) } else { Ok(NonNull::new_unchecked(res)) } + } +} + +/// Releases a virtual memory region of the given size. +/// +/// # Safety +/// +/// This function is unsafe because it uses raw pointers. +/// Make sure to only pass pointers acquired from [`virtual_reserve`]. +pub unsafe fn virtual_release(base: NonNull, _size: usize) { + unsafe { + // NOTE: `VirtualFree` fails if the pointer isn't + // a valid base address or if the size isn't zero. + VirtualFree(base.as_ptr() as *mut _, 0, MEM_RELEASE); + } +} + +/// Commits a virtual memory region of the given size. +/// +/// # Safety +/// +/// This function is unsafe because it uses raw pointers. +/// Make sure to only pass pointers acquired from [`virtual_reserve`] +/// and to pass a size less than or equal to the size passed to [`virtual_reserve`]. +pub unsafe fn virtual_commit(base: NonNull, size: usize) -> Result<(), AllocError> { + unsafe { + let res = VirtualAlloc(base.as_ptr() as *mut _, size, MEM_COMMIT, PAGE_READWRITE); + if res.is_null() { Err(AllocError) } else { Ok(()) } + } +} diff --git a/tools/grapheme-table-gen/Cargo.toml b/crates/unicode-gen/Cargo.toml similarity index 60% rename from tools/grapheme-table-gen/Cargo.toml rename to crates/unicode-gen/Cargo.toml index 083d705..78dc8d7 100644 --- a/tools/grapheme-table-gen/Cargo.toml +++ b/crates/unicode-gen/Cargo.toml @@ -1,7 +1,11 @@ [package] -name = "grapheme-table-gen" -version = "0.1.0" -edition = "2024" +name = "unicode-gen" +version = "0.0.0" + +edition.workspace = true +license.workspace = true +repository.workspace = true +rust-version.workspace = true [dependencies] anyhow = "1.0" diff --git a/tools/grapheme-table-gen/README.md b/crates/unicode-gen/README.md similarity index 100% rename from tools/grapheme-table-gen/README.md rename to crates/unicode-gen/README.md diff --git a/tools/grapheme-table-gen/src/main.rs b/crates/unicode-gen/src/main.rs similarity index 100% rename from tools/grapheme-table-gen/src/main.rs rename to crates/unicode-gen/src/main.rs diff --git a/tools/grapheme-table-gen/src/rules.rs b/crates/unicode-gen/src/rules.rs similarity index 100% rename from tools/grapheme-table-gen/src/rules.rs rename to crates/unicode-gen/src/rules.rs diff --git a/tools/grapheme-table-gen/Cargo.lock b/tools/grapheme-table-gen/Cargo.lock deleted file mode 100644 index 3bd26ec..0000000 --- a/tools/grapheme-table-gen/Cargo.lock +++ /dev/null @@ -1,377 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - -[[package]] -name = "anyhow" -version = "1.0.99" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" - -[[package]] -name = "autocfg" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" - -[[package]] -name = "bumpalo" -version = "3.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" - -[[package]] -name = "cc" -version = "1.2.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42bc4aea80032b7bf409b0bc7ccad88853858911b7713a8062fdc0623867bedc" -dependencies = [ - "shlex", -] - -[[package]] -name = "cfg-if" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" - -[[package]] -name = "chrono" -version = "0.4.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" -dependencies = [ - "android-tzdata", - "iana-time-zone", - "js-sys", - "num-traits", - "wasm-bindgen", - "windows-link", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" - -[[package]] -name = "crossbeam-deque" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" - -[[package]] -name = "either" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" - -[[package]] -name = "grapheme-table-gen" -version = "0.1.0" -dependencies = [ - "anyhow", - "chrono", - "indoc", - "pico-args", - "rayon", - "roxmltree", -] - -[[package]] -name = "iana-time-zone" -version = "0.1.63" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "log", - "wasm-bindgen", - "windows-core", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - -[[package]] -name = "indoc" -version = "2.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd" - -[[package]] -name = "js-sys" -version = "0.3.77" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" -dependencies = [ - "once_cell", - "wasm-bindgen", -] - -[[package]] -name = "libc" -version = "0.2.175" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" - -[[package]] -name = "log" -version = "0.4.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - -[[package]] -name = "once_cell" -version = "1.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" - -[[package]] -name = "pico-args" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" - -[[package]] -name = "proc-macro2" -version = "1.0.101" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rayon" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" -dependencies = [ - "crossbeam-deque", - "crossbeam-utils", -] - -[[package]] -name = "roxmltree" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97" - -[[package]] -name = "rustversion" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "syn" -version = "2.0.106" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "unicode-ident" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" - -[[package]] -name = "wasm-bindgen" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" -dependencies = [ - "cfg-if", - "once_cell", - "rustversion", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" -dependencies = [ - "bumpalo", - "log", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "windows-core" -version = "0.61.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" -dependencies = [ - "windows-implement", - "windows-interface", - "windows-link", - "windows-result", - "windows-strings", -] - -[[package]] -name = "windows-implement" -version = "0.60.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "windows-interface" -version = "0.59.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "windows-link" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" - -[[package]] -name = "windows-result" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" -dependencies = [ - "windows-link", -] - -[[package]] -name = "windows-strings" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" -dependencies = [ - "windows-link", -]