use std::fmt::Debug;
use std::ops::Range;
pub(super) mod combinators;
pub(super) mod types;
mod discrete;
pub use discrete::{DiscreteRanged, IntoSegmentedCoord, SegmentValue, SegmentedCoord};
pub trait DefaultValueFormatOption {}
pub struct DefaultFormatting;
impl DefaultValueFormatOption for DefaultFormatting {}
pub struct NoDefaultFormatting;
impl DefaultValueFormatOption for NoDefaultFormatting {}
pub trait ValueFormatter<V> {
fn format(_value: &V) -> String {
panic!("Unimplemented formatting method");
}
fn format_ext(&self, value: &V) -> String {
Self::format(value)
}
}
impl<R: Ranged<FormatOption = DefaultFormatting>> ValueFormatter<R::ValueType> for R
where
R::ValueType: Debug,
{
fn format(value: &R::ValueType) -> String {
format!("{:?}", value)
}
}
pub enum KeyPointWeight {
Bold,
Any,
}
impl KeyPointWeight {
pub fn allow_light_points(&self) -> bool {
match self {
KeyPointWeight::Bold => false,
KeyPointWeight::Any => true,
}
}
}
pub trait KeyPointHint {
fn max_num_points(&self) -> usize;
fn weight(&self) -> KeyPointWeight;
fn bold_points(&self) -> usize {
self.max_num_points()
}
}
impl KeyPointHint for usize {
fn max_num_points(&self) -> usize {
*self
}
fn weight(&self) -> KeyPointWeight {
KeyPointWeight::Any
}
}
pub struct BoldPoints(pub usize);
impl KeyPointHint for BoldPoints {
fn max_num_points(&self) -> usize {
self.0
}
fn weight(&self) -> KeyPointWeight {
KeyPointWeight::Bold
}
}
pub struct LightPoints {
bold_points_num: usize,
light_limit: usize,
}
impl LightPoints {
pub fn new(bold_count: usize, requested: usize) -> Self {
Self {
bold_points_num: bold_count,
light_limit: requested,
}
}
}
impl KeyPointHint for LightPoints {
fn max_num_points(&self) -> usize {
self.light_limit
}
fn bold_points(&self) -> usize {
self.bold_points_num
}
fn weight(&self) -> KeyPointWeight {
KeyPointWeight::Any
}
}
pub trait Ranged {
type FormatOption: DefaultValueFormatOption;
type ValueType;
fn map(&self, value: &Self::ValueType, limit: (i32, i32)) -> i32;
fn key_points<Hint: KeyPointHint>(&self, hint: Hint) -> Vec<Self::ValueType>;
fn range(&self) -> Range<Self::ValueType>;
#[allow(clippy::range_plus_one)]
fn axis_pixel_range(&self, limit: (i32, i32)) -> Range<i32> {
if limit.0 < limit.1 {
limit.0..limit.1
} else {
limit.1..limit.0
}
}
}
pub trait ReversibleRanged: Ranged {
fn unmap(&self, input: i32, limit: (i32, i32)) -> Option<Self::ValueType>;
}
pub trait AsRangedCoord: Sized {
type CoordDescType: Ranged<ValueType = Self::Value> + From<Self>;
type Value;
}
impl<T> AsRangedCoord for T
where
T: Ranged,
{
type CoordDescType = T;
type Value = T::ValueType;
}