#![no_std]
#![forbid(unsafe_code)]
#![feature(coverage_attribute)]
#![deny(missing_docs)]
extern crate alloc;
pub mod geometry;
pub mod impls;
pub mod map;
pub mod shape;
pub mod value;
use alloc::{string::String, vec::Vec};
pub use geometry::*;
pub use impls::*;
pub use map::*;
use serde::{Deserialize, Serialize};
pub use shape::*;
pub use value::*;
#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Default)]
pub enum Projection {
#[default]
S2,
WG,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Default)]
pub enum Face {
#[default]
Face0 = 0,
Face1 = 1,
Face2 = 2,
Face3 = 3,
Face4 = 4,
Face5 = 5,
}
impl From<Face> for u8 {
fn from(face: Face) -> Self {
face as u8
}
}
impl From<u8> for Face {
fn from(face: u8) -> Self {
match face {
1 => Face::Face1,
2 => Face::Face2,
3 => Face::Face3,
4 => Face::Face4,
5 => Face::Face5,
_ => Face::Face0,
}
}
}
impl serde::Serialize for Face {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_u8(*self as u8)
}
}
impl<'de> serde::Deserialize<'de> for Face {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let value = u8::deserialize(deserializer)?;
match value {
0 => Ok(Face::Face0),
1 => Ok(Face::Face1),
2 => Ok(Face::Face2),
3 => Ok(Face::Face3),
4 => Ok(Face::Face4),
5 => Ok(Face::Face5),
_ => Err(serde::de::Error::custom("Invalid face value")),
}
}
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)]
pub enum FeatureCollectionType {
#[default]
FeatureCollection,
}
impl From<&str> for FeatureCollectionType {
fn from(_: &str) -> Self {
FeatureCollectionType::FeatureCollection
}
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)]
pub enum S2FeatureCollectionType {
#[default]
S2FeatureCollection,
}
impl From<&str> for S2FeatureCollectionType {
fn from(_: &str) -> Self {
S2FeatureCollectionType::S2FeatureCollection
}
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)]
pub struct FeatureCollection<M = (), P: Clone + Default = Properties, D: Clone + Default = MValue> {
#[serde(rename = "type")]
pub _type: FeatureCollectionType,
pub features: Vec<Features<M, P, D>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub attributions: Option<Attributions>,
#[serde(skip_serializing_if = "Option::is_none")]
pub bbox: Option<BBox>,
}
impl<M, P: Clone + Default, D: Clone + Default> FeatureCollection<M, P, D> {
pub fn new(attributions: Option<Attributions>) -> Self {
Self { _type: "FeatureCollection".into(), features: Vec::new(), attributions, bbox: None }
}
pub fn update_bbox(&mut self, bbox: BBox) {
let mut self_bbox = self.bbox.unwrap_or_default();
self_bbox = self_bbox.merge(&bbox);
self.bbox = Some(self_bbox);
}
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)]
pub struct S2FeatureCollection<M = (), P: Clone + Default = Properties, D: Clone + Default = MValue>
{
#[serde(rename = "type")]
pub _type: S2FeatureCollectionType,
pub features: Vec<VectorFeature<M, P, D>>,
pub faces: Vec<Face>,
#[serde(skip_serializing_if = "Option::is_none")]
pub attributions: Option<Attributions>,
#[serde(skip_serializing_if = "Option::is_none")]
pub bbox: Option<BBox>,
}
impl<M, P: Clone + Default, D: Clone + Default> S2FeatureCollection<M, P, D> {
pub fn new(attributions: Option<Attributions>) -> Self {
Self {
_type: "S2FeatureCollection".into(),
features: Vec::new(),
faces: Vec::new(),
attributions,
bbox: None,
}
}
pub fn update_bbox(&mut self, bbox: BBox) {
let mut self_bbox = self.bbox.unwrap_or_default();
self_bbox = self_bbox.merge(&bbox);
self.bbox = Some(self_bbox);
}
pub fn add_face(&mut self, face: Face) {
if !self.faces.contains(&face) {
self.faces.push(face);
}
}
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)]
pub enum FeatureType {
#[default]
Feature,
}
impl From<&str> for FeatureType {
fn from(_: &str) -> Self {
FeatureType::Feature
}
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct Feature<M = (), P: Clone + Default = Properties, D: Clone + Default = MValue> {
#[serde(rename = "type")]
pub _type: FeatureType,
#[serde(skip_serializing_if = "Option::is_none")]
pub id: Option<u64>,
pub properties: P,
pub geometry: Geometry<D>,
#[serde(skip_serializing_if = "Option::is_none")]
pub metadata: Option<M>,
}
impl<M, P: Clone + Default, D: Clone + Default> Feature<M, P, D> {
pub fn new(id: Option<u64>, properties: P, geometry: Geometry<D>, metadata: Option<M>) -> Self {
Self { _type: "Feature".into(), id, properties, geometry, metadata }
}
}
impl<M, P: Clone + Default, D: Clone + Default> Default for Feature<M, P, D> {
fn default() -> Self {
Self {
_type: "Feature".into(),
id: None,
properties: Default::default(),
geometry: Default::default(),
metadata: None,
}
}
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)]
pub enum VectorFeatureType {
#[default]
VectorFeature,
S2Feature,
}
impl From<&str> for VectorFeatureType {
fn from(s: &str) -> Self {
match s {
"S2Feature" => VectorFeatureType::S2Feature,
_ => VectorFeatureType::VectorFeature,
}
}
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct VectorFeature<M = (), P: Clone + Default = Properties, D: Clone + Default = MValue> {
#[serde(rename = "type")]
pub _type: VectorFeatureType,
#[serde(skip_serializing_if = "Option::is_none")]
pub id: Option<u64>,
pub face: Face,
pub properties: P,
pub geometry: VectorGeometry<D>,
#[serde(skip_serializing_if = "Option::is_none")]
pub metadata: Option<M>,
}
impl<M, P: Clone + Default, D: Clone + Default> Default for VectorFeature<M, P, D> {
fn default() -> Self {
Self {
_type: "VectorFeature".into(),
face: 0.into(),
id: None,
properties: Default::default(),
geometry: Default::default(),
metadata: None,
}
}
}
impl<M, P: Clone + Default, D: Clone + Default> VectorFeature<M, P, D> {
pub fn new_wm(
id: Option<u64>,
properties: P,
geometry: VectorGeometry<D>,
metadata: Option<M>,
) -> Self {
Self { _type: "VectorFeature".into(), face: 0.into(), id, properties, geometry, metadata }
}
pub fn new_s2(
id: Option<u64>,
face: Face,
properties: P,
geometry: VectorGeometry<D>,
metadata: Option<M>,
) -> Self {
Self { _type: "S2Feature".into(), face, id, properties, geometry, metadata }
}
pub fn from_vector_feature(
feature: &VectorFeature<M, P, D>,
geometry: Option<VectorGeometry<D>>,
) -> Self
where
M: Clone,
{
Self {
_type: feature._type.clone(),
id: feature.id,
face: feature.face,
properties: feature.properties.clone(),
geometry: geometry.unwrap_or(feature.geometry.clone()),
metadata: feature.metadata.clone(),
}
}
pub fn to_m_vector_feature<M2>(
&self,
to_meta: impl FnOnce(Option<&M>) -> Option<M2>,
) -> VectorFeature<M2, Properties, MValue>
where
M: Clone,
P: MValueCompatible,
D: MValueCompatible,
{
VectorFeature {
_type: self._type.clone(),
id: self.id,
face: self.face,
properties: self.properties.clone().into(),
geometry: self.geometry.to_m_geometry(),
metadata: to_meta(self.metadata.as_ref()),
}
}
}
pub type Attributions = Map<String, String>;
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
#[serde(untagged)]
pub enum FeatureCollections<M = (), P: Clone + Default = Properties, D: Clone + Default = MValue> {
FeatureCollection(FeatureCollection<M, P, D>),
S2FeatureCollection(S2FeatureCollection<M, P, D>),
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
#[serde(untagged)]
pub enum Features<M = (), P: Clone + Default = Properties, D: Clone + Default = MValue> {
Feature(Feature<M, P, D>),
VectorFeature(VectorFeature<M, P, D>),
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
#[serde(untagged)]
pub enum JSONCollection<M = (), P: Clone + Default = Properties, D: Clone + Default = MValue> {
FeatureCollection(FeatureCollection<M, P, D>),
S2FeatureCollection(S2FeatureCollection<M, P, D>),
Feature(Feature<M, P, D>),
VectorFeature(VectorFeature<M, P, D>),
}