Skip to content

Commit 91c03aa

Browse files
authored
Merge pull request #8 from csd113/dev
## Chan-Net API (NEW) api.rs / network layer # What Why 1 Added listener mode via CLI flag (-chan-net -listen) Allows RustWave/RustChan pipeline to operate in passive receive mode 2 Implemented POST /chan/import endpoint Accepts zipped database payloads for cross-node synchronization 3 Zip extraction to temp dir before processing Prevents partial writes and enables validation before DB interaction 4 SQLite magic byte validation before import Rejects invalid/corrupt payloads safely before processing 5 Reuses existing import/restore pipeline Avoids duplication and keeps DB logic consistent 6 Introduced mode separation (Full vs Listener) Clean architecture boundary between active node and passive receiver 7 Listener mode disables outbound/export behavior Reduces attack surface and enforces one-way data flow 8 Optional GET /chan/status endpoint Provides basic health/status visibility for remote systems integration (rustwave ↔ rustchan) # What Why 1 Standardized zip-based payload format Simple, transport-agnostic data exchange 2 Defined pipeline: decode → import Aligns with audio transport system design 3 Separated responsibilities (data vs transport) RustChan handles DB; RustWave handles encoding/audio
2 parents a93b8b7 + b3f781e commit 91c03aa

18 files changed

Lines changed: 2217 additions & 126 deletions

Cargo.lock

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

Cargo.toml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,36 @@ name = "rustwave-cli"
1010
path = "src/main.rs"
1111

1212
[dependencies]
13+
# — existing —
1314
clap = { version = "4", features = ["derive"] }
1415
hound = "3"
1516
eframe = "0.31"
17+
18+
# — NEW: async runtime (required for axum) —
19+
tokio = { version = "1", features = ["full"] }
20+
21+
# — NEW: HTTP server —
22+
axum = { version = "0.7", features = ["multipart"] }
23+
tower = "0.4"
24+
tower-http = { version = "0.5", features = ["cors", "limit"] }
25+
26+
# — NEW: HTTP client (forward WAV to Broadcaster) —
27+
reqwest = { version = "0.12", features = ["multipart", "json"] }
28+
29+
# — NEW: serialisation —
30+
serde = { version = "1", features = ["derive"] }
31+
serde_json = "1"
32+
33+
# — NEW: UUID generation for tx_id / queued_id —
34+
uuid = { version = "1", features = ["v4", "serde"] }
35+
36+
# — NEW: logging / tracing —
37+
tracing = "0.1"
38+
tracing-subscriber = { version = "0.3", features = ["env-filter", "json"] }
39+
tracing-appender = "0.2"
40+
41+
# — NEW: in-memory byte buffers (WAV bytes without temp files) —
42+
bytes = "1"
43+
44+
# — NEW: error propagation in run_server —
45+
anyhow = "1"

dev-check-strict.sh

Lines changed: 99 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#!/usr/bin/env bash
2-
# dev-check.sh — full Rust quality gate
2+
# dev-check.sh — full Rust quality gate (macOS)
33
# Runs: fmt · fix · clippy (pedantic+nursery) · tests · audit · deny · dupes
44
# Produces per-file clustered clippy reports in clippy_reports/
55

@@ -8,10 +8,21 @@ set -Eeuo pipefail
88
# ─── Colours ──────────────────────────────────────────────────────────────────
99

1010
if [[ -t 1 ]]; then
11-
RED='\033[0;31m'; YELLOW='\033[0;33m'; GREEN='\033[0;32m'
12-
CYAN='\033[0;36m'; BOLD='\033[1m'; DIM='\033[2m'; RESET='\033[0m'
11+
RED='\033[0;31m'
12+
YELLOW='\033[0;33m'
13+
GREEN='\033[0;32m'
14+
CYAN='\033[0;36m'
15+
BOLD='\033[1m'
16+
DIM='\033[2m'
17+
RESET='\033[0m'
1318
else
14-
RED=''; YELLOW=''; GREEN=''; CYAN=''; BOLD=''; DIM=''; RESET=''
19+
RED=''
20+
YELLOW=''
21+
GREEN=''
22+
CYAN=''
23+
BOLD=''
24+
DIM=''
25+
RESET=''
1526
fi
1627

1728
# ─── Globals ──────────────────────────────────────────────────────────────────
@@ -29,7 +40,9 @@ SUMMARY_FILE="$REPORT_DIR/summary.txt"
2940

3041
# ─── Helpers ──────────────────────────────────────────────────────────────────
3142

32-
command_exists() { command -v "$1" >/dev/null 2>&1; }
43+
has_cmd() {
44+
type -P "$1" >/dev/null 2>&1
45+
}
3346

