use std::fmt;
use num_enum::TryFromPrimitive;
use crate::decoder::{Geometry, Id, Property};
use crate::{DecodeState, Lazy, Parsed};
#[non_exhaustive]
pub enum Layer<'a, S: DecodeState = Lazy> {
Tag01(Layer01<'a, S>),
Unknown(Unknown<'a>),
}
pub type ParsedLayer<'a> = Layer<'a, Parsed>;
impl<'a, S: DecodeState> fmt::Debug for Layer<'a, S>
where
Layer01<'a, S>: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Tag01(l) => f.debug_tuple("Tag01").field(l).finish(),
Self::Unknown(u) => f.debug_tuple("Unknown").field(u).finish(),
}
}
}
#[derive(Debug, Clone, Default, PartialEq)]
pub struct Unknown<'a> {
pub(crate) tag: u8,
pub(crate) value: &'a [u8],
}
impl<'a> Unknown<'a> {
#[must_use]
pub fn tag(&self) -> u32 {
u32::from(self.tag)
}
#[must_use]
pub fn data(&self) -> &'a [u8] {
self.value
}
}
#[derive(Debug, PartialEq)]
pub struct Column<'a> {
pub(crate) typ: ColumnType,
pub(crate) name: Option<&'a str>,
pub(crate) children: Vec<Self>,
}
#[derive(Debug, Clone, Copy, PartialEq, TryFromPrimitive)]
#[repr(u8)]
pub enum ColumnType {
Id = 0,
OptId = 1,
LongId = 2,
OptLongId = 3,
Geometry = 4,
Bool = 10,
OptBool = 11,
I8 = 12,
OptI8 = 13,
U8 = 14,
OptU8 = 15,
I32 = 16,
OptI32 = 17,
U32 = 18,
OptU32 = 19,
I64 = 20,
OptI64 = 21,
U64 = 22,
OptU64 = 23,
F32 = 24,
OptF32 = 25,
F64 = 26,
OptF64 = 27,
Str = 28,
OptStr = 29,
SharedDict = 30,
}
pub struct Layer01<'a, S: DecodeState = Lazy> {
pub name: &'a str,
pub extent: u32,
pub(crate) id: Option<Id<'a, S>>,
pub(crate) geometry: Geometry<'a, S>,
pub(crate) properties: Vec<Property<'a, S>>,
#[cfg(fuzzing)]
pub(crate) layer_order: Vec<crate::decoder::fuzzing::LayerOrdering>,
}
pub type ParsedLayer01<'a> = Layer01<'a, Parsed>;
impl<'a, S> fmt::Debug for Layer01<'a, S>
where
S: DecodeState,
Option<Id<'a, S>>: fmt::Debug,
Geometry<'a, S>: fmt::Debug,
Vec<Property<'a, S>>: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut s = f.debug_struct("Layer01");
s.field("name", &self.name)
.field("extent", &self.extent)
.field("id", &self.id)
.field("geometry", &self.geometry)
.field("properties", &self.properties);
#[cfg(fuzzing)]
s.field("layer_order", &self.layer_order);
s.finish()
}
}
impl<'a, S> Clone for Layer01<'a, S>
where
S: DecodeState,
Option<Id<'a, S>>: Clone,
Geometry<'a, S>: Clone,
Vec<Property<'a, S>>: Clone,
{
fn clone(&self) -> Self {
Self {
name: self.name,
extent: self.extent,
id: self.id.clone(),
geometry: self.geometry.clone(),
properties: self.properties.clone(),
#[cfg(fuzzing)]
layer_order: self.layer_order.clone(),
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct TileLayer {
pub name: String,
pub extent: u32,
pub property_names: Vec<String>,
pub features: Vec<TileFeature>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct TileFeature {
pub id: Option<u64>,
pub geometry: geo_types::Geometry<i32>,
pub properties: Vec<PropValue>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum PropValue {
Bool(Option<bool>),
I8(Option<i8>),
U8(Option<u8>),
I32(Option<i32>),
U32(Option<u32>),
I64(Option<i64>),
U64(Option<u64>),
F32(Option<f32>),
F64(Option<f64>),
Str(Option<String>),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, strum::IntoStaticStr)]
#[strum(serialize_all = "lowercase")]
pub enum PropKind {
Bool,
I8,
U8,
I32,
U32,
I64,
U64,
F32,
F64,
Str,
}
impl From<&PropValue> for PropKind {
fn from(prop: &PropValue) -> Self {
match prop {
PropValue::Bool(_) => Self::Bool,
PropValue::I8(_) => Self::I8,
PropValue::U8(_) => Self::U8,
PropValue::I32(_) => Self::I32,
PropValue::U32(_) => Self::U32,
PropValue::I64(_) => Self::I64,
PropValue::U64(_) => Self::U64,
PropValue::F32(_) => Self::F32,
PropValue::F64(_) => Self::F64,
PropValue::Str(_) => Self::Str,
}
}
}