# Ketheler

Ketheler is an OTP-inspired concurrency toolkit for Rust. It provides:

- `server`: a GenServer-style abstraction for stateful processes with `call`, `cast`, and `info` messages
- `scheduler`: a small green-thread work scheduler built on top of `may`

## Install

Add to your `Cargo.toml`:

```toml
[dependencies]
ketheler = "0.8.0"
```

## GenServer-Style API

```rust
use ketheler::server::{self, Response, ResponseKind, Server};

struct Counter;

enum Call {
    Get,
    Add(u64),
}

enum Cast {
    Inc,
}

impl Server for Counter {
    type State = u64;
    type Call = Call;
    type Cast = Cast;
    type Info = ();
    type Reply = u64;

    fn init() -> Self::State {
        0
    }

    fn handle_call(
        call: Self::Call,
        _from: server::CallRef<Self::Reply>,
        state: Self::State,
    ) -> Response<Self::Reply, Self::State> {
        match call {
            Call::Get => Response::Reply(state, state, Some(ResponseKind::Call)),
            Call::Add(delta) => {
                let next = state + delta;
                Response::Reply(next, next, Some(ResponseKind::Call))
            }
        }
    }

    fn handle_cast(
        cast: Self::Cast,
        state: Self::State,
    ) -> Response<Self::Reply, Self::State> {
        match cast {
            Cast::Inc => Response::NoReply(state + 1, Some(ResponseKind::Cast)),
        }
    }
}

let handle = server::start_link::<Counter>();
handle.cast(Cast::Inc).unwrap();
let value = handle.call(Call::Get).unwrap();
assert_eq!(value, 1);
```

## Agent Macro (feature)

Ketheler ships an `agent!` macro (behind the `agent` feature) for a minimal,
state-only server with `get` and `update` helpers.

Enable the feature:

```toml
[dependencies]
ketheler = { version = "0.6.1", features = ["agent"] }
```

Use it like this:

```rust
ketheler::agent!(u64);

let handle = Agent::start_link();
let value = Agent::get(&handle, |v| v);
let updated = Agent::get_and_update(&handle, |v| v + 1);
let set = Agent::update(&handle, 42);
```

The agent state type must implement:
`Default + Clone + Debug + Send + 'static`.

## Debugging And Status (OTP-style)

`ServerHandle::info()` requests OTP-style status data from a running server.
By default, `handle_info` uses the `Debug` representation of the state.

```rust
use ketheler::server;

let handle = server::start_link::<Echo>();
let status = handle.info().unwrap();
println!("{}", status.state);
```

The `debug` helper prints the status state string:

```rust
use ketheler::server;

let handle = server::start_link::<Echo>();
server::debug(&handle).unwrap();
```


```

## Scheduler

```rust
use ketheler::scheduler;

fn fib(n: u64) -> u64 {
    match n {
        0 => 0,
        1 => 1,
        _ => fib(n - 1) + fib(n - 2),
    }
}

let inputs = vec![35_u64, 36, 37, 38];
let results = scheduler::run(4, fib, inputs);
```

## Tests

```bash
cargo test
```
