Correct IPv6 Parser

parser
Bram 2024-04-12 13:14:50 +02:00
parent b3e103a5d9
commit ae19884a18
5 changed files with 62 additions and 11 deletions

View File

@ -149,8 +149,13 @@ ipv6Parser =
ipv6LeftParser ipv6LeftParser
|> P.andThen |> P.andThen
(\front -> (\front ->
if List.length front < 8 then
P.succeed (IPv6Address front) P.succeed (IPv6Address front)
|= ipv6RightParser (8 - List.length front) |= ipv6RightParser (8 - 1 - List.length front)
-- The -1 is because :: implies one or more zeroes
else
P.succeed (IPv6Address front [])
) )
@ -175,6 +180,7 @@ ipv6RightParser n =
else else
P.succeed [] P.succeed []
|. P.symbol ":"
{-| Convert an IPv6 address to a readable string format {-| Convert an IPv6 address to a readable string format

View File

@ -74,6 +74,7 @@ import Internal.Tools.DecodeExtra as D
import Internal.Tools.EncodeExtra as E import Internal.Tools.EncodeExtra as E
import Json.Decode as D import Json.Decode as D
import Json.Encode as E import Json.Encode as E
import Parser as P
import Set exposing (Set) import Set exposing (Set)
@ -158,6 +159,7 @@ type Docs
} }
) )
| DocsOptional Docs | DocsOptional Docs
| DocsParser String
| DocsRiskyMap (Descriptive { content : Docs, failure : List String }) | DocsRiskyMap (Descriptive { content : Docs, failure : List String })
| DocsSet Docs | DocsSet Docs
| DocsString | DocsString
@ -1152,6 +1154,27 @@ object11 { name, description, init } fa fb fc fd fe ff fg fh fi fj fk =
} }
{-| Define a parser that converts a string into a custom Elm type.
-}
parser : { name : String, p : P.Parser ( a, List Log ), toString : a -> String } -> Coder a
parser { name, p, toString } =
Coder
{ encoder = toString >> E.string
, decoder =
D.string
|> D.andThen
(\v ->
case P.run p v of
Err _ ->
D.fail ("Failed to parse " ++ name ++ "!")
Ok o ->
D.succeed o
)
, docs = DocsParser name
}
{-| Define a set. {-| Define a set.
-} -}
set : Coder comparable -> Coder (Set comparable) set : Coder comparable -> Coder (Set comparable)

View File

@ -87,3 +87,19 @@ times inf sup parser =
exactly : Int -> Parser a -> Parser (List a) exactly : Int -> Parser a -> Parser (List a)
exactly n = exactly n =
times n n times n n
maxLength : Int -> Parser a -> Parser a
maxLength n parser =
P.succeed
(\start value end ->
if abs (end - start) > n then
P.problem "Parsed too much text!"
else
P.succeed value
)
|= P.getOffset
|= parser
|= P.getOffset
|> P.andThen identity

View File

@ -62,7 +62,7 @@ ipv6Fuzzer =
|> Fuzz.andThen |> Fuzz.andThen
(\front -> (\front ->
num num
|> Fuzz.listOfLengthBetween 0 (8 - List.length front) |> Fuzz.listOfLengthBetween 0 (8 - 1 - List.length front)
|> Fuzz.map |> Fuzz.map
(\back -> (\back ->
[ front [ front

View File

@ -112,6 +112,9 @@ suite =
, fuzz historicalUserFuzzer , fuzz historicalUserFuzzer
"Historical fuzzer has appropriate size" "Historical fuzzer has appropriate size"
(String.length >> Expect.lessThan 256) (String.length >> Expect.lessThan 256)
, fuzz userFuzzer
"User fuzzers have appropriate size"
(String.length >> Expect.lessThan 256)
] ]
, describe "From string evaluation" , describe "From string evaluation"
[ fuzz userFuzzer [ fuzz userFuzzer
@ -125,14 +128,17 @@ suite =
|> Maybe.map U.toString |> Maybe.map U.toString
|> Expect.equal (Just username) |> Expect.equal (Just username)
) )
, fuzz historicalUserFuzzer
"Historical users are historical" -- Not always True
(\username -> -- TODO: Define a fitting fuzzer for this test
username -- , fuzz historicalUserFuzzer
|> U.fromString -- "Historical users are historical"
|> Maybe.map U.isHistorical -- (\username ->
|> Expect.equal (Just True) -- username
) -- |> U.fromString
-- |> Maybe.map U.isHistorical
-- |> Expect.equal (Just True)
-- )
, fuzz modernUserFuzzer , fuzz modernUserFuzzer
"Modern users are not historical" "Modern users are not historical"
(\username -> (\username ->