Есть ли лучший способ напрямую конвертировать документ Rust BSON в JSON?
Идея заключается в получении курсора из Mongo и сериализации набора результатов в JSON в виде строки. У меня есть рабочий код:
extern crate bson;
extern crate mongodb;
use mongodb::db::ThreadedDatabase;
use mongodb::{Client, ThreadedClient};
extern crate serde;
extern crate serde_json;
fn main() {
let client =
Client::connect("localhost", 27017).expect("Failed to initialize standalone client.");
let coll = client.db("foo").collection("bar");
let cursor = coll.find(None, None).ok().expect("Failed to execute find.");
let docs: Vec<_> = cursor.map(|doc| doc.unwrap()).collect();
let serialized = serde_json::to_string(&docs).unwrap();
println!("{}", serialized);
}
Есть лучший способ сделать это? Если нет, я закрою эту ветку.
1 ответ
Это такая ситуация, котораяserde-transcode
был сделан для. Что он делает, так это конвертирует напрямую междуserde
форматы. Как это работает: он принимает a и a , а затем напрямую вызывает соответствующую функцию сериализации для каждого десериализованного элемента. Концептуально это немного похоже на использованиеserde_json::Value
в качестве промежуточного формата, но может включать некоторую дополнительную информацию о типе, если она доступна во входном формате.
К сожалению,
bson
ящик не выставляется или
bson::ser::raw::Serializer
так что на данный момент это невозможно. Если вы посмотрите в документации,Deserializer
иSerializer
на самом деле ссылаются на разные структуры, которые обрабатывают преобразование в и изBson
перечисление
Еслиbson::de::raw::Deserializer
был общедоступным, то этот код имел бы желаемый эффект. Надеюсь, это будет полезно всем, у кого есть похожая проблема (или тем, кто этого хочет достаточно, чтобы поднять вопрос в своем репозитории).
let mut buffer = Vec::new();
// Manually add array separators because the proper way requires going through
// DeserializeSeed and that is a whole other topic.
buffer.push(b'[');
while cursor.advance().await? {
let bytes = cursor.current().as_bytes();
// Create deserializer and serializer
let deserializer = bson::de::raw::Deserializer::new(bytes, false);
let serializer = serde_json::Serializer::new(&mut buffer);
// Transcode between formats
serde_transcode::transcode(deserializer, serializer).unwrap();
// Manually add array separator
buffer.push(b',');
}
// Remove trailing comma and add closing bracket
if buffer.len() > 1 {
buffer.pop();
}
buffer.push(']');
// Do something with the result
println!("{}", String::from_utf8(buffer).unwrap())