#postal #zip #location #india #pincode

pypinindia

Rust library for Indian pincode lookup and geographical information

1 unstable release

0.1.0 Feb 1, 2026

#681 in Data structures

Apache-2.0

1.5MB
322 lines

pypinindia-rs

A Rust library for Indian pincode lookup and geographical information.

Crates.io Documentation License: Apache-2.0

What You Have

A complete Rust implementation of pypinindia with:

  • ✅ Core library (src/lib.rs, src/core.rs, src/models.rs, src/error.rs)
  • ✅ Comprehensive API matching Python version
  • ✅ Example code (examples/basic_usage.rs)
  • ✅ Documentation and README
  • ✅ Apache 2.0 License
  • ✅ Compiles successfully

Features

  • Comprehensive Pincode Database: Complete Indian pincode data with office information
  • Multiple Lookup Methods: Search by pincode, state, district, taluk, or office name
  • Fast Lookups: Efficient data structures for quick queries
  • Type-Safe API: Full Rust type safety with comprehensive error handling
  • Zero Dependencies: Minimal dependency footprint (only csv, serde, thiserror)

Installation

Add this to your Cargo.toml:

[dependencies]
pypinindia = "0.1.0"

Quick Start

1. Copy the Data File

cp pypinindia_pycode/pypinindia/All_India_pincode_data.csv .

2. Test the Library

# Run the example
PYPININDIA_DATA_FILE=All_India_pincode_data.csv cargo run --example basic_usage

# Or test with a simple program
cargo new --bin test_app
cd test_app
cargo add --path ..

3. Run Quality Checks

# Format code
cargo fmt

# Check for issues
cargo clippy --all-targets

# Build release
cargo build --release

# Generate docs
cargo doc --no-deps --open

Usage Examples

Basic Usage

use pypinindia::{PincodeData, get_state};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Set data file path via environment variable
    std::env::set_var("PYPININDIA_DATA_FILE", "All_India_pincode_data.csv");
    
    // Quick lookup using convenience functions
    let state = get_state("110001")?;
    println!("State: {}", state);
    
    // Using PincodeData for more operations
    let data = PincodeData::new(Some("All_India_pincode_data.csv"))?;
    let district = data.get_district("110001")?;
    println!("District: {}", district);
    
    Ok(())
}

Complete Pincode Lookup

use pypinindia::PincodeData;

let data = PincodeData::new(Some("All_India_pincode_data.csv"))?;

// Get complete information
let info = data.get_pincode_info("110001")?;
for office in info {
    println!("Office: {}", office.officename);
    println!("Type: {}", office.officetype);
    println!("State: {}", office.statename);
    println!("District: {}", office.districtname);
}

// Quick lookups
let state = data.get_state("110001")?;
let district = data.get_district("110001")?;
let taluk = data.get_taluk("110001")?;
let offices = data.get_offices("110001")?;

Search Operations

use pypinindia::PincodeData;

let data = PincodeData::new(Some("All_India_pincode_data.csv"))?;

// Search by state
let delhi_pincodes = data.search_by_state("Delhi");
println!("Found {} pincodes in Delhi", delhi_pincodes.len());

// Search by district
let mumbai_pincodes = data.search_by_district("Mumbai", Some("Maharashtra"));
println!("Found {} pincodes in Mumbai", mumbai_pincodes.len());

// Search by taluk
let taluks = data.search_by_taluk("Bangalore North", Some("Karnataka"), None);

// Search by office name (partial match)
let airport_offices = data.search_by_office("Airport");

// Get all states
let states = data.get_states();
println!("Total states: {}", states.len());

// Get districts in a state
let districts = data.get_districts(Some("Tamil Nadu"));

Statistics

use pypinindia::PincodeData;

let data = PincodeData::new(Some("All_India_pincode_data.csv"))?;

