I'm trying to read from a bson file containing a single bson document (in reality I'd want to read from a byte array passed by the caller). The file was created from a python dict usign the RawBsonDocument class.
This is the code used to create the file:
import bson
from bson.raw_bson import RawBSONDocument
docs = []
docs.append(RawBSONDocument(bson.encode({'_id': 'SOME_ID_VALUE', 'a': 11111, 'b': 222222, 'c': {'x': None, 'y': 3333333}})))
with open("file.bson", 'wb') as fh:
for doc in docs[:1]:
fh.write(doc.raw)
Here's my code so far:
fn read_bson_file(){
let mut f = File::open("file.bson").expect("no file found");
let mut buffer = vec![];
f.read_to_end(&mut buffer);
println!("buffer size {}", buffer.len());
let res = bson::raw::RawDocument::from_bytes(&buffer);
let rawdoc = match res {
Ok(raw) => raw,
Err(err) => panic!("{:?}", err)
};
}
how to convert the above rawdoc to the bson::Document type. Also, is there a way to directly create a bson::Document from the buffer I have above?
There's an implementation of TryFrom<RawDocument> for bson::Document:
https://docs.rs/bson/latest/bson/struct.Document.html#impl-TryFrom%3C%26RawDocument%3E-for-Document
Example of usage:
let bsonRawDocument = bson::raw::RawDocument::from_bytes(&buffer).unwrap();
let bsonDocument = bson::Document::try_from(&bsonRawDocument).unwrap();
Related
I am trying to convert a string to blob using web_sys
let json_string = json::stringify(data);
let json_jsvalue = JsValue::from_str(&json_string);
let json_blob_result = Blob::new_with_str_sequence(&json_jsvalue);
let json_blob = json_blob_result.unwrap();
It gives error:
panicked at 'called Result::unwrap() on an Err value: JsValue(TypeError: Blob constructor: Argument 1 can't be converted to a sequence.
As explained in MDN, to create a Blob from string you need to wrap it in array:
let json_string = json::stringify(data);
let json_jsvalue = JsValue::from_str(&json_string);
let json_jsvalue_array = js_sys::Array::from_iter(std::iter::once(json_jsvalue));
let json_blob_result = Blob::new_with_str_sequence(&json_jsvalue_array);
let json_blob = json_blob_result.unwrap();
Actually I'm returing a cloned struct
pub fn matrix_first_or_create(&self, schema: String, symbol: String) -> RewardMatrix {
....
let rewards = reward_matrix
.filter(state.eq(schema.clone()))
.filter(turn_symbol.eq(symbol.clone()))
.limit(1)
.load::<RewardMatrix>(&self.connection)
.expect("Error loading posts");
if rewards.len() > 0 {
return rewards.get(0).unwrap().clone();
}
....
}
Is this the right way to handle a result in Diesel? Can I "extract" and own the first and only result from this query?
What you need here is the .first() method of the RunQueryDsl trait.
Here is an example of how it works:
let reward: RewardMatrix = reward_matrix
.filter(state.eq(schema.clone()))
.filter(turn_symbol.eq(symbol.clone()))
.first(&self.connection)?;
But if your query may not return that row, it’s also good to use the .optional() method of QueryResult:
let reward: Option<RewardMatrix> = reward_matrix
.filter(state.eq(schema.clone()))
.filter(turn_symbol.eq(symbol.clone()))
.first(&self.connection)
.optional()?;
load returns a simple owned Vec<RewardMatrix>, so any solution for getting an owned element from a Vec works here:
if let Some(reward) = rewards.into_iter().next() {
return reward;
}
but Diesel also provides better-suited alternatives like get_result and first that don’t involve Vec at all (combine with optional as recommended in the documentation):
let reward = reward_matrix
.filter(state.eq(&schema))
.filter(turn_symbol.eq(&symbol))
.first::<RewardMatrix>(&self.connection)
.optional()
.expect("Error loading posts");
if let Some(reward) = reward {
return reward;
}
I'm trying to follow along the "hello compute" example from wgpu on Windows 10 (with some minor modifications, mainly gutting the shader so it does basically no actual computing), but when I read the buffer at the end, it's always zeroed out.
This is the shader I'm trying to run, it compiles fine and I think it's correct
[[block]]
struct Numbers
{
data: [[stride(4)]] array<u32>;
};
[[group(0), binding(0)]]
var<storage, read_write> numbers: Numbers;
[[stage(compute), workgroup_size(1)]]
fn main()
{
numbers.data[0] = numbers.data[0] + u32(1);
numbers.data[1] = numbers.data[1] + u32(1);
numbers.data[2] = numbers.data[2] + u32(1);
}
As for the wgpu code, it follows the tutorial quite closely:
I get the instance, device, and queue
let instance = Instance::new(Backends::PRIMARY);
let adapter = block_on(instance
.request_adapter(&RequestAdapterOptions
{
power_preference: PowerPreference::default(),
compatible_surface: None,
}))
.unwrap();
let (device, queue) = block_on(adapter
.request_device(&Default::default(), None))
.unwrap();
Compile the shader and make a pipeline:
let shader = device.create_shader_module(&ShaderModuleDescriptor
{
label: Some("shader"),
source: ShaderSource::Wgsl(shader_src.into()),
});
let pipeline = device.create_compute_pipeline(&ComputePipelineDescriptor
{
label: None,
layout: None,
module: &shader,
entry_point: "main",
});
Make the staging and storage buffer. The dbg!(size) prints 12, which should be correct for a 3-length array for 4-byte u32s.
let buffer = [1u32, 2, 3];
let size = std::mem::size_of_val(&buffer) as u64;
dbg!(size);
let staging_buffer = device.create_buffer(&BufferDescriptor
{
label: None,
size: size,
usage: BufferUsages::MAP_READ | BufferUsages::COPY_DST,
mapped_at_creation: false,
});
let storage_buffer = device.create_buffer_init(&BufferInitDescriptor
{
label: Some("storage buffer"),
contents: cast_slice(&buffer),
usage: BufferUsages::STORAGE
| BufferUsages::COPY_DST
| BufferUsages::COPY_SRC,
});
set up the bind group:
let bg_layout = pipeline.get_bind_group_layout(0);
let bind_group = device.create_bind_group(&BindGroupDescriptor
{
label: None,
layout: &bg_layout,
entries: &[BindGroupEntry
{
binding: 0,
resource: storage_buffer.as_entire_binding(),
}]
});
Get the encoder and create the compute pass. The copy_buffer_to_buffer should copy the storage buffer to the staging buffer so I can read it at the end.
let mut encoder = device.create_command_encoder(&CommandEncoderDescriptor
{
label: None,
});
{
let mut cpass = encoder.begin_compute_pass(&ComputePassDescriptor
{
label: None
});
cpass.set_pipeline(&pipeline);
cpass.set_bind_group(0, &bind_group, &[]);
cpass.dispatch(1, 1, 1);
}
encoder.copy_buffer_to_buffer(
&storage_buffer, 0,
&staging_buffer, 0,
size);
queue.submit(Some(encoder.finish()));
And then submit the compute pass and block for the result:
let buf_slice = staging_buffer.slice(..);
let buf_future = buf_slice.map_async(MapMode::Read);
device.poll(Maintain::Wait);
if let Ok(()) = block_on(buf_future)
{
let data = buf_slice.get_mapped_range();
let result = cast_slice::<u8, u32>(&data).to_vec();
drop(data);
staging_buffer.unmap();
println!("{:?}", result);
}
else
{
println!("error");
}
The error case isn't reached, and the program terminates with no errors, but the result is always printed [0, 0 ,0], when it should be [2, 3, 4].
What am I doing wrong?
The program works fine when I'm running it on my discrete graphics card, but wgpu is bugged on my integrated Intel HD Graphics 630, which is why the program appeared not to work.
I am using rust-protobuf version 2.4
I have following code
let mut msg = vec![];
let mut str = protobuf::CodedOutputStream::vec(&mut msg);
let mut rmsg = user_manager::user::user_data::new();
rmsg.set_id("1234".into());
rmsg.set_nick("test".into());
str.write_message(1, &rmsg).unwrap();
str.flush().unwrap();
println!("{:?}", msg);
let test: register_msg = protobuf::parse_from_bytes(&msg[..]).unwrap();
println!("serialized: {:?}\noriginal: {:?}", test, rmsg);
and the relevant proto description is as follows
message user_data{
string id = 1; //required
string nick = 2;
string theme = 3;
string admin_id = 4;
string lang = 5;
double credit = 6; //required
double bonus_credit = 7; //required
};
and what i get as a result is all messed up
First of all, why do I need to enter a number if im serializing the entire message? that's a really weird design.
Secondly, the first field as you may see in the proto file is the id but output from serialization shows the protobuf package serialized everything into the nick field which is the second field.
Am I doing something wrong or might this be a bug in the library?
UPDATE 1:
I have changed write_msg to write_to_bytes
this is how my code looks now.
let mut rmsg = user_manager::user::user_data::new();
rmsg.set_id("1234".into());
rmsg.set_nick("test".into());
let msg = rmsg.write_to_bytes().unwrap();
println!("{:?}", msg);
println!("{:?}", &msg[..]);
let test: register_msg = protobuf::parse_from_bytes(&msg).unwrap();
println!("serialized: {:?}\noriginal: {:?}", test, rmsg);
and still, the output is all messed up.
You can use Message::write_to_bytes to serialize a message that can be parsed with parse_from_bytes.
Also, make sure that you are deserializing the same type that you serialized.
Here's an example program that works correctly:
mod protos;
use protobuf::Message;
use protos::user_data::user_data;
fn main() {
let mut rmsg = user_data::new();
rmsg.set_id("1234".into());
rmsg.set_nick("test".into());
let msg = rmsg.write_to_bytes().unwrap();
println!("{:?}", msg);
let test: user_data = protobuf::parse_from_bytes(&msg).unwrap();
println!("serialized: {:?}\noriginal: {:?}", test, rmsg);
}
This line:
str.write_message(1, &rmsg).unwrap();
writes the message rmsg as a submessage with field id 1. So the fields end up one nesting level deeper, as if your .proto was:
message wrappermsg {
user_data msg = 1;
}
The correct method is:
rmsg.write_to(&mut str);
I would like to parse a web page, insert anchors at certain positions and render the modified DOM out again in order to generate docsets for Dash. Is this possible?
From the examples included in html5ever, I can see how to read an HTML file and do a poor man's HTML output, but I don't understand how I can modify the RcDom object I retrieved.
I would like to see a snippet inserting an anchor element (<a name="foo"></a>) to an RcDom.
Note: this is a question regarding Rust and html5ever specifically ... I know how to do it in other languages or simpler HTML parsers.
Here is some code that parses a document, adds an achor to the link and prints the new document:
extern crate html5ever;
use html5ever::{ParseOpts, parse_document};
use html5ever::tree_builder::TreeBuilderOpts;
use html5ever::rcdom::RcDom;
use html5ever::rcdom::NodeEnum::Element;
use html5ever::serialize::{SerializeOpts, serialize};
use html5ever::tendril::TendrilSink;
fn main() {
let opts = ParseOpts {
tree_builder: TreeBuilderOpts {
drop_doctype: true,
..Default::default()
},
..Default::default()
};
let data = "<!DOCTYPE html><html><body></body></html>".to_string();
let dom = parse_document(RcDom::default(), opts)
.from_utf8()
.read_from(&mut data.as_bytes())
.unwrap();
let document = dom.document.borrow();
let html = document.children[0].borrow();
let body = html.children[1].borrow(); // Implicit head element at children[0].
{
let mut a = body.children[0].borrow_mut();
if let Element(_, _, ref mut attributes) = a.node {
attributes[0].value.push_tendril(&From::from("#anchor"));
}
}
let mut bytes = vec![];
serialize(&mut bytes, &dom.document, SerializeOpts::default()).unwrap();
let result = String::from_utf8(bytes).unwrap();
println!("{}", result);
}
This prints the following:
<html><head></head><body></body></html>
As you can see, we can navigate through the child nodes via the children attribute.
And we can change an attribute present in the vector of attributes of an Element.