reikland
A ruby marshal parser and deserializer that's compatible with the normal serde::Deserialize trait. If you don't need that compatibility you probably want the wonderful alox-48 which was the inspiration to try this in the first place.
Read this before deciding to use this crate so you understand the why and how to use it properly
I found the marshal format to have a good degree of desync between the "intended" and "literal" ways to deserialize a value in Rust. For example: An instance variable is basically just a (T, HashMap<Symbol, Value>) but in many cases you (the lovely person reading this) just want T. However if I just made instance variables deserialize to T we are losing information so I made the executive decision to provide a collection of helpful wrappers to get at T with less pain.
; // Will deserialize T, but if it runs into a sequence (such as an ivar) it will try to take the first member as T
// Same as Transparent<T> but also captures the second value of a sequence if possible
// Deserialize an instance variable wrapper as (inner_value, ivars_map).
// Encoding pulls out the encoding specifically. WithEncoding<T> = Ivar<T, Encoding>.
;
// Deserialize a Ruby Object/Struct as (class_name, fields_map). RbStruct is an alias to the same
// Deserialize a Ruby Regex as its pattern and flags byte.
// Deserialize a Ruby Hash-with-default as the hash and its default value.
// Ruby hashes often have both integer and symbol keys pointing at the same data.
// owned variant
// These take a mixed-key hash and keep only one side:
; // keeps string keys, discards int keys
; // keeps int keys, discards string keys
; // keeps int-keyed values in insertion order
; // keeps int-keyed values indexed by their key (no holes allowed)
; // keeps int-keyed values indexed by their key and allows holes by leaving Option::None
All the struct types above implement Deref/DerefMut to their "main" field (the first generic) so you can use them without unwrapping in most cases.
In practice this looks like
// make your types as per usual
I don't like what you've done with the place
me neither That's fine! The parsing logic is exposed via reikland::marshal::parse which is used internally by the serde implementation so if you want to handle things yourself from the raw data go nuts. I parse the entire marshal object first before deserializing since it was simpler for me, and everything is stored flat with no scary recursive types.
Why does the crate's name suck?
I was playing a lot of Total War Warhammer 3 when I first decided to make it. Something something marshal my men, summon the elector counts...