use crate::geometry::Geometry;
use crate::graph::payload::{ArcPayload, EdgePayload, FacePayload, Payload, VertexPayload};
use crate::graph::storage::convert::{AsStorage, AsStorageMut};
use crate::graph::storage::Storage;
pub trait Consistent {}
impl<'a, T> Consistent for &'a T where T: Consistent {}
impl<'a, T> Consistent for &'a mut T where T: Consistent {}
pub trait Reborrow {
type Target;
fn reborrow(&self) -> &Self::Target;
}
pub trait ReborrowMut: Reborrow {
fn reborrow_mut(&mut self) -> &mut Self::Target;
}
impl<'a, T> Reborrow for &'a T {
type Target = T;
fn reborrow(&self) -> &Self::Target {
*self
}
}
impl<'a, T> Reborrow for &'a mut T {
type Target = T;
fn reborrow(&self) -> &Self::Target {
&**self
}
}
impl<'a, T> ReborrowMut for &'a mut T {
fn reborrow_mut(&mut self) -> &mut Self::Target {
*self
}
}
pub trait Bind<T, M>
where
T: Payload,
M: AsStorage<T>,
{
type Output;
fn bind(self, source: M) -> Self::Output;
}
pub struct Core<V = (), A = (), E = (), F = ()> {
vertices: V,
arcs: A,
edges: E,
faces: F,
}
impl Core {
pub fn empty() -> Self {
Core {
vertices: (),
arcs: (),
edges: (),
faces: (),
}
}
}
impl<V, A, E, F> Core<V, A, E, F> {
pub fn into_storage(self) -> (V, A, E, F) {
let Core {
vertices,
arcs,
edges,
faces,
..
} = self;
(vertices, arcs, edges, faces)
}
}
impl<V, A, E, F, G> AsStorage<VertexPayload<G>> for Core<V, A, E, F>
where
V: AsStorage<VertexPayload<G>>,
G: Geometry,
{
fn as_storage(&self) -> &Storage<VertexPayload<G>> {
self.vertices.as_storage()
}
}
impl<V, A, E, F, G> AsStorage<ArcPayload<G>> for Core<V, A, E, F>
where
A: AsStorage<ArcPayload<G>>,
G: Geometry,
{
fn as_storage(&self) -> &Storage<ArcPayload<G>> {
self.arcs.as_storage()
}
}
impl<V, A, E, F, G> AsStorage<EdgePayload<G>> for Core<V, A, E, F>
where
E: AsStorage<EdgePayload<G>>,
G: Geometry,
{
fn as_storage(&self) -> &Storage<EdgePayload<G>> {
self.edges.as_storage()
}
}
impl<V, A, E, F, G> AsStorage<FacePayload<G>> for Core<V, A, E, F>
where
F: AsStorage<FacePayload<G>>,
G: Geometry,
{
fn as_storage(&self) -> &Storage<FacePayload<G>> {
self.faces.as_storage()
}
}
impl<V, A, E, F, G> AsStorageMut<VertexPayload<G>> for Core<V, A, E, F>
where
V: AsStorageMut<VertexPayload<G>>,
G: Geometry,
{
fn as_storage_mut(&mut self) -> &mut Storage<VertexPayload<G>> {
self.vertices.as_storage_mut()
}
}
impl<V, A, E, F, G> AsStorageMut<ArcPayload<G>> for Core<V, A, E, F>
where
A: AsStorageMut<ArcPayload<G>>,
G: Geometry,
{
fn as_storage_mut(&mut self) -> &mut Storage<ArcPayload<G>> {
self.arcs.as_storage_mut()
}
}
impl<V, A, E, F, G> AsStorageMut<EdgePayload<G>> for Core<V, A, E, F>
where
E: AsStorageMut<EdgePayload<G>>,
G: Geometry,
{
fn as_storage_mut(&mut self) -> &mut Storage<EdgePayload<G>> {
self.edges.as_storage_mut()
}
}
impl<V, A, E, F, G> AsStorageMut<FacePayload<G>> for Core<V, A, E, F>
where
F: AsStorageMut<FacePayload<G>>,
G: Geometry,
{
fn as_storage_mut(&mut self) -> &mut Storage<FacePayload<G>> {
self.faces.as_storage_mut()
}
}
impl<V, A, E, F, G> Bind<VertexPayload<G>, V> for Core<(), A, E, F>
where
V: AsStorage<VertexPayload<G>>,
G: Geometry,
{
type Output = Core<V, A, E, F>;
fn bind(self, vertices: V) -> Self::Output {
let Core {
arcs, edges, faces, ..
} = self;
Core {
vertices,
arcs,
edges,
faces,
}
}
}
impl<V, A, E, F, G> Bind<ArcPayload<G>, A> for Core<V, (), E, F>
where
A: AsStorage<ArcPayload<G>>,
G: Geometry,
{
type Output = Core<V, A, E, F>;
fn bind(self, arcs: A) -> Self::Output {
let Core {
vertices,
edges,
faces,
..
} = self;
Core {
vertices,
arcs,
edges,
faces,
}
}
}
impl<V, A, E, F, G> Bind<EdgePayload<G>, E> for Core<V, A, (), F>
where
E: AsStorage<EdgePayload<G>>,
G: Geometry,
{
type Output = Core<V, A, E, F>;
fn bind(self, edges: E) -> Self::Output {
let Core {
vertices,
arcs,
faces,
..
} = self;
Core {
vertices,
arcs,
edges,
faces,
}
}
}
impl<V, A, E, F, G> Bind<FacePayload<G>, F> for Core<V, A, E, ()>
where
F: AsStorage<FacePayload<G>>,
G: Geometry,
{
type Output = Core<V, A, E, F>;
fn bind(self, faces: F) -> Self::Output {
let Core {
vertices,
arcs,
edges,
..
} = self;
Core {
vertices,
arcs,
edges,
faces,
}
}
}
pub mod alias {
use super::*;
use crate::graph::payload::{ArcPayload, FacePayload, VertexPayload};
use crate::graph::storage::Storage;
pub type OwnedCore<G> = Core<
Storage<VertexPayload<G>>,
Storage<ArcPayload<G>>,
Storage<EdgePayload<G>>,
Storage<FacePayload<G>>,
>;
pub type RefCore<'a, G> = Core<
&'a Storage<VertexPayload<G>>,
&'a Storage<ArcPayload<G>>,
&'a Storage<EdgePayload<G>>,
&'a Storage<FacePayload<G>>,
>;
}