From ef6f49f624fcbfcd9199ff0201b6034b39a52463 Mon Sep 17 00:00:00 2001 From: Philippe Pittoli Date: Fri, 12 Jan 2024 05:14:55 +0100 Subject: [PATCH] Split code, implement more of DomainParser. --- src/BaseFunctions.purs | 28 ++++++++ src/DomainParser.purs | 147 +++++++++++++++++++++++++++++++++++++++++ src/Main.purs | 64 +++++++++++++----- src/Parser.purs | 36 +++------- 4 files changed, 231 insertions(+), 44 deletions(-) create mode 100644 src/BaseFunctions.purs create mode 100644 src/DomainParser.purs diff --git a/src/BaseFunctions.purs b/src/BaseFunctions.purs new file mode 100644 index 0000000..23f6952 --- /dev/null +++ b/src/BaseFunctions.purs @@ -0,0 +1,28 @@ +module BaseFunctions where + +import Prelude (between, (<>), (==)) + +import Data.Array as A +import Data.String.CodeUnits (singleton) + +concat :: Char -> String -> String +concat c rest = singleton c <> rest + +isDigit :: Char -> Boolean +isDigit = between '0' '9' + +isLower :: Char -> Boolean +isLower = between 'a' 'z' + +isUpper :: Char -> Boolean +isUpper = between 'A' 'Z' + +isAlpha :: Char -> Boolean +isAlpha c = A.any (\f -> f c) [isLower, isUpper] + +isAlphaNum :: Char -> Boolean +isAlphaNum c = A.any (\f -> f c) [isAlpha, isDigit] + +isSpace :: Char -> Boolean +isSpace c = A.any (\v -> v == c) [' ', '\t', ' ', '\r', '\n'] + diff --git a/src/DomainParser.purs b/src/DomainParser.purs new file mode 100644 index 0000000..0222ad3 --- /dev/null +++ b/src/DomainParser.purs @@ -0,0 +1,147 @@ +-- | `DomainParser` is a simple parser for domain names as described in RFC 1035. +module DomainParser where + +import Prelude +--import Prelude (bind, discard, pure, show, ($), (<>), (>)) + +import Data.Maybe (Maybe(..)) +import Data.Array as A +import Data.String as S +import Data.Tuple (Tuple(..)) +import Data.Array.NonEmpty as NonEmpty +import Data.String.CodeUnits as CU +import Control.Alt ((<|>)) +import Control.Plus (empty) + +import Parser + +-- From RFC 1035: ::= | +let_dig :: Parser Char +let_dig = alphanum + +-- From RFC 1035: ::= | "-" +-- Either a Letter, Digital or an Hyphenation character. +let_dig_hyp :: Parser Char +let_dig_hyp = let_dig <|> char '-' + +-- From RFC 1035: ::= | +ldh_str :: Parser (Array Char) +ldh_str = many1 let_dig_hyp + +-- TODO: 63 +label_maxsize :: Int +label_maxsize = 7 + +last_char :: String -> Maybe Char +last_char = A.last <<< CU.toCharArray + +parse_last_char :: String -> Parser Char -> Boolean +parse_last_char s p = case last_char s of + Nothing -> false + Just c -> case parse p (CU.singleton c) of + Nothing -> false + _ -> true + +try :: Parser String -> Parser String +try p = Parser p' + where p' str = case parse p str of + Nothing -> Just (Tuple "" str) -- FIXME: This is flawed: we cannot know if it worked! + Just x -> pure x + +-- From RFC 1035: