| Crates.io | name-forge |
| lib.rs | name-forge |
| version | 0.1.1 |
| created_at | 2025-12-08 05:11:38.712816+00 |
| updated_at | 2025-12-08 06:05:57.621702+00 |
| description | Deterministic crate name forge with availability checks |
| homepage | https://github.com/factordynamics/name |
| repository | https://github.com/factordynamics/name |
| max_upload_size | |
| id | 1972747 |
| size | 89,832 |
Deterministic crate name forge backed by embedded dictionary data and crates.io availability checks. Candidates are walked breadth-first by length, deduplicated, optionally shuffled (with an optional seed), and filtered by prefix/suffix before being checked sequentially or in bounded parallel.
use name_crates_io_client::CratesClient;
use name_forge::{DictionarySource, GeneratorConfig, NameGenerator, NameStatus};
#[tokio::main]
async fn main() -> eyre::Result<()> {
let base_url =
std::env::var("CRATES_IO_BASE_URL").unwrap_or_else(|_| "https://crates.io".to_string());
let client = CratesClient::new(base_url);
let mut config = GeneratorConfig::new(3, 5);
config.results_limit = Some(5); // stop after 5 available names
config.limit = Some(100); // cap the total candidates inspected
config.dictionary = DictionarySource::Names;
config.parallel = true;
config.shuffle_seed = Some(7);
let generator = NameGenerator::new(client);
let results = generator.generate(&config).await?;
for result in results {
match result.status {
NameStatus::Available => println!("{} is free", result.name),
NameStatus::Taken { .. } => println!("{} is taken", result.name),
NameStatus::Error { ref error } => println!("{} errored: {error}", result.name),
}
}
Ok(())
}
Run the packaged example without touching crates.io by pointing at a mock service:
CRATES_IO_BASE_URL=http://localhost:8080 cargo run -p name-forge --example scan
GeneratorConfig:
min_len, max_lenlimit (total candidates) and results_limit (available names before stopping)prefix, suffixshuffle (defaults to true) and shuffle_seed for reproducible shufflesparallel flag (preserves ordered output)dictionary via DictionarySource::{Combined, Names, Words, CustomPath}NameGenerator::new(client: CratesClient) builds the engine with your HTTP client.NameGenerator::generate(&self, &GeneratorConfig) walks candidates (shuffled first when enabled), truncates to limit, and returns ordered NameResult values.NameGenerator::generate_with_callback exposes per-candidate callbacks while keeping ordered results.NameResult pairs a candidate with NameStatus::{Available, Taken { info }, Error { error }}; taken entries include optional CrateInfo metadata when available.Custom dictionary files are filtered to the configured length range and sorted by length then lexicographic order before scanning. When parallel is enabled, Tokio drives up to 16 in-flight requests while preserving deterministic output ordering.