Skip to content

Commit 30222ce

Browse files
committed
Merge branch 'main' into pr/1372
2 parents bdbeb1b + 1506972 commit 30222ce

File tree

230 files changed

+5653
-2908
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

230 files changed

+5653
-2908
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,8 @@ jobs:
103103
settings:
104104
- target: aarch64-apple-darwin
105105
runner: macos-latest
106-
# Windows can't take the disk usage lol
107-
# - target: x86_64-pc-windows-msvc
108-
# runner: windows-latest
106+
- target: x86_64-pc-windows-msvc
107+
runner: windows-latest
109108
runs-on: ${{ matrix.settings.runner }}
110109
permissions:
111110
contents: read

.vscode/extensions.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
"recommendations": ["tauri-apps.tauri-vscode", "rust-lang.rust-analyzer"]
2+
"recommendations": ["biomejs.biome", "rust-lang.rust-analyzer"]
33
}

AGENTS.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,26 @@
2222
- Runtime: Node 20, pnpm 10.x, Rust 1.88+, Docker for MySQL/MinIO.
2323
- **NO COMMENTS**: Never add comments to code (`//`, `/* */`, `///`, `//!`, `#`, etc.). Code must be self-explanatory through naming, types, and structure. This applies to all languages (TypeScript, Rust, JavaScript, etc.).
2424

25+
## Rust Clippy Rules (Workspace Lints)
26+
All Rust code must respect these workspace-level lints defined in `Cargo.toml`:
27+
28+
**Rust compiler lints:**
29+
- `unused_must_use = "deny"` — Always handle `Result`/`Option` or types marked `#[must_use]`; never ignore them.
30+
31+
**Clippy lints (all denied):**
32+
- `dbg_macro` — Never use `dbg!()` in code; use proper logging instead.
33+
- `let_underscore_future` — Never write `let _ = async_fn()` which silently drops futures; await or explicitly handle them.
34+
- `unchecked_duration_subtraction` — Use `saturating_sub` instead of `-` for `Duration` to avoid panics.
35+
- `collapsible_if` — Merge nested `if` statements: use `if a && b { }` instead of `if a { if b { } }`.
36+
- `clone_on_copy` — Don't call `.clone()` on `Copy` types; just copy them directly.
37+
- `redundant_closure` — Use function references directly: `iter.map(foo)` instead of `iter.map(|x| foo(x))`.
38+
- `ptr_arg` — Accept `&[T]` or `&str` instead of `&Vec<T>` or `&String` in function parameters.
39+
- `len_zero` — Use `.is_empty()` instead of `.len() == 0` or `.len() > 0`.
40+
- `let_unit_value` — Don't assign `()` to a variable: write `foo();` instead of `let _ = foo();` when return is unit.
41+
- `unnecessary_lazy_evaluations` — Use `.unwrap_or(val)` instead of `.unwrap_or_else(|| val)` for cheap values.
42+
- `needless_range_loop` — Use `for item in &collection` instead of `for i in 0..collection.len()` when index isn't needed.
43+
- `manual_clamp` — Use `.clamp(min, max)` instead of manual `if` chains or `.min().max()` patterns.
44+
2545
## Testing
2646
- TS/JS: Vitest where present (e.g., desktop). Name tests `*.test.ts(x)` near sources.
2747
- Rust: `cargo test` per crate; tests in `src` or `tests`.

CLAUDE.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,66 @@ Minimize `useEffect` usage: compute during render, handle logic in event handler
371371
- Strict TypeScript; avoid `any`; leverage shared types
372372
- Use Biome for linting/formatting; match existing formatting
373373

