systemprompt-extension 0.58.0

Compile-time extension framework for systemprompt.io AI governance infrastructure. Built on the inventory crate — registers schemas, API routes, jobs, and providers in the MCP governance pipeline.
Documentation
//! Schema migration value type.
//!
//! Copyright (c) systemprompt.io — Business Source License 1.1.
//! See <https://systemprompt.io> for licensing details.

#[macro_export]
macro_rules! extension_migrations {
    () => {
        include!(concat!(env!("OUT_DIR"), "/migrations.rs"))
    };
}

#[derive(Debug, Clone)]
pub struct Migration {
    pub version: u32,
    pub name: String,
    pub sql: &'static str,
    pub down: Option<&'static str>,
    pub no_transaction: bool,
    pub tombstone: bool,
    pub supersedes: Vec<&'static str>,
}

impl Migration {
    #[must_use]
    pub fn new(version: u32, name: impl Into<String>, sql: &'static str) -> Self {
        Self {
            version,
            name: name.into(),
            sql,
            down: None,
            no_transaction: false,
            tombstone: false,
            supersedes: Vec::new(),
        }
    }

    #[must_use]
    pub fn with_down(
        version: u32,
        name: impl Into<String>,
        up_sql: &'static str,
        down_sql: &'static str,
    ) -> Self {
        Self {
            version,
            name: name.into(),
            sql: up_sql,
            down: Some(down_sql),
            no_transaction: false,
            tombstone: false,
            supersedes: Vec::new(),
        }
    }

    #[must_use]
    pub fn new_no_transaction(version: u32, name: impl Into<String>, sql: &'static str) -> Self {
        Self {
            version,
            name: name.into(),
            sql,
            down: None,
            no_transaction: true,
            tombstone: false,
            supersedes: Vec::new(),
        }
    }

    #[must_use]
    pub fn tombstone(version: u32, name: impl Into<String>) -> Self {
        Self {
            version,
            name: name.into(),
            sql: "",
            down: None,
            no_transaction: false,
            tombstone: true,
            supersedes: Vec::new(),
        }
    }

    // Why: a checksum of a text this one replaces; a tracking row holding it
    // is moved to the current checksum without executing anything. One per
    // shipped text, so a slot corrected twice still recognises every row.
    #[must_use]
    pub fn superseding(mut self, old_checksum: &'static str) -> Self {
        self.supersedes.push(old_checksum);
        self
    }

    // Why: the digest is persisted in `extension_migrations.checksum` and
    // compared on every boot, so it must be a specified algorithm — std's
    // `DefaultHasher` is documented as free to change between releases.
    #[must_use]
    pub fn checksum(&self) -> String {
        format!("{:016x}", xxhash_rust::xxh64::xxh64(self.sql.as_bytes(), 0))
    }
}