aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Ashby <martin@ashbysoft.com>2023-11-24 20:04:26 +0000
committerMartin Ashby <martin@ashbysoft.com>2023-11-24 20:04:26 +0000
commit7f1f2b46ba140d25ffed4832c3fec52585f4a9bc (patch)
tree26d32f65c78395cdbdb90e5e908d4e26bb22b0ce
parenta20ce36876487b48dbbd18a38570f4ade522118e (diff)
downloadroctorrent-7f1f2b46ba140d25ffed4832c3fec52585f4a9bc.tar.gz
roctorrent-7f1f2b46ba140d25ffed4832c3fec52585f4a9bc.tar.bz2
roctorrent-7f1f2b46ba140d25ffed4832c3fec52585f4a9bc.tar.xz
roctorrent-7f1f2b46ba140d25ffed4832c3fec52585f4a9bc.zip
Add list decoding
-rw-r--r--main.roc130
1 files changed, 102 insertions, 28 deletions
diff --git a/main.roc b/main.roc
index a1c3e38..3d48fcd 100644
--- a/main.roc
+++ b/main.roc
@@ -4,13 +4,6 @@ app "roctorrent"
provides [main] to pf
-BVal: [
- BStr Str,
- BNum I64,
- BList (List BVal),
- # TODO add dict!
-]
-
# Decodes an exact string, errors if there is remaining unused data
bDecodeStr: List U8 -> Result (List U8) [Malformatted]
bDecodeStr = \i ->
@@ -110,29 +103,110 @@ expect
res = bDecodeNum (Str.toUtf8 case)
res == Err (Malformatted msg)
-bDecodeList: (List U8) -> Result (List BVal) [Malformatted]
-bDecodeList = \_i ->
- Ok [BNum 64, BStr "foo"]
- #when i is
- # ['l', .., 'e'] ->
- # _ -> Err Malformatted
-
-#bDecodeListInner: (List U8, List BVal) -> Result {res: (List BVal), others: (List U8)} [Malformatted]
-#bDecodeListInner = \i, o ->
-# when (List.first i) is
-# Ok first ->
-# when first is
-# '0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9' ->
-# when bDecodeStringAndRemainder first is
-# Ok {before, others} ->
-# Err _err -> Err Malformatted
-# 'i' ->
-# bDecode
-# Err _err -> Err Malformatted
+# Tags for storing heterogenous collections
+BVal: [
+ BStr (List U8),
+ BNum I64,
+ BList (List BVal),
+]
+
+# Detects and decodes any kind of element.
+bDecodeValueAndRem: (List U8) -> Result {res: BVal, others: (List U8)} [Malformatted, End (List U8)]
+bDecodeValueAndRem = \i ->
+ when (List.first i) is
+ Ok first ->
+ when first is
+ '0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9' ->
+ when bDecodeStrAndRemainder i is
+ Ok {before, others} ->
+ Ok {res: BStr before, others: others}
+ Err _err ->
+ Err Malformatted
+ 'i' ->
+ when bDecodeNumAndRem i is
+ Ok {num, rem} ->
+ Ok {res: BNum num, others: rem}
+ Err _err ->
+ Err Malformatted
+ 'l' ->
+ when bDecodeListAndRem i is
+ Ok {res, others} ->
+ Ok {res: BList res, others: others}
+ Err _err ->
+ Err Malformatted
+ 'e' ->
+ {before, others} = List.split i 1
+ Err (End others)
+ _ ->
+ Err Malformatted
+ Err _err -> Err Malformatted
+
+expect
+ res = bDecodeValueAndRem (Str.toUtf8 "i64efoo")
+ res == Ok {res: BNum 64, others: (Str.toUtf8 "foo")}
+
+expect
+ res = bDecodeValueAndRem (Str.toUtf8 "3:foo3:foo")
+ res == Ok {res: BStr (Str.toUtf8 "foo"), others: (Str.toUtf8 "3:foo")}
+
+expect
+ res = bDecodeValueAndRem (Str.toUtf8 "efoo")
+ res == Err (End (Str.toUtf8 "foo"))
expect
- res = bDecodeList (Str.toUtf8 "li64e3:fooe")
- res == Ok [BNum 64, BStr "foo"]
+ res = bDecodeValueAndRem (Str.toUtf8 "z")
+ res == Err Malformatted
+
+# Decodes a list. List elements can be any
+bDecodeList: (List U8) -> Result {res: (List BVal)} [Malformatted]
+bDecodeList = \i ->
+ when bDecodeListAndRem i is
+ Ok {res, others} ->
+ if (List.len others) == 0 then
+ Ok {res: res}
+ else
+ Err Malformatted
+ Err e ->
+ Err e
+
+bDecodeListAndRem: (List U8) -> Result {res: (List BVal), others: (List U8)} [Malformatted]
+bDecodeListAndRem = \i ->
+ when List.first i is
+ Ok f ->
+ if f == 'l' then
+ {before, others} = List.split i 1
+ bDecodeListAndRemInternal [] others
+ else
+ Err Malformatted
+ Err _e -> Err Malformatted
+
+bDecodeListAndRemInternal: List BVal, List U8 -> Result {res: (List BVal), others: (List U8)} [Malformatted]
+bDecodeListAndRemInternal = \l, i ->
+ when bDecodeValueAndRem i is
+ Ok {res, others} ->
+ l2 = List.append l res
+ bDecodeListAndRemInternal l2 others
+ Err e -> when e is
+ End others ->
+ Ok {res: l, others: others}
+ Malformatted ->
+ Err Malformatted
+
+expect
+ res = bDecodeList (Str.toUtf8 "le")
+ res == Ok { res: []}
+
+expect
+ res = bDecodeList (Str.toUtf8 "li123e3:fooe")
+ res == Ok { res: [BNum 123i64, BStr (Str.toUtf8 "foo")] }
+
+expect
+ res = bDecodeList (Str.toUtf8 "li123e3:fooe123")
+ res == Err Malformatted
+
+expect
+ res = bDecodeList (Str.toUtf8 "lli123eee")
+ res == Ok { res: [BList [BNum 123i64]]}
main =
Stdout.line "Hello, World" \ No newline at end of file