use std::marker::PhantomData;
use std::ops::{Deref, DerefMut};
use geometry::Geometry;
use graph::mesh::{Edge, Mesh};
use graph::storage::{EdgeKey, VertexKey};
use graph::topology::{OrphanView, Topological, View};
pub struct EdgeView<M, G>
where
M: AsRef<Mesh<G>>,
G: Geometry,
{
mesh: M,
key: EdgeKey,
phantom: PhantomData<G>,
}
impl<M, G> EdgeView<M, G>
where
M: AsRef<Mesh<G>>,
G: Geometry,
{
pub(crate) fn new(mesh: M, edge: EdgeKey) -> Self {
EdgeView {
mesh: mesh,
key: edge,
phantom: PhantomData,
}
}
pub fn key(&self) -> EdgeKey {
self.key
}
pub fn to_key_topology(&self) -> EdgeKeyTopology {
EdgeKeyTopology::new(self.key, (self.vertex, self.next().map(|edge| edge.vertex)))
}
pub fn opposite(&self) -> Option<EdgeView<&Mesh<G>, G>> {
self.opposite
.map(|opposite| EdgeView::new(self.mesh.as_ref(), opposite))
}
pub fn into_opposite(self) -> Option<Self> {
let opposite = self.opposite;
let mesh = self.mesh;
opposite.map(|opposite| EdgeView::new(mesh, opposite))
}
pub fn next(&self) -> Option<EdgeView<&Mesh<G>, G>> {
self.next
.map(|next| EdgeView::new(self.mesh.as_ref(), next))
}
pub fn into_next(self) -> Option<Self> {
let next = self.next;
let mesh = self.mesh;
next.map(|next| EdgeView::new(mesh, next))
}
#[allow(dead_code)]
fn with_mesh_ref(&self) -> EdgeView<&Mesh<G>, G> {
EdgeView::new(self.mesh.as_ref(), self.key)
}
}
impl<M, G> EdgeView<M, G>
where
M: AsRef<Mesh<G>> + AsMut<Mesh<G>>,
G: Geometry,
{
pub fn opposite_mut(&mut self) -> Option<OrphanEdgeView<G>> {
let opposite = self.opposite;
opposite.map(move |opposite| {
OrphanEdgeView::new(
self.mesh.as_mut().edges.get_mut(&opposite).unwrap(),
opposite,
)
})
}
pub fn next_mut(&mut self) -> Option<OrphanEdgeView<G>> {
let next = self.next;
next.map(move |next| {
OrphanEdgeView::new(self.mesh.as_mut().edges.get_mut(&next).unwrap(), next)
})
}
#[allow(dead_code)]
fn with_mesh_mut(&mut self) -> EdgeView<&mut Mesh<G>, G> {
EdgeView::new(self.mesh.as_mut(), self.key)
}
}
impl<M, G> AsRef<EdgeView<M, G>> for EdgeView<M, G>
where
M: AsRef<Mesh<G>>,
G: Geometry,
{
fn as_ref(&self) -> &EdgeView<M, G> {
self
}
}
impl<M, G> AsMut<EdgeView<M, G>> for EdgeView<M, G>
where
M: AsRef<Mesh<G>> + AsMut<Mesh<G>>,
G: Geometry,
{
fn as_mut(&mut self) -> &mut EdgeView<M, G> {
self
}
}
impl<M, G> Deref for EdgeView<M, G>
where
M: AsRef<Mesh<G>>,
G: Geometry,
{
type Target = Edge<G>;
fn deref(&self) -> &Self::Target {
self.mesh.as_ref().edges.get(&self.key).unwrap()
}
}
impl<M, G> DerefMut for EdgeView<M, G>
where
M: AsRef<Mesh<G>> + AsMut<Mesh<G>>,
G: Geometry,
{
fn deref_mut(&mut self) -> &mut Self::Target {
self.mesh.as_mut().edges.get_mut(&self.key).unwrap()
}
}
impl<M, G> Clone for EdgeView<M, G>
where
M: AsRef<Mesh<G>> + Clone,
G: Geometry,
{
fn clone(&self) -> Self {
EdgeView {
mesh: self.mesh.clone(),
key: self.key.clone(),
phantom: PhantomData,
}
}
}
impl<M, G> Copy for EdgeView<M, G>
where
M: AsRef<Mesh<G>> + Copy,
G: Geometry,
{
}
impl<M, G> View<M, G> for EdgeView<M, G>
where
M: AsRef<Mesh<G>>,
G: Geometry,
{
type Topology = Edge<G>;
fn from_mesh(mesh: M, key: <Self::Topology as Topological>::Key) -> Self {
EdgeView::new(mesh, key)
}
}
pub struct OrphanEdgeView<'a, G>
where
G: 'a + Geometry,
{
key: EdgeKey,
edge: &'a mut Edge<G>,
}
impl<'a, G> OrphanEdgeView<'a, G>
where
G: 'a + Geometry,
{
pub(crate) fn new(edge: &'a mut Edge<G>, key: EdgeKey) -> Self {
OrphanEdgeView {
key: key,
edge: edge,
}
}
pub fn key(&self) -> EdgeKey {
self.key
}
}
impl<'a, G> Deref for OrphanEdgeView<'a, G>
where
G: 'a + Geometry,
{
type Target = <Self as OrphanView<'a, G>>::Topology;
fn deref(&self) -> &Self::Target {
&*self.edge
}
}
impl<'a, G> DerefMut for OrphanEdgeView<'a, G>
where
G: 'a + Geometry,
{
fn deref_mut(&mut self) -> &mut Self::Target {
self.edge
}
}
impl<'a, G> OrphanView<'a, G> for OrphanEdgeView<'a, G>
where
G: 'a + Geometry,
{
type Topology = Edge<G>;
fn from_topology(
topology: &'a mut Self::Topology,
key: <Self::Topology as Topological>::Key,
) -> Self {
OrphanEdgeView::new(topology, key)
}
}
pub struct EdgeKeyTopology {
key: EdgeKey,
vertices: (VertexKey, Option<VertexKey>),
}
impl EdgeKeyTopology {
fn new(edge: EdgeKey, vertices: (VertexKey, Option<VertexKey>)) -> Self {
EdgeKeyTopology {
key: edge,
vertices: vertices,
}
}
pub fn key(&self) -> EdgeKey {
self.key
}
pub fn vertices(&self) -> (VertexKey, Option<VertexKey>) {
self.vertices
}
}