Skip to main content

Crate supplier_kit

Crate supplier_kit 

Source
Expand description

§supplier_kit

A modular toolkit for managing and grouping dynamic data suppliers.

supplier_kit helps you build robust and extensible architectures that rely on multiple external or internal data providers — known as suppliers. It is ideal for use cases such as federated API calls, service orchestration, or data aggregation (e.g., e-commerce platforms).


§✨ Features

  • Supplier trait: defines a common interface for all data providers
  • SupplierRegistry: a container for registering and accessing suppliers by name
  • SupplierGroup: abstraction to query multiple suppliers in a batch
  • SupplierGroupResult: returns per-supplier successes and failures
  • register_suppliers! macro: for easy supplier registration
  • Utility helpers like add_supplier_from_registry and add_suppliers_from_registry as an option

§🔧 Use Cases

  • Aggregating product listings from multiple platforms
  • Wrapping multiple internal microservices behind unified access
  • Resilient systems that gracefully handle partial failure

§🚀 Quick Start

§Example: Registering and Querying Multiple Suppliers

This example demonstrates how to use SupplierRegistry and BasicSupplierGroup to register multiple suppliers, group them, and execute a Search operation.

It includes:

  • Using the register_suppliers! macro
  • Handling partial failures using add_suppliers_from_registry
  • Group querying with SupplierGroup trait
use supplier_kit::models::{SupplierRequest, SupplierResponse, SupplierOperation};
use supplier_kit::supplier::{Supplier, SupplierRegistry};
use supplier_kit::supplier_group::{SupplierGroup, BasicSupplierGroup, SupplierGroupResult};
use supplier_kit::errors::SupplierError;
use supplier_kit::register_suppliers;
use serde_json::json;
use supplier_kit::utils::add_suppliers_from_registry;

struct MockSupplier {
    name: String,
    should_fail: bool,
}

impl MockSupplier {
    fn new(name: &str, should_fail: bool) -> Self {
        Self {
            name: name.to_string(),
            should_fail,
        }
    }
}

impl Supplier for MockSupplier {
    fn name(&self) -> &str {
        &self.name
    }

    fn query(&self, request: SupplierRequest) -> Result<SupplierResponse, SupplierError> {
        if self.should_fail {
            Err(SupplierError::Internal(format!("{} failed", self.name)))
        } else {
            Ok(SupplierResponse {
                data: json!({
                    "supplier": self.name,
                    "params": request.params
                }),
            })
        }
    }
}

fn main() -> Result<(), SupplierError> {
    let mut registry = SupplierRegistry::new();
    register_suppliers!(
        registry,
        "s1" => MockSupplier::new("s1", false),
        "s2" => MockSupplier::new("s2", true),
        "s3" => MockSupplier::new("s3", false),
    );

    let mut group = BasicSupplierGroup::new("example_group");

    let failures = add_suppliers_from_registry(&mut group, &registry, &["s1", "s2", "s4"]);

    if !failures.is_empty() {
        for (name, err) in failures {
            println!("Failed to add '{}': {}", name, err);
        }
    }

    let request = SupplierRequest {
        operation: SupplierOperation::Search,
        params: json!({ "keyword": "laptop" }),
    };

    let result: SupplierGroupResult = group.query(request);

    println!("Successes:");
    for (name, response) in result.successes {
        println!("- [{}] Response: {}", name, response.data);
    }

    println!("Failures:");
    for (name, error) in result.failures {
        println!("- [{}] Error: {}", name, error);
    }

    Ok(())
}

§📄 License

Licensed under the Apache-2.0 license


§👨 Author

Jerry Maheswara jerrymaheswara@gmail.com


§❤️ Built with Love in Rust

This project is built with ❤️ using Rust — a systems programming language that is safe, fast, and concurrent.
Rust is the perfect choice for building reliable and efficient applications.


§🤝 Contributing

Pull requests, issues, and feedback are welcome!
If you find this crate useful, give it a ⭐ and share it with others in the Rustacean community.


Modules§

errors
Module for handling errors throughout the supplier kit.
macros
Macros used throughout the supplier kit to improve ergonomics and reduce boilerplate code.
models
Module containing common data models used by the supplier kit.
supplier
Module for defining suppliers and their interactions.
supplier_group
Module for grouping suppliers together into logical collections.
utils
Utility module for helper functions and internal logic.

Macros§

register_suppliers
A helper function to register multiple suppliers at once in the SupplierRegistry.