英文:
Rust : Serialize the list of structs and write in a file in BSON format and deserialize back to struct
问题
I am trying to convert a list of structs and write them to a file in BSON format and deserialize them back to a struct. I am using the following crate:
bson = { version="2.6.0" }
I converted my list of structs to BSON, and then tried to find a way to convert the BSON to vec[u8]
, but I didn't find any.
I need to store BSON in their binary format only to a specific file.
Here is the code snippet:
use std::{fs::File, io::Write};
use serde::{Serialize, Deserialize};
#[derive(Debug, Serialize, Deserialize)]
struct Bison {
name: String,
age: u16,
place: String,
phone: u16,
}
pub fn check_bson() {
let mut bisons: Vec<Bison> = Vec::with_capacity(1000);
for i in 1..1001 {
bisons.push(Bison {
name: format!("Name {}", i),
age: i as u16,
place: format!("Place {}", i),
phone: i as u16,
});
}
let mut file = File::create("data.bson").expect("Failed to create file");
let s = bson::to_bson(&bisons).unwrap();
}
英文:
I am trying to convert list of structs and write in a file in BSON format and deserialize back to struct . I am using
bson = { version="2.6.0" }
crate . I converted my list of structs to Bson , and then tried finding any way to convert the bson to vec[u8] , but didn't find any .
I need to store bson in their binary format only to a specific file.
Here is the code snippet
use std::{fs::File, io::Write};
use serde::{Serialize, Deserialize};
#[derive(Debug,Serialize,Deserialize)]
struct Bison {
name: String,
age: u16,
place: String,
phone: u16,
}
pub fn check_bson() {
let mut bisons: Vec<Bison> = Vec::with_capacity(1000);
for i in 1..1001 {
bisons.push(Bison {
name: format!("Name {}", i),
age: i as u16,
place: format!("Place {}", i),
phone: i as u16,
});
}
let mut file = File::create("data.bson").expect("Failed to create file");
let s = bson::to_bson(&bisons).unwrap();
}
答案1
得分: 1
以下是您要翻译的代码部分:
[`BSON`](https://docs.rs/bson/latest/bson/enum.Bson.html) 枚举仅包含文档树。要获取 `Vec<u8>`,您需要实际编码 [`Document`](https://docs.rs/bson/latest/bson/struct.Document.html),可以这样做:
```rust
use bson::{SerializerOptions, Document};
use serde::{Serialize, Deserialize};
#[derive(Debug,Serialize,Deserialize)]
struct Bison {
name: String,
age: u16,
place: String,
phone: u16,
}
pub fn check_bson() {
let mut bisons: Vec<Bison> = Vec::with_capacity(1000);
for i in 1..1001 {
bisons.push(Bison {
name: format!("Name {}", i),
age: i as u16,
place: format!("Place {}", i),
phone: i as u16,
});
}
let options = SerializerOptions::builder().human_readable(false).build();
let bson = bson::to_bson_with_options(&bisons, options).unwrap();
println!("{:?}", bson);
let mut doc = Document::new();
doc.insert("array".to_string(), bson);
let mut buf = Vec::new();
doc.to_writer(&mut buf).unwrap();
std::fs::write("data.bson", buf).expect("Failed to create file");
}
请注意,我们必须为数组指定一个名称(在这种情况下,我选择了 "array"),因为 Array
本身不是 Document
类型,因此不能用于顶层。
或者,您可以使用 to_vec
,但您还必须考虑顶层元素不能是 BSON Array
,因此您必须像下面所示包装它:
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
struct Bison {
name: String,
age: u16,
place: String,
phone: u16,
}
#[derive(Debug, Serialize, Deserialize)]
struct RootElement {
array: Vec<Bison>,
}
pub fn check_bson() {
let mut bisons: Vec<Bison> = Vec::with_capacity(1000);
for i in 1..1001 {
bisons.push(Bison {
name: format!("Name {}", i),
age: i as u16,
place: format!("Place {}", i),
phone: i as u16,
});
}
// BSON 文档的根元素不能是数组(例如,rust 中的 Vec)。
let data = RootElement {
array: bisons
};
let buf = bson::to_vec(&data).unwrap();
std::fs::write("data.bson", buf).expect("Failed to create file");
}
<details>
<summary>英文:</summary>
The [`BSON`](https://docs.rs/bson/latest/bson/enum.Bson.html) enum only contains the document tree. In order to get a `Vec<u8>` you will need to actually encode the [`Document`](https://docs.rs/bson/latest/bson/struct.Document.html) which can be done like so:
```rust
use bson::{SerializerOptions, Document};
use serde::{Serialize, Deserialize};
#[derive(Debug,Serialize,Deserialize)]
struct Bison {
name: String,
age: u16,
place: String,
phone: u16,
}
pub fn check_bson() {
let mut bisons: Vec<Bison> = Vec::with_capacity(1000);
for i in 1..1001 {
bisons.push(Bison {
name: format!("Name {}", i),
age: i as u16,
place: format!("Place {}", i),
phone: i as u16,
});
}
let options = SerializerOptions::builder().human_readable(false).build();
let bson = bson::to_bson_with_options(&bisons, options).unwrap();
println!("{:?}", bson);
let mut doc = Document::new();
doc.insert("array".to_string(), bson);
let mut buf = Vec::new();
doc.to_writer(&mut buf).unwrap();
std::fs::write("data.bson", buf).expect("Failed to create file");
}
Please note, that we had to give a name to the array (in this case I chose "array"), because an Array
itself is a non-Document
type and can thus not be used at the top level.
Alternatively you can use to_vec
, but you will also have to consider that the top-level element can not be a BSON Array
, so you will have to wrap it like shown below:
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
struct Bison {
name: String,
age: u16,
place: String,
phone: u16,
}
#[derive(Debug, Serialize, Deserialize)]
struct RootElement {
array: Vec<Bison>,
}
pub fn check_bson() {
let mut bisons: Vec<Bison> = Vec::with_capacity(1000);
for i in 1..1001 {
bisons.push(Bison {
name: format!("Name {}", i),
age: i as u16,
place: format!("Place {}", i),
phone: i as u16,
});
}
// The root element of a BSON document can not be an array (e.g. a Vec in rust).
let data = RootElement {
array: bisons
};
let buf = bson::to_vec(&data).unwrap();
std::fs::write("data.bson", buf).expect("Failed to create file");
}
答案2
得分: 1
以下是您要翻译的内容:
"Your bson 文件的顶层必须是 Document
。Vec
遗憾地不能与顶层 bison 使用兼容。它必须是类似于键值映射的东西,例如 HashMap
或 struct
。
实现这一目标的最简单方法是将 struct
用作顶层对象。将其转换为二进制的实际调用是 bson::to_vec
:
use serde::{Deserialize, Serialize};
use std::fs::File;
#[derive(Debug, Serialize, Deserialize)]
struct Bison {
name: String,
age: u16,
place: String,
phone: u16,
}
#[derive(Debug, Serialize, Deserialize)]
struct BisonDoc {
bisons: Vec<Bison>,
}
pub fn main() {
// 写入文件
{
let mut bisons_doc = BisonDoc {
bisons: Vec::with_capacity(3),
};
for i in 1..=3 {
bisons_doc.bisons.push(Bison {
name: format!("Name {}", i),
age: i as u16,
place: format!("Place {}", i),
phone: i as u16,
});
}
let binary_data = bson::to_vec(&bisons_doc).expect("无法创建 bison 数据");
std::fs::write("data.bson", binary_data).expect("无法写入 bson 文件");
}
// 从文件读取
{
let file = File::open("data.bson").expect("无法打开文件");
let bisons: BisonDoc = bson::from_reader(file).expect("读取 bson 数据时出错");
println!("{:#?}", bisons);
}
}
BisonDoc {
bisons: [
Bison {
name: "Name 1",
age: 1,
place: "Place 1",
phone: 1,
},
Bison {
name: "Name 2",
age: 2,
place: "Place 2",
phone: 2,
},
Bison {
name: "Name 3",
age: 3,
place: "Place 3",
phone: 3,
},
],
}
英文:
The top level of your bson file has to be a Document
. A Vec
is sadly not compatible with top level bison usage. It has to be something that resembles a key-value mapping, like a HashMap
or a struct
.
The easiest way to achieve that is to use a struct
as the top level object. The actual call to convert it to binary is bson::to_vec
:
use serde::{Deserialize, Serialize};
use std::fs::File;
#[derive(Debug, Serialize, Deserialize)]
struct Bison {
name: String,
age: u16,
place: String,
phone: u16,
}
#[derive(Debug, Serialize, Deserialize)]
struct BisonDoc {
bisons: Vec<Bison>,
}
pub fn main() {
// Write to file
{
let mut bisons_doc = BisonDoc {
bisons: Vec::with_capacity(3),
};
for i in 1..=3 {
bisons_doc.bisons.push(Bison {
name: format!("Name {}", i),
age: i as u16,
place: format!("Place {}", i),
phone: i as u16,
});
}
let binary_data = bson::to_vec(&bisons_doc).expect("Unable to create bison data");
std::fs::write("data.bson", binary_data).expect("Failed to write bson file");
}
// Read from file
{
let file = File::open("data.bson").expect("Unable to open file");
let bisons: BisonDoc = bson::from_reader(file).expect("Error while reading bson data");
println!("{:#?}", bisons);
}
}
BisonDoc {
bisons: [
Bison {
name: "Name 1",
age: 1,
place: "Place 1",
phone: 1,
},
Bison {
name: "Name 2",
age: 2,
place: "Place 2",
phone: 2,
},
Bison {
name: "Name 3",
age: 3,
place: "Place 3",
phone: 3,
},
],
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论