radixdb-plugin 1.1.0

Safe authoring SDK and local test host for RadixDB native plugins
Documentation
use std::fmt;

pub type PluginResult<T> = Result<T, PluginError>;

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PluginErrorKind {
    InvalidInput,
    Domain,
    LimitExceeded,
    Cancelled,
    Internal,
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PluginError {
    kind: PluginErrorKind,
    detail: String,
    field: Option<String>,
}

impl PluginError {
    pub fn new(kind: PluginErrorKind, detail: impl Into<String>) -> Self {
        Self {
            kind,
            detail: bound_utf8(detail.into(), 4096),
            field: None,
        }
    }

    pub fn invalid_input(detail: impl Into<String>) -> Self {
        Self::new(PluginErrorKind::InvalidInput, detail)
    }

    pub fn domain(detail: impl Into<String>) -> Self {
        Self::new(PluginErrorKind::Domain, detail)
    }

    pub fn limit_exceeded(detail: impl Into<String>) -> Self {
        Self::new(PluginErrorKind::LimitExceeded, detail)
    }

    pub fn cancelled() -> Self {
        Self::new(PluginErrorKind::Cancelled, "plugin call cancelled")
    }

    pub fn internal(detail: impl Into<String>) -> Self {
        Self::new(PluginErrorKind::Internal, detail)
    }

    pub fn with_field(mut self, field: impl Into<String>) -> Self {
        self.field = Some(bound_utf8(field.into(), 255));
        self
    }

    pub fn kind(&self) -> PluginErrorKind {
        self.kind
    }

    pub fn detail(&self) -> &str {
        &self.detail
    }

    pub fn field(&self) -> Option<&str> {
        self.field.as_deref()
    }
}

impl fmt::Display for PluginError {
    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
        formatter.write_str(&self.detail)
    }
}

impl std::error::Error for PluginError {}

fn bound_utf8(mut value: String, max_bytes: usize) -> String {
    if value.len() <= max_bytes {
        return value;
    }
    let mut end = max_bytes;
    while !value.is_char_boundary(end) {
        end -= 1;
    }
    value.truncate(end);
    value
}