#serialization #single #integer #nested #encode-decode #data

nestle

使用单个整数编码/解码任意嵌套的树状数据。

1 个不稳定版本

0.1.0 2023年7月6日

#75 in #nested

MIT 许可证

33KB
760

Nestle

Codecov Dependency status

使用单个整数编码/解码任意嵌套的树状数据。


lib.rs:

Nestle

使用单个整数编码/解码任意嵌套的树状数据。

使用方法

简单地在您的枚举或结构体上使用 Nestle derive 宏。

如果顶级类型的宽度超出,编码时将在该点返回错误。

// This is the top-level type, so it should be 64 bits wide. It uses
// `repr(i16)` therefore occupies 16 bits, leaving 48 bits for the
// descendants.
#[derive(Nestle)]
#[nestle(width = 64)]
#[repr(i16)]
enum Instrument {
    Spot(CurrencyPair) = 1,
    Options(Options) = 2,
    PerpetualFutures(CurrencyPair) = 3,
}

// This type is 48 bits wide, so it can be encoded as a descendant of
// `Instrument`.
#[derive(Nestle)]
#[nestle(width = 48)]
struct Options {
    expiry: u16,
    pair: CurrencyPair,
}

// This type doesn't use all the available space, which is fine.
#[derive(Nestle)]
#[nestle(width = 32)]
struct CurrencyPair {
    base: Currency,
    quote: Currency,
}

// The discriminants of this enum will be used to encode the values.
#[derive(Nestle)]
#[repr(i16)]
enum Currency {
    Btc = 1,
    Eth = 2,
    Doge = 3,
    Usd = 4,
}

let instrument = Instrument::Options(Options {
    expiry: 365,
    pair: CurrencyPair {
        base: Currency::Eth,
        quote: Currency::Usd,
    },
});

let instrument_id = 564517616615428;
// This is the unique, semantic identifier for this instrument.
assert_eq!(instrument.encode().unwrap(), instrument_id);
// It's the result of the discriminants shifted in to the appropriate
// bit positions.
assert_eq!(
    instrument.encode().unwrap(),
    2 << 48 | 365 << 32 | 2 << 16 | 4
);

// The decode method will return the original value.
assert_eq!(Instrument::decode(instrument_id).unwrap(), instrument);
// Ids have semantic meaning, giving them reproducibility and
// mathematical properties.
assert_eq!(
    Instrument::decode(instrument_id - 1).unwrap(),
    Instrument::Options(Options {
        expiry: 365,
        pair: CurrencyPair {
            base: Currency::Eth,
            quote: Currency::Doge,
        },
    })
);
// The decode method will fail only if the id is not a valid encoding.
assert!(Instrument::decode(instrument_id + 1).is_err());

依赖关系

~0.3–0.8MB
~18K SLoC