{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE OverloadedStrings #-}
module Brok.Parser.Links
( links
, url
) where
import ClassyPrelude
import Data.Attoparsec.Text
import Data.List (nub)
import Brok.Parser.Attoparsec
import Brok.Types.Link (URL)
type Token = Maybe URL
parens :: Parser Text -> Parser Text
parens parser = surround '(' ')' parser <|> surround '[' ']' parser
urlChar :: Parser Char
urlChar = digit <|> letter <|> choice (char <$> "-._~:/?#%@!$&*+,;=")
urlChars :: Parser Text
urlChars = concat <$> many1 (parens urlChars <|> (pack <$> many1 urlChar))
url :: Parser Text
url = concat4 <$> string "http" <*> chopt 's' <*> string "://" <*> urlChars
noise :: Parser Token
noise = anyChar >> return Nothing
urls :: Parser [URL]
urls = nub . catMaybes <$> many1 ((Just <$> url) <|> noise)
links :: Text -> Either Text [URL]
links "" = Right []
links content =
case parseOnly urls content of
Right c -> Right c
Left e -> Left $ tshow e