1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
use diesel::expression::{AsExpression, Expression}; use diesel::pg::expression::operators::IsContainedBy; use super::operators::SameAs; use sql_types::{self, Circle, Point}; pub trait PgSameAsExpressionMethods<ST>: Expression + Sized { /// Creates a PostgresSQL `~=` expression. /// /// The "same as" operator, ~=, represents the usual notion of equality for the `point`, `box`, /// `polygon`, and `circle` types. Some of these types have an = operator, but = compares for /// equal areas only. The other scalar operators (<= and so on) likewise compare areas for /// these types. /// /// # Example /// ```rust /// # #![allow(dead_code)] /// # #[macro_use] extern crate diesel; /// # extern crate diesel_geometry; /// # include!("../../doctest_setup.rs"); /// # use diesel_geometry::data_types::PgPoint; /// # /// # fn main() { /// # use schema::shapes::dsl::*; /// # let connection = establish_connection(); /// let found_drawing_id = shapes /// .select(drawing_id) /// .filter(centroid.same_as(PgPoint(1.0, 2.0))) /// .first(&connection); /// assert_eq!(Ok(2), found_drawing_id); /// # } fn same_as<T>(self: Self, other: T) -> SameAs<Self, T::Expression> where T: AsExpression<ST>, { SameAs::new(self, other.as_expression()) } } impl<T: Expression<SqlType = Point>> PgSameAsExpressionMethods<Point> for T {} impl<T: Expression<SqlType = sql_types::Box>> PgSameAsExpressionMethods<sql_types::Box> for T {} impl<T: Expression<SqlType = Circle>> PgSameAsExpressionMethods<Circle> for T {} pub trait PgIsContainedByExpressionMethods<ST>: Expression + Sized { /// Creates a PostgresSQL `<@` expression. /// /// For geometric types. /// /// # Example /// ```rust /// # #![allow(dead_code)] /// # #[macro_use] extern crate diesel; /// # extern crate diesel_geometry; /// # include!("../../doctest_setup.rs"); /// # use diesel_geometry::data_types::{PgBox, PgPoint}; /// # use diesel_geometry::sql_types; /// # /// # fn main() { /// # use schema::shapes::dsl::*; /// # let connection = establish_connection(); /// // Looking for point at (1,2) /// let found_drawing_id = shapes /// .select(drawing_id) /// .filter( /// centroid.is_contained_by( /// PgBox(PgPoint(0.5, 1.5), PgPoint(3.0,5.0)).into_sql::<sql_types::Box>() /// ) /// ) /// .first(&connection); /// assert_eq!(Ok(2), found_drawing_id); /// # } fn is_contained_by<T>(self: Self, other: T) -> IsContainedBy<Self, T::Expression> where T: AsExpression<ST>, { IsContainedBy::new(self, other.as_expression()) } } // A Circle can contain a Point or a Circle but not a Box pub trait CanBeContainedByCircle {} impl CanBeContainedByCircle for Point {} impl CanBeContainedByCircle for Circle {} // A Box can contain a Point, Circle, and a Box pub trait CanBeContainedByBox {} impl CanBeContainedByBox for Point {} impl CanBeContainedByBox for Circle {} impl CanBeContainedByBox for sql_types::Box {} impl<T> PgIsContainedByExpressionMethods<Circle> for T where T: Expression, T::SqlType: CanBeContainedByCircle, {} impl<T> PgIsContainedByExpressionMethods<sql_types::Box> for T where T: Expression, T::SqlType: CanBeContainedByBox, {}