use crate::cityjson::core::attributes::Attributes;
use crate::cityjson::core::metadata::BBox;
use crate::error::Result;
use crate::resources::id::ResourceId;
use crate::resources::pool::{DefaultResourcePool, ResourcePool};
use crate::resources::storage::StringStorage;
#[derive(Debug, Clone)]
pub(crate) struct CityObjectsCore<SS: StringStorage, RR: ResourceId, CO> {
pub(crate) inner: DefaultResourcePool<CO, RR>,
_phantom: std::marker::PhantomData<SS>,
}
impl<SS: StringStorage, RR: ResourceId, CO> Default for CityObjectsCore<SS, RR, CO> {
fn default() -> Self {
Self::new()
}
}
impl<SS: StringStorage, RR: ResourceId, CO> CityObjectsCore<SS, RR, CO> {
#[must_use]
pub fn new() -> Self {
Self {
inner: DefaultResourcePool::new(),
_phantom: std::marker::PhantomData,
}
}
#[must_use]
pub fn with_capacity(capacity: usize) -> Self {
Self {
inner: DefaultResourcePool::with_capacity(capacity),
_phantom: std::marker::PhantomData,
}
}
pub(crate) fn reserve(&mut self, additional: usize) -> Result<()> {
self.inner.reserve(additional)
}
pub fn add(&mut self, city_object: CO) -> Result<RR> {
self.inner.add(city_object)
}
pub fn get(&self, id: RR) -> Option<&CO> {
self.inner.get(id)
}
pub fn get_mut(&mut self, id: RR) -> Option<&mut CO> {
self.inner.get_mut(id)
}
pub fn remove(&mut self, id: RR) -> Option<CO> {
self.inner.remove(id)
}
#[must_use]
pub fn len(&self) -> usize {
self.inner.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn iter(&self) -> impl Iterator<Item = (RR, &CO)> {
self.inner.iter()
}
pub fn iter_mut(&mut self) -> impl Iterator<Item = (RR, &mut CO)> {
self.inner.iter_mut()
}
#[must_use]
pub fn first(&self) -> Option<(RR, &CO)> {
self.inner.first()
}
#[must_use]
pub fn last(&self) -> Option<(RR, &CO)> {
self.inner.last()
}
pub fn ids(&self) -> impl Iterator<Item = RR> + '_ {
self.inner.iter().map(|(id, _)| id)
}
pub fn add_many<I: IntoIterator<Item = CO>>(&mut self, objects: I) -> Result<Vec<RR>> {
objects.into_iter().map(|obj| self.add(obj)).collect()
}
pub fn clear(&mut self) {
self.inner.clear();
}
pub fn filter<F>(&self, predicate: F) -> impl Iterator<Item = (RR, &CO)>
where
F: Fn(&CO) -> bool,
{
self.inner.iter().filter(move |(_, obj)| predicate(obj))
}
}
#[derive(Debug, Default, Clone)]
pub(crate) struct CityObjectCore<SS: StringStorage, RR: ResourceId, CoType> {
id: SS::String,
type_cityobject: CoType,
geometry: Option<Vec<RR>>,
attributes: Option<Attributes<SS>>,
geographical_extent: Option<BBox>,
children: Option<Vec<RR>>,
parents: Option<Vec<RR>>,
extra: Option<Attributes<SS>>,
}
impl<SS: StringStorage, RR: ResourceId, CoType> CityObjectCore<SS, RR, CoType> {
pub fn new(id: SS::String, type_cityobject: CoType) -> Self {
Self {
id,
type_cityobject,
geometry: None,
attributes: None,
geographical_extent: None,
children: None,
parents: None,
extra: None,
}
}
pub fn id(&self) -> &SS::String {
&self.id
}
pub fn type_cityobject(&self) -> &CoType {
&self.type_cityobject
}
pub fn geometry(&self) -> Option<&Vec<RR>> {
self.geometry.as_ref()
}
pub fn geometry_mut(&mut self) -> &mut Vec<RR> {
self.geometry.get_or_insert_with(Vec::new)
}
pub fn attributes(&self) -> Option<&Attributes<SS>> {
self.attributes.as_ref()
}
pub fn attributes_mut(&mut self) -> &mut Attributes<SS> {
self.attributes.get_or_insert_with(Attributes::new)
}
pub fn geographical_extent(&self) -> Option<&BBox> {
self.geographical_extent.as_ref()
}
pub fn set_geographical_extent(&mut self, bbox: Option<BBox>) {
self.geographical_extent = bbox;
}
pub fn children(&self) -> Option<&Vec<RR>> {
self.children.as_ref()
}
pub fn children_mut(&mut self) -> &mut Vec<RR> {
self.children.get_or_insert_with(Vec::new)
}
pub fn parents(&self) -> Option<&Vec<RR>> {
self.parents.as_ref()
}
pub fn parents_mut(&mut self) -> &mut Vec<RR> {
self.parents.get_or_insert_with(Vec::new)
}
pub fn extra(&self) -> Option<&Attributes<SS>> {
self.extra.as_ref()
}
pub fn extra_mut(&mut self) -> &mut Attributes<SS> {
self.extra.get_or_insert_with(Attributes::new)
}
}