@hyrious/marshal
Ruby marshal for the browser and Node.js.
Install
npm add @hyrious/marshal
Usage
import { dump, load } from "@hyrious/marshal";
dump(null); // Uint8Array(3) [ 4, 8, 48 ]
load("\x04\b0"); // null
// in Node.js
load(fs.readFileSync("data"));
// in Browser
load(await file.arrayBuffer());
Ruby ↔ JavaScript
Ruby | JavaScript |
---|---|
nil |
null |
"string" |
"string" |
:symbol |
Symbol("symbol") [^1] |
123456 |
123456 (number) |
123.456 |
123.456 (number) |
/cat/im |
/cat/im (RegExp) |
[] |
[] [^2] |
{} |
{} (plain object) [^3] |
Object.new |
RubyObject { class: Symbol(object) } [^2] |
[^1]: Symbols are always decoded in UTF-8 even if they may have other encodings.
[^2]: Instance variables are stored directly as props, i.e. obj[Symbol(@a)] = 1
.
[^3]: String/symbol/number keys are always decoded as JS object props.
String
Because users may store binary data that cannot be decoded as UTF-8 in Ruby,
strings are decoded into Uint8Array
firstly, then converted to string
using TextDecoder
if seeing an instance variable indicating the encoding.
load('\x04\b"\0'); //=> Uint8Array []
load('\x04\bI"\0\x06:\x06ET'); //=> ""
The special instance variables are:
name | value | encoding |
---|---|---|
:E |
true / false | UTF-8 / ASCII |
:encoding |
"enc" | enc |
So for strict compatibility, you should check if a string is Uint8Array before using it:
var a = load(data);
if (a instanceof Uint8Array) a = decode(a); // if you know it must be a string
if (typeof a === "string") do_something(a);
Or you can use options.string
to control the behavior, see options.string.
Symbols
You can use Symbol.keyFor(sym)
in JavaScript to get the symbol name in string.
RegExp
Only i
(ignore case) and m
(multi-line) flags are preserved.
Hash
This library decodes Hash as plain object by default, which means unusual keys
like an object is ignored. However, it is still possible to keep these keys
using Map
or wrapper classes, see options.hash.
Instance Variables
This library decodes instance variables (often @a = 1
) as object props.
It is guaranteed that you can retrieve these properties using Object.getOwnPropertySymbols()
.
It is possible to convert these symbols to strings, see options.ivarToString.
API Reference
FAQ
ChangeLog
Develop
- Run
npm t
to run tests. - Run
npm t clone
to only runclone.ts
.
Reference
- marshal.c
- Marshal Format (official doc)
- node marshal
- @qnighy/marshal
- A little/another/final dip into Ruby's Marshal format
License
MIT @ hyrious