nkscan 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. nkscan-0.1.0/.envrc +1 -0
  2. nkscan-0.1.0/.github/workflows/ci.yml +135 -0
  3. nkscan-0.1.0/.github/workflows/release.yml +178 -0
  4. nkscan-0.1.0/.gitignore +5 -0
  5. nkscan-0.1.0/CONTRIBUTING.md +38 -0
  6. nkscan-0.1.0/Cargo.lock +2241 -0
  7. nkscan-0.1.0/Cargo.toml +79 -0
  8. nkscan-0.1.0/LICENSE-APACHE +202 -0
  9. nkscan-0.1.0/LICENSE-MIT +17 -0
  10. nkscan-0.1.0/PKG-INFO +143 -0
  11. nkscan-0.1.0/README.md +123 -0
  12. nkscan-0.1.0/flake.lock +98 -0
  13. nkscan-0.1.0/flake.nix +128 -0
  14. nkscan-0.1.0/nkscan.pyi +205 -0
  15. nkscan-0.1.0/pyproject.toml +32 -0
  16. nkscan-0.1.0/rust-toolchain.toml +4 -0
  17. nkscan-0.1.0/src/bin/nkscan/main.rs +453 -0
  18. nkscan-0.1.0/src/bin/stub_gen.rs +45 -0
  19. nkscan-0.1.0/src/decode.rs +232 -0
  20. nkscan-0.1.0/src/devices.rs +403 -0
  21. nkscan-0.1.0/src/lib.rs +14 -0
  22. nkscan-0.1.0/src/output.rs +163 -0
  23. nkscan-0.1.0/src/python.rs +492 -0
  24. nkscan-0.1.0/src/scanners/ls50/boundaries.rs +197 -0
  25. nkscan-0.1.0/src/scanners/ls50/calibration.rs +91 -0
  26. nkscan-0.1.0/src/scanners/ls50/capabilities.rs +172 -0
  27. nkscan-0.1.0/src/scanners/ls50/cdbs/mod.rs +3 -0
  28. nkscan-0.1.0/src/scanners/ls50/cdbs/vendor_read_write.rs +210 -0
  29. nkscan-0.1.0/src/scanners/ls50/decode.rs +40 -0
  30. nkscan-0.1.0/src/scanners/ls50/dtc.rs +157 -0
  31. nkscan-0.1.0/src/scanners/ls50/geometry.rs +289 -0
  32. nkscan-0.1.0/src/scanners/ls50/holder.rs +164 -0
  33. nkscan-0.1.0/src/scanners/ls50/mod.rs +1013 -0
  34. nkscan-0.1.0/src/scanners/ls50/status.rs +164 -0
  35. nkscan-0.1.0/src/scanners/ls50/window.rs +195 -0
  36. nkscan-0.1.0/src/scanners/ls5000/boundaries.rs +229 -0
  37. nkscan-0.1.0/src/scanners/ls5000/calibration.rs +113 -0
  38. nkscan-0.1.0/src/scanners/ls5000/capabilities.rs +188 -0
  39. nkscan-0.1.0/src/scanners/ls5000/cdbs/mod.rs +1 -0
  40. nkscan-0.1.0/src/scanners/ls5000/cdbs/vendor_read_write.rs +206 -0
  41. nkscan-0.1.0/src/scanners/ls5000/decode.rs +49 -0
  42. nkscan-0.1.0/src/scanners/ls5000/dtc.rs +209 -0
  43. nkscan-0.1.0/src/scanners/ls5000/geometry.rs +361 -0
  44. nkscan-0.1.0/src/scanners/ls5000/holder.rs +160 -0
  45. nkscan-0.1.0/src/scanners/ls5000/mod.rs +564 -0
  46. nkscan-0.1.0/src/scanners/ls5000/status.rs +163 -0
  47. nkscan-0.1.0/src/scanners/ls5000/tests.rs +576 -0
  48. nkscan-0.1.0/src/scanners/ls5000/window.rs +200 -0
  49. nkscan-0.1.0/src/scanners/ls9000/boundaries.rs +533 -0
  50. nkscan-0.1.0/src/scanners/ls9000/calibration.rs +121 -0
  51. nkscan-0.1.0/src/scanners/ls9000/capabilities.rs +72 -0
  52. nkscan-0.1.0/src/scanners/ls9000/cdbs/mod.rs +4 -0
  53. nkscan-0.1.0/src/scanners/ls9000/cdbs/trigger.rs +26 -0
  54. nkscan-0.1.0/src/scanners/ls9000/cdbs/vendor_read_write.rs +156 -0
  55. nkscan-0.1.0/src/scanners/ls9000/decode.rs +526 -0
  56. nkscan-0.1.0/src/scanners/ls9000/dtc.rs +180 -0
  57. nkscan-0.1.0/src/scanners/ls9000/geometry.rs +284 -0
  58. nkscan-0.1.0/src/scanners/ls9000/holder.rs +93 -0
  59. nkscan-0.1.0/src/scanners/ls9000/mod.rs +977 -0
  60. nkscan-0.1.0/src/scanners/ls9000/status.rs +212 -0
  61. nkscan-0.1.0/src/scanners/ls9000/window.rs +245 -0
  62. nkscan-0.1.0/src/scanners/mod.rs +274 -0
  63. nkscan-0.1.0/src/scanners/nikon/capabilities.rs +238 -0
  64. nkscan-0.1.0/src/scanners/nikon/cdbs.rs +153 -0
  65. nkscan-0.1.0/src/scanners/nikon/decode.rs +243 -0
  66. nkscan-0.1.0/src/scanners/nikon/dtc.rs +122 -0
  67. nkscan-0.1.0/src/scanners/nikon/metering.rs +300 -0
  68. nkscan-0.1.0/src/scanners/nikon/mod.rs +189 -0
  69. nkscan-0.1.0/src/scsi/asc.rs +212 -0
  70. nkscan-0.1.0/src/scsi/cdbs/inquiry.rs +225 -0
  71. nkscan-0.1.0/src/scsi/cdbs/mod.rs +22 -0
  72. nkscan-0.1.0/src/scsi/cdbs/mode_select.rs +60 -0
  73. nkscan-0.1.0/src/scsi/cdbs/mode_sense.rs +280 -0
  74. nkscan-0.1.0/src/scsi/cdbs/read_send.rs +255 -0
  75. nkscan-0.1.0/src/scsi/cdbs/reservation.rs +130 -0
  76. nkscan-0.1.0/src/scsi/cdbs/scan.rs +99 -0
  77. nkscan-0.1.0/src/scsi/cdbs/send_diagnostic.rs +120 -0
  78. nkscan-0.1.0/src/scsi/cdbs/test_unit_ready.rs +28 -0
  79. nkscan-0.1.0/src/scsi/cdbs/window.rs +490 -0
  80. nkscan-0.1.0/src/scsi/fields.rs +47 -0
  81. nkscan-0.1.0/src/scsi/linux.rs +394 -0
  82. nkscan-0.1.0/src/scsi/macos.rs +34 -0
  83. nkscan-0.1.0/src/scsi/mock.rs +223 -0
  84. nkscan-0.1.0/src/scsi/mod.rs +380 -0
  85. nkscan-0.1.0/src/scsi/mode_pages/measurement_units.rs +147 -0
  86. nkscan-0.1.0/src/scsi/mode_pages/mod.rs +45 -0
  87. nkscan-0.1.0/src/scsi/usb.rs +253 -0
  88. nkscan-0.1.0/src/scsi/windows.rs +289 -0
  89. nkscan-0.1.0/src/session/ls50.rs +219 -0
  90. nkscan-0.1.0/src/session/ls5000.rs +236 -0
  91. nkscan-0.1.0/src/session/ls9000.rs +295 -0
  92. nkscan-0.1.0/src/session/mod.rs +597 -0
