rs-query 0.0.1

TanStack Query-inspired async state management for GPUI
Documentation
//! Query state enum representing all possible states

use crate::QueryError;

/// Represents the state of a query.
///
/// This enum carries data in its variants for ergonomic pattern matching:
///
/// ```rust,ignore
/// match state {
///     QueryState::Success(data) => { /* use data directly */ }
///     QueryState::Error { error, stale_data } => { /* handle error */ }
///     QueryState::Loading => { /* show spinner */ }
///     _ => {}
/// }
/// ```
#[derive(Debug, Clone, Default)]
pub enum QueryState<T: Clone> {
    /// Initial state, no data yet
    #[default]
    Idle,
    /// Currently fetching (first time)
    Loading,
    /// Data available, refetching in background
    Refetching(T),
    /// Fresh data available
    Success(T),
    /// Data is stale but still usable
    Stale(T),
    /// Error occurred (with optional stale data)
    Error {
        error: QueryError,
        stale_data: Option<T>,
    },
}

impl<T: Clone> QueryState<T> {
    pub fn is_idle(&self) -> bool {
        matches!(self, Self::Idle)
    }

    pub fn is_loading(&self) -> bool {
        matches!(self, Self::Loading)
    }

    pub fn is_fetching(&self) -> bool {
        matches!(self, Self::Loading | Self::Refetching(_))
    }

    pub fn is_success(&self) -> bool {
        matches!(self, Self::Success(_))
    }

    pub fn is_stale(&self) -> bool {
        matches!(self, Self::Stale(_))
    }

    pub fn is_error(&self) -> bool {
        matches!(self, Self::Error { .. })
    }

    /// Get data if available (success, stale, refetching, or error with stale)
    pub fn data(&self) -> Option<&T> {
        match self {
            Self::Success(d) | Self::Stale(d) | Self::Refetching(d) => Some(d),
            Self::Error { stale_data, .. } => stale_data.as_ref(),
            _ => None,
        }
    }

    /// Get error if in error state
    pub fn error(&self) -> Option<&QueryError> {
        match self {
            Self::Error { error, .. } => Some(error),
            _ => None,
        }
    }

    /// Unwrap data or return default
    pub fn unwrap_or_default(&self) -> T
    where
        T: Default,
    {
        self.data().cloned().unwrap_or_default()
    }
}