{-# LANGUAGE FlexibleContexts #-} module Saturn.Unstable.Type.Range where import qualified Control.Monad as Monad import qualified Data.Coerce as Coerce import qualified Data.Set as Set import qualified Data.Text.Lazy.Builder as Builder import qualified Data.Word as Word import qualified Saturn.Unstable.Extra.Tuple as Tuple import qualified Saturn.Unstable.Type.Number as Number import qualified Text.Parsec as Parsec newtype Range = Range (Number.Number, Number.Number) deriving (Range -> Range -> Bool forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a /= :: Range -> Range -> Bool $c/= :: Range -> Range -> Bool == :: Range -> Range -> Bool $c== :: Range -> Range -> Bool Eq, Int -> Range -> ShowS [Range] -> ShowS Range -> String forall a. (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a showList :: [Range] -> ShowS $cshowList :: [Range] -> ShowS show :: Range -> String $cshow :: Range -> String showsPrec :: Int -> Range -> ShowS $cshowsPrec :: Int -> Range -> ShowS Show) fromTuple :: (Number.Number, Number.Number) -> Maybe Range fromTuple :: (Number, Number) -> Maybe Range fromTuple (Number lo, Number hi) = if Number -> Word8 Number.toWord8 Number lo forall a. Ord a => a -> a -> Bool > Number -> Word8 Number.toWord8 Number hi then forall a. Maybe a Nothing else forall a. a -> Maybe a Just forall a b. (a -> b) -> a -> b $ (Number, Number) -> Range Range (Number lo, Number hi) toTuple :: Range -> (Number.Number, Number.Number) toTuple :: Range -> (Number, Number) toTuple = coerce :: forall a b. Coercible a b => a -> b Coerce.coerce parsec :: (Parsec.Stream s m Char) => Parsec.ParsecT s u m Range parsec :: forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Range parsec = do Number lo <- forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Number Number.parsec forall (f :: * -> *) a. Functor f => f a -> f () Monad.void forall a b. (a -> b) -> a -> b $ forall s (m :: * -> *) u. Stream s m Char => Char -> ParsecT s u m Char Parsec.char Char '-' Number hi <- forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Number Number.parsec forall b a. b -> (a -> b) -> Maybe a -> b maybe (forall (m :: * -> *) a. MonadFail m => String -> m a fail String "invalid Range") forall (f :: * -> *) a. Applicative f => a -> f a pure forall a b. (a -> b) -> a -> b $ (Number, Number) -> Maybe Range fromTuple (Number lo, Number hi) toBuilder :: Range -> Builder.Builder toBuilder :: Range -> Builder toBuilder Range range = let (Number lo, Number hi) = Range -> (Number, Number) toTuple Range range in Number -> Builder Number.toBuilder Number lo forall a. Semigroup a => a -> a -> a <> Char -> Builder Builder.singleton Char '-' forall a. Semigroup a => a -> a -> a <> Number -> Builder Number.toBuilder Number hi isValid :: (Word.Word8, Word.Word8) -> Range -> Bool isValid :: (Word8, Word8) -> Range -> Bool isValid (Word8, Word8) tuple = forall a b c. (a -> b -> c) -> (a, b) -> c uncurry Bool -> Bool -> Bool (&&) forall b c a. (b -> c) -> (a -> b) -> a -> c . forall a b. (a -> b) -> (a, a) -> (b, b) Tuple.mapBoth ((Word8, Word8) -> Number -> Bool Number.isValid (Word8, Word8) tuple) forall b c a. (b -> c) -> (a -> b) -> a -> c . Range -> (Number, Number) toTuple expand :: Range -> Set.Set Word.Word8 expand :: Range -> Set Word8 expand = forall a. Ord a => [a] -> Set a Set.fromList forall b c a. (b -> c) -> (a -> b) -> a -> c . forall a. Enum a => (a, a) -> [a] Tuple.toSequence forall b c a. (b -> c) -> (a -> b) -> a -> c . forall a b. (a -> b) -> (a, a) -> (b, b) Tuple.mapBoth Number -> Word8 Number.toWord8 forall b c a. (b -> c) -> (a -> b) -> a -> c . Range -> (Number, Number) toTuple