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();
Related
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();
I have a few PathBufs in my Rust application:
let mut dog_path = PathBuf::from("./animals/dog.png");
let mut cow_path = PathBuf::from("./animals/bovine/cow.jpg");
How could I change these PathBufs so that they're being referred to from the ./animals directory?
// an operation on dog_path
// same operation on cow_path
assert_eq!(PathBuf::from("./dog.png"), dog_path);
assert_eq!(PathBuf::from("./bovine/cow.jpg"), cow_path);
I think you want Path::strip_prefix:
let dog_path = PathBuf::from("./animals/dog.png");
let cow_path = PathBuf::from("./animals/bovine/cow.jpg");
let dog_path_rel = dog_path.strip_prefix("./animals").unwrap();
let cow_path_rel = cow_path.strip_prefix("./animals").unwrap();
assert_eq!(Path::new("dog.png"), dog_path_rel);
assert_eq!(Path::new("bovine/cow.jpg"), cow_path_rel);
But that won't include the leading ./. If that's important to you, you can add it manually:
let dog_path_prefixed = Path::new("./").join(dog_path_rel);
let cow_path_prefixed = Path::new("./").join(cow_path_rel);
assert_eq!(PathBuf::from("./dog.png"), dog_path_prefixed);
assert_eq!(PathBuf::from("./bovine/cow.jpg"), cow_path_prefixed);
playground
Note that strip_prefix returns a Result, meaning it could fail if the path doesn't begin with the given prefix. You may want to handle this case instead of unwraping the result (causing your program to exit with a panic), or you may want to use .expect("your message here") instead to provide a meaningful error message.
If you want a general solution you could look at relative-path crate. It looks like it provide the functionality you want.
use std::path::PathBuf;
use relative_path::RelativePath;
fn main() {
let dog_path = PathBuf::from("./animals/dog.png");
let cow_path = PathBuf::from("./animals/bovine/cow.jpg");
let dog_path = RelativePath::from_path(&dog_path).unwrap();
let cow_path = RelativePath::from_path(&cow_path).unwrap();
let animals_dir = RelativePath::new("./animals");
let dog_path = animals_dir.relative(&dog_path).to_path(".");
let cow_path = animals_dir.relative(&cow_path).to_path(".");
assert_eq!(PathBuf::from("./dog.png"), dog_path);
assert_eq!(PathBuf::from("./bovine/cow.jpg"), cow_path);
}
This is a quick draft, but it shows how to do in a generic way what you are trying to accomplish. I think it could be further optimized, but I literally found this crate 10 minutes ago.
goal convert this HTMl string into macro or into node element
use html_parser::Dom;
let html = r#"<span class="text_editor"><h1 title="title is here">hello world</h1><p>hi paragraph</p></span>"#;
let nodes = Dom::parse(html).unwrap_throw();
// add the html
let doc = window().unwrap_throw().document().unwrap_throw();
let my_dom_element = &doc.get_element_by_id("1").unwrap_throw();
my_dom_element.append_child(&nodes.children[0]).unwrap_throw();
31 | my_dom_element.append_child(&nodes.children[0]).unwrap_throw();
| ^^^^^^^^^^^^^^^^^ expected struct `web_sys::Node`, found enum `html_parser::Node`
use web_sys::{window};
let doc = window().unwrap_throw().document().unwrap_throw();
let my_dom_element = &doc.get_element_by_id("1").unwrap_throw();
let html = r#"<span class="text_editor"><h1 title="title is here">hello world</h1><p>hi paragraph</p></span>"#;
my_dom_element.set_inner_html(html);
I'm following the example from the rusqlite git hub https://github.com/rusqlite/rusqlite/blob/master/src/vtab/array.rs#L206. I have the exact same code but I get the compile error
the trait bound `std::vec::Vec<rusqlite::types::Value>: rusqlite::ToSql` is not satisfied
A snippet of the code is below. ids is a Vec of String
let intValues:Vec<i64> = ids.into_iter().map(|s| s.parse::<i64>().expect("Id Parse error.")).collect();
let values:Vec<rusqlite::types::Value> = intValues.into_iter().map(rusqlite::types::Value::from).collect();
let ptr = std::rc::Rc::new(values);
let mut statement = db_connection
.prepare("select * from item where id in rarray(?);")
.expect("Failed to prepare second query.");
let results = statement
// This is the error line
.query_map(&[&ptr], |row| {
Ok(database::ItemData {
id: row.get(0)?,
name: row.get(1)?,
time_to_prepare: row.get(2)?
})
});
I had to add "array" to the feature in the toml file.
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);