sqlite-functions 0.1.1

A small toolkit for authoring Rust functions for SQLite
Documentation
use rusqlite::functions::FunctionFlags;

/// The number of SQL arguments accepted by a function.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Arity {
    /// Accept exactly this many arguments.
    Exact(u16),
    /// Accept any number of arguments allowed by SQLite.
    Variadic,
}

impl Arity {
    pub(crate) const fn as_sqlite(self) -> i32 {
        match self {
            Self::Exact(value) => value as i32,
            Self::Variadic => -1,
        }
    }
}

/// Name, arity, and SQLite properties for a function registration.
///
/// Options default to UTF-8 and do not claim that a callback is deterministic,
/// innocuous, or direct-only. These properties must reflect the callback's
/// actual behavior, so authors opt into them explicitly.
#[derive(Clone, Debug)]
pub struct FunctionOptions {
    name: String,
    arity: Arity,
    flags: FunctionFlags,
}

impl FunctionOptions {
    /// Create schema-accessible UTF-8 function options.
    #[must_use]
    pub fn new(name: impl Into<String>, arity: Arity) -> Self {
        Self {
            name: name.into(),
            arity,
            flags: FunctionFlags::SQLITE_UTF8,
        }
    }

    /// Declare that equal inputs always produce equal outputs.
    #[must_use]
    pub fn deterministic(mut self) -> Self {
        self.flags |= FunctionFlags::SQLITE_DETERMINISTIC;
        self
    }

    /// Declare that the function has no harmful side effects or data leaks.
    #[must_use]
    pub fn innocuous(mut self) -> Self {
        self.flags |= FunctionFlags::SQLITE_INNOCUOUS;
        self
    }

    /// Restrict the function to top-level SQL.
    #[must_use]
    pub fn direct_only(mut self) -> Self {
        self.flags |= FunctionFlags::SQLITE_DIRECTONLY;
        self
    }

    /// Add advanced `rusqlite` function flags.
    #[must_use]
    pub fn with_flags(mut self, flags: FunctionFlags) -> Self {
        self.flags |= flags;
        self
    }

    /// SQL function name.
    #[must_use]
    pub fn name(&self) -> &str {
        &self.name
    }

    /// Declared SQL arity.
    #[must_use]
    pub const fn arity(&self) -> Arity {
        self.arity
    }

    /// Effective SQLite function flags.
    #[must_use]
    pub const fn flags(&self) -> FunctionFlags {
        self.flags
    }

    pub(crate) fn into_parts(self) -> (String, i32, FunctionFlags) {
        (self.name, self.arity.as_sqlite(), self.flags)
    }
}