nkscan-0.1.0/.envrc ADDED
@@ -0,0 +1 @@
1
+ use flake
@@ -0,0 +1,135 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ paths-ignore: &docs-paths
7
+ - "**.md"
8
+ - "LICENSE-*"
9
+ pull_request:
10
+ branches: [main]
11
+ paths-ignore: *docs-paths
12
+ workflow_dispatch:
13
+
14
+ # Cancel superseded runs for the same branch/PR - these nix jobs are heavy.
15
+ concurrency:
16
+ group: ci-${{ github.ref }}
17
+ cancel-in-progress: true
18
+
19
+ permissions:
20
+ contents: read
21
+ packages: write
22
+
23
+ jobs:
24
+ check:
25
+ name: Nix Flake Check
26
+ runs-on: ubuntu-latest
27
+ permissions:
28
+ contents: read
29
+ security-events: write # upload clippy findings as code scanning results
30
+ steps:
31
+ - name: Checkout repository
32
+ uses: actions/checkout@v4
33
+
34
+ - name: Install Nix
35
+ uses: DeterminateSystems/nix-installer-action@v13
36
+
37
+ - name: Setup Nix cache
38
+ uses: DeterminateSystems/magic-nix-cache-action@v7
39
+
40
+ - name: Run flake checks
41
+ run: nix flake check --print-build-logs --keep-going
42
+
43
+ # The stub is what a consumer sees of an abi3 extension, since one carries no introspectable
44
+ # signatures. It is generated, so this only has to catch a commit that forgot to regenerate.
45
+ stubs:
46
+ name: Stub is up to date
47
+ runs-on: ubuntu-latest
48
+ steps:
49
+ - name: Checkout repository
50
+ uses: actions/checkout@v4
51
+
52
+ - name: Install Rust
53
+ uses: dtolnay/rust-toolchain@master
54
+ with:
55
+ toolchain: "1.96"
56
+
57
+ - name: Cache Rust artifacts
58
+ uses: Swatinem/rust-cache@v2
59
+
60
+ # pyo3 needs an interpreter to build against. numpy is not needed: the generator
61
+ # reads type information rather than calling into it.
62
+ - name: Install Python
63
+ uses: actions/setup-python@v5
64
+ with:
65
+ python-version: "3.13"
66
+
67
+ - name: Regenerate
68
+ run: cargo run --features python --bin stub_gen
69
+
70
+ - name: Fail if it differs from what is committed
71
+ run: |
72
+ if ! git diff --exit-code nkscan.pyi; then
73
+ echo "::error::nkscan.pyi is stale, run: cargo run --features python --bin stub_gen"
74
+ exit 1
75
+ fi
76
+
77
+ # The flake checks that the bindings compile, but only a manylinux build proves the wheel a
78
+ # consumer would actually install. Nix cannot produce one: it links against nix-store glibc
79
+ # with nix-store rpaths, and the result is tagged linux_x86_64, which no index accepts.
80
+ #
81
+ # Run on every change rather than at tag time, when a release is already half published.
82
+ wheel:
83
+ name: Build wheel
84
+ runs-on: ubuntu-latest
85
+ steps:
86
+ - name: Checkout repository
87
+ uses: actions/checkout@v4
88
+
89
+ - name: Build wheel
90
+ uses: PyO3/maturin-action@v1
91
+ with:
92
+ args: --release --out dist
93
+ manylinux: auto
94
+
95
+ # The runner's default python is older than the abi3 floor, so pip would refuse a
96
+ # cp313 wheel. Both versions are installed to prove the point of abi3: one wheel
97
+ # covers the floor and every interpreter after it.
98
+ - name: Install the interpreters the wheel claims to support
99
+ uses: actions/setup-python@v5
100
+ with:
101
+ python-version: |
102
+ 3.13
103
+ 3.14
104
+
105
+ - name: Check it is tagged for redistribution
106
+ run: |
107
+ ls -l dist/
108
+ # abi3 names one interpreter floor and works on every later one, so a wheel
109
+ # tagged for a single version means the abi3 feature stopped taking effect
110
+ for wheel in dist/*.whl; do
111
+ case "$wheel" in
112
+ *abi3-manylinux*) echo "ok: $wheel" ;;
113
+ *) echo "::error::$wheel will not install off this machine" && exit 1 ;;
114
+ esac
115
+ done
116
+
117
+ - name: Check it installs and imports on every one of them
118
+ run: |
119
+ for python in python3.13 python3.14; do
120
+ echo "--- $python"
121
+ "$python" -m pip install --upgrade pip
122
+ "$python" -m pip install dist/*.whl
123
+ "$python" - <<'PY'
124
+ import nkscan, sys
125
+ print(" running on", sys.version.split()[0])
126
+ # No scanner is attached to a runner, so this exercises enumeration finding none
127
+ assert nkscan.list_devices() == []
128
+ assert issubclass(nkscan.TransportError, nkscan.TransientError)
129
+ try:
130
+ nkscan.Session("nonsense")
131
+ except nkscan.DeviceNotFound:
132
+ pass
133
+ print(" import, enumeration and error hierarchy all fine")
134
+ PY
135
+ done
@@ -0,0 +1,178 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ permissions:
9
+ contents: write
10
+ packages: write
11
+
12
+ jobs:
13
+ build-linux:
14
+ name: Build Linux artifacts
15
+ runs-on: ubuntu-latest
16
+ steps:
17
+ - name: Checkout repository
18
+ uses: actions/checkout@v4
19
+
20
+ - name: Install Nix
21
+ uses: DeterminateSystems/nix-installer-action@v13
22
+
23
+ - name: Setup Nix cache
24
+ uses: DeterminateSystems/magic-nix-cache-action@v7
25
+
26
+ - name: Build x86_64 binary
27
+ run: |
28
+ nix build --print-build-logs
29
+ cp result/bin/nkscan nkscan-x86_64-unknown-linux-gnu
30
+
31
+ - name: Upload Linux binaries to release
32
+ uses: softprops/action-gh-release@v2
33
+ with:
34
+ files: |
35
+ nkscan-x86_64-unknown-linux-gnu
36
+
37
+ build-windows:
38
+ name: Build Windows artifact
39
+ runs-on: windows-latest
40
+ steps:
41
+ - name: Checkout repository
42
+ uses: actions/checkout@v4
43
+
44
+ - name: Install Rust
45
+ uses: dtolnay/rust-toolchain@master
46
+ with:
47
+ toolchain: "1.96"
48
+
49
+ - name: Cache Rust artifacts
50
+ uses: Swatinem/rust-cache@v2
51
+
52
+ - name: Build Windows binary
53
+ run: |
54
+ cargo build --release -p nkscan --features=cli
55
+ cp target/release/nkscan.exe nkscan-x86_64-pc-windows-msvc.exe
56
+
57
+ - name: Upload Windows binary to release
58
+ uses: softprops/action-gh-release@v2
59
+ with:
60
+ files: nkscan-x86_64-pc-windows-msvc.exe
61
+
62
+ # ---- Python wheels
63
+ #
64
+ # maturin rather than nix: a nix-built extension links against nix-store glibc with
65
+ # nix-store rpaths and its wheel is tagged linux_x86_64, which no index accepts and which
66
+ # would not load off this machine anyway. maturin builds Linux wheels inside manylinux
67
+ # containers and runs auditwheel over the result.
68
+ #
69
+ # One wheel per platform, not per interpreter: the abi3-py313 feature makes a single build
70
+ # work on 3.13 and everything after it, which is the floor NegPy asks for.
71
+ wheels:
72
+ name: Wheel ${{ matrix.platform }} ${{ matrix.target }}
73
+ runs-on: ${{ matrix.runner }}
74
+ strategy:
75
+ fail-fast: false
76
+ matrix:
77
+ include:
78
+ - { platform: linux, runner: ubuntu-latest, target: x86_64 }
79
+ - { platform: linux, runner: ubuntu-latest, target: aarch64 }
80
+ - { platform: macos, runner: macos-latest, target: x86_64 }
81
+ - { platform: macos, runner: macos-latest, target: aarch64 }
82
+ - { platform: windows, runner: windows-latest, target: x64 }
83
+ steps:
84
+ - name: Checkout repository
85
+ uses: actions/checkout@v4
86
+
87
+ - name: Build wheel
88
+ uses: PyO3/maturin-action@v1
89
+ with:
90
+ target: ${{ matrix.target }}
91
+ args: --release --out dist
92
+ # Cross-compiles the aarch64 Linux wheel in a manylinux container
93
+ manylinux: auto
94
+ sccache: "true"
95
+
96
+ - name: Upload wheel
97
+ uses: actions/upload-artifact@v4
98
+ with:
99
+ name: wheel-${{ matrix.platform }}-${{ matrix.target }}
100
+ path: dist
101
+
102
+ # A version on PyPI can never be reused, and maturin takes the version from Cargo.toml
103
+ # rather than from the tag, so a mistyped tag would otherwise publish the wrong one.
104
+ version:
105
+ name: Tag matches Cargo.toml
106
+ runs-on: ubuntu-latest
107
+ steps:
108
+ - name: Checkout repository
109
+ uses: actions/checkout@v4
110
+
111
+ - name: Compare
112
+ run: |
113
+ crate=$(sed -n 's/^version = "\(.*\)"/\1/p' Cargo.toml | head -1)
114
+ tag=${GITHUB_REF_NAME#v}
115
+ echo "Cargo.toml says $crate, tag says $tag"
116
+ if [ "$crate" != "$tag" ]; then
117
+ echo "::error::tag $GITHUB_REF_NAME does not match Cargo.toml version $crate"
118
+ exit 1
119
+ fi
120
+
121
+ sdist:
122
+ name: Source distribution
123
+ runs-on: ubuntu-latest
124
+ steps:
125
+ - name: Checkout repository
126
+ uses: actions/checkout@v4
127
+
128
+ - name: Build sdist
129
+ uses: PyO3/maturin-action@v1
130
+ with:
131
+ command: sdist
132
+ args: --out dist
133
+
134
+ - name: Upload sdist
135
+ uses: actions/upload-artifact@v4
136
+ with:
137
+ name: wheel-sdist
138
+ path: dist
139
+
140
+ publish:
141
+ name: Publish to PyPI
142
+ needs: [version, wheels, sdist]
143
+ runs-on: ubuntu-latest
144
+ environment: pypi
145
+ permissions:
146
+ # Trusted publishing: PyPI verifies this workflow by OIDC, so there is no long-lived
147
+ # token in the repository. Register the publisher once at
148
+ # pypi.org/manage/account/publishing with owner, repo and this workflow's filename.
149
+ id-token: write
150
+ steps:
151
+ - name: Collect every wheel and the sdist
152
+ uses: actions/download-artifact@v4
153
+ with:
154
+ pattern: wheel-*
155
+ path: dist
156
+ merge-multiple: true
157
+
158
+ - name: Publish
159
+ uses: pypa/gh-action-pypi-publish@release/v1
160
+ with:
161
+ packages-dir: dist
162
+
163
+ attach-wheels:
164
+ name: Attach wheels to the release
165
+ needs: [version, wheels, sdist]
166
+ runs-on: ubuntu-latest
167
+ steps:
168
+ - name: Collect every wheel and the sdist
169
+ uses: actions/download-artifact@v4
170
+ with:
171
+ pattern: wheel-*
172
+ path: dist
173
+ merge-multiple: true
174
+
175
+ - name: Upload to release
176
+ uses: softprops/action-gh-release@v2
177
+ with:
178
+ files: dist/*
@@ -0,0 +1,5 @@
1
+ /target
2
+ .direnv
3
+ *.tiff
4
+ nkscan-wb.txt
5
+ result
@@ -0,0 +1,38 @@
1
+ # Contributing to this project
2
+
3
+ All help is welcome and greatly appreciated!
4
+ If you would like to contribute to the project, we ask you adhere to the following policies:
5
+
6
+ ## Before you open a PR
7
+
8
+ ```sh
9
+ cargo fmt
10
+ cargo clippy --all-targets # should be silent
11
+ cargo test
12
+ rg -nP '[^\x00-\x7F]' src/ examples/ # should find nothing
13
+ ```
14
+
15
+ The source is ASCII only. No em dashes, smart quotes or arrows, in code or comments.
16
+
17
+ ## AI Assistance
18
+
19
+ Using AI tools to help you contribute is nominally ok, we just want to remind you that
20
+ *you* are asking the maintainers (human people) review your code and you need to be in the loop of that process.
21
+ As such, we ask that you use AI as a tool to help you write code, not as an agent that autonomously generates
22
+ an entire contribution and submits it on your behalf.
23
+
24
+ A few simple expectations:
25
+
26
+ - **Understand your code.** You should be able to explain and answer questions about anything you submit.
27
+ - **Write the PR description in your own words.** A short, clear explanation of *your* change is far more useful than a pasted AI summary.
28
+ - **Test your change** before opening the PR.
29
+ - **Keep it focused.** A PR that claims to fix one thing but touches a lot of unrelated code is hard to review (broad prompts tend to cause this).
30
+ - **Disclose AI assistance** in the PR description, along with roughly how much was used (e.g. docs only vs. code generation). Trivial tab-completion of single keywords or short phrases doesn't need to be disclosed.
31
+
32
+ Example disclosures:
33
+
34
+ > **AI Disclosure:** This PR was written primarily by Claude Code.
35
+ > **AI Disclosure:** I consulted ChatGPT to understand the codebase, but the solution was authored manually.
36
+ > **AI Disclosure:** None.
37
+
38
+ Disclosure isn't about discouraging AI use,it just helps reviewers know how much scrutiny a change needs, and it's a courtesy to the humans on the other end of the pull request.