This is an automated email from the ASF dual-hosted git repository.

leerho pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/datasketches-rust.git


The following commit(s) were added to refs/heads/main by this push:
     new 792b4c5  build: set up workspace layout  (#43)
792b4c5 is described below

commit 792b4c5a34e3121100ac4d71fa2e8287b90a6244
Author: tison <[email protected]>
AuthorDate: Thu Dec 25 16:59:04 2025 +0800

    build: set up workspace layout  (#43)
    
    * build: set up workspace layout
    
    Signed-off-by: tison <[email protected]>
    
    * fixup
    
    Signed-off-by: tison <[email protected]>
    
    * try fix windows compile
    
    Signed-off-by: tison <[email protected]>
    
    * fix(xtask): exclude xtask binary from build command to avoid file locking 
on Windows
    
    * workaround windows issue
    
    Signed-off-by: tison <[email protected]>
    
    * windows runner has no yq
    
    Signed-off-by: tison <[email protected]>
    
    ---------
    
    Signed-off-by: tison <[email protected]>
---
 Cargo.toml => .cargo/config.toml                   |  36 +---
 .github/workflows/ci.yml                           |  23 +--
 CONTRIBUTING.md                                    |   8 +-
 Cargo.lock                                         | 220 +++++++++++++++++++++
 Cargo.toml                                         |  29 ++-
 Cargo.toml => datasketches/Cargo.toml              |  26 +--
 {src => datasketches/src}/error.rs                 |   0
 {src => datasketches/src}/hash/mod.rs              |   0
 {src => datasketches/src}/hash/murmurhash.rs       |   0
 {src => datasketches/src}/hll/array4.rs            |   0
 {src => datasketches/src}/hll/array6.rs            |   0
 {src => datasketches/src}/hll/array8.rs            |   0
 {src => datasketches/src}/hll/aux_map.rs           |   0
 .../src}/hll/composite_interpolation.rs            |   0
 {src => datasketches/src}/hll/container.rs         |   0
 {src => datasketches/src}/hll/coupon_mapping.rs    |   0
 .../src}/hll/cubic_interpolation.rs                |   0
 {src => datasketches/src}/hll/estimator.rs         |   0
 {src => datasketches/src}/hll/harmonic_numbers.rs  |   0
 {src => datasketches/src}/hll/hash_set.rs          |   0
 {src => datasketches/src}/hll/list.rs              |   0
 {src => datasketches/src}/hll/mod.rs               |   0
 {src => datasketches/src}/hll/mode.rs              |   0
 {src => datasketches/src}/hll/serialization.rs     |   0
 {src => datasketches/src}/hll/sketch.rs            |   0
 {src => datasketches/src}/hll/union.rs             |   0
 {src => datasketches/src}/lib.rs                   |   0
 {src => datasketches/src}/tdigest/mod.rs           |   0
 {src => datasketches/src}/tdigest/serialization.rs |   0
 {src => datasketches/src}/tdigest/sketch.rs        |   0
 {tests => datasketches/tests}/.gitignore           |   0
 {tests => datasketches/tests}/common.rs            |   0
 .../tests}/hll_serialization_test.rs               |   0
 {tests => datasketches/tests}/hll_union_test.rs    |   0
 {tests => datasketches/tests}/hll_update_test.rs   |   0
 .../tests}/tdigest_serialization_test.rs           |   0
 {tests => datasketches/tests}/tdigest_test.rs      |   0
 .../test_data/tdigest_ref_k100_n10000_double.sk    | Bin
 .../test_data/tdigest_ref_k100_n10000_float.sk     | Bin
 Cargo.toml => examples/Cargo.toml                  |  38 ++--
 examples/{hll_usage.rs => src/hll_update.rs}       |   0
 tools/generate_serialization_test_data.py          |  19 +-
 Cargo.toml => xtask/Cargo.toml                     |  41 ++--
 xtask/src/main.rs                                  | 171 ++++++++++++++++
 44 files changed, 467 insertions(+), 144 deletions(-)

diff --git a/Cargo.toml b/.cargo/config.toml
similarity index 50%
copy from Cargo.toml
copy to .cargo/config.toml
index 46b91f0..f86e56b 100644
--- a/Cargo.toml
+++ b/.cargo/config.toml
@@ -15,36 +15,8 @@
 # specific language governing permissions and limitations
 # under the License.
 
