Skip to main content

Dependencies

The general rule is the repository's: prefer a mature crate (or a std API) over hand-rolled code, and write down why a dependency is there. Every entry below has a comment in Cargo.toml saying what it is responsible for.

  • duckfn: attribute macros that register ordinary Rust functions with DuckDB. The dependency names its two features explicitly, cli and chrono, and deliberately avoids all: all also turns on duckdb-1-5 (the same switch in quack-rs), the unstable region of the C API — copy functions, the host VFS, the scalar bind/init slots — and staying out of that region is what lets a later DuckDB release load the binary (see the USE_UNSTABLE_C_API=0 note in the Makefile). owned-connection, which is what brings in duck_vfs since 0.0.15, is not needed either: persistence is std::fs on a native build and skipped altogether on wasm (see Design notes), so there is no use for a host file system. What this extension uses is:
    • chrono, which converts the time wrapper types (DuckDate::to_naive_date and friends);
    • DuckLazySlot<T>, which turns "parse the DuckLazy argument once" into a type;
    • cli, the command-line tool behind src/bin/duckfn.rs (it pulls clap and csv into duckfn).
    • The macros also generate a SQL_NAME constant per signature — the name the function is really registered under — so error prefixes read that instead of a hand-written copy of the function-name literal, while description / comment / example on the attribute are the one source of the function-description CSV (see Function descriptions).
  • quack-rs: DuckDB C API bindings; the code expanded from duckfn_entrypoint! refers to it directly.
  • libduckdb-sys: headers only, with loadable-extension enabled — so no local DuckDB build is required. The version floor is >= 1.10500 (DuckDB 1.5.0: the crate encodes a DuckDB version as 1.<major*10000 + minor*100 + patch>.0, so 1.5.6 is 1.10506.0), which is the release this build rests on. duckfn and quack-rs each carry a >=1.4.4, <2 floor of their own; holding it tighter here is this project's own choice, and it pins which headers the dependency tree uses. It is no longer driven by the duckdb-1-5 feature — that one is off (see the duckfn entry above).
  • quantstats-rs: the report itself. Its public API exposes only html() as a callable entry point (mod stats is private, so compute_performance_metrics is unreachable), so both paths are built on it instead of recomputing metrics — that would create a second source of truth for numbers the report already prints.
  • chrono: used directly for local time — report file names (shared by persistence and the temporary file) start with a %Y%m%d-%H%M%S stamp (chrono::Local, see naming.rs). The date side is duckfn's chrono feature (DuckDate::to_naive_date), whose NaiveDate is exactly what quantstats-rs' ReturnSeries::new takes; all three share one chrono 0.4.
  • sanitize-filename and fastrand: the two halves of a report file name — which parts are legal (illegal and control characters, Windows reserved device names, trailing dots and spaces) and the random suffix. Both stay shared dependencies rather than moving to the non-wasm table: naming.rs is compiled for every target, and keeping that module free of cfgs is worth more than dropping two small crates from a wasm build that names no files anyway (nothing calls it there). fastrand is already in the tree (tempfile uses it internally), so a direct dependency costs no extra compilation.
  • lol_html: the translation feature's one HTML rewrite (Translation). It targets CSS selectors, streams, and can rewrite text and markup as it goes — which is what "only the positions in the catalog, not one character anywhere else" needs. Hand-rolled string replacement cannot do that, and hand-writing an HTML parser for it would not be worth it. Its version is pinned exactly: 3.x uses let-chains, which need Rust 1.88 while this project pins 1.86 (the rust-version = "1.85" 3.x declares is an upstream mistake), so 2.7.0 is the last release that compiles here.
  • open and tempfile: open_in_browser's two jobs — starting the browser and, without output_dir, creating a uniquely named temporary file. Non-wasm targets only (see Design notes), which is why they live in a target-specific dependency table instead of the main one.