module Okapi.HTTP.RFC9651.List ( List, parser, printer, item, innerList, items, raw, ) where import Data.ByteString (ByteString) import Data.ByteString qualified as BS import Data.Kind (Type) import Okapi.Tree (Failure, Leaf, Parser, Printer, Context) import Okapi.Tree qualified as Tree import Okapi.Tree (Tree (..)) import Okapi.Tree qualified as Tree import Okapi.HTTP.RFC9651.BareItem (BareItem, parseInnerToList, renderInner) import Okapi.HTTP.RFC9651.Item (Item) import Okapi.HTTP.RFC9651.Item qualified as Item import Okapi.HTTP.RFC9651.Lexer (ParseError (..), firstAndRest, splitTop, strip) type List :: Type -> Type data List a where ListItem :: Tree Item a a -> List a InnerList :: Leaf BareItem a -> List [a] Items :: Tree Item a a -> List [a] Raw :: List ByteString type instance Context List = ByteString type instance Failure List = ParseError item :: Tree Item a a -> Tree List a a item :: forall a. Tree Item a a -> Tree List a a item = List a -> Tree List a a forall (t :: * -> *) i. t i -> Tree t i i Node (List a -> Tree List a a) -> (Tree Item a a -> List a) -> Tree Item a a -> Tree List a a forall b c a. (b -> c) -> (a -> b) -> a -> c . Tree Item a a -> List a forall a. Tree Item a a -> List a ListItem innerList :: Leaf BareItem a -> Tree List [a] [a] innerList :: forall a. Leaf BareItem a -> Tree List [a] [a] innerList = List [a] -> Tree List [a] [a] forall (t :: * -> *) i. t i -> Tree t i i Node (List [a] -> Tree List [a] [a]) -> (Leaf BareItem a -> List [a]) -> Leaf BareItem a -> Tree List [a] [a] forall b c a. (b -> c) -> (a -> b) -> a -> c . Leaf BareItem a -> List [a] forall a. Leaf BareItem a -> List [a] InnerList items :: Tree Item a a -> Tree List [a] [a] items :: forall a. Tree Item a a -> Tree List [a] [a] items = List [a] -> Tree List [a] [a] forall (t :: * -> *) i. t i -> Tree t i i Node (List [a] -> Tree List [a] [a]) -> (Tree Item a a -> List [a]) -> Tree Item a a -> Tree List [a] [a] forall b c a. (b -> c) -> (a -> b) -> a -> c . Tree Item a a -> List [a] forall a. Tree Item a a -> List [a] Items raw :: Tree List ByteString ByteString raw :: Tree List ByteString ByteString raw = List ByteString -> Tree List ByteString ByteString forall (t :: * -> *) i. t i -> Tree t i i Node List ByteString Raw parser :: Tree List i o -> Parser List o parser :: forall i o. Tree List i o -> Parser List o parser = (forall a. List a -> Parser List a) -> Tree List i o -> Context List -> (Either (Failure List) o, Context List) forall (t :: * -> *) i o. (forall a. t a -> Parser t a) -> Tree t i o -> Parser t o Tree.parser List a -> Parser List a forall a. List a -> Parser List a alg where alg :: List a -> Parser List a alg :: forall a. List a -> Parser List a alg List a t Context List s = case List a t of ListItem Tree Item a a c -> let (ByteString m, ByteString rest) = Word8 -> ByteString -> (ByteString, ByteString) firstAndRest Word8 44 ByteString Context List s in ((Either ParseError a, ByteString) -> Either ParseError a forall a b. (a, b) -> a fst (Tree Item a a -> Parser Item a forall i o. Tree Item i o -> Parser Item o Item.parser Tree Item a a c (ByteString -> ByteString strip ByteString m)), ByteString Context List rest) InnerList Leaf BareItem a vLeaf -> let (ByteString m, ByteString rest) = Word8 -> ByteString -> (ByteString, ByteString) firstAndRest Word8 44 ByteString Context List s in (Leaf BareItem a -> ByteString -> Either ParseError [a] forall a. Leaf BareItem a -> ByteString -> Either ParseError [a] parseInnerToList Leaf BareItem a vLeaf (ByteString -> ByteString strip ByteString m), ByteString Context List rest) Items Tree Item a a c -> ((ByteString -> Either ParseError a) -> [ByteString] -> Either ParseError [a] forall (t :: * -> *) (f :: * -> *) a b. (Traversable t, Applicative f) => (a -> f b) -> t a -> f (t b) forall (f :: * -> *) a b. Applicative f => (a -> f b) -> [a] -> f [b] traverse (\ByteString m -> (Either ParseError a, ByteString) -> Either ParseError a forall a b. (a, b) -> a fst (Tree Item a a -> Parser Item a forall i o. Tree Item i o -> Parser Item o Item.parser Tree Item a a c ByteString Context Item m)) (ByteString -> [ByteString] members ByteString Context List s), ByteString Context List BS.empty) List a Raw -> (a -> Either ParseError a forall a b. b -> Either a b Right a Context List s, ByteString Context List BS.empty) where members :: ByteString -> [ByteString] members ByteString bs = (ByteString -> Bool) -> [ByteString] -> [ByteString] forall a. (a -> Bool) -> [a] -> [a] filter (Bool -> Bool not (Bool -> Bool) -> (ByteString -> Bool) -> ByteString -> Bool forall b c a. (b -> c) -> (a -> b) -> a -> c . ByteString -> Bool BS.null) ((ByteString -> ByteString) -> [ByteString] -> [ByteString] forall a b. (a -> b) -> [a] -> [b] map ByteString -> ByteString strip (Word8 -> ByteString -> [ByteString] splitTop Word8 44 ByteString bs)) printer :: Tree List i o -> Printer List i printer :: forall i o. Tree List i o -> Printer List i printer = (forall a. List a -> Printer List a) -> Tree List i o -> i -> Context List forall (t :: * -> *) i o. Monoid (Context t) => (forall a. t a -> Printer t a) -> Tree t i o -> Printer t i Tree.printer List a -> Printer List a forall a. List a -> Printer List a alg where alg :: List a -> Printer List a alg :: forall a. List a -> Printer List a alg (ListItem Tree Item a a c) a a = ByteString ", " ByteString -> ByteString -> ByteString forall a. Semigroup a => a -> a -> a <> Tree Item a a -> Printer Item a forall i o. Tree Item i o -> Printer Item i Item.printer Tree Item a a c a a alg (InnerList Leaf BareItem a vLeaf) a xs = ByteString ", " ByteString -> ByteString -> ByteString forall a. Semigroup a => a -> a -> a <> Leaf BareItem a -> [a] -> ByteString forall a. Leaf BareItem a -> [a] -> ByteString renderInner Leaf BareItem a vLeaf a [a] xs alg (Items Tree Item a a c) a xs = [ByteString] -> ByteString BS.concat [ByteString ", " ByteString -> ByteString -> ByteString forall a. Semigroup a => a -> a -> a <> Tree Item a a -> Printer Item a forall i o. Tree Item i o -> Printer Item i Item.printer Tree Item a a c a x | a x <- a [a] xs] alg List a Raw a bs = a Context List bs