let stats = data.get_statistics();
println!("Total records: {}", stats.total_records);
println!("Unique pincodes: {}", stats.unique_pincodes);
println!("Unique states: {}", stats.unique_states);

// Get post office summary for a pincode
let summary = data.get_postoffice_summary("110001")?;
println!("Total offices: {}", summary.total);
println!("Office types: {:?}", summary.types);

Error Handling

use pypinindia::{PincodeData, PincodeError};

let data = PincodeData::new(Some("All_India_pincode_data.csv"))?;

match data.get_state("12345") {
    Ok(state) => println!("State: {}", state),
    Err(PincodeError::InvalidPincode(pin)) => {
        println!("Invalid pincode format: {}", pin);
    }
    Err(PincodeError::DataNotFound(pin)) => {
        println!("Pincode not found: {}", pin);
    }
    Err(e) => println!("Error: {}", e),
}

API Overview

Key Features Implemented

  • get_pincode_info() - Complete pincode information
  • get_state(), get_district(), get_taluk(), get_offices()
  • search_by_state(), search_by_district(), search_by_taluk()
  • search_by_office() - Partial name matching
  • get_states(), get_districts(), get_unique_taluks()
  • get_statistics() - Dataset statistics
  • get_postoffice_summary() - Office type distribution
  • ✅ Comprehensive error handling
  • ✅ Convenience functions with singleton pattern

Data Format

The library expects CSV data with the following columns:

  • pincode: 6-digit pincode
  • officename: Name of the post office
  • officetype: Type of office (S.O, B.O, H.O, etc.)
  • Deliverystatus: Delivery status (Delivery, Non-Delivery)
  • divisionname: Postal division name
  • regionname: Postal region name
  • circlename: Postal circle name
  • taluk: Taluk/Tehsil name
  • districtname: District name
  • statename: State/Territory name

Publishing to crates.io

Prepare for Publishing

Before publishing to crates.io:

  1. Check name availability: Visit https://crates.io/crates/pypinindia

    • If taken, update the name in Cargo.toml
  2. Update Cargo.toml:

    • Add your name and email
    • Add your GitHub repository URL
  3. Create crates.io account:

  4. Login:

    cargo login
    # Paste your API token
    
  5. Dry run:

    cargo publish --dry-run
    
  6. Publish:

    cargo publish
    

See PUBLISHING_GUIDE.md for detailed instructions.

Differences from Python Version

  1. No pandas dependency - Uses native Rust data structures
  2. No async batch processing - Can be added if needed
  3. No CLI tool - Can be added with clap crate
  4. Data file required - See PUBLISHING_GUIDE.md for bundling options
  5. Type safety - Compile-time guarantees vs runtime checks

Adding Missing Features

CLI Tool

Add to Cargo.toml:

[dependencies]
clap = { version = "4.0", features = ["derive"] }

Create src/bin/pypinindia.rs for CLI implementation.

Async Batch Processing

Add to Cargo.toml:

[dependencies]
tokio = { version = "1", features = ["full"] }
rayon = "1.7"

Fuzzy Search (like Python's suggest_states)

Add to Cargo.toml:

[dependencies]
strsim = "0.10"

Project Structure

.
├── Cargo.toml              # Package manifest
├── README.md               # User documentation
├── LICENSE                 # Apache 2.0
├── PUBLISHING_GUIDE.md     # Publishing instructions
├── src/
│   ├── lib.rs             # Public API
│   ├── core.rs            # Core functionality
│   ├── models.rs          # Data structures
│   └── error.rs           # Error types
└── examples/
    └── basic_usage.rs     # Example code

Building from Source

git clone https://github.com/yourusername/pypinindia-rs.git
cd pypinindia-rs
cargo build --release

Running Tests

cargo test

API Documentation

Full API documentation is available at docs.rs/pypinindia.

License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

Acknowledgments

  • Inspired by the Python pypinindia library
  • India Post for providing the comprehensive pincode database

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Resources

Dependencies

~5.5MB
~153K SLoC