osars 0.2.2

Rust client library for OpenScheduleAPI - educational schedule management system
Documentation
# OSARS Client Library

A comprehensive Rust client library for interacting with the OpenScheduleAPI. This library provides type-safe access to college, campus, group, and schedule data from educational institutions through the OpenScheduleAPI backend.

**Built for OpenScheduleAPI**  
GitHub: [thisishyum/OpenScheduleApi](https://github.com/thisishyum/OpenScheduleApi)

## Features

- **Full OpenScheduleAPI Coverage**: Complete access to colleges, campuses, student groups, and schedules
- **Type-Safe Queries**: Builder pattern for constructing complex queries against OpenScheduleAPI
- **Async/Await Ready**: Built on tokio and reqwest for high-performance async operations
- **Comprehensive Error Handling**: Detailed error types for all OpenScheduleAPI failure scenarios
- **Serde Support**: Full serialization/deserialization support for all OpenScheduleAPI data models
- **Flexible HTTP Client**: Use default client or bring your own configured client
- **Logging Support**: Optional tracing-based logging via feature flag

## Installation

Add this to your `Cargo.toml`:

```toml
[dependencies]
osars = "0.1.0"
```

For logging support, enable the feature:

```toml
[dependencies]
osars = { version = "0.1.0", features = ["logging"] }
```

## Quick Start

```rust
use osars::Client;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Initialize client with OpenScheduleAPI endpoint
    let client = Client::new("https://api.thisishyum.ru/schedule_api/tyumen/");

    // List all colleges from OpenScheduleAPI
    let colleges = client.colleges().send().await?;
    println!("Available colleges:");
    for college in colleges {
        println!("- {} (ID: {})", college.name, college.college_id);
    }

    // Set default college and explore its structure
    let client = client.with_college(1);
    
    // Get campuses for the college from OpenScheduleAPI
    let campuses = client.campuses()?.send().await?;
    println!("Campuses:");
    for campus in campuses {
        println!("- {} (ID: {})", campus.name, campus.id);
    }

    // Get groups for first campus
    if let Some(first_campus) = campuses.first() {
        let groups = client.groups(first_campus.id).send().await?;
        println!("Groups at {}:", first_campus.name);
        for group in groups {
            println!("- {} (ID: {})", group.name, group.id);
        }

        // Get schedule for first group from OpenScheduleAPI
        if let Some(first_group) = groups.first() {
            let schedule = client.schedule(first_group.id).send().await?;
            println!("Schedule for {}:", first_group.name);
            for day_schedule in schedule {
                println!("Date: {}", day_schedule.date);
                for lesson in day_schedule.lessons {
                    println!("  {}: {} with {} in {}", 
                        lesson.start_time, lesson.title, lesson.teacher, lesson.cabinet);
                }
            }
        }
    }

    Ok(())
}
```

## Core Concepts

### Client
The main entry point that manages OpenScheduleAPI connections and provides query builders.

```rust
// Basic client for OpenScheduleAPI
let client = Client::new("https://api.thisishyum.ru/schedule_api/tyumen/");

// Client with custom HTTP configuration for OpenScheduleAPI
let http_client = reqwest::Client::builder()
    .timeout(std::time::Duration::from_secs(30))
    .build()?;
let client = Client::with_client("https://api.thisishyum.ru/schedule_api/tyumen/", http_client);

// Client with default college for OpenScheduleAPI queries
let client = client.with_college(123);
```

### Query Builders
Chain methods to build complex queries against OpenScheduleAPI:

```rust
// College queries from OpenScheduleAPI
client.colleges().name("техн").send().await?;

// Campus queries from OpenScheduleAPI
client.with_college(1).campuses()?.name("main").send().await?;

// Group queries from OpenScheduleAPI
client.groups(123).name("CS").send().await?;

// Schedule queries from OpenScheduleAPI
client.schedule(456)
    .today()
    .send().await?;

client.schedule(456)
    .week(Week::Current)
    .weekday(Weekday::Monday)
    .send().await?;

client.schedule(456)
    .date("2024-01-15")
    .send().await?;
```

## OpenScheduleAPI Data Models

All models correspond directly to the OpenScheduleAPI response formats.

### College
Represents an educational institution from OpenScheduleAPI.

```rust
pub struct College {
    pub college_id: u32,
    pub name: String,
    pub calls: Vec<Call>,
    pub campuses: Vec<Campus>,
}
```

### Campus
A physical location of a college from OpenScheduleAPI.

```rust
pub struct Campus {
    pub id: u32,
    pub name: String,
    pub college_id: u32,
    pub groups: Vec<Group>,
}
```

### Group
A student group that attends classes together from OpenScheduleAPI.

```rust
pub struct Group {
    pub id: u32,
    pub name: String,
    pub campus_id: u32,
}
```

### Schedule
Daily schedule for a student group from OpenScheduleAPI.

```rust
pub struct Schedule {
    pub group_id: u32,
    pub date: NaiveDate,
    pub lessons: Vec<Lesson>,
}
```

### Lesson
Individual class session from OpenScheduleAPI.

```rust
pub struct Lesson {
    pub title: String,
    pub cabinet: String,
    pub teacher: String,
    pub order: u32,
    pub start_time: NaiveTime,
    pub end_time: NaiveTime,
}
```

### Call
Lesson period time slots from OpenScheduleAPI.

```rust
pub struct Call {
    pub call_id: u32,
    pub weekday: u8,
    pub begins: NaiveTime,
    pub ends: NaiveTime,
    pub order: u32,
}
```

## Advanced Usage

### Error Handling for OpenScheduleAPI

```rust
use osars::{Client, Error};

match client.colleges().send().await {
    Ok(colleges) => {
        // Process colleges from OpenScheduleAPI
    }
    Err(Error::Api { status_code, message }) => {
        eprintln!("OpenScheduleAPI error {}: {}", status_code, message);
    }
    Err(Error::Reqwest(e)) => {
        eprintln!("Network error connecting to OpenScheduleAPI: {}", e);
    }
    Err(Error::Serialization(e)) => {
        eprintln!("Data parsing error from OpenScheduleAPI: {}", e);
    }
    Err(Error::Validation(msg)) => {
        eprintln!("Validation error for OpenScheduleAPI query: {}", msg);
    }
    Err(Error::NotFound(msg)) => {
        eprintln!("Resource not found in OpenScheduleAPI: {}", msg);
    }
}
```

### Custom OpenScheduleAPI Endpoints

```rust
// For different OpenScheduleAPI instances
let tyumen_client = Client::new("https://api.thisishyum.ru/schedule_api/tyumen/");
let other_client = Client::new("https://api.example.com/schedule_api/");
```

### Logging with OpenScheduleAPI

Enable the logging feature and initialize:

```rust
use osars::logging;

// Initialize logging
logging::init();

let client = Client::new("https://api.thisishyum.ru/schedule_api/tyumen/");
// All OpenScheduleAPI requests and responses will be logged
```

## Testing

The library includes comprehensive tests against the actual OpenScheduleAPI:

```bash
# Run unit tests
cargo test

# Run integration tests against OpenScheduleAPI
cargo test --test integration_test

# Run documentation tests
cargo test --doc
```

## API Reference

### Client Methods
- `new(base_url)` - Create client for OpenScheduleAPI
- `with_client(base_url, http_client)` - Create client with custom HTTP client
- `with_college(college_id)` - Set default college for queries
- `colleges()` - Query all colleges from OpenScheduleAPI
- `college()` - Query default college
- `campuses()` - Query campuses for default college
- `campus(campus_id)` - Query specific campus
- `groups(campus_id)` - Query groups for campus
- `schedule(group_id)` - Query schedule for group
- `today(group_id)` - Query today's schedule
- `tomorrow(group_id)` - Query tomorrow's schedule

### Query Parameters
- `name(pattern)` - Filter by name pattern
- `date("YYYY-MM-DD")` - Specific date schedule
- `week(Week)` - Week-based schedule (Previous/Current/Next)
- `weekday(Weekday)` - Specific weekday schedule
- `today()` - Today's schedule
- `tomorrow()` - Tomorrow's schedule

## Contributing

This client library is designed to work with the OpenScheduleAPI project. For issues related to the API itself, please refer to the main repository: [thisishyum/OpenScheduleApi](https://github.com/thisishyum/OpenScheduleApi)

## License

This project is licensed under the same license as the OpenScheduleAPI project.

## Related Projects

- [OpenScheduleAPI]https://github.com/thisishyum/OpenScheduleApi - The main API backend
- OpenScheduleAPI Documentation - Comprehensive API documentation

## Support

For issues with this client library, open an issue in this repository. For issues with the OpenScheduleAPI backend, please refer to the main OpenScheduleAPI repository.