aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Ashby <martin@ashbysoft.com>2023-11-25 19:45:40 +0000
committerMartin Ashby <martin@ashbysoft.com>2023-11-25 19:45:40 +0000
commit108abb1804da1b1c27894755f2239de5e8215015 (patch)
tree003c3c862e0cfe809602905bf7abfbcc5108c20b
parentd73f8b321f7251e816ba32c24e09b7c175466306 (diff)
downloadroctorrent-108abb1804da1b1c27894755f2239de5e8215015.tar.gz
roctorrent-108abb1804da1b1c27894755f2239de5e8215015.tar.bz2
roctorrent-108abb1804da1b1c27894755f2239de5e8215015.tar.xz
roctorrent-108abb1804da1b1c27894755f2239de5e8215015.zip
Alias Bytes: (List U8) and use it everywhere it makes sense
Add tests and prevent warnings
-rw-r--r--main.roc77
1 files 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")