arc-vector-rust 1.4.0

Rust client for Arc Vector Search Engine
Documentation
use crate::arc_vector;
use crate::arc_vector::condition::ConditionOneOf;
use crate::arc_vector::points_selector::PointsSelectorOneOf;
use crate::arc_vector::r#match::MatchValue;
use crate::arc_vector::{
    Condition, FieldCondition, Filter, GeoBoundingBox, GeoRadius, HasIdCondition, IsEmptyCondition,
    IsNullCondition, PointId, PointsSelector, Range, ValuesCount,
};

impl From<Filter> for PointsSelector {
    fn from(filter: Filter) -> Self {
        PointsSelector {
            points_selector_one_of: Some(PointsSelectorOneOf::Filter(filter)),
        }
    }
}

impl From<FieldCondition> for Condition {
    fn from(field_condition: FieldCondition) -> Self {
        Condition {
            condition_one_of: Some(ConditionOneOf::Field(field_condition)),
        }
    }
}

impl From<IsEmptyCondition> for Condition {
    fn from(is_empty_condition: IsEmptyCondition) -> Self {
        Condition {
            condition_one_of: Some(ConditionOneOf::IsEmpty(is_empty_condition)),
        }
    }
}

impl From<IsNullCondition> for Condition {
    fn from(is_null_condition: IsNullCondition) -> Self {
        Condition {
            condition_one_of: Some(ConditionOneOf::IsNull(is_null_condition)),
        }
    }
}

impl From<HasIdCondition> for Condition {
    fn from(has_id_condition: HasIdCondition) -> Self {
        Condition {
            condition_one_of: Some(ConditionOneOf::HasId(has_id_condition)),
        }
    }
}

impl From<Filter> for Condition {
    fn from(filter: Filter) -> Self {
        Condition {
            condition_one_of: Some(ConditionOneOf::Filter(filter)),
        }
    }
}

impl arc_vector::Filter {
    /// create a Filter where all of the conditions must be satisfied
    pub fn must(conds: impl IntoIterator<Item = arc_vector::Condition>) -> Self {
        Self {
            must: conds.into_iter().collect(),
            ..Default::default()
        }
    }

    /// create a Filter where at least one of the conditions should be satisfied
    pub fn should(conds: impl IntoIterator<Item = arc_vector::Condition>) -> Self {
        Self {
            should: conds.into_iter().collect(),
            ..Default::default()
        }
    }

    /// create a Filter where none of the conditions must be satisfied
    pub fn must_not(conds: impl IntoIterator<Item = arc_vector::Condition>) -> Self {
        Self {
            must_not: conds.into_iter().collect(),
            ..Default::default()
        }
    }

    /// Alias for [`should`](Self::should)
    /// create a Filter that matches if any of the conditions match
    pub fn any(conds: impl IntoIterator<Item = arc_vector::Condition>) -> Self {
        Self::should(conds)
    }

    /// Alias for [`must`](Self::must)
    /// create a Filter that matches if all of the conditions match
    pub fn all(conds: impl IntoIterator<Item = arc_vector::Condition>) -> Self {
        Self::must(conds)
    }

    /// Alias for [`must_not`](Self::must_not)
    /// create a Filter that matches if none of the conditions match
    pub fn none(conds: impl IntoIterator<Item = arc_vector::Condition>) -> Self {
        Self::must_not(conds)
    }
}

impl arc_vector::Condition {
    /// create a Condition to check if a field is empty
    ///
    /// # Examples:
    /// ```
    /// arc_vector_rust::arc_vector::Condition::is_empty("field");
    /// ```
    pub fn is_empty(key: impl Into<String>) -> Self {
        Self::from(arc_vector::IsEmptyCondition { key: key.into() })
    }

    /// create a Condition to check if the point has a null key
    ///
    /// # Examples:
    /// ```
    /// arc_vector_rust::arc_vector::Condition::is_empty("remark");
    /// ```
    pub fn is_null(key: impl Into<String>) -> Self {
        Self::from(arc_vector::IsNullCondition { key: key.into() })
    }

    /// create a Condition to check if the point has one of the given ids
    ///
    /// # Examples:
    /// ```
    /// arc_vector_rust::arc_vector::Condition::has_id([0, 8, 15]);
    /// ```
    pub fn has_id(ids: impl IntoIterator<Item = impl Into<PointId>>) -> Self {
        Self::from(arc_vector::HasIdCondition {
            has_id: ids.into_iter().map(Into::into).collect(),
        })
    }

