{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE UnboxedSums #-}
{-# LANGUAGE UnboxedTuples #-}

module Data.Maybe.Unpacked.Text.Short
  ( MaybeShortText(..)
  , just
  , nothing

  , maybe

  , isJust
  , isNothing
  , fromMaybe
  , listToMaybe
  , maybeToList
  , catMaybes
  , mapMaybe

  , toBaseMaybe
  , fromBaseMaybe
  ) where 

import Prelude hiding (Maybe,maybe)

import GHC.Base (build)
import Data.ByteString.Short.Internal (ShortByteString(SBS))
import Data.Text.Short (ShortText,toShortByteString)
import Data.Text.Short.Unsafe (fromShortByteStringUnsafe)
import GHC.Exts (ByteArray#)

import GHC.Read (Read(readPrec))
import Text.Read (parens, Lexeme(Ident), lexP, (+++))
import Text.ParserCombinators.ReadPrec (prec, step)

import qualified Prelude as P

-- | Either a 'ShortText' or nothing. Do not use the
-- data constructor directly since it allows you to
-- circumvent encoding invariants.
data MaybeShortText = MaybeShortText (# (# #) | ByteArray# #)

unboxShortText :: ShortText -> ByteArray#
unboxShortText :: ShortText -> ByteArray#
unboxShortText ShortText
x = case ShortText -> ShortByteString
toShortByteString ShortText
x of SBS ByteArray#
y -> ByteArray#
y

boxShortText :: ByteArray# -> ShortText
boxShortText :: ByteArray# -> ShortText
boxShortText ByteArray#
x = ShortByteString -> ShortText
fromShortByteStringUnsafe (ByteArray# -> ShortByteString
SBS ByteArray#
x)

instance Eq MaybeShortText where
  MaybeShortText
ma == :: MaybeShortText -> MaybeShortText -> Bool
== MaybeShortText
mb =
    Bool -> (ShortText -> Bool) -> MaybeShortText -> Bool
forall a. a -> (ShortText -> a) -> MaybeShortText -> a
maybe (MaybeShortText -> Bool
isNothing MaybeShortText
mb)
          (\ShortText
a -> Bool -> (ShortText -> Bool) -> MaybeShortText -> Bool
forall a. a -> (ShortText -> a) -> MaybeShortText -> a
maybe Bool
False (\ShortText
b -> ShortText
a ShortText -> ShortText -> Bool
forall a. Eq a => a -> a -> Bool
== ShortText
b) MaybeShortText
mb) MaybeShortText
ma
    
instance Ord MaybeShortText where
  compare :: MaybeShortText -> MaybeShortText -> Ordering
compare MaybeShortText
ma MaybeShortText
mb = Ordering -> (ShortText -> Ordering) -> MaybeShortText -> Ordering
forall a. a -> (ShortText -> a) -> MaybeShortText -> a
maybe Ordering
LT (\ShortText
a -> Ordering -> (ShortText -> Ordering) -> MaybeShortText -> Ordering
forall a. a -> (ShortText -> a) -> MaybeShortText -> a
maybe Ordering
GT (ShortText -> ShortText -> Ordering
forall a. Ord a => a -> a -> Ordering
compare ShortText
a) MaybeShortText
mb) MaybeShortText
ma  

instance Show MaybeShortText where
  showsPrec :: Int -> MaybeShortText -> ShowS
showsPrec Int
p (MaybeShortText (# (# #) | ByteArray# #)
m) = case (# (# #) | ByteArray# #)
m of
    (# (# #) | #) -> String -> ShowS
showString String
"nothing"
    (# | ByteArray#
i #) -> Bool -> ShowS -> ShowS
showParen (Int
p Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
10)
      (ShowS -> ShowS) -> ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ String -> ShowS
showString String
"just "
      ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> ShortText -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
11 (ByteArray# -> ShortText
boxShortText ByteArray#
i)

instance Read MaybeShortText where
  readPrec :: ReadPrec MaybeShortText
readPrec = ReadPrec MaybeShortText -> ReadPrec MaybeShortText
forall a. ReadPrec a -> ReadPrec a
parens (ReadPrec MaybeShortText -> ReadPrec MaybeShortText)
-> ReadPrec MaybeShortText -> ReadPrec MaybeShortText
forall a b. (a -> b) -> a -> b
$ ReadPrec MaybeShortText
nothingP ReadPrec MaybeShortText
-> ReadPrec MaybeShortText -> ReadPrec MaybeShortText
forall a. ReadPrec a -> ReadPrec a -> ReadPrec a
+++ ReadPrec MaybeShortText
justP
    where
      nothingP :: ReadPrec MaybeShortText
nothingP = Int -> ReadPrec MaybeShortText -> ReadPrec MaybeShortText
forall a. Int -> ReadPrec a -> ReadPrec a
prec Int
10 (ReadPrec MaybeShortText -> ReadPrec MaybeShortText)
-> ReadPrec MaybeShortText -> ReadPrec MaybeShortText
forall a b. (a -> b) -> a -> b
$ do
        Ident String
"nothing" <- ReadPrec Lexeme
lexP
        MaybeShortText -> ReadPrec MaybeShortText
forall a. a -> ReadPrec a
forall (m :: * -> *) a. Monad m => a -> m a
return MaybeShortText
nothing
      justP :: ReadPrec MaybeShortText
justP = Int -> ReadPrec MaybeShortText -> ReadPrec MaybeShortText
forall a. Int -> ReadPrec a -> ReadPrec a
prec Int
10 (ReadPrec MaybeShortText -> ReadPrec MaybeShortText)
-> ReadPrec MaybeShortText -> ReadPrec MaybeShortText
forall a b. (a -> b) -> a -> b
$ do
        Ident String
"just" <- ReadPrec Lexeme
lexP
        ShortText
a <- ReadPrec ShortText -> ReadPrec ShortText
forall a. ReadPrec a -> ReadPrec a
step ReadPrec ShortText
forall a. Read a => ReadPrec a
readPrec
        MaybeShortText -> ReadPrec MaybeShortText
forall a. a -> ReadPrec a
forall (m :: * -> *) a. Monad m => a -> m a
return (ShortText -> MaybeShortText
just ShortText
a)

listToMaybe :: [ShortText] -> MaybeShortText
listToMaybe :: [ShortText] -> MaybeShortText
listToMaybe [] = MaybeShortText
nothing
listToMaybe (ShortText
x:[ShortText]
_) = ShortText -> MaybeShortText
just ShortText
x

maybeToList :: MaybeShortText -> [ShortText]
maybeToList :: MaybeShortText -> [ShortText]
maybeToList = [ShortText]
-> (ShortText -> [ShortText]) -> MaybeShortText -> [ShortText]
forall a. a -> (ShortText -> a) -> MaybeShortText -> a
maybe [] (ShortText -> [ShortText] -> [ShortText]
forall a. a -> [a] -> [a]
: [])

catMaybes :: [MaybeShortText] -> [ShortText]
catMaybes :: [MaybeShortText] -> [ShortText]
catMaybes = (MaybeShortText -> MaybeShortText)
-> [MaybeShortText] -> [ShortText]
forall a. (a -> MaybeShortText) -> [a] -> [ShortText]
mapMaybe MaybeShortText -> MaybeShortText
forall a. a -> a
id

mapMaybe :: (a -> MaybeShortText) -> [a] -> [ShortText]
mapMaybe :: forall a. (a -> MaybeShortText) -> [a] -> [ShortText]
mapMaybe a -> MaybeShortText
_ [] = []
mapMaybe a -> MaybeShortText
f (a
a : [a]
as) =
  let ws :: [ShortText]
ws = (a -> MaybeShortText) -> [a] -> [ShortText]
forall a. (a -> MaybeShortText) -> [a] -> [ShortText]
mapMaybe a -> MaybeShortText
f [a]
as
  in [ShortText]
-> (ShortText -> [ShortText]) -> MaybeShortText -> [ShortText]
forall a. a -> (ShortText -> a) -> MaybeShortText -> a
maybe [ShortText]
ws (ShortText -> [ShortText] -> [ShortText]
forall a. a -> [a] -> [a]
: [ShortText]
ws) (a -> MaybeShortText
f a
a)
{-# NOINLINE [1] mapMaybe #-}

{-# RULES
"mapMaybe"     [~1] forall f xs. mapMaybe f xs
                    = build (\c n -> foldr (mapMaybeFB c f) n xs)
"mapMaybeList" [1]  forall f. foldr (mapMaybeFB (:) f) [] = mapMaybe f
  #-}

{-# NOINLINE [0] mapMaybeFB #-}
mapMaybeFB :: (ShortText -> r -> r) -> (a -> MaybeShortText) -> a -> r -> r
mapMaybeFB :: forall r a.
(ShortText -> r -> r) -> (a -> MaybeShortText) -> a -> r -> r
mapMaybeFB ShortText -> r -> r
cons a -> MaybeShortText
f a
x r
next = r -> (ShortText -> r) -> MaybeShortText -> r
forall a. a -> (ShortText -> a) -> MaybeShortText -> a
maybe r
next ((ShortText -> r -> r) -> r -> ShortText -> r
forall a b c. (a -> b -> c) -> b -> a -> c
flip ShortText -> r -> r
cons r
next) (a -> MaybeShortText
f a
x)

isNothing :: MaybeShortText -> Bool
isNothing :: MaybeShortText -> Bool
isNothing = Bool -> (ShortText -> Bool) -> MaybeShortText -> Bool
forall a. a -> (ShortText -> a) -> MaybeShortText -> a
maybe Bool
True (Bool -> ShortText -> Bool
forall a b. a -> b -> a
const Bool
False)

isJust :: MaybeShortText -> Bool
isJust :: MaybeShortText -> Bool
isJust = Bool -> (ShortText -> Bool) -> MaybeShortText -> Bool
forall a. a -> (ShortText -> a) -> MaybeShortText -> a
maybe Bool
False (Bool -> ShortText -> Bool
forall a b. a -> b -> a
const Bool
True)

nothing :: MaybeShortText
nothing :: MaybeShortText
nothing = (# (# #) | ByteArray# #) -> MaybeShortText
MaybeShortText (# (# #) | #)

just :: ShortText -> MaybeShortText
just :: ShortText -> MaybeShortText
just ShortText
x = (# (# #) | ByteArray# #) -> MaybeShortText
MaybeShortText (# | ShortText -> ByteArray#
unboxShortText ShortText
x #)

fromMaybe :: ShortText -> MaybeShortText -> ShortText
fromMaybe :: ShortText -> MaybeShortText -> ShortText
fromMaybe ShortText
a (MaybeShortText (# (# #) | ByteArray# #)
m) = case (# (# #) | ByteArray# #)
m of
  (# (# #) | #) -> ShortText
a
  (# | ByteArray#
i #) -> ByteArray# -> ShortText
boxShortText ByteArray#
i

maybe :: a -> (ShortText -> a) -> MaybeShortText -> a
maybe :: forall a. a -> (ShortText -> a) -> MaybeShortText -> a
maybe a
a ShortText -> a
f (MaybeShortText (# (# #) | ByteArray# #)
m) = case (# (# #) | ByteArray# #)
m of
  (# (# #) | #) -> a
a
  (# | ByteArray#
i #) -> ShortText -> a
f (ByteArray# -> ShortText
boxShortText ByteArray#
i)

toBaseMaybe :: MaybeShortText -> P.Maybe ShortText
toBaseMaybe :: MaybeShortText -> Maybe ShortText
toBaseMaybe = Maybe ShortText
-> (ShortText -> Maybe ShortText)
-> MaybeShortText
-> Maybe ShortText
forall a. a -> (ShortText -> a) -> MaybeShortText -> a
maybe Maybe ShortText
forall a. Maybe a
P.Nothing ShortText -> Maybe ShortText
forall a. a -> Maybe a
P.Just

fromBaseMaybe :: P.Maybe ShortText -> MaybeShortText
fromBaseMaybe :: Maybe ShortText -> MaybeShortText
fromBaseMaybe = MaybeShortText
-> (ShortText -> MaybeShortText)
-> Maybe ShortText
-> MaybeShortText
forall b a. b -> (a -> b) -> Maybe a -> b
P.maybe MaybeShortText
nothing ShortText -> MaybeShortText
just