Skip to content

refactor(cache): bring PR #17 diff into rust-standards compliance - #19

Closed
vshengbro wants to merge 1 commit into
masterfrom
refactor/rust-standards-compliance
Closed

vshengbro wants to merge 1 commit into
masterfrom
refactor/rust-standards-compliance

Conversation

@vshengbro

Copy link
Copy Markdown
Collaborator

refactor(cache): bring PR #17 diff into rust-standards compliance

PR #17 (refactor(cache): replace regex resource extraction with HTML parser + JS AST) replaced the fragile regex-based resource discovery with scraper::Html + swc_ecma_parser, but the 870-line diff introduced three categories of rust-standards violations that would block reviewer approval:

1. R11.4 — four Selector::parse(...).unwrap() calls in extract_resources_with_scraper

  • Selector::parse("script[src]").unwrap() x 4 selectors
  • The selector strings are compile-time constants, so the panic is theoretical, but rust-standards bans unwrap / expect / panic! in production unconditionally and forbids #[allow]-macro lint silencing.
  • Fix: lazily-initialize a OnceLock<Result<[Selector; 4], String>> in cache/static.rs via RESOURCE_SELECTORS. The init_resource_selectors helper returns Result and Selector::parse(...) errors are converted via map_err(|e: SelectorErrorKind| e.to_string()) + ?. The caller matches on Result and early-returns with euv_log! if initialization fails.

2. R1.3c — hardcoded byte/string literals in fn.rs

  • 4 CSS selector strings: "script[src]", "link[href]", "img[src]", "script:not([src])"
  • 5 URL scheme prefixes: "http://", "https://", "data:", "//", "://"
  • 16 resource-extension suffixes: .wasm, .js, .mjs, .css, .json, .png, .jpg, .jpeg, .gif, .svg, .ico, .woff, .woff2, .ttf, .otf, .webp
  • Fix: move every one to cache/const.rs as pub(crate) const. The 16 extensions become a single RESOURCE_EXTENSIONS: &[&str] slice, and is_resource_path() becomes:
    RESOURCE_EXTENSIONS.iter().any(|s: &&str| value.ends_with(*s))
  • The three duplicate if !src.starts_with("http://") && !src.starts_with("https://") && !src.starts_with("//") && !src.starts_with("data:") && !paths.contains(...) blocks collapse into a single is_external_resource_url(url: &str) -> bool helper using HTTP_PREFIX / HTTPS_PREFIX / SCHEME_RELATIVE / DATA_PREFIX constants.

3. R6.4-pitfall-b — swc_ecma_ast::Expr / Lit / Callee / MemberProp / ... long-path calls in sub-file fn.rs

  • Sub-file fn.rs already has use super::*; and lib.rs already re-exports swc_ecma_ast::{EsVersion, Program} — but the new extract_resources_from_expr / _stmt / _js_ast / is_resource_path body uses 50+ long-path swc_ecma_ast::Variant patterns that should have been brought into the re-export block.
  • Fix: extend lib.rs pub(crate) use swc_ecma_ast::{...} to also expose ArrowFunctionBody, Callee, Decl, Expr, Lit, MemberProp, ModuleDecl, ModuleItem, Prop, PropOrSpread, Stmt, VarDeclOrExpr, and the corresponding swc_common::FileName + scraper::selector::SelectorErrorKind. Replace every swc_ecma_ast::xxx reference in fn.rs with the short name.

Verification

