3个版本

0.1.2 2024年6月20日
0.1.1 2024年3月22日
0.1.0 2024年3月22日

#147 in 无标准库


cbor-macro中使用

MIT/Apache

15KB
89

cboritem 许可: MIT OR Apache-2.0 cboritem on crates.io cboritem on docs.rs 源代码仓库

cboritem: 序列化的CBOR项

CborItem<'a> 是围绕 &'a [u8] 的新类型,它维护包含单个序列化CBOR项的不变量。一个 ThinCborItem<'a> 是其起始指针;访问它时,用户依赖于该属性以在项的末尾停止读取。

从某种意义上说,这些类型类似于 &strCStr,后者将遵循 计划 成为瘦指针。

库的使用

它们的使用是为了有效地存储经过预验证的CBOR项切片,例如在实现打包CBOR时。它们也可以作为CBOR库之间的接口点,简化错误处理(因为流结束和数据后字节错误是值得panic的不变量;如果解析器无法处理任何格式良好的数据,或者违反了基本有效性要求,则可能仍然会发生其他解析错误),并且可以作为标记类型,通过该类型CBOR解析器可以被告知将任何项处理为切片以进行后续的详细检查。

这个包不是CBOR库,因此它不包含创建任何类型的函数(因为这需要CBOR解析器)。相反,它的目的是在CBOR解析器验证了不变性之后被生成。

不变性定义

这个包中类型的维护的不变性是,它们的字节正好是一个按照RFC8949定义的格式良好的CBOR项目;具体来说,这意味着它们至少包含一个字节。

这个包中的不变性是正确性不变性:接收CBOR项目的接收者,在发现无效的CBOR时,不仅不能直接崩溃,还可能引发未定义的行为(例如,通过调用unreachable_unchecked。因此,创建CBOR项目需要使用unsafe关键字,不变性由创建项目的解析器进行检查。

这是提供瘦指针的必然结果:不变性被通过原始指针读取的用户所依赖,在不准确的数据上这会导致读取超出原始分配对象,这是未定义的行为。

示例

use cboritem::{CborItem, ThinCborItem};
let onehundred = [0x24, 0x64];
assert_eq!(onehundred[0], 0x24);
let onehundred = unsafe { CborItem::new(&onehundred) };
let onehundred: ThinCborItem<'_> = onehundred.as_thin();
assert_eq!(core::mem::size_of_val(&onehundred), core::mem::size_of::<&u8>());
// One byte can always be read, so we don't need a CBOR parser to tell us it is safe
if onehundred.first() == 0x24 {
    assert_eq!(unsafe { onehundred.offset(1).read() }, 100);
} else {
    panic!("Unexpected type or integer size");
}

未来开发

未来的版本可能会添加类型或当前类型的变体(通过关联类型和默认值实现),例如,以描述附加约束,如

  • 嵌入式字符串是UTF-8
  • 没有重复的键存在
  • 遵循通用确定性编码
  • 不包含不定长度项
  • CBOR项目符合某些特定的CDDL结构

如果任何扩展改变了CBOR的有效性规则(例如,i=28被定义为128位整数参数),则这个包将经历一个主要版本发布来支持它们。

无运行时依赖