Access a variable from another function in rust - rust

Hello I have a variable with a string here:
#[post("/select_date", data = "<time>")]
fn select_date(time: Form<SelectDate>) -> Result<Redirect, Error>{
println!("{:#?}", time.date);
let f_time = &time.date;
Ok(Redirect::to("/"))
}
and I need to have the variable readable from here in the same file
#[get("/")]
async fn index(user: Option<User>) -> Template {
let f_time = "";//here i would like to have that string
Template::render("index", json!({ "user": user, "f_time ": f_time }))
}
I can't return the string in the select_date function because it needs to return the redirect to the index page otherwise it would be a black page.

Related

How to handle String.parse<_> ParseIntError [rust]

I finished converting the Rust books guessing game example to an Iced GUI application and wanted to handle error handling for the input from the user.
I have a String trying to convert to an i32 and am not sure how to handle the error if the user puts a String in the text_input or just hits return. I figured out a simple solution of:
self.hidden_compare = self.user_guess_text.trim().parse::<i32>().unwrap_or(0);
Rather than having self.hidden_compare default to 0. I would rather have self.user_guess_text default to a String I have set to earlier in the application and am unsure of how to accomplish this still being fairly new.
Edit: Full function added for clarification.
fn update(&mut self, message: Message) -> Command<Message> {
match message {
Message::BtnGuessNow => {
self.hidden_compare = self.user_guess_text.trim().parse::<i32>().unwrap_or(0);
if self.hidden_value == self.hidden_compare {
self.label_compare = String::from("A WINNER!");
self.number_ofguesses.push(self.hidden_compare.to_string() + ", A WINNER!");
}
else if self.hidden_value > self.hidden_compare {
self.label_compare = String::from("Too Low");
self.number_ofguesses.push(self.hidden_compare.to_string() + ", Too Low!");
}
else if self.hidden_value < self.hidden_compare {
self.label_compare = String::from("Too Big");
self.number_ofguesses.push(self.hidden_compare.to_string()+ ", Too Big!");
}
self.user_guess_text = "".to_string();
Command::none()
}
Message::UserInputValueUpdate(x) => {
self.user_guess_text = x;
Command::none()
}
}
and a relevant function that handles the Vec output:
fn guess_output_calc(&self) -> String {
let mut tempoutput = String::new();
for (i, x) in self.number_ofguesses.iter().enumerate().skip(1) {
let guessfmt = String::from(format!("Guess# {} Was: {}\n", i, x));
tempoutput.push_str(&guessfmt);
};
return
I would rather have self.user_guess_text default to a String
I'm not entirely sure what you mean with that, but I interpret this as "I want to set the self.user_guess_text variable to a specific value if it can't be converted to an integer". If this is wrong, then please update your question.
This is how I would approach this (simplified):
fn main() {
let mut user_guess_text = " a ";
match user_guess_text.trim().parse::<i32>() {
Ok(value) => {
println!("Parsed to value: {}", value);
}
Err(_) => {
println!("Unable to parse. Resetting variable.");
user_guess_text = "fallback text!";
}
}
println!("user_guess_text: {}", user_guess_text);
}
Unable to parse. Resetting variable.
user_guess_text: default text!

Sending &str numerals as input fails a condition check while hard coding the same &str numeral doesn't (RUST) [duplicate]

This question already has answers here:
Why does my string not match when reading user input from stdin?
(3 answers)
Closed 1 year ago.
Hello I'm trying to get user input using the get_input() which will return a String. get_input() is called by check_input() which uses match to check if the input String has only numerals or not and will return a bool depending on the input. I sliced the String and stored it as &str and even then my check_input() function returns false even if the input value was only numerals. Now if I hard code a &str and pass it in the match it returns true.
I'm trying to learn Rust and am very new to the lang (started Rust 3 days ago) so an in-depth explanation on what went wrong would be very welcome. And please give me any critiques/pointers you think one would need to get good at Rust.
CODE:
// // use std::io; // to take user input
use std::io; // to take user input
fn main() {
//let mut grid_size = get_input().trim().parse::<i64>().unwrap();
//println!("{}", grid_size + 2 );
println!("From main ---> {:?}",checkinput());
}
fn get_input() -> String{
// fn get_input() -> &'static str{
println!("Please enter the grid size" );
let mut input_string = String::new();
std::io::stdin().read_line(&mut input_string).expect("Failed");
return input_string;
// let my_own_str: String = input_string.to_owned();
// let sliced_str: &str = &my_own_str[..];
// println!("sliced_str ---> {}\nmy_own_string ---> {}", sliced_str, my_own_str);
// return sliced_str;
// let my_test_str: &str = "2";
// return my_test_str;
}
fn checkinput() -> bool{
// match get_input().bytes().all(|c| c.is_ascii_digit()) {
// let test = get_input().bytes().all(|c| c.is_ascii_digit());
// let test = get_input().chars().all(char::is_numeric);
let test_var = get_input(); // i get a String
let my_own_str: String = test_var.to_owned(); // i own the Strin
let sliced_str: &str = &my_own_str[..]; // i cut Strin into str
let sliced_str_new: &str = "123312"; // i cut Strin into str
// let sliced_str: &str = test_var.as_str(); // i cut Strin into str
// let sliced_str: &str = "123"; // if i put a str "123" then true
println!("sliced_str ---> {}", sliced_str); // print to check input val
println!("my_own_string ---> {}", my_own_str); // print to check input val
let test = sliced_str.chars().all(char::is_numeric); // check if my str is a numeric
println!("---------------------------------------");
println!("Type of my_own_str");
find_type(&my_own_str);
println!("---------------------------------------");
println!("Type of sliced_str");
find_type(&sliced_str);
println!("---------------------------------------");
println!("Type of sliced_str_new");
find_type(&sliced_str_new);
println!("---------------------------------------");
println!("TEST ---> {}", test); // print bool
match test {
true => return true,
false => return false,
}
}
fn find_type<T>(_: &T) {
println!("{}", std::any::type_name::<T>())
}
add a .trim() before .chars():
let test = sliced_str.trim().chars().all(char::is_numeric);

How can I concatenate a string to an ident in a macro derive?

I need to create a macro derive where the name is part of the function name. (This code does not work, it is only to show the problem)
fn impl_logic(ast: &syn::DeriveInput) -> TokenStream {
let name:&syn::Ident = &ast.ident;
let gen = quote! {
pub fn #name_logic() -> Arc<Mutex<UiAplicacion>> {
...
}
};
gen.into()
}
How can I do this?
Based on quote's docs, you can construct a new identifier with syn::Ident:
let fname = format!("{}_logic", name);
let varname = syn::Ident::new(&fname, ident.span());
and then interpolate it:
let gen = quote! {
pub fn #varname() -> Arc<Mutex<UiAplicacion>> {
...
}

Struct property accessable from method but not from outside

I'm trying to build a basic web crawler in Rust, which I'm trying to port to html5ever. As of right now, I have a function with a struct inside that is supposed to return a Vec<String>. It gets this Vec from the struct in the return statement. Why does it always return an empty vector? (Does it have anything to do with the lifetime parameters?)
fn find_urls_in_html<'a>(
original_url: &Url,
raw_html: String,
fetched_cache: &Vec<String>,
) -> Vec<String> {
#[derive(Clone)]
struct Sink<'a> {
original_url: &'a Url,
returned_vec: Vec<String>,
fetched_cache: &'a Vec<String>,
}
impl<'a> TokenSink for Sink<'a> {
type Handle = ();
fn process_token(&mut self, token: Token, _line_number: u64) -> TokenSinkResult<()> {
trace!("token {:?}", token);
match token {
TagToken(tag) => {
if tag.kind == StartTag && tag.attrs.len() != 0 {
let _attribute_name = get_attribute_for_elem(&tag.name);
if _attribute_name == None {
return TokenSinkResult::Continue;
}
let attribute_name = _attribute_name.unwrap();
for attribute in &tag.attrs {
if &attribute.name.local != attribute_name {
continue;
}
trace!("element {:?} found", tag);
add_urls_to_vec(
repair_suggested_url(
self.original_url,
(&attribute.name.local, &attribute.value),
),
&mut self.returned_vec,
&self.fetched_cache,
);
}
}
}
ParseError(error) => {
warn!("error parsing html for {}: {:?}", self.original_url, error);
}
_ => {}
}
return TokenSinkResult::Continue;
}
}
let html = Sink {
original_url: original_url,
returned_vec: Vec::new(),
fetched_cache: fetched_cache,
};
let mut byte_tendril = ByteTendril::new();
{
let tendril_push_result = byte_tendril.try_push_bytes(&raw_html.into_bytes());
if tendril_push_result.is_err() {
warn!("error pushing bytes to tendril: {:?}", tendril_push_result);
return Vec::new();
}
}
let mut queue = BufferQueue::new();
queue.push_back(byte_tendril.try_reinterpret().unwrap());
let mut tok = Tokenizer::new(html.clone(), std::default::Default::default()); // default default! default?
let feed = tok.feed(&mut queue);
return html.returned_vec;
}
The output ends with no warning (and a panic, caused by another function due to this being empty). Can anyone help me figure out what's going on?
Thanks in advance.
When I initialize the Tokenizer, I use:
let mut tok = Tokenizer::new(html.clone(), std::default::Default::default());
The problem is that I'm telling the Tokenizer to use html.clone() instead of html. As such, it is writing returned_vec to the cloned object, not html. Changing a few things, such as using a variable with mutable references, fixes this problem.