3447
step() {
3548
echo ""
@@ -38,44 +51,52 @@ step() {
3851

3952
pass() {
4053
echo -e " ${GREEN}${RESET} $1"
41-
(( PASS_COUNT++ )) || true
54+
PASS_COUNT=$(( PASS_COUNT + 1 ))
4255
}
4356

4457
fail() {
4558
echo -e " ${RED}${RESET} $1"
46-
(( FAIL_COUNT++ )) || true
59+
FAIL_COUNT=$(( FAIL_COUNT + 1 ))
4760
FAILED_STEPS+=("$1")
4861
}
4962

5063
skip() {
5164
echo -e " ${DIM}${RESET} $1 ${DIM}(skipped — tool not installed)${RESET}"
52-
(( SKIP_COUNT++ )) || true
65+
SKIP_COUNT=$(( SKIP_COUNT + 1 ))
5366
}
5467

55-
warn() { echo -e " ${YELLOW}${RESET} $1"; }
56-
57-
require_tool() {
58-
local tool="$1" install_hint="$2"
59-
if ! command_exists "$tool"; then
60-
echo -e "${RED}Error:${RESET} required tool '${BOLD}$tool${RESET}' is not installed."
61-
echo -e " Install with: ${DIM}$install_hint${RESET}"
62-
exit 1
63-
fi
68+
warn() {
69+
echo -e " ${YELLOW}${RESET} $1"
6470
}
6571

66-
optional_tool() {
67-
local tool="$1" install_hint="$2"
68-
if ! command_exists "$tool"; then
69-
warn "'$tool' not installed — step will be skipped."
70-
warn "Install with: $install_hint"
71-
fi
72+
die() {
73+
echo -e "${RED}Error:${RESET} $1"
74+
echo -e " Install with: ${DIM}$2${RESET}"
75+
exit 1
7276
}
7377

7478
elapsed() {
7579
local secs=$(( SECONDS - SCRIPT_START ))
7680
printf '%dm%02ds' $(( secs / 60 )) $(( secs % 60 ))
7781
}
7882

83+
# ─── Strip cargo noise from clippy output ─────────────────────────────────────
84+
85+
filter_clippy() {
86+
grep -Ev \
87+
'^[[:space:]]*(Compiling|Checking|Downloading|Updating|Fresh|Finished|Blocking|Locking|Dirty|Scraping|Running|Doctest)[[:space:]]' \
88+
| grep -Ev \
89+
'^[[:space:]]*= note: `#\[' \
90+
| grep -Ev \
91+
'^warning: [0-9]+ warning(s)? emitted' \
92+
| grep -Ev \
93+
'^error: aborting due to' \
94+
| grep -Ev \
95+
'^[[:space:]]*= note: for more information' \
96+
| sed '/^[[:space:]]*$/d' \
97+
|| true
98+
}
99+
79100
# ─── Header ───────────────────────────────────────────────────────────────────
80101

81102
echo -e "${BOLD}"
@@ -84,30 +105,44 @@ echo "║ Rust Full Quality Gate Check ║"
84105
echo "╚══════════════════════════════════════════════════╝"
85106
echo -e "${RESET}"
86107

87-
# ─── CPU cores ────────────────────────────────────────────────────────────────
108+
# ─── CPU cores (macOS-aware) ──────────────────────────────────────────────────
88109

89-
if command_exists sysctl; then
90-
export CARGO_BUILD_JOBS; CARGO_BUILD_JOBS=$(sysctl -n hw.ncpu 2>/dev/null || echo 4)
91-
elif command_exists nproc; then
92-
export CARGO_BUILD_JOBS; CARGO_BUILD_JOBS=$(nproc)
93-
else
94-
export CARGO_BUILD_JOBS=4
95-
fi
110+
export CARGO_BUILD_JOBS
111+
CARGO_BUILD_JOBS=$(sysctl -n hw.logicalcpu 2>/dev/null || echo 4)
96112
echo -e " ${DIM}Using ${BOLD}${CARGO_BUILD_JOBS}${RESET}${DIM} CPU cores${RESET}"
97113

98114
# ─── Required tools ───────────────────────────────────────────────────────────
99115

100116
step "Verifying required tools"
101117

102-
require_tool "cargo" "https://rustup.rs"
103-
require_tool "rustfmt" "rustup component add rustfmt"
104-
require_tool "clippy-driver" "rustup component add clippy"
118+
if ! has_cmd cargo; then
119+
die "required tool 'cargo' is not installed." "https://rustup.rs"
120+
fi
121+
122+
if ! has_cmd rustfmt; then
123+
die "required tool 'rustfmt' is not installed." "rustup component add rustfmt"
124+
fi
125+
126+
# clippy-driver is not always on PATH on macOS — check via cargo subcommand instead
127+
if ! cargo clippy --version >/dev/null 2>&1; then
128+
die "required tool 'clippy' is not installed." "rustup component add clippy"
129+
fi
130+
105131
pass "cargo · rustfmt · clippy all present"
106132

107-
optional_tool "cargo-audit" "cargo install cargo-audit"
108-
optional_tool "cargo-deny" "cargo install cargo-deny"
109-
optional_tool "cargo-udeps" "cargo install cargo-udeps"
110-
optional_tool "cargo-msrv" "cargo install cargo-msrv"
133+
# Optional tools — warn but do not exit
134+
if ! has_cmd cargo-audit; then
135+
warn "'cargo-audit' not installed — step will be skipped. cargo install cargo-audit"
136+
fi
137+
if ! has_cmd cargo-deny; then
138+
warn "'cargo-deny' not installed — step will be skipped. cargo install cargo-deny"
139+
fi
140+
if ! has_cmd cargo-udeps; then
141+
warn "'cargo-udeps' not installed — step will be skipped. cargo install cargo-udeps"
142+
fi
143+
if ! has_cmd cargo-msrv; then
144+
warn "'cargo-msrv' not installed — step will be skipped. cargo install cargo-msrv"
145+
fi
111146

112147
# ─── Prepare report directory ─────────────────────────────────────────────────
113148

@@ -118,7 +153,11 @@ mkdir -p "$CLUSTER_DIR"
118153

119154
if [[ "${1:-}" == "--update" ]]; then
120155
step "Updating dependency index"
121-
if cargo update 2>&1; then pass "cargo update"; else fail "cargo update"; fi
156+
if cargo update 2>&1; then
157+
pass "cargo update"
158+
else
159+
fail "cargo update"
160+
fi
122161
fi
123162

124163
# ─── 1. Format ────────────────────────────────────────────────────────────────
@@ -131,7 +170,6 @@ else
131170
fail "cargo fmt --all"
132171
fi
133172

134-
# Verify nothing was left dirty (useful in CI)
135173
if git diff --quiet 2>/dev/null; then
136174
pass "No unstaged format changes"
137175
else
@@ -153,42 +191,25 @@ fi
153191
step "3 · Lint (cargo clippy — pedantic + nursery)"
154192

155193
CLIPPY_FLAGS=(
156-
# Hard errors
157194
"-D" "warnings"
158-
159-
# Pedantic: correctness, performance, style improvements
160195
"-W" "clippy::pedantic"
161-
162-
# Nursery: newer lints, some may be noisy — catches subtle bugs early
163196
"-W" "clippy::nursery"
164-
165-
# Catch common correctness bugs missed by the default set
166197
"-W" "clippy::correctness"
167198
"-W" "clippy::suspicious"
168199
"-W" "clippy::complexity"
169200
"-W" "clippy::perf"
170-
171-
# Panic/unwrap hygiene — forces explicit error handling
172201
"-W" "clippy::unwrap_used"
173202
"-W" "clippy::expect_used"
174203
"-W" "clippy::panic"
175204
"-W" "clippy::todo"
176205
"-W" "clippy::unimplemented"
177206
"-W" "clippy::unreachable"
178-
179-
# Index panic risk
180207
"-W" "clippy::indexing_slicing"
181-
182-
# Integer overflow in casts
183208
"-W" "clippy::cast_possible_truncation"
184209
"-W" "clippy::cast_possible_wrap"
185210
"-W" "clippy::cast_sign_loss"
186211
"-W" "clippy::cast_precision_loss"
187-
188-
# Arithmetic that can panic
189212
"-W" "clippy::arithmetic_side_effects"
190-
191-
# Formatting / style discipline
192213
"-W" "clippy::format_collect"
193214
"-W" "clippy::uninlined_format_args"
194215
"-W" "clippy::redundant_closure_for_method_calls"
@@ -209,6 +230,7 @@ CLIPPY_CMD=(
209230
cargo clippy
210231
--all-targets
211232
--all-features
233+
--message-format=short
212234
--
213235
"${CLIPPY_FLAGS[@]}"
214236
)
@@ -217,14 +239,17 @@ echo -e " ${DIM}Running: ${CLIPPY_CMD[*]}${RESET}"
217239
echo ""
218240

219241
CLIPPY_EXIT=0
220-
"${CLIPPY_CMD[@]}" 2>&1 | tee "$RAW_FILE" || CLIPPY_EXIT=$?
242+
"${CLIPPY_CMD[@]}" 2>&1 \
243+
| filter_clippy \
244+
| tee "$RAW_FILE" \
245+
|| CLIPPY_EXIT=${PIPESTATUS[0]}
221246

222-
# ── Cluster clippy output by source file ─────────────────────────────────────
247+
# ── Cluster clippy output by source file ─────────────────────────────────────
223248

224249
echo ""
225250
echo -e " ${DIM}Clustering clippy output by file...${RESET}"
226251

227-
OUTFILE=""
252+
CURRENT_OUTFILE=""
228253
while IFS= read -r line; do
229254
if [[ $line =~ ([a-zA-Z0-9_/.-]+\.rs):[0-9]+:[0-9]+ ]]; then
230255
FILE="${BASH_REMATCH[1]}"
@@ -234,16 +259,16 @@ while IFS= read -r line; do
234259
else
235260
CLUSTER=$(echo "$DIR" | tr '/' '_')
236261
fi
237-
OUTFILE="$CLUSTER_DIR/${CLUSTER}.txt"
262+
CURRENT_OUTFILE="$CLUSTER_DIR/${CLUSTER}.txt"
238263
{
239264
echo ""
240265
echo "----------------------------------------"
241266
echo "FILE: $FILE"
242267
echo "----------------------------------------"
243-
} >> "$OUTFILE"
268+
} >> "$CURRENT_OUTFILE"
244269
fi
245-
if [[ -n "$OUTFILE" ]]; then
246-
echo "$line" >> "$OUTFILE"
270+
if [[ -n "$CURRENT_OUTFILE" ]]; then
271+
echo "$line" >> "$CURRENT_OUTFILE"
247272
fi
248273
done < "$RAW_FILE"
249274

@@ -273,7 +298,6 @@ TEST_EXIT=0
273298
cargo test --all --all-features 2>&1 || TEST_EXIT=$?
274299

275300
if [[ $TEST_EXIT -eq 0 ]]; then
276-
PASSED=$(grep -oP '\d+(?= passed)' <<< "$(cargo test --all --all-features 2>&1)" | tail -1 || echo "?")
277301
pass "All tests passed"
278302
else
279303
fail "Test suite failed (exit $TEST_EXIT)"
@@ -283,7 +307,7 @@ fi
283307

284308
step "5 · Security audit (cargo audit)"
285309

286-
if command_exists cargo-audit; then
310+
if has_cmd cargo-audit; then
287311
AUDIT_EXIT=0
288312
cargo audit 2>&1 || AUDIT_EXIT=$?
289313
if [[ $AUDIT_EXIT -eq 0 ]]; then
@@ -299,7 +323,7 @@ fi
299323

300324
step "6 · Dependency policy (cargo deny)"
301325

302-
if command_exists cargo-deny; then
326+
if has_cmd cargo-deny; then
303327
DENY_EXIT=0
304328
cargo deny check 2>&1 || DENY_EXIT=$?
305329
if [[ $DENY_EXIT -eq 0 ]]; then
@@ -315,7 +339,7 @@ fi
315339

316340
step "7 · Unused dependencies (cargo udeps)"
317341

318-
if command_exists cargo-udeps; then
342+
if has_cmd cargo-udeps; then
319343
UDEPS_EXIT=0
320344
cargo +nightly udeps --all-targets 2>&1 || UDEPS_EXIT=$?
321345
if [[ $UDEPS_EXIT -eq 0 ]]; then
@@ -331,7 +355,7 @@ fi
331355

332356
step "8 · Minimum supported Rust version (cargo msrv)"
333357

334-
if command_exists cargo-msrv; then
358+
if has_cmd cargo-msrv; then
335359
MSRV_EXIT=0
336360
cargo msrv verify 2>&1 || MSRV_EXIT=$?
337361
if [[ $MSRV_EXIT -eq 0 ]]; then
@@ -350,8 +374,8 @@ step "9 · Duplicate dependencies (cargo tree -d)"
350374
DUPES=$(cargo tree -d 2>&1 || true)
351375
if echo "$DUPES" | grep -q '\['; then
352376
warn "Duplicate crate versions detected:"
353-
echo "$DUPES" | grep '^\[' | sort -u | while read -r line; do
354-
echo -e " ${YELLOW}$line${RESET}"
377+
echo "$DUPES" | grep '^\[' | sort -u | while IFS= read -r line; do
378+
echo -e " ${YELLOW}${line}${RESET}"
355379
done
356380
else
357381
pass "No duplicate crate versions"
@@ -382,7 +406,9 @@ TOTAL_SECS=$(( SECONDS - SCRIPT_START ))
382406
if [[ ${#FAILED_STEPS[@]} -gt 0 ]]; then
383407
echo ""
384408
echo "Failed steps:"
385-
for s in "${FAILED_STEPS[@]}"; do echo " - $s"; done
409+
for s in "${FAILED_STEPS[@]}"; do
410+
echo " - $s"
411+
done
386412
fi
387413
} | tee "$SUMMARY_FILE"
388414

@@ -407,4 +433,4 @@ else
407433
echo ""
408434
echo -e " ${DIM}Reports saved to: $REPORT_DIR/${RESET}"
409435
exit 1
410-
fi
436+
fi

0 commit comments

Comments
 (0)