    /// create a Condition that matches a field against a certain value
    ///
    /// # Examples:
    /// ```
    /// arc_vector_rust::arc_vector::Condition::matches("number", 42);
    /// arc_vector_rust::arc_vector::Condition::matches("tag", vec!["i".to_string(), "em".into()]);
    /// ```
    pub fn matches(field: impl Into<String>, r#match: impl Into<MatchValue>) -> Self {
        Self {
            condition_one_of: Some(ConditionOneOf::Field(arc_vector::FieldCondition {
                key: field.into(),
                r#match: Some(arc_vector::Match {
                    match_value: Some(r#match.into()),
                }),
                ..Default::default()
            })),
        }
    }

    /// create a Condition that checks numeric fields against a range
    ///
    /// # Examples:
    ///
    /// ```
    /// use arc_vector_rust::arc_vector::Range;
    /// arc_vector_rust::arc_vector::Condition::range("number", Range {
    ///     gte: Some(42.),
    ///     ..Default::default()
    /// });
    /// ```
    pub fn range(field: impl Into<String>, range: Range) -> Self {
        Self {
            condition_one_of: Some(ConditionOneOf::Field(arc_vector::FieldCondition {
                key: field.into(),
                range: Some(range),
                ..Default::default()
            })),
        }
    }

    /// create a Condition that checks geo fields against a radius
    ///
    /// # Examples:
    ///
    /// ```
    /// use arc_vector_rust::arc_vector::{GeoPoint, GeoRadius};
    /// arc_vector_rust::arc_vector::Condition::geo_radius("location", GeoRadius {
    ///   center: Some(GeoPoint { lon: 42., lat: 42. }),
    ///   radius: 42.,
    /// });
    pub fn geo_radius(field: impl Into<String>, geo_radius: GeoRadius) -> Self {
        Self {
            condition_one_of: Some(ConditionOneOf::Field(arc_vector::FieldCondition {
                key: field.into(),
                geo_radius: Some(geo_radius),
                ..Default::default()
            })),
        }
    }

    /// create a Condition that checks geo fields against a bounding box
    ///
    /// # Examples:
    ///
    /// ```
    /// use arc_vector_rust::arc_vector::{GeoPoint, GeoBoundingBox};
    /// arc_vector_rust::arc_vector::Condition::geo_bounding_box("location", GeoBoundingBox {
    ///   top_left: Some(GeoPoint { lon: 42., lat: 42. }),
    ///   bottom_right: Some(GeoPoint { lon: 42., lat: 42. }),
    /// });
    pub fn geo_bounding_box(field: impl Into<String>, geo_bounding_box: GeoBoundingBox) -> Self {
        Self {
            condition_one_of: Some(ConditionOneOf::Field(arc_vector::FieldCondition {
                key: field.into(),
                geo_bounding_box: Some(geo_bounding_box),
                ..Default::default()
            })),
        }
    }

    /// create a Condition that checks count of values in a field
    ///
    /// # Examples:
    ///
    /// ```
    /// use arc_vector_rust::arc_vector::ValuesCount;
    /// arc_vector_rust::arc_vector::Condition::values_count("tags", ValuesCount {
    ///  gte: Some(42),
    ///  ..Default::default()
    /// });
    pub fn values_count(field: impl Into<String>, values_count: ValuesCount) -> Self {
        Self {
            condition_one_of: Some(ConditionOneOf::Field(arc_vector::FieldCondition {
                key: field.into(),
                values_count: Some(values_count),
                ..Default::default()
            })),
        }
    }
}

impl From<bool> for MatchValue {
    fn from(value: bool) -> Self {
        Self::Boolean(value)
    }
}

impl From<i64> for MatchValue {
    fn from(value: i64) -> Self {
        Self::Integer(value)
    }
}

impl From<String> for MatchValue {
    fn from(value: String) -> Self {
        if value.contains(char::is_whitespace) {
            Self::Text(value)
        } else {
            Self::Keyword(value)
        }
    }
}

impl From<Vec<i64>> for MatchValue {
    fn from(integers: Vec<i64>) -> Self {
        Self::Integers(arc_vector::RepeatedIntegers { integers })
    }
}

impl From<Vec<String>> for MatchValue {
    fn from(strings: Vec<String>) -> Self {
        Self::Keywords(arc_vector::RepeatedStrings { strings })
    }
}

impl std::ops::Not for MatchValue {
    type Output = Self;

    fn not(self) -> Self::Output {
        match self {
            Self::Keyword(s) => Self::ExceptKeywords(arc_vector::RepeatedStrings { strings: vec![s] }),
            Self::Integer(i) => {
                Self::ExceptIntegers(arc_vector::RepeatedIntegers { integers: vec![i] })
            }
            Self::Boolean(b) => Self::Boolean(!b),
            Self::Keywords(ks) => Self::ExceptKeywords(ks),
            Self::Integers(is) => Self::ExceptIntegers(is),
            Self::ExceptKeywords(ks) => Self::Keywords(ks),
            Self::ExceptIntegers(is) => Self::Integers(is),
            Self::Text(_) => panic!("cannot negate a MatchValue::Text"),
        }
    }
}