beencode

Types

An error that might take place while trying to decode a bencoded value with the decode function.

pub type BDecodeError {
  ExpectingEof
  UnexpectedEof
  UnexpectedChar(byte_index: Int)
  EmptyNumber(byte_index: Int)
  NegativeZero(byte_index: Int)
  LeadingZero(byte_index: Int)
  InvalidDictKey(byte_index: Int)
  StringShorterThanExpected(byte_index: Int)
}

Constructors

  • ExpectingEof

    This happens if after decoding a BValue we haven’t consumed the entire BitArray and we still have some other leftover bytes.

    i123ei1e
    ┬───╴┬──
    │    ╰─ After consuming the first integer we're
    │       left with this piece here but the only way to have
    │       multiple values would be to wrap everything
    │       into a list. This is an invalid bencoded string!
    │
    ╰─ This is consumed just fine.
    
  • UnexpectedEof

    This happens if we unexpectedly reach the end of the BitArray while in the middle of parsing a value.

  • UnexpectedChar(byte_index: Int)
  • EmptyNumber(byte_index: Int)

    This happens if we run into the invalid empty number ie. A number should have at least a digit between its start i and its end e.

  • NegativeZero(byte_index: Int)

    This happens if we find i-0e which is not allowed by the bencoding specification. Zero should only be encoded as i0e.

  • LeadingZero(byte_index: Int)

    This happens if a bencoded integer starts with one or more leading zeros, which is not allowed by the bencoding specification.

    i001e
     ┬─
     ╰─ The leading zeros are not allowed,
        this should just be `i1e`.
    
  • InvalidDictKey(byte_index: Int)

    This happens if a key of a dictionary is anything else besides a bencoded string.

    di1e2:aae
     ┬─╴
     ╰─ This key is an integer, not a string.
    
  • StringShorterThanExpected(byte_index: Int)

    This happens if the specified length of a bencoded string is longer than the actual string following the :.

    10:aa
    ┬─
    ╰─ According to this the string should be 10-bytes
       long, but there's only two bytes here!
    

A bencoded value.

pub type BValue {
  BString(BitArray)
  BInt(Int)
  BList(List(BValue))
  BDict(Dict(BitArray, BValue))
}

Constructors

  • BString(BitArray)

    The bencoding specification doesn’t enforce strings to be utf8-encoded. This means a bencoded string is represented as a Gleam’s BitArray and not a String that would have to be utf8-encoded.

  • BInt(Int)
  • BList(List(BValue))
  • BDict(Dict(BitArray, BValue))

Functions

pub fn decode(input: BitArray) -> Result(BValue, BDecodeError)

Decodes a bencoded BitArray into a BValue.

⚠️ According to the bencode specification the keys of a dictionary should always be sorted lexicographically. This decoder is a bit more permissive and will successfully decode a dictionary even if its keys appear in a different order.

Examples

decode(<<"i1e":utf8>>)
// -> BInt(1)

decode(<<"6:wibble":utf8>>)
// -> BString("wibble")

decode(<<"li1e6:wibblee":utf8>>)
// -> BList([BInt(1), BString("wibble")])

decode(<<"d6:wibblei1ee">>)
// -> BDict(dict.from_list([#(BString("wibble"), BInt(1))]))
pub fn encode(value: BValue) -> BitArray

Encodes a BValue into a bencoded BitArray.

Examples

encode(BInt(1))
// -> <<"i1e":utf8>>

encode(BString("wibble"))
// -> <<"6:wibble":utf8>>

encode(BList([BInt(1), BString("wibble")]))
// -> <<"li1e6:wibblee":utf8>>

encode(BDict(dict.from_list([#(BString("wibble"), BInt(1))])))
// -> <<"d6:wibblei1ee">>
Search Document