374+
## Rust Clippy Rules (Workspace Lints)
375+
All Rust code must respect these workspace-level lints defined in `Cargo.toml`. Violating any of these will fail CI:
376+
377+
**Rust compiler lints:**
378+
- `unused_must_use = "deny"` — Always handle `Result`/`Option` or types marked `#[must_use]`; never ignore them.
379+
380+
**Clippy lints (all denied — code MUST NOT contain these patterns):**
381+
- `dbg_macro` — Never use `dbg!()` in code; use proper logging (`tracing::debug!`, etc.) instead.
382+
- `let_underscore_future` — Never write `let _ = async_fn()` which silently drops futures; await or explicitly handle them.
383+
- `unchecked_duration_subtraction` — Use `duration.saturating_sub(other)` instead of `duration - other` to avoid panics on underflow.
384+
- `collapsible_if` — Merge nested `if` statements: write `if a && b { }` instead of `if a { if b { } }`.
385+
- `clone_on_copy` — Don't call `.clone()` on `Copy` types (integers, bools, etc.); just copy them directly.
386+
- `redundant_closure` — Use function references directly: `iter.map(foo)` instead of `iter.map(|x| foo(x))`.
387+
- `ptr_arg` — Accept `&[T]` or `&str` instead of `&Vec<T>` or `&String` in function parameters for flexibility.
388+
- `len_zero` — Use `.is_empty()` instead of `.len() == 0` or `.len() > 0` / `.len() != 0`.
389+
- `let_unit_value` — Don't assign `()` to a variable: write `foo();` instead of `let _ = foo();` or `let x = foo();` when return is unit.
390+
- `unnecessary_lazy_evaluations` — Use `.unwrap_or(val)` instead of `.unwrap_or_else(|| val)` when the default is a simple/cheap value.
391+
- `needless_range_loop` — Use `for item in &collection` or `for (i, item) in collection.iter().enumerate()` instead of `for i in 0..collection.len()`.
392+
- `manual_clamp` — Use `value.clamp(min, max)` instead of manual `if` chains or `.min(max).max(min)` patterns.
393+
394+
**Examples of violations to avoid:**
395+
396+
```rust
397+
dbg!(value);
398+
let _ = some_async_function();
399+
let duration = duration_a - duration_b;
400+
if condition {
401+
if other_condition {
402+
do_something();
403+
}
404+
}
405+
let x = 5.clone();
406+
vec.iter().map(|x| process(x))
407+
fn example(v: &Vec<i32>) { }
408+
if vec.len() == 0 { }
409+
let _ = returns_unit();
410+
option.unwrap_or_else(|| 42)
411+
for i in 0..vec.len() { println!("{}", vec[i]); }
412+
value.min(max).max(min)
413+
```
414+
415+
**Correct alternatives:**
416+
417+
```rust
418+
tracing::debug!(?value);
419+
some_async_function().await;
420+
let duration = duration_a.saturating_sub(duration_b);
421+
if condition && other_condition {
422+
do_something();
423+
}
424+
let x = 5;
425+
vec.iter().map(process)
426+
fn example(v: &[i32]) { }
427+
if vec.is_empty() { }
428+
returns_unit();
429+
option.unwrap_or(42)
430+
for item in &vec { println!("{}", item); }
431+
value.clamp(min, max)
432+
```
433+
374434
## Security & Privacy Considerations
375435

376436
### Data Handling

Cargo.lock

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/desktop/scripts/prepare.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ async function semverToWIXCompatibleVersion(cargoFilePath) {
3131
let build = 0;
3232
if (buildOrPrerelease) {
3333
const numMatch = buildOrPrerelease.match(/\d+$/);
34-
build = numMatch ? parseInt(numMatch[0]) : 0;
34+
build = numMatch ? parseInt(numMatch[0], 10) : 0;
3535
}
3636
const wixVersion = `${major}.${minor}.${patch}${
3737
build === 0 ? "" : `.${build}`

apps/desktop/src-tauri/src/audio_meter.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,6 @@ fn samples_to_f64(samples: &MicrophoneSamples) -> impl Iterator<Item = f64> + us
140140
SampleFormat::F64 => f64::from_ne_bytes([
141141
data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7],
142142
]),
143-
_ => todo!(),
143+
_ => 0.0,
144144
})
145145
}

apps/desktop/src-tauri/src/camera.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@ pub enum CameraPreviewShape {
4343

4444
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Type)]
4545
pub struct CameraPreviewState {
46-
size: f32,
47-
shape: CameraPreviewShape,
48-
mirrored: bool,
46+
pub size: f32,
47+
pub shape: CameraPreviewShape,
48+
pub mirrored: bool,
4949
}
5050

5151
impl Default for CameraPreviewState {
@@ -123,6 +123,11 @@ impl CameraPreviewManager {
123123
) -> anyhow::Result<()> {
124124
let (camera_tx, camera_rx) = flume::bounded(4);
125125

126+
actor
127+
.ask(feeds::camera::AddSender(camera_tx))
128+
.await
129+
.context("Error attaching camera feed consumer")?;
130+
126131
let default_state = self
127132
.get_state()
128133
.map_err(|err| error!("Error getting camera preview state: {err}"))
@@ -144,11 +149,6 @@ impl CameraPreviewManager {
144149

145150
self.preview = Some(InitializedCameraPreview { reconfigure });
146151

147-
actor
148-
.ask(feeds::camera::AddSender(camera_tx))
149-
.await
150-
.context("Error attaching camera feed consumer")?;
151-
152152
Ok(())
153153
}
154154

0 commit comments

Comments
 (0)