#![ cfg_attr( not( feature = "use_std" ), no_std ) ] #![ doc( html_logo_url = "https://raw.githubusercontent.com/Wandalen/wTools/master/asset/img/logo_v3_trans_square.png" ) ] #![ doc( html_favicon_url = "https://raw.githubusercontent.com/Wandalen/wTools/alpha/asset/img/logo_v3_trans_square_icon_small_v2.ico" ) ] #![ doc( html_root_url = "https://docs.rs/winterval/latest/winterval/" ) ] #![ warn( rust_2018_idioms ) ] #![ warn( missing_debug_implementations ) ] #![ warn( missing_docs ) ] /* zzz : consider https://doc.rust-lang.org/std/ops/trait.RangeBounds.html */ /* zzz : implement iterator */ //! //! Interval adapter for both open/closed implementations of intervals ( ranges ). //! #![ doc = include_str!( concat!( env!( "CARGO_MANIFEST_DIR" ), "/Readme.md" ) ) ] /// Internal namespace. #[ cfg( feature = "use_std" ) ] pub( crate ) mod private { /// /// Interval adapter. Interface to interval-like structures. /// pub trait IntervalAdapter< T = isize > where T : std::ops::Sub< Output = T > + std::ops::Add< Output = T > + Copy, isize : Into< T >, { /// the first element of the ( closed ) interval fn first( &self ) -> T; /// the last element of the ( closed ) interval fn last( &self ) -> T; /// number of discrete elements in the interval fn len( &self ) -> T { let one : T = 1.into(); self.last() - self.first() + one } /// interval in closed format as pair of numbers fn closed( &self ) -> ( T, T ) { ( self.first(), self.last() ) } /// interval in closed-open format as pair of numbers fn closed_open( &self ) -> ( T, T ) { let one : T = 1.into(); ( self.first(), self.last() + one ) } /// interval in first-length format as pair of numbers fn first_len( &self ) -> ( T, T ) { ( self.first(), self.len() ) } } /// /// Alternative implementation of interval. /// /// Both [core::ops::Range], [core::ops::RangeInclusive] are convertable to [crate::Interval] /// #[ derive( PartialEq, Debug ) ] pub struct Interval< T = isize > where T : std::ops::Sub< Output = T > + std::ops::Add< Output = T > + Copy, isize : Into< T >, { _first : T, _last : T, } impl< T > Interval< T > where T : std::ops::Sub< Output = T > + std::ops::Add< Output = T > + Copy, isize : Into< T >, { /// Constructor of an interval. Expects closed interval in arguments. pub fn new( first : T, last : T ) -> Self { Self { _first : first, _last : last } } } impl< T > IntervalAdapter< T > for Interval< T > where T : std::ops::Sub< Output = T > + std::ops::Add< Output = T > + Copy, isize : Into< T >, { fn first( &self ) -> T { self._first } fn last( &self ) -> T { self._last } } // // IntervalAdapter for std // impl< T > IntervalAdapter< T > for ::core::ops::Range< T > where T : std::ops::Sub< Output = T > + std::ops::Add< Output = T > + Copy, isize : Into< T >, { fn first( &self ) -> T { self.start } fn last( &self ) -> T { let one : T = 1.into(); self.end - one } } impl< T > IntervalAdapter< T > for ::core::ops::RangeInclusive< T > where T : std::ops::Sub< Output = T > + std::ops::Add< Output = T > + Copy, isize : Into< T >, { fn first( &self ) -> T { *self.start() } fn last( &self ) -> T { *self.end() } } // // from for std // impl< T > From< ::core::ops::Range< T > > for Interval< T > where T : std::ops::Sub< Output = T > + std::ops::Add< Output = T > + Copy, isize : Into< T >, { fn from( src : ::core::ops::Range< T > ) -> Self { let one : T = 1.into(); Self { _first : src.start, _last : src.end - one } } } // impl< T > From< ::core::ops::RangeInclusive< T > > for Interval< T > where T : std::ops::Sub< Output = T > + std::ops::Add< Output = T > + Copy, isize : Into< T >, { fn from( src : ::core::ops::RangeInclusive< T > ) -> Self { Self { _first : *src.start(), _last : *src.end() } } } } /// Protected namespace of the module. pub mod protected { pub use super::orphan::*; } pub use protected::*; /// Parented namespace of the module. pub mod orphan { pub use super::exposed::*; } /// Exposed namespace of the module. pub mod exposed { pub use super::prelude::*; #[ cfg( feature = "use_std" ) ] pub use super::private:: { IntervalAdapter, Interval, }; } pub use exposed::*; /// Prelude to use essentials: `use my_module::prelude::*`. pub mod prelude { }