// (c) 2023 John A. Breaux // This code is licensed under MIT license (see LICENSE for details) //! Holder for any [Range] // This is super over-engineered, considering it was originally meant to help with only one LOC use std::ops::{Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive}; use thiserror::Error; #[macro_use] mod macros; #[derive(Clone, Debug, Error, PartialEq, Eq, Hash)] #[error("Failed to convert variant {0} back into range.")] /// Emitted when conversion back into a [std::ops]::Range\* fails. pub struct AnyRangeError(AnyRange); /// Holder for any [Range] #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub enum AnyRange { /// Bounded exclusive [Range] i.e. `0..10` Range(Range), /// Unbounded [RangeFrom], i.e. `0..` RangeFrom(RangeFrom), /// Unbounded [RangeFull], i.e. `..` RangeFull(RangeFull), /// Bounded inclusive [RangeInclusive], i.e. `0..=10` RangeInclusive(RangeInclusive), /// Unbounded [RangeTo], i.e. `..10` RangeTo(RangeTo), /// Unbounded inclusive [RangeToInclusive], i.e. `..=10` RangeToInclusive(RangeToInclusive), } variant_from! { match impl (From, TryInto) for AnyRange { type Error = AnyRangeError; Range => AnyRange::Range, RangeFrom => AnyRange::RangeFrom, RangeFull => AnyRange::RangeFull, RangeInclusive => AnyRange::RangeInclusive, RangeTo => AnyRange::RangeTo, RangeToInclusive => AnyRange::RangeToInclusive, } } /// Convenient conversion functions from [AnyRange] to the inner type impl AnyRange { try_into_fn! { /// Converts from [AnyRange::Range] into a [Range], else [None] pub fn range(self) -> Option>; /// Converts from [AnyRange::RangeFrom] into a [RangeFrom], else [None] pub fn range_from(self) -> Option>; /// Converts from [AnyRange::RangeFull] into a [RangeFull], else [None] pub fn range_full(self) -> Option; /// Converts from [AnyRange::RangeInclusive] into a [RangeInclusive], else [None] pub fn range_inclusive(self) -> Option>; /// Converts from [AnyRange::RangeTo] into a [RangeTo], else [None] pub fn range_to(self) -> Option>; /// Converts from [AnyRange::RangeToInclusive] into a [RangeToInclusive], else [None] pub fn range_to_inclusive(self) -> Option>; } } impl From> for AnyRangeError { fn from(value: AnyRange) -> Self { AnyRangeError(value) } }