28 个版本
0.8.17 | 2024 年 3 月 21 日 |
---|---|
0.8.15 | 2022 年 11 月 3 日 |
0.8.3 | 2021 年 12 月 7 日 |
0.7.0 | 2021 年 11 月 28 日 |
0.2.1 | 2020 年 12 月 31 日 |
#421 in Rust 模式
616 每月下载量
用于 8 个crate (6 直接)
215KB
5K SLoC
一个用于将 CBOR 作为动态形状数据的内存表示的库。
关于数据格式的详细信息,请参阅 RFC 8949。它通常用作数据交换格式,它模拟了 JSON 特性的超集,同时使用更紧凑的二进制表示。因此,数据表示更倾向于较小的内存大小,而不是最快的数据访问速度。
此库在使用此数据格式时提供了一系列权衡。您可以仅使用从线或文件中获得的位,无需支付除扫描字节以检查有效编码之外的初始开销,但然后在处理数据时可能造成分配。或者您可以在使用之前对位进行规范化,确保在数据中索引永远不会分配。
关于性能,您应该记住,数组和字典被编码为其元素的平坦并列组合,这意味着索引将必须解码项,在跳过它们时进行解码。
关于解析数据的解释,您可以选择检查特定的编码(通过在 ItemKind
上进行模式匹配)或检查更高级的 CborValue
。在后一种情况下,许多二进制表示可能产生相同的结果,例如,当请求整数时,结果可能来自非最佳编码(如将 57 编写为 64 位值)或来自具有 570 非常数和 -1 指数的 BigDecimal。
示例
use cbor_data::{CborBuilder, Encoder, Writer, constants::*};
// create some nonsense CBOR item
let cbor = CborBuilder::new().encode_dict(|builder| {
builder.with_key("name", |builder| builder.encode_str("Actyx"));
builder.with_key("founded", |b| b.write_str("2016-02-11T13:00:00+01:00", [TAG_ISO8601]));
builder.with_key("founders", |builder| builder.encode_array(|builder| {
builder
.encode_str("Oliver Stollmann")
.encode_str("Maximilian Fischer")
.encode_str("Roland Kuhn");
}));
});
// access properties
use cbor_data::{PathElement, index_str, CborValue, value::Timestamp};
use std::borrow::Cow::{self, Borrowed};
let item = cbor.index(index_str("name")).unwrap();
assert_eq!(item.decode(), CborValue::Str(Borrowed("Actyx")));
// decoding references source bytes where possible, use make_static() to break ties
let decoded =
cbor.index([PathElement::String(Borrowed("founded"))]).unwrap().decode().make_static();
// if you know what you’re looking for, you can use the as_* or to_* methods:
let ts = decoded.as_timestamp().unwrap();
assert_eq!(ts.unix_epoch(), 1_455_192_000);
assert_eq!(ts.nanos(), 0);
assert_eq!(ts.tz_sec_east(), 3600);
let item = cbor.index(index_str("founders[1]")).unwrap();
let name = item.decode().to_str();
// to_str() returns an Option<Cow<str>> to allow you to avoid allocations
// (i.e. this still takes the string’s bytes from `&cbor` in this case)
assert_eq!(name.as_ref().map(Cow::as_ref), Some("Maximilian Fischer"));
// access low-level encoding
use cbor_data::ItemKind;
let item = cbor.index(index_str("founded")).unwrap();
assert_eq!(item.tags().collect::<Vec<_>>(), [TAG_ISO8601]);
assert!(matches!(item.kind(), ItemKind::Str(s) if s == "2016-02-11T13:00:00+01:00"));
依赖关系
~0.5–6.5MB
~30K SLoC