python3 ~/.agents/skills/rust-standards/scripts/audit_rust_standards.py .
PASS: 1. non-keyword prod files
PASS: 2. #[allow] in production
PASS: 3. production unwrap/expect/panic
PASS: 4. #[test] in production
PASS: 5. // comments in mod.rs
PASS: 6. mod.rs missing trailing use super::*
PASS: 7. sub-file first line not use super::*
PASS: 8. #[cfg(test)] in production
PASS: 9. long-path use crate::xxx in sub-files
PASS: 10. inline generic bounds
PASS: 11. r# on non-keyword file
PASS: 12. implicit Vec::new() without type
PASS: 13. #![cfg(test)] in test fn.rs
PASS: 14. comments in test files (R14.5)
PASS: 15. pure &Foo helper in fn.rs should be impl method (R1.3.1)
PASS: 16. column-0 decl type mismatch in keyword files (R1.3a, raw-string-aware)
PASS: 17. sub-file body uses external crate full path (R6.4-pitfall-b)
PASS: 18. fn.rs hardcoded byte/string literals (R1.3c literal purity)
PASS: 19. fn-body blank lines (R9.1 §9.1 item 10)
=== SUMMARY: 19/19 PASS ===

cargo fmt --all is idempotent (no diff after second run).

Files changed (4)

  • src-tauri/src/cache/const.rs — +35 lines (10 new constants + 1 extension slice + doc comments)
  • src-tauri/src/cache/fn.rs — refactor: 4 unwrap -> ? + match, magic literals -> const refs, 50 swc_ecma_ast::X -> short names
  • src-tauri/src/cache/static.rs — +9 lines (new RESOURCE_SELECTORS OnceLock)
  • src-tauri/src/lib.rs — extend pub(crate) use blocks with SelectorExprKind, FileName, and 10 new swc_ecma_ast variants

Scope discipline

This PR is strictly a refactor of the PR #17 diff itself; no behavior changes. The 4 selectors compile to the same Selector instances, the 16 extension suffixes produce identical matches, and the AST walk visits the same Expr / Stmt variants. The only behavioral differences are:

  • Failed selector initialization logs a warning and skips the <script src> / <link href> / <img src> / inline-<script> extraction instead of panicking. (In practice this is unreachable because the selector strings are compile-time constants.)

Test surface

extract_resources_with_scraper / extract_resources_from_js_ast / is_resource_path are private. End-to-end validation requires a Tauri build, which happens via the existing Build APK workflow on merge.

…wc paths via lib.rs

PR #17 introduced scraper HTML parsing + swc_ecma_parser AST walking as the
replacement for the regex-based resource extraction, but the diff had three
rust-standards violations that block reviewer approval:

1. Four Selector::parse(...).unwrap() calls (R11.4 - no unwrap in production).
   The selector strings are compile-time constants, so the panic is
   theoretical, but rust-standards bans unwrap/expect/panic unconditionally
   and forbids #[allow] macros for silencing lint. Fix: lazy-init a
   OnceLock<Result<[Selector; 4], String>> in cache/static.rs, surface the
   (impossible) parse error via euv_log! + early return.

2. fn.rs hardcoded byte/string literals (R1.3c literal purity). Move CSS
   selector strings (script[src], link[href], img[src], script:not([src])),
   URL scheme prefixes (http://, https://, data:, //, ://), and the 16
   resource-extension suffixes (.wasm, .js, .mjs, .css, ...) to const.rs.
   Replace the long if/else chain in is_resource_path() with a
   RESOURCE_EXTENSIONS.iter().any(|s| value.ends_with(*s)) loop.

3. swc_ecma_ast::Expr / Lit / Callee / MemberProp / etc. long-path calls in
   sub-file fn.rs bodies (R6.4-pitfall-b). The sub-file already has
   use super::*; and the lib.rs already re-exports swc_ecma_ast::{EsVersion,
   Program} - extend that block to also expose ArrowFunctionBody, Callee, Decl,
   Expr, Lit, MemberProp, ModuleDecl, ModuleItem, Prop, PropOrSpread, Stmt,
   VarDeclOrExpr, and the corresponding swc_common::FileName +
   scraper::selector::SelectorErrorKind. Replace every swc_ecma_ast::xxx
   reference with the short name (Expr, Stmt, ...).

Resulting audit: 19/19 PASS.
@vshengbro vshengbro closed this Sep 21, 2026
@vshengbro
vshengbro deleted the refactor/rust-standards-compliance branch September 21, 2026 09:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant