zpack 0.1.17

A fast, configurable package manager which builds programs from source
Documentation
use std::collections::HashSet;

use pyo3::{
    IntoPyObjectExt, basic::CompareOp, exceptions::PyNotImplementedError,
    prelude::*,
};

use crate::{
    package::{
        self,
        constraint::{Cmp, CmpType, Constraint, ConstraintUtils},
        outline::SolverError,
    },
    spec::{self, SpecOptionValue},
};

#[pyclass]
#[derive(Clone, Debug)]
pub struct Value {
    #[pyo3(get, set)]
    pub value: SpecOptionValue,
}

impl ConstraintUtils for Value {
    fn get_value_type<'a, V>(
        &'a self,
        _registry: Option<&package::registry::Registry<'a, V>>,
    ) -> Option<spec::SpecOptionType> {
        Some(self.value.to_type())
    }

    fn set_value_type<'a>(
        &'a self,
        _wip_registry: &mut package::WipRegistry<'a>,
        _value_type: spec::SpecOptionType,
    ) {
        tracing::error!("Cannot change datatype of Value constraint")
    }

    fn type_check<'a>(
        &'a self,
        wip_registry: &mut package::WipRegistry<'a>,
    ) -> Result<(), Box<SolverError>> {
        match &self.value {
            SpecOptionValue::Bool(_)
            | SpecOptionValue::Int(_)
            | SpecOptionValue::Float(_)
            | SpecOptionValue::Str(_) => (),
            SpecOptionValue::Version(version) => {
                wip_registry.version_registry_mut().push(version.clone());
            }
        }

        Ok(())
    }

    fn extract_spec_options(&self) -> Vec<(&str, &str, spec::SpecOption)> {
        Vec::new()
    }

    fn extract_dependencies(&self) -> HashSet<String> {
        HashSet::default()
    }

    fn cmp_to_z3<'a>(
        &self,
        _other: &Constraint,
        _op: CmpType,
        _registry: &mut package::BuiltRegistry<'a>,
    ) -> Result<z3::ast::Dynamic, Box<SolverError>> {
        todo!()
    }

    fn to_z3_clauses<'a>(
        &self,
        registry: &mut package::BuiltRegistry<'a>,
    ) -> Result<Vec<z3::ast::Dynamic>, Box<SolverError>> {
        Ok(self.value.to_z3_dynamic(registry))
    }

    fn to_python_any<'py>(
        &self,
        py: pyo3::Python<'py>,
    ) -> pyo3::PyResult<pyo3::Bound<'py, pyo3::PyAny>> {
        self.clone().into_bound_py_any(py)
    }
}

impl From<Value> for Constraint {
    fn from(val: Value) -> Self {
        Constraint::Value(Box::new(val))
    }
}

impl std::fmt::Display for Value {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self.value)
    }
}

#[pymethods]
impl Value {
    fn __richcmp__(
        &self,
        rhs: Constraint,
        op: CompareOp,
    ) -> Result<Constraint, PyErr> {
        Cmp::py_richcmp_helper(self.clone().into(), rhs.clone(), op.into())
    }
}