42 lines
1.3 KiB
Plaintext
42 lines
1.3 KiB
Plaintext
module App.Validation.Label where
|
|
|
|
import Prelude
|
|
|
|
import Data.Either (Either(..))
|
|
import Data.Maybe (Maybe(..))
|
|
import Data.Validation.Semigroup (V, invalid, toEither)
|
|
|
|
import GenericParser.Parser as G
|
|
import GenericParser.SomeParsers as SomeParsers
|
|
import GenericParser.DomainParser.Common (DomainError) as DomainParser
|
|
import GenericParser.DomainParserRFC1035 (label) as RFC1035
|
|
|
|
data LabelParsingError
|
|
= CannotParse (DomainParser.DomainError)
|
|
| CannotEntirelyParse
|
|
| Size Int Int Int
|
|
|
|
data Error
|
|
= ParsingError (G.Error LabelParsingError)
|
|
|
|
min_label_size = 1 :: Int -- arbitrary
|
|
max_label_size = 63 :: Int -- arbitrary
|
|
|
|
parse :: forall e v. G.Parser e v -> String -> ((G.Error e) -> Error) -> V (Array Error) v
|
|
parse (G.Parser p) str c = case p { string: str, position: 0 } of
|
|
Left x -> invalid $ [c x]
|
|
Right x -> pure x.result
|
|
|
|
label_parser :: G.Parser LabelParsingError String
|
|
label_parser = do
|
|
input <- G.current_input
|
|
_ <- RFC1035.label G.<:> \e -> CannotParse e
|
|
_ <- SomeParsers.eof G.<:> \_ -> CannotEntirelyParse
|
|
pos <- G.current_position
|
|
if between min_label_size max_label_size pos
|
|
then pure input.string
|
|
else G.errorParser (Just $ Size min_label_size max_label_size pos)
|
|
|
|
label :: String -> Either (Array Error) String
|
|
label s = toEither $ parse label_parser s ParsingError
|