-[package]
-name = "datasketches"
-version = "0.1.0"
+[alias]
+x = "run --package x --"
 
-edition = "2024"
-rust-version = "1.85.0"
-
-categories = ["data-structures", "algorithms"]
-description = "A software library of stochastic streaming algorithms (a.k.a. 
sketches)"
-homepage = "https://datasketches.apache.org";
-keywords = ["sketch", "hyperloglog", "probabilistic"]
-license = "Apache-2.0"
-readme = "README.md"
-repository = "https://github.com/apache/datasketches-rust";
-
-[package.metadata.docs.rs]
-all-features = true
-rustdoc-args = ["--cfg", "docsrs"]
-
-[dependencies]
-byteorder = { version = "1.5.0" }
-
-[dev-dependencies]
-googletest = { version = "0.14.2" }
-
-[lints.rust]
-unknown_lints = "deny"
-unsafe_code = "deny"
-unused_must_use = "deny"
-
-[lints.clippy]
-dbg_macro = "deny"
-too_many_arguments = "allow"
+[env]
+CARGO_WORKSPACE_DIR = { value = "", relative = true }
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 6ce091d..318599e 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -34,6 +34,10 @@ on:
 concurrency:
   group: ${{ github.workflow }}-${{ github.event_name }}-${{ 
github.event.number || github.run_id }}
   cancel-in-progress: true
+
+env:
+  RUST_BACKTRACE: 1
+
 jobs:
   check:
     name: Check
@@ -49,12 +53,7 @@ jobs:
         with:
           tool: typos-cli,taplo-cli,hawkeye
       - name: Check all
-        run: |
-          hawkeye check
-          taplo format --check
-          typos
-          cargo +nightly fmt --all -- --check
-          cargo +nightly clippy --all-targets --all-features -- -D warnings
+        run: cargo x lint
 
   msrv:
     name: Resolve MSRV
@@ -65,7 +64,7 @@ jobs:
       - uses: actions/checkout@v6
       - id: metadata
         run: |
-          msrv=$(yq '.package.rust-version' Cargo.toml)
+          msrv=$(yq '.workspace.package.rust-version' Cargo.toml)
           echo "MSRV: $msrv"
           echo "rust-versions=[\"${msrv}\", \"stable\"]" >> "$GITHUB_OUTPUT"
 
@@ -94,16 +93,18 @@ jobs:
       - name: Prepare test data
         shell: bash
         run: ./tools/generate_serialization_test_data.py
-      - name: Build
-        run: cargo build --workspace --all-features --bins --tests --examples 
--benches --lib
       - name: Run unit tests
         shell: bash
-        run: cargo test --all-features -- --nocapture
+        run: cargo x test
       - name: Run examples
         shell: bash
+        working-directory: examples
         run: |
           set -x
