nerve-ipc 0.2.0

Binary framing protocol for local IPC over Unix Domain Sockets
Documentation
//! Request lifecycle tracking per connection.
//!
//! `RequestTable` maintains `RequestId` → `RequestState` mappings and
//! provides operations to start, stream, complete, cancel, and cleanup.

use crate::types::RequestId;
use std::collections::HashMap;

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum RequestState {
    Init,
    Running,
    Streaming,
    Completed,
    Cancelled,
    Error,
}

// lives per connection
pub struct RequestTable {
    requests: HashMap<RequestId, RequestState>,
}

impl Default for RequestTable {
    fn default() -> Self {
        Self::new()
    }
}

impl RequestTable {
    #[must_use]
    pub fn new() -> Self {
        Self {
            requests: HashMap::new(),
        }
    }

    pub fn start(&mut self, id: RequestId) {
        self.requests.insert(id, RequestState::Running);
    }

    pub fn mark_streaming(&mut self, id: RequestId) {
        if let Some(state) = self.requests.get_mut(&id)
            && *state == RequestState::Running
        {
            *state = RequestState::Streaming;
        }
    }

    pub fn complete(&mut self, id: RequestId) {
        self.requests.insert(id, RequestState::Completed);
    }

    pub fn cancel(&mut self, id: RequestId) -> bool {
        match self.requests.get_mut(&id) {
            Some(RequestState::Running | RequestState::Streaming) => {
                self.requests.insert(id, RequestState::Cancelled);
                true
            }
            _ => false,
        }
    }

    #[must_use]
    pub fn is_cancelled(&self, id: RequestId) -> bool {
        matches!(self.requests.get(&id), Some(RequestState::Cancelled))
    }

    pub fn cleanup(&mut self, id: RequestId) {
        self.requests.remove(&id);
    }
}