use panproto_inst::WInstance;
use panproto_schema::Schema;
use crate::Lens;
use crate::asymmetric::{Complement, get, put};
use crate::error::LensError;
pub struct SymmetricLens {
pub left: Lens,
pub right: Lens,
pub middle: Schema,
}
impl SymmetricLens {
pub fn from_span(left: Lens, right: Lens) -> Result<Self, LensError> {
if left.src_schema.protocol != right.src_schema.protocol
|| left.src_schema.vertex_count() != right.src_schema.vertex_count()
{
return Err(LensError::CompositionMismatch);
}
if left
.src_schema
.vertices
.keys()
.collect::<std::collections::BTreeSet<_>>()
!= right
.src_schema
.vertices
.keys()
.collect::<std::collections::BTreeSet<_>>()
{
return Err(LensError::CompositionMismatch);
}
let middle = left.src_schema.clone();
Ok(Self {
left,
right,
middle,
})
}
pub fn sync_left_to_right(
&self,
left_view: &WInstance,
left_complement: &Complement,
) -> Result<(WInstance, Complement), LensError> {
let middle_instance = put(&self.left, left_view, left_complement)?;
get(&self.right, &middle_instance)
}
pub fn sync_right_to_left(
&self,
right_view: &WInstance,
right_complement: &Complement,
) -> Result<(WInstance, Complement), LensError> {
let middle_instance = put(&self.right, right_view, right_complement)?;
get(&self.left, &middle_instance)
}
}