name-forge

Crates.ioname-forge
lib.rsname-forge
version0.1.1
created_at2025-12-08 05:11:38.712816+00
updated_at2025-12-08 06:05:57.621702+00
descriptionDeterministic crate name forge with availability checks
homepagehttps://github.com/factordynamics/name
repositoryhttps://github.com/factordynamics/name
max_upload_size
id1972747
size89,832
refcell (refcell)

documentation

README

Name Forge

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.

Quickstart

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

API

  • GeneratorConfig:
    • Bounds: min_len, max_len
    • Caps: limit (total candidates) and results_limit (available names before stopping)
    • Filtering: prefix, suffix
    • Ordering: shuffle (defaults to true) and shuffle_seed for reproducible shuffles
    • Execution: parallel flag (preserves ordered output)
    • Data: 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.

Commit count: 0

cargo fmt