tdbe 0.10.0

ThetaData Binary Encoding -- market data types, FIT/FIE codecs, Black-Scholes Greeks
Documentation
//! `ThetaData` HTTP/gRPC error code mapping.
//!
//! The MDDS server returns numeric error codes in HTTP status and gRPC
//! metadata. This module maps those codes to human-readable names and
//! descriptions.

/// A `ThetaData` error code with its HTTP status, short name, and description.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ThetaDataError {
    pub http_code: u16,
    pub name: &'static str,
    pub description: &'static str,
}

const ERRORS: &[ThetaDataError] = &[
    ThetaDataError {
        http_code: 200,
        name: "OK",
        description: "Request completed successfully.",
    },
    ThetaDataError {
        http_code: 404,
        name: "NO_IMPL",
        description: "Endpoint or feature is not implemented.",
    },
    ThetaDataError {
        http_code: 429,
        name: "OS_LIMIT",
        description: "Rate limit exceeded for the current subscription tier.",
    },
    ThetaDataError {
        http_code: 470,
        name: "GENERAL",
        description: "General server-side error.",
    },
    ThetaDataError {
        http_code: 471,
        name: "PERMISSION",
        description: "Insufficient permissions for the requested data.",
    },
    ThetaDataError {
        http_code: 472,
        name: "NO_DATA",
        description: "No data available for the requested parameters.",
    },
    ThetaDataError {
        http_code: 473,
        name: "INVALID_PARAMS",
        description: "One or more request parameters are invalid.",
    },
    ThetaDataError {
        http_code: 474,
        name: "DISCONNECTED",
        description: "Client is disconnected from the server.",
    },
    ThetaDataError {
        http_code: 475,
        name: "TERMINAL_PARSE",
        description: "Server failed to parse the terminal request.",
    },
    ThetaDataError {
        http_code: 476,
        name: "WRONG_IP",
        description: "Request originated from an unauthorized IP address.",
    },
    ThetaDataError {
        http_code: 477,
        name: "NO_PAGE_FOUND",
        description: "The requested page was not found.",
    },
    ThetaDataError {
        http_code: 478,
        name: "INVALID_SESSION_ID",
        description: "The session ID is invalid or expired.",
    },
    ThetaDataError {
        http_code: 571,
        name: "SERVER_STARTING",
        description: "Server is still starting up; retry shortly.",
    },
    ThetaDataError {
        http_code: 572,
        name: "UNCAUGHT_ERROR",
        description: "An uncaught server-side error occurred.",
    },
];

/// Look up a `ThetaDataError` by its HTTP status code.
#[inline]
#[must_use]
pub fn error_from_http_code(code: u16) -> Option<&'static ThetaDataError> {
    ERRORS.iter().find(|e| e.http_code == code)
}

/// Metadata key carrying the ThetaData HTTP status in gRPC responses.
pub const HTTP_STATUS_CODE_KEY: &str = "http_status_code";

/// Human-readable error name for an HTTP status code, or `"UNKNOWN"`.
#[inline]
#[must_use]
pub fn error_name(code: u16) -> &'static str {
    error_from_http_code(code).map_or("UNKNOWN", |e| e.name)
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn known_codes() {
        assert_eq!(error_from_http_code(200).unwrap().name, "OK");
        assert_eq!(error_from_http_code(472).unwrap().name, "NO_DATA");
        assert_eq!(error_from_http_code(571).unwrap().name, "SERVER_STARTING");
        assert_eq!(error_from_http_code(572).unwrap().name, "UNCAUGHT_ERROR");
    }

    #[test]
    fn unknown_code() {
        assert!(error_from_http_code(999).is_none());
        assert!(error_from_http_code(500).is_none());
    }

    #[test]
    fn error_name_helper() {
        assert_eq!(error_name(429), "OS_LIMIT");
        assert_eq!(error_name(999), "UNKNOWN");
    }
}