unical 0.1.0

A unified Rust crate for retrieving and interacting with public holidays in various countries
Documentation
# `unical` - A unified API to retrieve public holidays

**`unical`** is a platform-agnostic calendar library for Rust that integrates with multiple Calendar data providers. It provides a simple, asynchronous interface to fetch holiday information and can be easily extended to support additional calendar services.

We have rolled out support for Calendarific, with support for other platforms coming soon.

## Features

- **Asynchronous HTTP Requests:** Built on top of [reqwest]https://crates.io/crates/reqwest with Tokio.
- **JSON Serialization/Deserialization:** Utilizes [serde]https://crates.io/crates/serde and [serde_json]https://crates.io/crates/serde_json for handling API responses.
- **Modular Design:** Easily extend the library to support multiple calendar providers.

## Installation

Add `unical` to your `Cargo.toml`:

```toml
[dependencies]
unical = "0.1"
```

Ensure you have the following dependencies (or similar) in your Cargo.toml:

```toml
[dependencies]
reqwest = { version = "0.12.12", features = ["json"] }
serde = { version = "1.0.217", features = ["derive"] }
serde_json = "1.0.138"
tokio = { version = "1.43.0", features = ["full"] }
```

## Usage

### Setting Up

Before you begin, obtain an API key from your provider (Calendarific, etc) and set it in your environment:

```
export CALENDARIFIC_API_KEY=your_real_api_key_here
```

### Example: Fetching Holidays from Calendarific

Here’s a simple example using the Calendarific client provided by Unical:

```rust
use unical::calendarific::client::CalendarificClient;
use unical::models::Holiday;

#[tokio::main]
async fn main() {
    // Retrieve your Calendarific API key from the environment
    let api_key = std::env::var("CALENDARIFIC_API_KEY")
        .expect("CALENDARIFIC_API_KEY environment variable not set");

    // Create a new Calendarific client
    let client = CalendarificClient::new(&api_key);

    // Specify the country code and year
    let country = "US";
    let year = 2025;

    // Fetch holidays
    match client.get_holidays(country, year).await {
        Ok(holidays) => {
            println!("Found {} holiday(s) for {} in {}:", holidays.len(), country, year);
            for holiday in holidays {
                println!("{} - {}", holiday.date.iso, holiday.name);
            }
        }
        Err(err) => eprintln!("Error fetching holidays: {}", err),
    }
}
```

Running the Example

1. Set your API key:

`export CALENDARIFIC_API_KEY=your_real_api_key_here`

2. Run your project:

`cargo run`

### Testing

`unical` includes integration tests that make real HTTP calls to Calendarific. To run the tests, ensure your `CALENDARIFIC_API_KEY` is set in your environment:

```
export CALENDARIFIC_API_KEY=your_real_api_key_here
cargo test
```

    Note:
    These tests rely on network access and the availability of the Calendarific API. They may be slower than unit tests and can be skipped or marked as ignored if necessary.

### Extending `unical`

`unical` is designed to be modular. If you plan to integrate additional calendar platforms (such as Google Calendar), consider adding new modules (for example, src/google/client.rs) and re-exporting the relevant clients in your lib.rs.

### License

This project is licensed under the MIT License. See the LICENSE file for details.

### Contributing

Contributions, issues, and feature requests are welcome!

Happy coding!