use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
pub enum DistanceUnit {
#[default]
Meters,
Kilometers,
Miles,
Feet,
}
impl DistanceUnit {
#[inline]
pub const fn conversion_factor(&self) -> f64 {
match self {
Self::Meters => 1.0,
Self::Kilometers => 1000.0,
Self::Miles => 1609.34,
Self::Feet => 0.3048,
}
}
pub fn parse(s: &str) -> Option<Self> {
if s.eq_ignore_ascii_case("m") {
Some(Self::Meters)
} else if s.eq_ignore_ascii_case("km") {
Some(Self::Kilometers)
} else if s.eq_ignore_ascii_case("mi") {
Some(Self::Miles)
} else if s.eq_ignore_ascii_case("ft") {
Some(Self::Feet)
} else {
None
}
}
#[inline]
pub fn to_meters(&self, dist: f64) -> f64 {
dist * self.conversion_factor()
}
#[inline]
pub fn from_meters(&self, meters: f64) -> f64 {
meters / self.conversion_factor()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
pub enum DistanceSort {
#[default]
None,
Asc,
Desc,
}
impl DistanceSort {
pub fn parse(s: &str) -> Option<Self> {
if s.eq_ignore_ascii_case("asc") {
Some(Self::Asc)
} else if s.eq_ignore_ascii_case("desc") {
Some(Self::Desc)
} else {
None
}
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum OriginPoint {
Coord { lon: f64, lat: f64 },
Member(String),
}
impl OriginPoint {
#[inline]
pub const fn coord(lon: f64, lat: f64) -> Self {
Self::Coord { lon, lat }
}
#[inline]
pub fn member(m: impl Into<String>) -> Self {
Self::Member(m.into())
}
}
#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
pub struct GeoPoint {
pub longitude: f64,
pub latitude: f64,
pub member: String,
pub dist: f64,
pub score: f64,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct GeoHashBits {
pub bits: u64,
pub step: u8,
}
impl GeoHashBits {
#[inline]
pub const fn is_zero(&self) -> bool {
self.bits == 0 && self.step == 0
}
}
#[derive(Debug, Clone, Copy, PartialEq, Default)]
pub struct GeoHashRange {
pub min: f64,
pub max: f64,
}
impl GeoHashRange {
#[inline]
pub const fn is_zero(&self) -> bool {
self.min == 0.0 && self.max == 0.0
}
}
#[derive(Debug, Clone, Copy, PartialEq, Default)]
pub struct GeoHashArea {
pub hash: GeoHashBits,
pub longitude: GeoHashRange,
pub latitude: GeoHashRange,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct GeoHashNeighbors {
pub north: GeoHashBits,
pub east: GeoHashBits,
pub west: GeoHashBits,
pub south: GeoHashBits,
pub north_east: GeoHashBits,
pub south_east: GeoHashBits,
pub north_west: GeoHashBits,
pub south_west: GeoHashBits,
}
#[derive(Debug, Clone, Copy, PartialEq, Default)]
pub struct GeoHashRadius {
pub hash: GeoHashBits,
pub area: GeoHashArea,
pub neighbors: GeoHashNeighbors,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum GeoShapeType {
#[default]
None,
Circular,
Rectangular,
}
#[derive(Debug, Clone, PartialEq)]
pub struct GeoShape {
pub shape_type: GeoShapeType,
pub center_lon: f64,
pub center_lat: f64,
pub radius: f64,
pub width: f64,
pub height: f64,
pub conversion: f64,
pub bounds: [f64; 4], }
#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
pub struct GeoRadiusOption {
pub with_coord: bool,
pub with_dist: bool,
pub with_hash: bool,
pub count: Option<usize>,
pub any: bool,
pub sort: DistanceSort,
pub store_key: Option<String>,
pub store_dist_key: Option<String>,
pub unit: DistanceUnit,
}
#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
pub struct GeoSearch {
pub with_coord: bool,
pub with_dist: bool,
pub with_hash: bool,
pub count: Option<usize>,
pub any: bool,
pub asc: bool,
pub sort: DistanceSort,
pub unit: DistanceUnit,
}
#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
pub struct GeoSearchStoreOption {
pub count: Option<usize>,
pub any: bool,
pub sort: DistanceSort,
pub store_dist: bool,
pub unit: DistanceUnit,
}