use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Duration {
pub months: i64,
pub days: i64,
pub seconds: i64,
pub nanos: i32,
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub struct Point {
pub srid: i32,
pub x: f64,
pub y: f64,
pub z: Option<f64>,
}
pub const SRID_CARTESIAN_2D: i32 = 7203;
pub const SRID_CARTESIAN_3D: i32 = 9157;
pub const SRID_WGS84_2D: i32 = 4326;
pub const SRID_WGS84_3D: i32 = 4979;
impl Point {
pub fn crs_name(&self) -> &'static str {
match self.srid {
SRID_CARTESIAN_2D => "cartesian",
SRID_CARTESIAN_3D => "cartesian-3d",
SRID_WGS84_2D => "wgs-84",
SRID_WGS84_3D => "wgs-84-3d",
_ => "unknown",
}
}
pub fn is_geographic(&self) -> bool {
matches!(self.srid, SRID_WGS84_2D | SRID_WGS84_3D)
}
pub fn is_3d(&self) -> bool {
self.z.is_some()
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type", content = "value")]
pub enum Property {
Null,
String(String),
Int64(i64),
Float64(f64),
Bool(bool),
List(Vec<Property>),
Map(HashMap<String, Property>),
DateTime {
nanos: i128,
tz_offset_secs: Option<i32>,
tz_name: Option<String>,
},
LocalDateTime(i128),
Date(i64),
Duration(Duration),
Time {
nanos: i64,
tz_offset_secs: Option<i32>,
},
Point(Point),
}
impl Property {
pub fn type_name(&self) -> &'static str {
match self {
Property::Null => "Null",
Property::String(_) => "String",
Property::Int64(_) => "Int64",
Property::Float64(_) => "Float64",
Property::Bool(_) => "Bool",
Property::List(_) => "List",
Property::Map(_) => "Map",
Property::DateTime { .. } => "DateTime",
Property::LocalDateTime(_) => "LocalDateTime",
Property::Date(_) => "Date",
Property::Duration(_) => "Duration",
Property::Time { .. } => "Time",
Property::Point(_) => "Point",
}
}
}
impl From<String> for Property {
fn from(v: String) -> Self {
Property::String(v)
}
}
impl From<&str> for Property {
fn from(v: &str) -> Self {
Property::String(v.to_string())
}
}
impl From<i64> for Property {
fn from(v: i64) -> Self {
Property::Int64(v)
}
}
impl From<i32> for Property {
fn from(v: i32) -> Self {
Property::Int64(v as i64)
}
}
impl From<f64> for Property {
fn from(v: f64) -> Self {
Property::Float64(v)
}
}
impl From<bool> for Property {
fn from(v: bool) -> Self {
Property::Bool(v)
}
}
impl<T: Into<Property>> From<Vec<T>> for Property {
fn from(v: Vec<T>) -> Self {
Property::List(v.into_iter().map(Into::into).collect())
}
}