plexus-engine 0.3.4

Engine integration traits for consuming Plexus plans
Documentation
use plexus_serde::{CapabilityOrderingContract as WireOrderingContract, Version};
use serde::{Deserialize, Serialize};

use crate::capabilities::ordering::OpOrderingContract;
use crate::capabilities::types::{CapabilityError, PlanSemver, VersionRange};

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct EngineCapabilityDocument {
    pub version_range: VersionRange,
    pub supported_ops: Vec<String>,
    pub supported_exprs: Vec<String>,
    #[serde(default)]
    pub op_ordering_contracts: Vec<OpOrderingDocument>,
    #[serde(default)]
    pub supports_graph_ref: bool,
    #[serde(default)]
    pub supports_multi_graph: bool,
    #[serde(default)]
    pub supports_graph_params: bool,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct OpOrderingDocument {
    pub op: String,
    pub contract: OpOrderingContract,
}

pub(crate) fn to_wire_ordering_contract(contract: OpOrderingContract) -> WireOrderingContract {
    match contract {
        OpOrderingContract::EngineDefinedStable => WireOrderingContract::EngineDefinedStable,
        OpOrderingContract::StablePassThrough => WireOrderingContract::StablePassThrough,
        OpOrderingContract::FanOutDeterministicPerInput => {
            WireOrderingContract::FanOutDeterministicPerInput
        }
        OpOrderingContract::DeterministicSortStableTies => {
            WireOrderingContract::DeterministicSortStableTies
        }
        OpOrderingContract::UnspecifiedWithoutSort => WireOrderingContract::UnspecifiedWithoutSort,
        OpOrderingContract::StableConcatOrUnspecifiedDistinct => {
            WireOrderingContract::StableConcatOrUnspecifiedDistinct
        }
        OpOrderingContract::ScoreDescStableTies => WireOrderingContract::ScoreDescStableTies,
    }
}

pub(crate) fn from_wire_ordering_contract(contract: WireOrderingContract) -> OpOrderingContract {
    match contract {
        WireOrderingContract::EngineDefinedStable => OpOrderingContract::EngineDefinedStable,
        WireOrderingContract::StablePassThrough => OpOrderingContract::StablePassThrough,
        WireOrderingContract::FanOutDeterministicPerInput => {
            OpOrderingContract::FanOutDeterministicPerInput
        }
        WireOrderingContract::DeterministicSortStableTies => {
            OpOrderingContract::DeterministicSortStableTies
        }
        WireOrderingContract::UnspecifiedWithoutSort => OpOrderingContract::UnspecifiedWithoutSort,
        WireOrderingContract::StableConcatOrUnspecifiedDistinct => {
            OpOrderingContract::StableConcatOrUnspecifiedDistinct
        }
        WireOrderingContract::ScoreDescStableTies => OpOrderingContract::ScoreDescStableTies,
    }
}

pub fn check_version_compat(version: &Version, range: VersionRange) -> Result<(), CapabilityError> {
    let pv = PlanSemver::from(version);
    if range.supports(pv) {
        return Ok(());
    }
    Err(CapabilityError::UnsupportedPlanVersion {
        plan_major: pv.major,
        plan_minor: pv.minor,
        plan_patch: pv.patch,
        min_major: range.min_supported.major,
        min_minor: range.min_supported.minor,
        min_patch: range.min_supported.patch,
        max_major: range.max_supported.major,
        max_minor: range.max_supported.minor,
        max_patch: range.max_supported.patch,
    })
}