ferrotorch_hub/lib.rs
1//! Pretrained model registry, download, and caching for ferrotorch.
2//!
3//! This crate provides a central hub for discovering, downloading, and caching
4//! pretrained model weights. It mirrors the workflow of `torch.hub` and
5//! `torchvision.models` with pretrained weight support.
6//!
7//! # Quick start
8//!
9//! ```rust,no_run
10//! use ferrotorch_core::FerrotorchError;
11//! use ferrotorch_hub::{list_models, load_pretrained};
12//!
13//! fn main() -> Result<(), FerrotorchError> {
14//! // Browse available models.
15//! for model in list_models() {
16//! println!("{}: {} ({} params)", model.name, model.description, model.num_parameters);
17//! }
18//!
19//! // Load pretrained weights (requires cached weights on disk).
20//! let _state_dict = load_pretrained::<f32>("resnet50")?;
21//! Ok(())
22//! }
23//! ```
24//!
25//! ## REQ status (per `.design/ferrotorch-hub/lib.md`)
26//!
27//! | REQ | Status | Evidence |
28//! |---|---|---|
29//! | REQ-1 | SHIPPED | `pub mod` declarations in `lib.rs` (`auth` / `discovery` http-gated; `cache` / `download` / `hf_config` / `registry` unconditional); non-test consumer: `ferrotorch-llama/src/config.rs` imports `HfTransformerConfig` from the crate root. |
30//! | REQ-2 | SHIPPED | `pub use` re-export block in `lib.rs` flattening the user-facing surface; non-test consumer: `ferrotorch/src/lib.rs` `pub mod hub { pub use ferrotorch_hub::*; }` (feature `hub`) re-exports the whole flat surface through the meta-crate; `ferrotorch-jit/examples/jit_trace_dump.rs` imports `load_pretrained` directly from the crate root. |
31//! | REQ-3 | SHIPPED | crate-level `#![warn(clippy::all, clippy::pedantic)]` + `#![deny(rust_2018_idioms)]` + per-lint `#![allow]` block with one-line justifications in `lib.rs`; non-test consumer: every dependent crate (`ferrotorch-llama`, `ferrotorch-bert`, `ferrotorch-diffusion`, `ferrotorch-jit`, `ferrotorch-rl`, `ferrotorch-graph`) requires `cargo clippy -p ferrotorch-hub --lib -- -D warnings` to pass before its own build can succeed. |
32//! | REQ-4 | SHIPPED | the deliberately-omitted `unsafe_code` deny in the lint-header block (documented in the comment); non-test consumer: `auth.rs::mod tests` is `#[cfg(test)]`-only so production callers never trip the `unsafe` paths; the lint posture lets the test module compile without crate-root override. |
33//! | REQ-5 | SHIPPED | `#[cfg(feature = "http")]` guards on `pub mod auth;`, `pub mod discovery;`, `pub use auth::…;`, `pub use discovery::…;`, and `pub use download::hf_download_model;`; offline path in `download.rs::download_weights`; non-test consumer: `ferrotorch-jit/Cargo.toml` declares `ferrotorch-hub = { workspace = true, features = ["http"] }` for the `jit_trace_dump` example; the meta-crate's `hub` cargo feature flows through to the same conditional. |
34
35// Lint baseline mirrors the workspace pattern (see ferrotorch-core,
36// ferrotorch-jit, ferrotorch-ml). `missing_docs` and
37// `missing_debug_implementations` are held at `allow` while the
38// workspace-wide rustdoc / Debug pass is tracked separately — diverging
39// unilaterally from a leaf crate would be Step 4 architectural
40// unilateralism. `unsafe_code` is intentionally NOT denied: the test
41// modules need `unsafe` for env::set_var (Rust 2024) and per-block
42// SAFETY substantiation lives at each `unsafe { ... }` site.
43#![warn(clippy::all, clippy::pedantic)]
44#![deny(rust_2018_idioms)]
45#![allow(missing_docs, missing_debug_implementations)]
46// Pedantic lints we explicitly accept across this crate. Each allow
47// names a concrete reason — the alternative would be churn-for-zero-
48// benefit or a worse API. Mirrors the ferrotorch-core / -jit baselines;
49// add to this list only with a one-line justification.
50#![allow(
51 // Hub types (HubCache, HfModelInfo, etc.) intentionally repeat the
52 // crate name; renaming them would weaken the API.
53 clippy::module_name_repetitions,
54 // # Errors / # Panics rustdoc sections are added per-fn where they
55 // matter; a crate-wide deny would force noisy boilerplate on every
56 // tiny helper.
57 clippy::missing_errors_doc,
58 clippy::missing_panics_doc,
59 // `#[must_use]` on every getter is churn for marginal value.
60 clippy::must_use_candidate,
61 // Builder-style methods on SearchQuery already document their
62 // consume-and-return pattern; `#[must_use]` is noise.
63 clippy::return_self_not_must_use,
64 // Doc comments mention paths like `~/.cache/huggingface/token` and
65 // bare HF URLs that don't gain readability from backticks; the
66 // `doc_markdown` pedantic rule is too aggressive for technical prose.
67 clippy::doc_markdown,
68 // `format!(..)` appended to existing `String` is the natural
69 // shape for the discovery query-string builder; rewriting to
70 // `write!(s, ...).unwrap()` introduces a fallible path that
71 // genuinely can't fail and obscures the build pattern.
72 clippy::format_push_string,
73 // Test/helper closures define small fns after `let`-bindings inside
74 // `hf_download_model`; hoisting them would split the helper from
75 // its only caller.
76 clippy::items_after_statements,
77 // Tests use `format!("{:?}", path)` to surface PathBuf state for
78 // diagnostics; uninlining harms readability of test failure output.
79 clippy::uninlined_format_args,
80 // PathBuf doesn't implement Display; `{:?}` is the conventional
81 // formatting for path errors and matches the rest of the workspace.
82 clippy::unnecessary_debug_formatting,
83 // Test fixtures and example HF download counts (e.g. 1234567)
84 // intentionally use round numbers without underscore separators;
85 // they're test data, not code that needs to be visually parsed.
86 clippy::unreadable_literal,
87 // `hf_download_model` mirrors the HF API call sequence (config →
88 // index → shards → tokenizer); splitting reduces traceability against
89 // the spec at <https://huggingface.co/docs/hub/api>.
90 clippy::too_many_lines,
91)]
92
93#[cfg(feature = "http")]
94pub mod auth;
95pub mod cache;
96#[cfg(feature = "http")]
97pub mod discovery;
98pub mod download;
99pub mod hf_config;
100pub mod registry;
101
102#[cfg(feature = "http")]
103pub use auth::{hf_token, with_auth};
104pub use cache::{HubCache, default_cache_dir};
105#[cfg(feature = "http")]
106pub use discovery::{
107 HfModelInfo, HfModelSummary, HfRepoFile, SearchQuery, get_model, search_models,
108};
109#[cfg(feature = "http")]
110pub use download::hf_download_model;
111pub use download::{download_weights, load_pretrained};
112pub use hf_config::HfTransformerConfig;
113pub use registry::{EntryKind, ModelInfo, WeightsFormat, get_model_info, list_models};