Parsing an url in Iron and getting a dynamic part

I have 2 routes in Iron:
/something/:some_int # integer
/something2/:some_str # string
How can I get these :some_{int, str} parts of them?
fn my_something_int_route_handler(req: &mut Request) -> IronResult<Response> {
let ref query = req.extensions.get::<Router>().unwrap().find("query").unwrap_or("/");
//what next ???
// how can I get the ":some_int" from :/something/:some_int
fn my_something2_str_route_handler(req: &mut Request) -> IronResult<Response> {
let ref query = req.extensions.get::<Router>().unwrap().find("query").unwrap_or("/");
// how can I get the ":some_str" from :/something/:some_str
Use the router crate:
let mut router = Router::new();
router.get("/users/:user_id", user_show, "user_show");
let _server = Iron::new(router).http(("127.0.0.1", 8787)).unwrap();
Inside your handler, you get a reference to the Router's Params which lets you get the value for each named parameter. Note that the argument to Params::find matches the names assigned when the route was defined:
fn user_show(req: &mut Request) -> IronResult<Response> {
let router = req.extensions.get::<Router>()
.expect("Unable to get router");
user_id = router.find("user_id")
.expect("A user id is required");
}
One you have a parameter as string, you parse it into a number like anywhere else in Rust.

Resources