module Unicode.CharacterDatabase.Parser.Properties.Multiple (parse, Entry (..)) where
import Data.ByteString qualified as B
import Data.ByteString.Char8 qualified as B8
import Data.ByteString.Short qualified as BS
import Data.List qualified as L
import Unicode.CharacterDatabase.Parser.Internal (
CodePointRange,
parseCodePointRange,
withParser,
pattern HashTag,
pattern SemiColon,
)
data Entry = Entry
{ Entry -> CodePointRange
range ∷ !CodePointRange
, Entry -> ShortByteString
property ∷ !BS.ShortByteString
, Entry -> Maybe ShortByteString
value ∷ !(Maybe BS.ShortByteString)
}
deriving (Entry -> Entry -> Bool
(Entry -> Entry -> Bool) -> (Entry -> Entry -> Bool) -> Eq Entry
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Entry -> Entry -> Bool
== :: Entry -> Entry -> Bool
$c/= :: Entry -> Entry -> Bool
/= :: Entry -> Entry -> Bool
Eq, Int -> Entry -> ShowS
[Entry] -> ShowS
Entry -> String
(Int -> Entry -> ShowS)
-> (Entry -> String) -> ([Entry] -> ShowS) -> Show Entry
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Entry -> ShowS
showsPrec :: Int -> Entry -> ShowS
$cshow :: Entry -> String
show :: Entry -> String
$cshowList :: [Entry] -> ShowS
showList :: [Entry] -> ShowS
Show)
parse ∷ B.ByteString → [Entry]
parse :: ByteString -> [Entry]
parse = (ByteString -> Maybe (Entry, ByteString)) -> ByteString -> [Entry]
forall b a. (b -> Maybe (a, b)) -> b -> [a]
L.unfoldr ((ByteString -> Maybe Entry)
-> ByteString -> Maybe (Entry, ByteString)
forall a.
(ByteString -> Maybe a) -> ByteString -> Maybe (a, ByteString)
withParser ByteString -> Maybe Entry
parsePropertyLine)
parsePropertyLine ∷ B.ByteString → Maybe Entry
parsePropertyLine :: ByteString -> Maybe Entry
parsePropertyLine ByteString
line
| ByteString -> Bool
B.null ByteString
line Bool -> Bool -> Bool
|| HasCallStack => ByteString -> Word8
ByteString -> Word8
B.head ByteString
line Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
HashTag = Maybe Entry
forall a. Maybe a
Nothing
| Bool
otherwise = Entry -> Maybe Entry
forall a. a -> Maybe a
Just Entry{Maybe ShortByteString
ShortByteString
CodePointRange
$sel:range:Entry :: CodePointRange
$sel:property:Entry :: ShortByteString
$sel:value:Entry :: Maybe ShortByteString
range :: CodePointRange
property :: ShortByteString
value :: Maybe ShortByteString
..}
where
(ByteString
rawRange, ByteString
line1) = (Word8 -> Bool) -> ByteString -> (ByteString, ByteString)
B.span (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
/= Word8
SemiColon) ByteString
line
line2 :: ByteString
line2 = (Word8 -> Bool) -> ByteString -> ByteString
B.takeWhile (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
/= Word8
HashTag) (HasCallStack => ByteString -> ByteString
ByteString -> ByteString
B.tail ByteString
line1)
range :: CodePointRange
range = ByteString -> CodePointRange
parseCodePointRange (ByteString -> ByteString
B8.strip ByteString
rawRange)
(ByteString
rawProperty, ByteString -> ByteString
B8.strip → ByteString
rawValue) = (Word8 -> Bool) -> ByteString -> (ByteString, ByteString)
B.span (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
/= Word8
SemiColon) ByteString
line2
property :: ShortByteString
property = ByteString -> ShortByteString
BS.toShort (ByteString -> ByteString
B8.strip ByteString
rawProperty)
value :: Maybe ShortByteString
value = if ByteString -> Bool
B.null ByteString
rawValue then Maybe ShortByteString
forall a. Maybe a
Nothing else ShortByteString -> Maybe ShortByteString
forall a. a -> Maybe a
Just (ByteString -> ShortByteString
BS.toShort (ByteString -> ByteString
B8.strip (Int -> ByteString -> ByteString
B.drop Int
1 ByteString
rawValue)))