4 个版本
0.2.1 | 2021 年 10 月 2 日 |
---|---|
0.2.0 | 2021 年 9 月 19 日 |
0.1.1 | 2021 年 7 月 26 日 |
0.1.0 | 2021 年 7 月 23 日 |
#1654 in Rust 模式
180KB
4K SLoC
Flexpiler
该包旨在提供一种方式,以便用户可以自定义 Rust 对象的读写格式。目的是减轻希望快速启动自己的项目且不太关心数据存储方式的私有开发者的负担。
目前,该包处于早期阶段,仅支持反序列化形式为 Rust 结构体和枚举的简化形式,其格式与 Rust 自身初始化结构体和枚举的方式相似。
如何使用
该项目使用其姐妹包 flexpiler_derive
来提供 #[derive]
宏。此宏生成代码,使得被推导的结构体/枚举获得对 flexpiler::Deserialize
的实现。从那时起,您可以通过调用 YourType::deserialize(reader_mut_ref)
从字符串或文件读取器中反序列化类型。
extern crate flexpiler;
#[derive(flexpiler::Deserialize)]
struct MyPoint {
x: i32,
y: i32,
}
#[test]
fn basic() {
// Trait that implements deserialize<...>(...)
use flexpiler::Deserialize;
// namespace of common flexpiler reader implementations
use flexpiler::common::reader;
// Provide data via reading a string
// You may at this point provide a file handle or similar instead
let mut reader = reader::String::from(
"MyPoint{x:5,y:7}"
);
// Try and deserialize our object, modifying the reader in the process
let parse_result = MyPoint::deserialize(&mut reader);
// flexpiler deserialization ends in a std::result::Result
let my_point = match parse_result {
Ok(value) => value,
Err(error) => {
assert!(false, "parade() test ended in a failed deserialization:\n{}", error);
return;
}
};
// Check if our deserialized object contains the correct values for its fields
assert_eq!(my_point.x, 5);
assert_eq!(my_point.y, 7);
}
当前限制
最后更新:版本 0.2.0
该项目不支持像我期望的那样多的标准类型。特别是 HashMap<KeyType, DataType>
和各种原始类型目前在我的实现清单中。
Flexpiler目前使用自定义的flexpiler::reader::Trait
解析实现,并期望用户将文件读取器、字符串读取器或其他类型的读取器转换为实现了它的类型。该项目应包含各种常见实现,并可能支持从常见的实践类型(如BufReader
)到其隐式转换。
目前不支持Rust联合。
该项目目前无法处理泛型。
未来计划
作为一个alpha版crate,该项目的API将在每次“小版本”增量(x.y.z => x.y+1.z)时发生变化。然而,目前从外部使用的所需API遵循即将到来的非明确愿景。
use flexpiler::{Deserialize}
struct CakeFormat {
// [ some error handling functionality of an unspecified format ]
}
#[derive(flexpiler::Deserialize)]
#[flexpiler_format = CakeFormat]
#[flexpiler_format_style = "{[glazing]}\n{[cream]}\n{[flour_in_grams]}"]
struct MyCustomizedType {
glazing: std::string,
cream: MyCreamType,
flour_in_grams:i32,
}
[#test]
fn test_flexpiler() {
use flexpiler::Deserialize;
use flexpiler::common::reader;
let mut reader = reader::String::from(
"{\"Strawberry\"}\n{MyCreamType::Vanilla}\n{525}"
);
let parse_result = MyCustomizedType::deserialize(&mut reader);
let my_customized_type = match parse_result {
Ok(value) => value,
Err(error) => {
assert!(false, "test_flexpiler() test ended in a failed deserialization:\n{}", error);
return;
}
};
assert_eq!(my_customized_type.glazing.as_str(), "Strawberry");
assert_eq!(my_customized_type.cream, MyCreamType::Vanilla);
assert_eq!(my_customized_type.flour_in_grams, 525);
}
请注意,该项目目前无法完成此操作。但这正是我们未来努力的方向。
工作原理
本质上,该衍生宏功能创建了一个中间结构体,用于在对象最终构建之前保存您的数据。然后,它从头开始编写整个deserialize
函数,包括解析和错误转发,假设每个子类型都有自己的Deserialize
实现。
Deserialize
已经在flexpiler::common::deserializer
中实现,用于各种常见类型,例如i32、std::string。然而,目前对于某些标准类,您需要提供自己的flexpiler::Deserialization
实现。
依赖项
~1.5MB
~35K SLoC