{-|
Module      : Monomer.Widgets.Util.Parser
Copyright   : (c) 2018 Francisco Vallarino
License     : BSD-3-Clause (see the LICENSE file)
Maintainer  : fjvallarino@gmail.com
Stability   : experimental
Portability : non-portable

Very basic parsing helpers used by numeric input fields.
-}
{-# LANGUAGE Strict #-}

module Monomer.Widgets.Util.Parser where

import Control.Applicative ((<|>))
import Data.Text (Text)

import qualified Data.Attoparsec.Text as A
import qualified Data.Text as T

-- | Combines a list of text parsers.
join :: [A.Parser Text] -> A.Parser Text
join :: [Parser Text] -> Parser Text
join [] = forall (m :: * -> *) a. Monad m => a -> m a
return Text
T.empty
join (Parser Text
x:[Parser Text]
xs) = forall a. Semigroup a => a -> a -> a
(<>) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Text
x forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> [Parser Text] -> Parser Text
join [Parser Text]
xs

-- | Combines a parser up to a maximum of repetitions.
upto :: Int -> A.Parser Text -> A.Parser Text
upto :: Int -> Parser Text -> Parser Text
upto Int
n Parser Text
p
  | Int
n forall a. Ord a => a -> a -> Bool
> Int
0 = forall a. Semigroup a => a -> a -> a
(<>) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall i a. Parser i a -> Parser i a
A.try Parser Text
p forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int -> Parser Text -> Parser Text
upto (Int
nforall a. Num a => a -> a -> a
-Int
1) Parser Text
p forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return Text
T.empty
  | Bool
otherwise = forall (m :: * -> *) a. Monad m => a -> m a
return Text
T.empty

-- | Matches a single character.
single :: Char -> A.Parser Text
single :: Char -> Parser Text
single Char
c = Char -> Text
T.singleton forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Char -> Parser Char
A.char Char
c