{-# 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 (Range -> Range -> Bool) -> (Range -> Range -> Bool) -> Eq Range forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a $c== :: Range -> Range -> Bool == :: Range -> Range -> Bool $c/= :: Range -> Range -> Bool /= :: Range -> Range -> Bool Eq, Int -> Range -> ShowS [Range] -> ShowS Range -> String (Int -> Range -> ShowS) -> (Range -> String) -> ([Range] -> ShowS) -> Show Range forall a. (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a $cshowsPrec :: Int -> Range -> ShowS showsPrec :: Int -> Range -> ShowS $cshow :: Range -> String show :: Range -> String $cshowList :: [Range] -> ShowS showList :: [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 Word8 -> Word8 -> Bool forall a. Ord a => a -> a -> Bool > Number -> Word8 Number.toWord8 Number hi then Maybe Range forall a. Maybe a Nothing else Range -> Maybe Range forall a. a -> Maybe a Just (Range -> Maybe Range) -> Range -> Maybe Range 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 = Range -> (Number, Number) 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 <- ParsecT s u m Number forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Number Number.parsec ParsecT s u m Char -> ParsecT s u m () forall (f :: * -> *) a. Functor f => f a -> f () Monad.void (ParsecT s u m Char -> ParsecT s u m ()) -> ParsecT s u m Char -> ParsecT s u m () forall a b. (a -> b) -> a -> b $ Char -> ParsecT s u m Char forall s (m :: * -> *) u. Stream s m Char => Char -> ParsecT s u m Char Parsec.char Char '-' Number hi <- ParsecT s u m Number forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Number Number.parsec ParsecT s u m Range -> (Range -> ParsecT s u m Range) -> Maybe Range -> ParsecT s u m Range forall b a. b -> (a -> b) -> Maybe a -> b maybe (String -> ParsecT s u m Range forall a. String -> ParsecT s u m a forall (m :: * -> *) a. MonadFail m => String -> m a fail String "invalid Range") Range -> ParsecT s u m Range forall a. a -> ParsecT s u m a forall (f :: * -> *) a. Applicative f => a -> f a pure (Maybe Range -> ParsecT s u m Range) -> Maybe Range -> ParsecT s u m Range 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 Builder -> Builder -> Builder forall a. Semigroup a => a -> a -> a <> Char -> Builder Builder.singleton Char '-' Builder -> Builder -> Builder 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 = (Bool -> Bool -> Bool) -> (Bool, Bool) -> Bool forall a b c. (a -> b -> c) -> (a, b) -> c uncurry Bool -> Bool -> Bool (&&) ((Bool, Bool) -> Bool) -> (Range -> (Bool, Bool)) -> Range -> Bool forall b c a. (b -> c) -> (a -> b) -> a -> c . (Number -> Bool) -> (Number, Number) -> (Bool, Bool) forall a b. (a -> b) -> (a, a) -> (b, b) Tuple.mapBoth ((Word8, Word8) -> Number -> Bool Number.isValid (Word8, Word8) tuple) ((Number, Number) -> (Bool, Bool)) -> (Range -> (Number, Number)) -> Range -> (Bool, Bool) 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 = [Word8] -> Set Word8 forall a. Ord a => [a] -> Set a Set.fromList ([Word8] -> Set Word8) -> (Range -> [Word8]) -> Range -> Set Word8 forall b c a. (b -> c) -> (a -> b) -> a -> c . (Word8, Word8) -> [Word8] forall a. Enum a => (a, a) -> [a] Tuple.toSequence ((Word8, Word8) -> [Word8]) -> (Range -> (Word8, Word8)) -> Range -> [Word8] forall b c a. (b -> c) -> (a -> b) -> a -> c . (Number -> Word8) -> (Number, Number) -> (Word8, Word8) forall a b. (a -> b) -> (a, a) -> (b, b) Tuple.mapBoth Number -> Word8 Number.toWord8 ((Number, Number) -> (Word8, Word8)) -> (Range -> (Number, Number)) -> Range -> (Word8, Word8) forall b c a. (b -> c) -> (a -> b) -> a -> c . Range -> (Number, Number) toTuple