-          cargo run --example hll_usage
+          EXAMPLES=( hll_update )
+          for example in $EXAMPLES; do
+            cargo run --bin "$example"
+          done
 
   required:
     name: Required
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index a041789..d714ddf 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -30,13 +30,7 @@ cargo version
 # cargo 1.85.0 (<hash> 2024-12-31)
 ```
 
-To keep code style consistent, we use the following tools:
-
-* Nightly `rustfmt` for code formatting: `cargo +nightly fmt --all -- --check`
-* Nightly `clippy` for linting: `cargo +nightly clippy --all-targets 
--all-features -- -D warnings`
-* [`typos`](https://github.com/crate-ci/typos) for spell checking: `cargo 
install typos-cli` and then `typos`
-* [`taplo`](https://taplo.tamasfe.dev/) for checking `toml` files: `cargo 
install taplo-cli` and then `taplo check`
-* [`hawkeye`](https://github.com/korandoru/hawkeye) for checking license 
header: `cargo install hawkeye` and then `hawkeye check`
+To keep code style consistent, run `cargo x lint --fix` to automatically fix 
any style issues before committing your changes.
 
 ## Code of Conduct
 
diff --git a/Cargo.lock b/Cargo.lock
index cb421e2..ba741cd 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -11,18 +11,120 @@ dependencies = [
  "memchr",
 ]
 
+[[package]]
+name = "anstream"
+version = "0.6.21"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a"
+dependencies = [
+ "anstyle",
+ "anstyle-parse",
+ "anstyle-query",
+ "anstyle-wincon",
+ "colorchoice",
+ "is_terminal_polyfill",
+ "utf8parse",
+]
+
+[[package]]
+name = "anstyle"
+version = "1.0.13"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78"
+
+[[package]]
+name = "anstyle-parse"
+version = "0.2.7"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2"
+dependencies = [
+ "utf8parse",
+]
+
+[[package]]
+name = "anstyle-query"
+version = "1.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc"
+dependencies = [
+ "windows-sys",
+]
+
+[[package]]
+name = "anstyle-wincon"
+version = "3.0.11"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d"
+dependencies = [
+ "anstyle",
+ "once_cell_polyfill",
+ "windows-sys",
+]
+
 [[package]]
 name = "autocfg"
 version = "1.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
 
+[[package]]
+name = "bitflags"
+version = "2.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3"
+
 [[package]]
 name = "byteorder"
 version = "1.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
 
+[[package]]
+name = "clap"
+version = "4.5.53"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8"
+dependencies = [
+ "clap_builder",
+ "clap_derive",
+]
+
+[[package]]
+name = "clap_builder"
+version = "4.5.53"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00"
+dependencies = [
+ "anstream",
+ "anstyle",
+ "clap_lex",
+ "strsim",
+]
+
+[[package]]
+name = "clap_derive"
+version = "4.5.49"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671"
+dependencies = [
+ "heck",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "clap_lex"
+version = "0.7.6"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d"
+
+[[package]]
+name = "colorchoice"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
+
 [[package]]
 name = "datasketches"
 version = "0.1.0"
@@ -31,6 +133,29 @@ dependencies = [
  "googletest",
 ]
 
+[[package]]
+name = "env_home"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "c7f84e12ccf0a7ddc17a6c41c93326024c42920d7ee630d04950e6926645c0fe"
+
+[[package]]
+name = "errno"
+version = "0.3.14"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
+dependencies = [
+ "libc",
+ "windows-sys",
+]
+
+[[package]]
+name = "examples"
+version = "0.0.0"
+dependencies = [
+ "datasketches",
+]
+
 [[package]]
 name = "googletest"
 version = "0.14.2"
@@ -54,6 +179,30 @@ dependencies = [
  "syn",
 ]
 
+[[package]]
+name = "heck"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
+
+[[package]]
+name = "is_terminal_polyfill"
+version = "1.70.2"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"
+
+[[package]]
+name = "libc"
+version = "0.2.178"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091"
+
+[[package]]
+name = "linux-raw-sys"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039"
+
 [[package]]
 name = "memchr"
 version = "2.7.6"
@@ -69,6 +218,12 @@ dependencies = [
  "autocfg",
 ]
 
+[[package]]
+name = "once_cell_polyfill"
+version = "1.70.2"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
+
 [[package]]
 name = "proc-macro2"
 version = "1.0.103"
@@ -116,12 +271,31 @@ version = "0.8.8"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58"
 
+[[package]]
+name = "rustix"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e"
+dependencies = [
+ "bitflags",
+ "errno",
+ "libc",
+ "linux-raw-sys",
+ "windows-sys",
+]
+
 [[package]]
 name = "rustversion"
 version = "1.0.22"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
 
+[[package]]
+name = "strsim"
+version = "0.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
+
 [[package]]
 name = "syn"
 version = "2.0.111"
@@ -138,3 +312,49 @@ name = "unicode-ident"
 version = "1.0.22"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
+
+[[package]]
+name = "utf8parse"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
+
+[[package]]
+name = "which"
+version = "8.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "d3fabb953106c3c8eea8306e4393700d7657561cb43122571b172bbfb7c7ba1d"
+dependencies = [
+ "env_home",
+ "rustix",
+ "winsafe",
+]
+
+[[package]]
+name = "windows-link"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
+
+[[package]]
+name = "windows-sys"
+version = "0.61.2"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
+dependencies = [
+ "windows-link",
+]
+
+[[package]]
+name = "winsafe"
+version = "0.0.19"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904"
+
+[[package]]
+name = "x"
+version = "0.0.0"
+dependencies = [
+ "clap",
+ "which",
+]
diff --git a/Cargo.toml b/Cargo.toml
index 46b91f0..e991913 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -15,36 +15,33 @@
 # specific language governing permissions and limitations
 # under the License.
 
-[package]
-name = "datasketches"
-version = "0.1.0"
+[workspace]
+members = ["datasketches", "examples", "xtask"]
+resolver = "3"
 
+[workspace.package]
 edition = "2024"
-rust-version = "1.85.0"
-
-categories = ["data-structures", "algorithms"]
-description = "A software library of stochastic streaming algorithms (a.k.a. 
sketches)"
 homepage = "https://datasketches.apache.org";
-keywords = ["sketch", "hyperloglog", "probabilistic"]
 license = "Apache-2.0"
 readme = "README.md"
 repository = "https://github.com/apache/datasketches-rust";
+rust-version = "1.85.0"
 
-[package.metadata.docs.rs]
-all-features = true
-rustdoc-args = ["--cfg", "docsrs"]
+[workspace.dependencies]
+# Workspace dependencies
+datasketches = { path = "datasketches" }
 
-[dependencies]
+# Crates.io dependencies
 byteorder = { version = "1.5.0" }
-
-[dev-dependencies]
+clap = { version = "4.5.20", features = ["derive"] }
 googletest = { version = "0.14.2" }
+which = { version = "8.0.0" }
 
-[lints.rust]
+[workspace.lints.rust]
 unknown_lints = "deny"
 unsafe_code = "deny"
 unused_must_use = "deny"
 
-[lints.clippy]
+[workspace.lints.clippy]
 dbg_macro = "deny"
 too_many_arguments = "allow"
diff --git a/Cargo.toml b/datasketches/Cargo.toml
similarity index 73%
copy from Cargo.toml
copy to datasketches/Cargo.toml
index 46b91f0..bddcb7e 100644
--- a/Cargo.toml
+++ b/datasketches/Cargo.toml
@@ -19,32 +19,26 @@
 name = "datasketches"
 version = "0.1.0"
 
-edition = "2024"
-rust-version = "1.85.0"
+edition.workspace = true
+homepage.workspace = true
+license.workspace = true
+readme.workspace = true
+repository.workspace = true
+rust-version.workspace = true
 
 categories = ["data-structures", "algorithms"]
 description = "A software library of stochastic streaming algorithms (a.k.a. 
sketches)"
-homepage = "https://datasketches.apache.org";
 keywords = ["sketch", "hyperloglog", "probabilistic"]
-license = "Apache-2.0"
-readme = "README.md"
-repository = "https://github.com/apache/datasketches-rust";
 
 [package.metadata.docs.rs]
 all-features = true
 rustdoc-args = ["--cfg", "docsrs"]
 
 [dependencies]
-byteorder = { version = "1.5.0" }
+byteorder = { workspace = true }
 
 [dev-dependencies]
-googletest = { version = "0.14.2" }
+googletest = { workspace = true }
 
-[lints.rust]
-unknown_lints = "deny"
-unsafe_code = "deny"
-unused_must_use = "deny"
-
-[lints.clippy]
-dbg_macro = "deny"
-too_many_arguments = "allow"
+[lints]
+workspace = true
diff --git a/src/error.rs b/datasketches/src/error.rs
similarity index 100%
rename from src/error.rs
rename to datasketches/src/error.rs
diff --git a/src/hash/mod.rs b/datasketches/src/hash/mod.rs
similarity index 100%
rename from src/hash/mod.rs
rename to datasketches/src/hash/mod.rs
diff --git a/src/hash/murmurhash.rs b/datasketches/src/hash/murmurhash.rs
similarity index 100%
rename from src/hash/murmurhash.rs
rename to datasketches/src/hash/murmurhash.rs
diff --git a/src/hll/array4.rs b/datasketches/src/hll/array4.rs
similarity index 100%
rename from src/hll/array4.rs
rename to datasketches/src/hll/array4.rs
diff --git a/src/hll/array6.rs b/datasketches/src/hll/array6.rs
similarity index 100%
rename from src/hll/array6.rs
rename to datasketches/src/hll/array6.rs
diff --git a/src/hll/array8.rs b/datasketches/src/hll/array8.rs
similarity index 100%
rename from src/hll/array8.rs
rename to datasketches/src/hll/array8.rs
diff --git a/src/hll/aux_map.rs b/datasketches/src/hll/aux_map.rs
similarity index 100%
rename from src/hll/aux_map.rs
rename to datasketches/src/hll/aux_map.rs
diff --git a/src/hll/composite_interpolation.rs 
b/datasketches/src/hll/composite_interpolation.rs
similarity index 100%
rename from src/hll/composite_interpolation.rs
rename to datasketches/src/hll/composite_interpolation.rs
diff --git a/src/hll/container.rs b/datasketches/src/hll/container.rs
similarity index 100%
rename from src/hll/container.rs
rename to datasketches/src/hll/container.rs
diff --git a/src/hll/coupon_mapping.rs b/datasketches/src/hll/coupon_mapping.rs
similarity index 100%
rename from src/hll/coupon_mapping.rs
rename to datasketches/src/hll/coupon_mapping.rs
diff --git a/src/hll/cubic_interpolation.rs 
b/datasketches/src/hll/cubic_interpolation.rs
similarity index 100%
rename from src/hll/cubic_interpolation.rs
rename to datasketches/src/hll/cubic_interpolation.rs
diff --git a/src/hll/estimator.rs b/datasketches/src/hll/estimator.rs
similarity index 100%
rename from src/hll/estimator.rs
rename to datasketches/src/hll/estimator.rs
diff --git a/src/hll/harmonic_numbers.rs 
b/datasketches/src/hll/harmonic_numbers.rs
similarity index 100%
rename from src/hll/harmonic_numbers.rs
rename to datasketches/src/hll/harmonic_numbers.rs
diff --git a/src/hll/hash_set.rs b/datasketches/src/hll/hash_set.rs
similarity index 100%
rename from src/hll/hash_set.rs
rename to datasketches/src/hll/hash_set.rs
diff --git a/src/hll/list.rs b/datasketches/src/hll/list.rs
similarity index 100%
rename from src/hll/list.rs
rename to datasketches/src/hll/list.rs
diff --git a/src/hll/mod.rs b/datasketches/src/hll/mod.rs
similarity index 100%
rename from src/hll/mod.rs
rename to datasketches/src/hll/mod.rs
diff --git a/src/hll/mode.rs b/datasketches/src/hll/mode.rs
similarity index 100%
rename from src/hll/mode.rs
rename to datasketches/src/hll/mode.rs
diff --git a/src/hll/serialization.rs b/datasketches/src/hll/serialization.rs
similarity index 100%
rename from src/hll/serialization.rs
rename to datasketches/src/hll/serialization.rs
diff --git a/src/hll/sketch.rs b/datasketches/src/hll/sketch.rs
similarity index 100%
rename from src/hll/sketch.rs
rename to datasketches/src/hll/sketch.rs
diff --git a/src/hll/union.rs b/datasketches/src/hll/union.rs
similarity index 100%
rename from src/hll/union.rs
rename to datasketches/src/hll/union.rs
diff --git a/src/lib.rs b/datasketches/src/lib.rs
similarity index 100%
rename from src/lib.rs
rename to datasketches/src/lib.rs
diff --git a/src/tdigest/mod.rs b/datasketches/src/tdigest/mod.rs
similarity index 100%
rename from src/tdigest/mod.rs
rename to datasketches/src/tdigest/mod.rs
diff --git a/src/tdigest/serialization.rs 
b/datasketches/src/tdigest/serialization.rs
similarity index 100%
rename from src/tdigest/serialization.rs
rename to datasketches/src/tdigest/serialization.rs
diff --git a/src/tdigest/sketch.rs b/datasketches/src/tdigest/sketch.rs
similarity index 100%
rename from src/tdigest/sketch.rs
rename to datasketches/src/tdigest/sketch.rs
diff --git a/tests/.gitignore b/datasketches/tests/.gitignore
similarity index 100%
rename from tests/.gitignore
rename to datasketches/tests/.gitignore
diff --git a/tests/common.rs b/datasketches/tests/common.rs
similarity index 100%
rename from tests/common.rs
rename to datasketches/tests/common.rs
diff --git a/tests/hll_serialization_test.rs 
b/datasketches/tests/hll_serialization_test.rs
similarity index 100%
rename from tests/hll_serialization_test.rs
rename to datasketches/tests/hll_serialization_test.rs
diff --git a/tests/hll_union_test.rs b/datasketches/tests/hll_union_test.rs
similarity index 100%
rename from tests/hll_union_test.rs
rename to datasketches/tests/hll_union_test.rs
diff --git a/tests/hll_update_test.rs b/datasketches/tests/hll_update_test.rs
similarity index 100%
rename from tests/hll_update_test.rs
rename to datasketches/tests/hll_update_test.rs
diff --git a/tests/tdigest_serialization_test.rs 
b/datasketches/tests/tdigest_serialization_test.rs
similarity index 100%
rename from tests/tdigest_serialization_test.rs
rename to datasketches/tests/tdigest_serialization_test.rs
diff --git a/tests/tdigest_test.rs b/datasketches/tests/tdigest_test.rs
similarity index 100%
rename from tests/tdigest_test.rs
rename to datasketches/tests/tdigest_test.rs
diff --git a/tests/test_data/tdigest_ref_k100_n10000_double.sk 
b/datasketches/tests/test_data/tdigest_ref_k100_n10000_double.sk
similarity index 100%
rename from tests/test_data/tdigest_ref_k100_n10000_double.sk
rename to datasketches/tests/test_data/tdigest_ref_k100_n10000_double.sk
diff --git a/tests/test_data/tdigest_ref_k100_n10000_float.sk 
b/datasketches/tests/test_data/tdigest_ref_k100_n10000_float.sk
similarity index 100%
rename from tests/test_data/tdigest_ref_k100_n10000_float.sk
rename to datasketches/tests/test_data/tdigest_ref_k100_n10000_float.sk
diff --git a/Cargo.toml b/examples/Cargo.toml
similarity index 52%
copy from Cargo.toml
copy to examples/Cargo.toml
index 46b91f0..0942c3d 100644
--- a/Cargo.toml
+++ b/examples/Cargo.toml
@@ -16,35 +16,21 @@
 # under the License.
 
 [package]
-name = "datasketches"
-version = "0.1.0"
+name = "examples"
+publish = false
 
-edition = "2024"
-rust-version = "1.85.0"
+edition.workspace = true
+rust-version.workspace = true
 
-categories = ["data-structures", "algorithms"]
-description = "A software library of stochastic streaming algorithms (a.k.a. 
sketches)"
-homepage = "https://datasketches.apache.org";
-keywords = ["sketch", "hyperloglog", "probabilistic"]
-license = "Apache-2.0"
-readme = "README.md"
-repository = "https://github.com/apache/datasketches-rust";
+[[bin]]
+name = "hll_update"
+path = "src/hll_update.rs"
 
-[package.metadata.docs.rs]
-all-features = true
-rustdoc-args = ["--cfg", "docsrs"]
+[package.metadata.release]
+release = false
 
 [dependencies]
-byteorder = { version = "1.5.0" }
+datasketches = { workspace = true }
 
-[dev-dependencies]
-googletest = { version = "0.14.2" }
-
-[lints.rust]
-unknown_lints = "deny"
-unsafe_code = "deny"
-unused_must_use = "deny"
-
-[lints.clippy]
-dbg_macro = "deny"
-too_many_arguments = "allow"
+[lints]
+workspace = true
diff --git a/examples/hll_usage.rs b/examples/src/hll_update.rs
similarity index 100%
rename from examples/hll_usage.rs
rename to examples/src/hll_update.rs
diff --git a/tools/generate_serialization_test_data.py 
b/tools/generate_serialization_test_data.py
index 512c02f..7fb488b 100755
--- a/tools/generate_serialization_test_data.py
+++ b/tools/generate_serialization_test_data.py
@@ -47,7 +47,7 @@ def run_command(command, cwd=None, shell=False):
         sys.exit(1)
 
 
-def generate_java_files(project_root):
+def generate_java_files(workspace_dir, project_dir):
     print("--- Generating Java Test Data ---")
 
     # 1. Check prerequisites
@@ -59,8 +59,8 @@ def generate_java_files(project_root):
     check_command_installed(mvn_cmd_name)
 
     # 2. Define paths
-    temp_dir = project_root / "tmp_datasketches_java"
-    output_dir = project_root / "tests" / "serialization_test_data" / 
"java_generated_files"
+    temp_dir = workspace_dir / "tmp_datasketches_java"
+    output_dir = project_dir / "tests" / "serialization_test_data" / 
"java_generated_files"
 
     # 3. Setup temporary directory
     if temp_dir.exists():
@@ -104,7 +104,7 @@ def generate_java_files(project_root):
         print(f"Successfully copied {files_copied} files.")
 
 
-def generate_cpp_files(project_root):
+def generate_cpp_files(workspace_dir, project_root):
     print("--- Generating C++ Test Data ---")
 
     # 1. Check prerequisites
@@ -113,7 +113,7 @@ def generate_cpp_files(project_root):
     check_command_installed("ctest")
 
     # 2. Define paths
-    temp_dir = project_root / "tmp_datasketches_cpp"
+    temp_dir = workspace_dir / "tmp_datasketches_cpp"
     output_dir = project_root / "tests" / "serialization_test_data" / 
"cpp_generated_files"
 
     # 3. Setup temporary directory
@@ -175,14 +175,15 @@ def main():
     if not args.java and not args.cpp and not args.all:
         args.all = True
 
-    script_dir = Path(__file__).resolve().parent
-    project_root = script_dir.parent
+    tools_dir = Path(__file__).resolve().parent
+    workspace_dir = tools_dir.parent
+    project_dir = workspace_dir / "datasketches"
 
     if args.java or args.all:
-        generate_java_files(project_root)
+        generate_java_files(workspace_dir, project_dir)
 
     if args.cpp or args.all:
-        generate_cpp_files(project_root)
+        generate_cpp_files(workspace_dir, project_dir)
 
 if __name__ == "__main__":
     main()
diff --git a/Cargo.toml b/xtask/Cargo.toml
similarity index 52%
copy from Cargo.toml
copy to xtask/Cargo.toml
index 46b91f0..5b04167 100644
--- a/Cargo.toml
+++ b/xtask/Cargo.toml
@@ -16,35 +16,22 @@
 # under the License.
 
 [package]
-name = "datasketches"
-version = "0.1.0"
+name = "x"
+publish = false
 
-edition = "2024"
-rust-version = "1.85.0"
+edition.workspace = true
+homepage.workspace = true
+license.workspace = true
+readme.workspace = true
+repository.workspace = true
+rust-version.workspace = true
 
-categories = ["data-structures", "algorithms"]
-description = "A software library of stochastic streaming algorithms (a.k.a. 
sketches)"
-homepage = "https://datasketches.apache.org";
-keywords = ["sketch", "hyperloglog", "probabilistic"]
-license = "Apache-2.0"
-readme = "README.md"
-repository = "https://github.com/apache/datasketches-rust";
-
-[package.metadata.docs.rs]
-all-features = true
-rustdoc-args = ["--cfg", "docsrs"]
+[package.metadata.release]
+release = false
 
 [dependencies]
-byteorder = { version = "1.5.0" }
-
-[dev-dependencies]
-googletest = { version = "0.14.2" }
-
-[lints.rust]
-unknown_lints = "deny"
-unsafe_code = "deny"
-unused_must_use = "deny"
+clap = { workspace = true }
+which = { workspace = true }
 
-[lints.clippy]
-dbg_macro = "deny"
-too_many_arguments = "allow"
+[lints]
+workspace = true
diff --git a/xtask/src/main.rs b/xtask/src/main.rs
new file mode 100644
index 0000000..24f0138
--- /dev/null
+++ b/xtask/src/main.rs
@@ -0,0 +1,171 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use std::process::Command as StdCommand;
+
+use clap::Parser;
+use clap::Subcommand;
+
+#[derive(Parser)]
+struct Command {
+    #[clap(subcommand)]
+    sub: SubCommand,
+}
+
+impl Command {
+    fn run(self) {
+        match self.sub {
+            SubCommand::Lint(cmd) => cmd.run(),
+            SubCommand::Test(cmd) => cmd.run(),
+        }
+    }
+}
+
+#[derive(Subcommand)]
+enum SubCommand {
+    #[clap(about = "Run format and clippy checks.")]
+    Lint(CommandLint),
+    #[clap(about = "Run unit tests.")]
+    Test(CommandTest),
+}
+
+#[derive(Parser)]
+struct CommandTest {
+    #[arg(long, help = "Run tests serially and do not capture output.")]
+    no_capture: bool,
+}
+
+impl CommandTest {
+    fn run(self) {
+        run_command(make_test_cmd(self.no_capture, &[]));
+    }
+}
+
+#[derive(Parser)]
+#[clap(name = "lint")]
+struct CommandLint {
+    #[arg(long, help = "Automatically apply lint suggestions.")]
+    fix: bool,
+}
+
+impl CommandLint {
+    fn run(self) {
+        run_command(make_clippy_cmd(self.fix));
+        run_command(make_format_cmd(self.fix));
+        run_command(make_taplo_cmd(self.fix));
+        run_command(make_typos_cmd());
+        run_command(make_hawkeye_cmd(self.fix));
+    }
+}
+
+fn find_command(cmd: &str) -> StdCommand {
+    match which::which(cmd) {
+        Ok(exe) => {
+            let mut cmd = StdCommand::new(exe);
+            cmd.current_dir(env!("CARGO_WORKSPACE_DIR"));
+            cmd
+        }
+        Err(err) => {
+            panic!("{cmd} not found: {err}");
+        }
+    }
+}
+
+fn ensure_installed(bin: &str, crate_name: &str) {
+    if which::which(bin).is_err() {
+        let mut cmd = find_command("cargo");
+        cmd.args(["install", crate_name]);
+        run_command(cmd);
+    }
+}
+
+fn run_command(mut cmd: StdCommand) {
+    println!("{cmd:?}");
+    let status = cmd.status().expect("failed to execute process");
+    assert!(status.success(), "command failed: {status}");
+}
+
+fn make_test_cmd(no_capture: bool, features: &[&str]) -> StdCommand {
+    let mut cmd = find_command("cargo");
+    cmd.args(["test", "--workspace", "--no-default-features"]);
+    if !features.is_empty() {
+        cmd.args(["--features", features.join(",").as_str()]);
+    }
+    if no_capture {
+        cmd.args(["--", "--nocapture"]);
+    }
+    cmd
+}
+
+fn make_format_cmd(fix: bool) -> StdCommand {
+    let mut cmd = find_command("cargo");
+    cmd.args(["+nightly", "fmt", "--all"]);
+    if !fix {
+        cmd.arg("--check");
+    }
+    cmd
+}
+
+fn make_clippy_cmd(fix: bool) -> StdCommand {
+    let mut cmd = find_command("cargo");
+    cmd.args([
+        "+nightly",
+        "clippy",
+        "--tests",
+        "--all-features",
+        "--all-targets",
+        "--workspace",
+    ]);
+    if fix {
+        cmd.args(["--allow-staged", "--allow-dirty", "--fix"]);
+    } else {
+        cmd.args(["--", "-D", "warnings"]);
+    }
+    cmd
+}
+
+fn make_hawkeye_cmd(fix: bool) -> StdCommand {
+    ensure_installed("hawkeye", "hawkeye");
+    let mut cmd = find_command("hawkeye");
+    if fix {
+        cmd.args(["format", "--fail-if-updated=false"]);
+    } else {
+        cmd.args(["check"]);
+    }
+    cmd
+}
+
+fn make_typos_cmd() -> StdCommand {
+    ensure_installed("typos", "typos-cli");
+    find_command("typos")
+}
+
+fn make_taplo_cmd(fix: bool) -> StdCommand {
+    ensure_installed("taplo", "taplo-cli");
+    let mut cmd = find_command("taplo");
+    if fix {
+        cmd.args(["format"]);
+    } else {
+        cmd.args(["format", "--check"]);
+    }
+    cmd
+}
+
+fn main() {
+    let cmd = Command::parse();
+    cmd.run()
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to