From 108abb1804da1b1c27894755f2239de5e8215015 Mon Sep 17 00:00:00 2001 From: Martin Ashby Date: Sat, 25 Nov 2023 19:45:40 +0000 Subject: Alias Bytes: (List U8) and use it everywhere it makes sense Add tests and prevent warnings --- main.roc | 77 +++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 40 insertions(+), 37 deletions(-) diff --git a/main.roc b/main.roc index c0850f6..e322130 100644 --- a/main.roc +++ b/main.roc @@ -3,22 +3,22 @@ app "roctorrent" imports [pf.Stdout] provides [main] to pf -dbgStr: List U8 -> Str -dbgStr = \s -> Result.withDefault (Str.fromUtf8 s) "!!!Invalid UTF-8!!!" +# Bencoded strings are not character strings i.e. text but binary data +Bytes: (List U8) # Decodes an exact string, errors if there is remaining unused data -bDecodeStr: List U8 -> Result (List U8) [Malformatted Str] +bDecodeStr: Bytes -> Result (Bytes) [Malformatted Str] bDecodeStr = \i -> when bDecodeStrAndRem i is Ok {res, others} -> if List.len others == 0 then Ok res else - Err (Malformatted "bDecodeStr: trailing characters in string \(dbgStr others)") - Err s -> Err s + Err (Malformatted "bDecodeStr: trailing characters") + Err (Malformatted s) -> Err (Malformatted "bDecodeStr: error calling bDecodeStrAndRem \(s)") # Decodes a string and returns the remainder of the input as well if there was any -bDecodeStrAndRem: List U8 -> Result {res: List U8, others: List U8} [Malformatted Str] +bDecodeStrAndRem: Bytes -> Result {res: Bytes, others: Bytes} [Malformatted Str] bDecodeStrAndRem = \i -> when (List.splitFirst i ':') is Ok {before, after} -> @@ -31,9 +31,9 @@ bDecodeStrAndRem = \i -> Ok {res: r2.before, others: r2.others} else Err (Malformatted "bDecodeStrAndRem: len exceeds remaining data") - Err _err -> Err (Malformatted "bDecodeStrAndRem: failed to parse number \(dbgStr i)") + Err _err -> Err (Malformatted "bDecodeStrAndRem: failed to parse number") Err _err -> Err (Malformatted "bDecodeStrAndRem: failed to parse utf8") - Err _err -> Err (Malformatted "bDecodeStrAndRem: no ':' found \(dbgStr i)") + Err _err -> Err (Malformatted "bDecodeStrAndRem: no ':' found") expect res = bDecodeStr (Str.toUtf8 "3:foo") @@ -41,21 +41,24 @@ expect expect errCases = [ - {case: "", err: "bDecodeStrAndRem: no ':' found "}, - #{case: "foo", err: "bDecodeStrAndRem: no ':' found"}, - #{case: "1:foo", err: "bDecodeStr: trailing characters"}, - #{case: "4:foo",err: "bDecodeStrAndRem: len exceeds remaining data"}, - #{case: ":", err: "bDecodeStrAndRem: failed to parse utf8"}, - #{case: "foo:", err: "bDecodeStrAndRem: failed to parse number"}, - #{case: "1:",err: "bDecodeStrAndRem: len exceeds remaining data"}, - #{case: "::",err: "bDecodeStrAndRem: failed to parse utf8"}, + {case: "", err: "bDecodeStr: error calling bDecodeStrAndRem bDecodeStrAndRem: no ':' found"}, + {case: "foo", err: "bDecodeStr: error calling bDecodeStrAndRem bDecodeStrAndRem: no ':' found"}, + {case: "1:foo", err: "bDecodeStr: trailing characters"}, + {case: "4:foo",err: "bDecodeStr: error calling bDecodeStrAndRem bDecodeStrAndRem: len exceeds remaining data"}, + {case: ":", err: "bDecodeStr: error calling bDecodeStrAndRem bDecodeStrAndRem: failed to parse number"}, + {case: "foo:", err: "bDecodeStr: error calling bDecodeStrAndRem bDecodeStrAndRem: failed to parse number"}, + {case: "1:",err: "bDecodeStr: error calling bDecodeStrAndRem bDecodeStrAndRem: len exceeds remaining data"}, + {case: "::",err: "bDecodeStr: error calling bDecodeStrAndRem bDecodeStrAndRem: failed to parse number"}, ] - List.all errCases \t -> - res = bDecodeStr (Str.toUtf8 t.case) - res == Err (Malformatted t.err) + results = List.map errCases \t -> + when bDecodeStr (Str.toUtf8 t.case) is + Ok _ -> "Malformatted input \(t.case) should have failed!" + Err (Malformatted err) -> err + expected = List.map errCases \t -> t.err + results == expected # Decodes an exact number, exta input causes an error -bDecodeNum: List U8 -> Result I64 [Malformatted Str] +bDecodeNum: Bytes -> Result I64 [Malformatted Str] bDecodeNum = \i -> when bDecodeNumAndRem i is Ok {num, rem} -> @@ -66,7 +69,7 @@ bDecodeNum = \i -> Err e -> Err e # Decodes a number and returns the number and any unused input -bDecodeNumAndRem: List U8 -> Result {num: I64, rem: (List U8)} [Malformatted Str] +bDecodeNumAndRem: Bytes -> Result {num: I64, rem: (Bytes)} [Malformatted Str] bDecodeNumAndRem = \i -> when (List.first i) is Ok f -> @@ -108,14 +111,14 @@ expect # Tags for storing heterogenous collections BVal: [ - BStr (List U8), + BStr (Bytes), BNum I64, BList (List BVal), - BDict (Dict (List U8) BVal) + BDict (Dict (Bytes) BVal) ] # Detects and decodes any kind of element. -bDecodeValueAndRem: (List U8) -> Result {res: BVal, others: (List U8)} [Malformatted, End (List U8)] +bDecodeValueAndRem: (Bytes) -> Result {res: BVal, others: (Bytes)} [Malformatted, End (Bytes)] bDecodeValueAndRem = \i -> when (List.first i) is Ok first -> @@ -145,8 +148,8 @@ bDecodeValueAndRem = \i -> Err _err -> Err Malformatted 'e' -> - {before, others} = List.split i 1 - Err (End others) + r = List.split i 1 + Err (End r.others) _ -> Err Malformatted Err _err -> Err Malformatted @@ -168,7 +171,7 @@ expect res == Err Malformatted # Decodes a list. List elements can be any -bDecodeList: (List U8) -> Result (List BVal) [Malformatted] +bDecodeList: (Bytes) -> Result (List BVal) [Malformatted] bDecodeList = \i -> when bDecodeListAndRem i is Ok {res, others} -> @@ -179,18 +182,18 @@ bDecodeList = \i -> Err e -> Err e -bDecodeListAndRem: (List U8) -> Result {res: (List BVal), others: (List U8)} [Malformatted] +bDecodeListAndRem: (Bytes) -> Result {res: (List BVal), others: (Bytes)} [Malformatted] bDecodeListAndRem = \i -> when List.first i is Ok f -> if f == 'l' then - {before, others} = List.split i 1 - bDecodeListAndRemInternal [] others + r = List.split i 1 + bDecodeListAndRemInternal [] r.others else Err Malformatted Err _e -> Err Malformatted -bDecodeListAndRemInternal: List BVal, List U8 -> Result {res: (List BVal), others: (List U8)} [Malformatted] +bDecodeListAndRemInternal: List BVal, Bytes -> Result {res: (List BVal), others: (Bytes)} [Malformatted] bDecodeListAndRemInternal = \l, i -> when bDecodeValueAndRem i is Ok {res, others} -> @@ -219,7 +222,7 @@ expect res == Ok [BList [BNum 123i64]] -bDecodeDict: (List U8) -> Result (Dict (List U8) BVal) [Malformatted Str] +bDecodeDict: (Bytes) -> Result (Dict (Bytes) BVal) [Malformatted Str] bDecodeDict = \i -> when bDecodeDictAndRem i is Ok {res, others} -> @@ -230,18 +233,18 @@ bDecodeDict = \i -> Err e -> Err e -bDecodeDictAndRem: (List U8) -> Result {res: (Dict (List U8) BVal), others: (List U8)} [Malformatted Str] +bDecodeDictAndRem: (Bytes) -> Result {res: (Dict (Bytes) BVal), others: (Bytes)} [Malformatted Str] bDecodeDictAndRem = \i -> when List.first i is Ok f -> if f == 'd' then - {before, others} = List.split i 1 - bDecodeDictAndRemInternal (Dict.empty{}) others + r = List.split i 1 + bDecodeDictAndRemInternal (Dict.empty{}) r.others else Err (Malformatted "first character not 'd'") Err _e -> Err (Malformatted "empty input") -bDecodeDictAndRemInternal: (Dict (List U8) BVal), (List U8) -> Result {res: (Dict (List U8) BVal), others: (List U8)} [Malformatted Str] +bDecodeDictAndRemInternal: (Dict (Bytes) BVal), (Bytes) -> Result {res: (Dict (Bytes) BVal), others: (Bytes)} [Malformatted Str] bDecodeDictAndRemInternal = \d, i -> when bDecodeValueAndRem i is Ok r1 -> @@ -254,7 +257,7 @@ bDecodeDictAndRemInternal = \d, i -> d2 = Dict.insert d key val bDecodeDictAndRemInternal d2 r2.others Err e -> when e is - End others -> + End _ -> Err (Malformatted "key with no value") Malformatted -> Err (Malformatted "bDecodeDictAndRemInternal: error decoding value") -- cgit v1.2.3-ZIG