This is a MessagePack implementation for MoonBit, ported from Deno's std/msgpack.
MessagePack is an efficient binary serialization format. It lets you exchange data among multiple languages like JSON, but it's faster and smaller. Small integers are encoded into a single byte, and typical short strings require only one extra byte in addition to the strings themselves.
- ✅ Basic data types: nil, boolean, integers, floats, strings
- ✅ Collections: arrays and maps
- ✅ Binary data: arbitrary byte sequences
- ✅ Efficient encoding: Uses MessagePack's optimized formats (fixint, fixstr, fixarray, fixmap)
- ✅ Round-trip compatibility: Encode and decode with full fidelity
- ✅ Error handling: Comprehensive error types with descriptive messages
The library supports encoding and decoding the following types:
nilvaluesbooleanvalues (true/false)- Integers: 32-bit (
Int), 64-bit signed (Int64), 64-bit unsigned (UInt64) - Floating-point: 64-bit (
Double) - UTF-8 strings
- Binary data (
Bytes) - Arrays of values
- Maps with string keys
enum Value {
Nil
Bool(Bool)
Int(Int)
Int64(Int64)
UInt64(UInt64)
Float(Double)
String(String)
Binary(Bytes)
Array(Array[Value])
Map(Map[String, Value])
}
enum MsgPackError {
IOError(String)
TypeMismatch(String)
InvalidData(String)
}// Encode a MessagePack value to bytes
fn encode(value : Value) -> Bytes
// Decode bytes to a MessagePack value
fn decode(data : Bytes) -> Result[Value, MsgPackError]fn create_nil() -> Value
fn create_bool(b : Bool) -> Value
fn create_int(i : Int) -> Value
fn create_int64(i : Int64) -> Value
fn create_uint64(u : UInt64) -> Value
fn create_float(f : Double) -> Value
fn create_string(s : String) -> Value
fn create_binary(b : Bytes) -> Value
fn create_array(arr : Array[Value]) -> Value
fn create_map(map : Map[String, Value]) -> Valuefn Value::to_string(self : Value) -> Result[String, MsgPackError]
fn Value::to_int(self : Value) -> Result[Int, MsgPackError]
fn Value::to_bool(self : Value) -> Result[Bool, MsgPackError]// Create values
let nil_val = create_nil()
let bool_val = create_bool(true)
let int_val = create_int(42)
let str_val = create_string("hello")
// Encode to MessagePack
let nil_encoded = encode(nil_val) // 1 byte: [0xc0]
let bool_encoded = encode(bool_val) // 1 byte: [0xc3]
let int_encoded = encode(int_val) // 1 byte: [0x2a]
let str_encoded = encode(str_val) // 6 bytes: [0xa5, 'h', 'e', 'l', 'l', 'o']
// Decode from MessagePack
match decode(nil_encoded) {
Ok(Nil) => println("Successfully decoded nil")
Ok(_) => println("Wrong type")
Err(e) => println("Error: " + e.to_string())
}// Create an array
let array_val = create_array([
create_int(1),
create_int(2),
create_int(3)
])
// Create a map
let map = Map::new()
map["name"] = create_string("MoonBit")
map["version"] = create_int(1)
let map_val = create_map(map)
// Encode collections
let array_encoded = encode(array_val) // [0x93, 0x01, 0x02, 0x03]
let map_encoded = encode(map_val) // [0x82, ...] // Original data
let original = create_array([
create_nil(),
create_bool(true),
create_int(42),
create_string("hello")
])
// Encode and decode
let encoded = encode(original)
match decode(encoded) {
Ok(decoded) => {
// `decoded` should be equivalent to `original`
println("Round-trip successful!")
}
Err(e) => println("Round-trip failed: " + e.to_string())
}This implementation follows the official MessagePack specification. Key format features:
- Positive fixint (0x00-0x7f): Single-byte encoding for integers 0-127
- Negative fixint (0xe0-0xff): Single-byte encoding for integers -32 to -1
- fixstr (0xa0-0xbf): Compact encoding for strings up to 31 bytes
- fixarray (0x90-0x9f): Compact encoding for arrays up to 15 elements
- fixmap (0x80-0x8f): Compact encoding for maps up to 15 key-value pairs
- Extended formats: Support for larger strings, arrays, and maps
- Type safety: Strong typing prevents encoding/decoding errors
To see the library in action:
moon run .This will run a comprehensive demo showing:
- Basic type encoding and decoding
- Round-trip encoding/decoding tests
- MessagePack format verification
- Collection handling (arrays and maps)
This is a basic implementation with some current limitations:
- Float encoding: Currently uses placeholder bytes instead of proper IEEE 754 encoding
- 64-bit integers: Simplified encoding (currently encoded as 32-bit placeholders)
- Binary data: Basic support (currently encodes length headers only)
- String encoding: Proper UTF-8 support but simplified length handling
- Extended types: MessagePack extension types are not yet implemented
- Proper IEEE 754 float encoding/decoding
- Full 64-bit integer support
- Complete binary data handling
- MessagePack extension types
- Streaming encoder/decoder for large data
- Performance optimizations
- More comprehensive error reporting
The library includes comprehensive tests covering:
- Basic type encoding/decoding
- Round-trip compatibility
- MessagePack format compliance
- Error handling
- Edge cases
Run tests with:
moon testThis library was created as a learning exercise in porting JavaScript/TypeScript libraries to MoonBit. Contributions are welcome to improve the implementation and add missing features.
This implementation is inspired by and ported from the Deno standard library's MessagePack implementation, which is MIT licensed.