#![no_std]
#![forbid(unsafe_code)]
#![deny(missing_docs)]
#![cfg_attr(docsrs, feature(doc_cfg))]
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>,
        #[serde(default)]
    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>,
        #[serde(default)]
    pub face: Face,
        #[serde(default)]
    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>),
}