crator 0.4.0

The CRATOR library offers core functions to retrieve crate metadata from crates.io via raw TCP/TLS connections, process the JSON response, and present the data in a user-friendly format.
Documentation


Features

  • Fetch crate data asynchronously
  • Proper error handling
  • Human-readable number formatting
  • Extensive usage examples

About

This library offers core functions to retrieve crate metadata from crates.io via raw TCP/TLS connections, process the JSON response, and present the data in a user-friendly format.

Installation

To include crator in your Rust project, run:

cargo add crator

Note: If you are creating a new project or your project does not already include tokio as a dependency, you also need to add tokio to enable asynchronous features:

cargo add tokio

Or try

cargo add tokio --features full

This ensures that the project has the necessary asynchronous runtime support to use functions like crate_data.

Key Components

  • CrateInfo: Struct holding the latest version and download count.
  • format_number: Function to convert large numbers into compact, human-readable strings.
  • crate_data: Async function to fetch and parse crate info from crates.io API.

Example Usage

Below are various ways to call crate_data. These include different error handling approaches, concurrency patterns, and usage in both synchronous and asynchronous contexts.

Example 1: Basic usage with an explicit runtime and unwrap()

use crator::crate_data;
use tokio::runtime::Runtime;

fn main() {
    // Create a new Tokio runtime
    let rt = Runtime::new().unwrap();
    let crate_name = "crator";
    let crate_info = rt.block_on(async {
        crate_data(crate_name).await
    }).unwrap();
    println!(
        "Latest: v{}, Downloads: {}, Total Downloads: {}, Versions: {}, [D/V] Ratio: {}, License: {}",
        crate_info.latest, crate_info.downloads, crate_info.total_downloads, crate_info.versions, crate_info.d_v_ratio, crate_info.license
    );
    // Result (e.g.):
    // crate_info.latest: v0.1.0
    // crate_info.downloads: 5.9k
    // crate_info.downloads: 11
    // crate_info.versions: 1
    // crate_info.d_v_ratio: 11
    // crate_info.license: MIT OR Apache-2.0
    // Latest: v0.1.0, Downloads: 11, Versions: 1, [D/V] Ratio: 11, License: MIT OR Apache-2.0
}

Example 2: Basic usage with an explicit runtime and expect()

use crator::crate_data;
use tokio::runtime::Runtime;

fn main() {
    // Create a new Tokio runtime
    let rt = Runtime::new().unwrap();
    let crate_name = "fluxor";
    let crate_info = rt.block_on(async {
        crate_data(crate_name).await
    }).expect("Failed to get crate info");
    println!("Latest version: {}", crate_info.latest);
    println!("Downloads: {}", crate_info.downloads);
    println!("Versions: {}", crate_info.versions);
    println!("[D/V] Ratio: {}", crate_info.d_v_ratio);
    println!("License: {}", crate_info.license);
}

Example 3: Basic usage with an explicit runtime and unwrap_or_else()

use crator::crate_data;
use tokio::runtime::Runtime;

fn main() {
    // Create a new Tokio runtime
    let rt = Runtime::new().unwrap();
    let crate_name = "serde";
    let crate_info = rt.block_on(async {
        crate_data(crate_name).await
    }).unwrap_or_else(|err| {
        eprintln!("Error fetching crate data: {}", err);
        std::process::exit(1);
    });
    println!(
        "Latest: v{}, Downloads: {}, Total Downloads: {}, Versions: {}, [D/V] Ratio: {}, License: {}",
        crate_info.latest, crate_info.downloads, crate_info.total_downloads, crate_info.versions, crate_info.d_v_ratio, crate_info.license
    );
}

Example 4: Basic usage with an explicit runtime and match

use crator::crate_data;
use tokio::runtime::Runtime;

fn main() {
    // Create a new Tokio runtime
    let rt = Runtime::new().unwrap();
    let crate_name = "tokio";
    let crate_info = match rt.block_on(async {
        match crate_data(crate_name).await {
            Ok(info) => Ok(info),
            Err(err) => {
                eprintln!("Error fetching crate data: {}", err);
                Err(err)
            }
        }
    }) {
        Ok(info) => info,
        Err(_) => {
            // Handle error, e.g., exit or default
            return;
        }
    };
    println!(
        "Latest: v{}, Downloads: {}, Total Downloads: {}, Versions: {}, [D/V] Ratio: {}, License: {}",
        crate_info.latest, crate_info.downloads, crate_info.total_downloads, crate_info.versions, crate_info.d_v_ratio, crate_info.license
    );
}

Example 5: Basic usage with tokio::main and unwrap()

use crator::crate_data;

#[tokio::main]
async fn main() {
    let crate_name = "crator";
    let info = crate_data(crate_name).await.unwrap();
    println!(
        "Latest: v{}, Downloads: {}, Total Downloads: {}, Versions: {}, [D/V] Ratio: {}, License: {}",
        info.latest, info.downloads, info.total_downloads, info.versions, info.d_v_ratio, info.license
    );
}

Example 6: Basic usage with tokio::main and expect()

use crator::crate_data;

#[tokio::main]
async fn main() {
    let crate_name = "fluxor";
    let info = crate_data(crate_name).await.expect("Failed to fetch crate info");
    println!(
        "Latest: v{}, Downloads: {}, Total Downloads: {}, Versions: {}, [D/V] Ratio: {}, License: {}",
        info.latest, info.downloads, info.total_downloads, info.versions, info.d_v_ratio, info.license
    );
}

Example 7: Basic usage with tokio::main and unwrap_or_else()

use crator::crate_data;

#[tokio::main]
async fn main() {
    let crate_name = "serde";
    let crate_info = crate_data(crate_name).await.unwrap_or_else(|err| {
        eprintln!("Error fetching crate data: {}", err);
        std::process::exit(1);
    });
    println!(
        "Latest: v{}, Downloads: {}, Total Downloads: {}, Versions: {}, [D/V] Ratio: {}, License: {}",
        crate_info.latest, crate_info.downloads, crate_info.total_downloads, crate_info.versions, crate_info.d_v_ratio, crate_info.license
    );
}

Example 8: Basic usage with tokio::main and match

use crator::crate_data;

#[tokio::main]
async fn main() {
    let crate_name = "tokio";
    let crate_info = match crate_data(crate_name).await {
        Ok(info) => info,
        Err(err) => {
            eprintln!("Error fetching crate data: {}", err);
            return;
        }
    };
    println!(
        "Latest: v{}, Downloads: {}, Total Downloads: {}, Versions: {}, [D/V] Ratio: {}, License: {}",
        crate_info.latest, crate_info.downloads, crate_info.total_downloads, crate_info.versions, crate_info.d_v_ratio, crate_info.license
    );
}

License

This project is licensed under the MIT License or Apache 2.0 License.