use std::io::Write;
use crate::idx::Idx;
use crate::moc::{
CellMOCIterator, CellOrCellRangeMOCIterator, NonOverlapping, RangeMOCIterator, ZSorted,
};
use crate::qty::MocQty;
use crate::deser::ascii::{moc2d_to_ascii_ivoa, AsciiError};
use crate::deser::json::cellmoc2d_to_json_aladin;
pub mod adapters;
pub mod builder;
pub mod cell;
pub mod cellcellrange;
pub mod range;
use self::range::{
op::or::{or, OrRange2Iter},
RangeMOC2, RangeMOC2Elem,
};
pub trait HasTwoMaxDepth {
fn depth_max_1(&self) -> u8;
fn depth_max_2(&self) -> u8;
}
pub trait MOC2Properties: HasTwoMaxDepth + ZSorted + NonOverlapping {}
pub trait CellOrCellRangeMOC2ElemIt<T: Idx, Q: MocQty<T>, U: Idx, R: MocQty<U>> {
type It1: CellOrCellRangeMOCIterator<T, Qty = Q>;
type It2: CellOrCellRangeMOCIterator<U, Qty = R>;
fn cellcellrange_mocs_it(self) -> (Self::It1, Self::It2);
}
pub trait CellOrCellRangeMOC2Iterator<
T: Idx,
Q: MocQty<T>,
I: CellOrCellRangeMOCIterator<T, Qty = Q>,
U: Idx,
R: MocQty<U>,
J: CellOrCellRangeMOCIterator<U, Qty = R>,
K: CellOrCellRangeMOC2ElemIt<T, Q, U, R, It1 = I, It2 = J>,
>: Sized + MOC2Properties + Iterator<Item = K>
{
fn to_ascii_ivoa<W: Write>(
self,
fold: Option<usize>,
use_offset: bool,
writer: W,
) -> Result<(), AsciiError> {
moc2d_to_ascii_ivoa(self, &fold, use_offset, writer)
}
}
pub trait CellOrCellRangeMOC2IntoIterator<
T: Idx,
Q: MocQty<T>,
I: CellOrCellRangeMOCIterator<T, Qty = Q>,
U: Idx,
R: MocQty<U>,
J: CellOrCellRangeMOCIterator<U, Qty = R>,
K: CellOrCellRangeMOC2ElemIt<T, Q, U, R, It1 = I, It2 = J>,
>: Sized
{
type IntoCellOrCellRangeMOC2Iter: CellOrCellRangeMOC2Iterator<T, Q, I, U, R, J, K>;
fn into_cellcellrange_moc2_iter(self) -> Self::IntoCellOrCellRangeMOC2Iter;
}
pub trait CellMOC2ElemIt<T: Idx, Q: MocQty<T>, U: Idx, R: MocQty<U>> {
type It1: CellMOCIterator<T, Qty = Q>;
type It2: CellMOCIterator<U, Qty = R>;
fn cell_mocs_it(self) -> (Self::It1, Self::It2);
}
pub trait CellMOC2Iterator<
T: Idx,
Q: MocQty<T>,
I: CellMOCIterator<T, Qty = Q>,
U: Idx,
R: MocQty<U>,
J: CellMOCIterator<U, Qty = R>,
K: CellMOC2ElemIt<T, Q, U, R, It1 = I, It2 = J>,
>: Sized + MOC2Properties + Iterator<Item = K>
{
fn to_json_aladin<W: Write>(self, fold: &Option<usize>, writer: W) -> std::io::Result<()> {
cellmoc2d_to_json_aladin(self, fold, writer)
}
}
pub trait CellMOC2IntoIterator<
T: Idx,
Q: MocQty<T>,
I: CellMOCIterator<T, Qty = Q>,
U: Idx,
R: MocQty<U>,
J: CellMOCIterator<U, Qty = R>,
K: CellMOC2ElemIt<T, Q, U, R, It1 = I, It2 = J>,
>: Sized
{
type IntoCellMOC2Iter: CellMOC2Iterator<T, Q, I, U, R, J, K>;
fn into_cell_moc2_iter(self) -> Self::IntoCellMOC2Iter;
}
pub trait RangeMOC2ElemIt<T: Idx, Q: MocQty<T>, U: Idx, R: MocQty<U>> {
type It1: RangeMOCIterator<T, Qty = Q>;
type It2: RangeMOCIterator<U, Qty = R>;
fn range_mocs_it(self) -> (Self::It1, Self::It2);
}
pub trait RangeMOC2Iterator<
T: Idx,
Q: MocQty<T>,
I: RangeMOCIterator<T, Qty = Q>,
U: Idx,
R: MocQty<U>,
J: RangeMOCIterator<U, Qty = R>,
K: RangeMOC2ElemIt<T, Q, U, R, It1 = I, It2 = J>,
>: Sized + MOC2Properties + Iterator<Item = K>
{
fn into_range_moc2(self) -> RangeMOC2<T, Q, U, R> {
let depth_max_l = self.depth_max_1();
let depth_max_r = self.depth_max_2();
let elems: Vec<RangeMOC2Elem<T, Q, U, R>> = self
.map(|e| {
let (it_l, it_r) = e.range_mocs_it();
RangeMOC2Elem::new(it_l.into_range_moc(), it_r.into_range_moc())
})
.collect();
RangeMOC2::new(depth_max_l, depth_max_r, elems)
}
fn stats(self) -> (u64, u64, u64) {
self.fold((0, 0, 0), |(n, n1, n2), e| {
let (it1, it2) = e.range_mocs_it();
(n + 1, n1 + it1.count() as u64, n2 + it2.count() as u64)
})
}
fn or<I2, J2, K2, L2>(self, rhs: L2) -> OrRange2Iter<T, Q, U, R, I, J, K, Self, I2, J2, K2, L2>
where
I2: RangeMOCIterator<T, Qty = Q>,
J2: RangeMOCIterator<U, Qty = R>,
K2: RangeMOC2ElemIt<T, Q, U, R, It1 = I2, It2 = J2>,
L2: RangeMOC2Iterator<T, Q, I2, U, R, J2, K2>,
{
or(self, rhs)
}
}
pub trait RangeMOC2IntoIterator<
T: Idx,
Q: MocQty<T>,
I: RangeMOCIterator<T, Qty = Q>,
U: Idx,
R: MocQty<U>,
J: RangeMOCIterator<U, Qty = R>,
K: RangeMOC2ElemIt<T, Q, U, R, It1 = I, It2 = J>,
>: Sized
{
type IntoRangeMOC2Iter: RangeMOC2Iterator<T, Q, I, U, R, J, K>;
fn into_range_moc2_iter(self) -> Self::IntoRangeMOC2Iter;
}