Function returns &Option and not Option [closed] - rust

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 10 months ago.
Improve this question
I am a beginner in Rust and I don't understand the behaviour I am encountering. Function number 1 should return me an Option type but returns an &Option type. I have worked around this by doing function 2 but I don't understand why this works. What am I doing wrong in my function?
Function 1:
pub fn manage_request(&self, request:String) -> Option<Some type> {
let words : Vec<&str> = request.split_whitespace().collect();
match words[0] {
"attach" => &self.hashmap.get(words[1]),
_ => None,
}
}
Function 2:
pub fn manage_request(&self, request:String) -> Option<Some type> {
let words : Vec<&str> = request.split_whitespace().collect();
match words[0] {
"attach" => match &self.hashmap.get(words[1]){
None => None,
Some(x) => Some(x)
}
_ => None,
}
}
Here is a link to rust playground with the code

Correct me if Im wrong but I think you actually did this properly but might have missed a typo.
In your playground your signature consumes self by saying fn manage_request(self). If you change this to take a reference to self like fn manage_request(&self) I believe it works.
Updated playground link runs without compiler errors:

Related

"no rules expected the token" when using macro to implement methods [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 months ago.
Improve this question
I previously used C/C++ and recently started using Rust. I'm experiencing difficulties on writing simple macro_rules! to automatically implement some helper methods.
Originally, I had Scanner struct, which scans data from stdio and converts them into a given type.
struct Scanner {
buffer: Vec<String>
}
impl Scanner {
fn next<T: std::str::FromStr>(&mut self) -> T { /* tldr */ }
}
After that, I tried to implement a helper macro to implement two methods which return T and Vec<T> respectively.
// It doesn't work 😢
macro_rules! scanner_shortcut {
($scan_type:ident, $single_scan_ident:ident, &multi_scan_ident:ident) => {
impl Scanner {
fn $single_scan_ident(&mut self) -> $scan_type {
self.next()
}
fn $multi_scan_ident(&mut self, n: usize) -> Vec<$scan_type> {
(0..n).map(|_| self.next()).collect()
}
}
};
}
scanner_shortcut!(i32, scan_i32, scan_i32s);
scanner_shortcut!(i64, scan_i64, scan_i64s);
However, I got the following error message: no rules expected this token in macro call
error: no rules expected the token `scan_i32s`
--> src/bin/playground.rs:36:34
|
23 | macro_rules! scanner_shortcut {
| ----------------------------- when calling this macro
...
36 | scanner_shortcut!(i32, scan_i32, scan_i32s);
| ^^^^^^^^^ no rules expected this token in macro call
error: no rules expected the token `scan_i64s`
--> src/bin/playground.rs:37:34
|
23 | macro_rules! scanner_shortcut {
| ----------------------------- when calling this macro
...
37 | scanner_shortcut!(i64, scan_i64, scan_i64s);
| ^^^^^^^^^ no rules expected this token in macro call
I struggled to get rid of this problem, and I found that when I remove &multi_scan_ident:ident and the corresponding method declaration, it works well!
// It works well...  🧐
macro_rules! scanner_shortcut {
($scan_type:ident, $single_scan_ident:ident) => {
impl Scanner {
fn $single_scan_ident(&mut self) -> $scan_type {
self.next()
}
}
};
}
scanner_shortcut!(i32, scan_i32);
scanner_shortcut!(i64, scan_i64);
I guess the first code has some syntactic problems with the macro definition because the second version works well, but I couldn't figure out the exact reason. What makes this difference?
Any help will be appreciated!
You have a syntax error:
&multi_scan_ident:ident
This should be:
$multi_scan_ident:ident

How should doc comments be spread over multiple elements? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 months ago.
Improve this question
I need to document a piece of code that is 3-fold. I have an enum element, an associated constructor and a method that uses the enum to do work. Here is a minimal example:
use regex::{Error, Regex};
pub enum Element {
And {
lhs: Box<Element>,
rhs: Box<Element>,
},
Value {
regex: Regex,
},
}
impl Element {
pub fn new_and(lhs: Element, rhs: Element) -> Self {
Element::And {
lhs: Box::new(lhs),
rhs: Box::new(rhs),
}
}
pub fn new_value(regex: &str) -> Result<Self, Error> {
let regex = Regex::new(regex)?;
Ok(Element::Value { regex })
}
pub fn is_match(&self, values: &Vec<String>) -> bool {
match self {
Element::And { lhs, rhs } => lhs.is_match(values) && rhs.is_match(values),
Element::Value { regex } => {
for value in values {
if regex.is_match(value) {
return true;
}
}
false
}
}
}
}
fn main() {}
There definitely needs to be a comment on new_value() to document the possible error. But where should I put information on how the actual element is evaluated?
Put this also in the comment of new_value() to have all in one place?
Put it in a comment for Element::Value and is_match() only says that elements are
evaluated as documented there?
Put all evaluation information for all enum values in the comment for is_match() and leave Element::Value empty?
Repeat the evaluation information in all 3 locations?
Disclaimer: A lot of this will come down to personal preference and taste, there's not really any hard and fast rules
That being said, I like to look at the standard library's documentation for inspiration.
Generally, if a function returns a Result, some explanation of when it returns an error is probably a good idea. For example: Returns an error if the regex fails to parse. You could also look at the docs for Regex::new to see what they say about it.
When documenting the behaviour of is_match, you should probably put the comment on is_match.
But I'd also suggest putting a more comprehensive comment (preferably with a usage example) either in the module (with //! at the top) or on pub enum Element. Examples are really underrated IMO, and even a simple one can really help a reader to understand the purpose of this type.
For example, the docs for String (https://doc.rust-lang.org/std/string/struct.String.html) have quite a lot of detail on various uses of String as doc comments on the String struct itself.

I have an arg with type Option which i need to use in a http get request but Option type puts Some(T) into the formatted url [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 10 months ago.
Improve this question
This is the function for making the http get request and using selector to select a specific class of css.
pub async fn test(amount: Option<&str>, from: Option<&str>, to: Option<&str>) -> Result<(), Box<dyn std::error::Error>> {
let url_final = format!("https://www.xe.com/currencyconverter/convert/?Amount={:?}&From={:?}&To={:?}", amount, from, to); //used debug cuz Option does not impl Display
}
output:
https://www.xe.com/currencyconverter/convert/?Amount=Some(1)&From=Some("USD")&To=Some("HUF")
basically my question is there any way to remove the Some( ) and only leave the value.
This is what the http get request looks like btw:
let req = reqwest::get(url_final).await?;
FIXED with: let url = url_final.replace("\"", "");
Also added:
amount.unwrap_or_default from.unwrap_or_default to.unwrap_or_default
The Debug implementation for Option<T> will print the Some and None variant names. That's the point of Debug, which is what you'll get when you use {:?} in a format string.
You can use unwrap_or("") or unwrap_or_default():
let url_final = format!(
"https://www.xe.com/currencyconverter/convert/?Amount={}&From={}&To={}",
amount.unwrap_or_default(),
from.unwrap_or_default(),
to.unwrap_or_default()
);
Given you are using reqwest, a nicer way to do this is to use a struct for your query parameters, and make use of serde to omit the None values:
use serde::Serialize;
#[derive(Serialize)]
#[serde(rename_all = "PascalCase")]
struct XeArgs<'a> {
amount: Option<&'a str>,
to: Option<&'a str>,
from: Option<&'a str>,
}
let client = reqwest::Client::new();
let query = XeArgs {
amount: None,
to: Some("USD"),
from: None,
};
let response = client
.get("https://www.xe.com/currencyconverter/convert/")
.query(&query)
.send()
.await?;

Return an error and exit gracefully in clap cli [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 10 months ago.
Improve this question
I'd like to implement a simple clap cli that operates on git repositories, but that isn't critical to the question; it will help clarify I believe. I'm trying to identify the most idiomatic way to exit with an error if not run from the root of a repository. Here are three options; I'm not sure any are good.
What is the best way to do these steps:
check that I've run from repo root
if so continue, if not exit
if no command is given, generate help
if command is given, run the command
Ideally, I'd be able to output the error and usage. Also, there will be other errors that happen in the subcommands, and I'm not sure the best way to exit gracefully in those cases.
Consider the following cli definition:
use clap::ErrorKind::Io;
use clap::{Parser, Subcommand};
use git2::Repository;
use std::process;
#[derive(Debug, Parser)]
#[clap(author, version, about, long_about = None)]
struct Cli {
#[clap(subcommand)]
command: Commands,
}
#[derive(Debug, Subcommand)]
enum Commands {
/// Do a thing.
Do,
}
The three main options I see currently are:
Option 1
fn main() -> Result<(), String> {
let repo = match Repository::open(".") {
Ok(repo) => repo,
Err(_) => return Err("must be run from root of repository".to_owned()),
};
let args = Cli::parse();
match args.command {
Commands::Do => {
println!("{:?}: Doing a thing with the repository.", repo.workdir());
}
}
Ok(())
}
Option 2
fn main() {
let repo = match Repository::open(".") {
Ok(repo) => repo,
Err(_) => {
eprintln!("{}", "must be run from root of repository".to_owned());
process::exit(1);
}
};
let args = Cli::parse();
match args.command {
Commands::Do => {
println!("{:?}: Doing a thing with the repository.", repo.workdir());
}
}
}
Option 3
fn main() -> clap::Result<(), clap::Error> {
let repo = match Repository::open(".") {
Ok(repo) => repo,
Err(_) => return Err(clap::Error::raw(Io, "not in repo")),
};
let args = Cli::parse();
match args.command {
Commands::Do => {
println!("{:?}: Doing a thing with the repository.", repo.workdir());
}
}
Ok(())
}
Are any or all of these horrific, serviceable, or improvable?
I see a closure vote for seeking subjective information, but what I'm after is maybe more binary than it seems. I will of course respect the will of the community, but I am wondering if any or all of these are grossly out of the norm of are problematic for some reason.
I'm personally a big fan of error wrapper libraries like anyhow, eyre or miette.
Some remarks:
consider using .map_err() instead of match for transposing an error into a different one, it's a lot more compact and easier to read
consider using the ? operator instead of return to propagate errors upwards. The ? operator is a short version of "unwrap if Ok and return error if Err" and makes code a lot easier to read.
Here's an example using anyhow:
fn main() -> anyhow::Result<()> {
let repo = Repository::open(".").map_err(|_| anyhow!("must be run from root of repository"))?;
let args = Cli::parse();
match args.command {
Commands::Do => {
println!("{:?}: Doing a thing with the repository.", repo.workdir());
}
}
Ok(())
}

How to return a struct with references in rust? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I'm using crossbeam-epoch to write a lock-free data structure in rust. crossbeam-epoch uses a guard to load the heap-allocated atomic pointer. One example of the data structure's interface is:
fn get(&self, index: IndexType, guard: &'guard Guard) -> Option<&'guard Value>
This method requires a guard which has the same lifetime with the returned value's reference.
Now, I want to wrap this method without providing a Guard. For example:
struct ReturnType<'guard, Value> {
guard: Guard,
value: Option<&'guard Value>
}
impl<'guard, Value> MyDataStructure<Value> {
fn my_get(&self, index: IndexType) -> ReturnType<'guard, Value> {
let guard = pin();
let value = self.get(index, &guard);
ReturnType {
guard: guard,
value: value
}
}
}
But the compiler won't allow me to do this.
My question is how to implement the method my_get?
This question needs some improvement. You should always add a minimal reproducable example and you haven't shown what the compiler error was either.
Anyways, in your code, you just forget to specify what the lifetime should be linked to. If the guard at least lives as long as self, then you should declare your method with:
fn my_get<'guard>(&'guard self, index: IndexType) -> ReturnType<'guard, Value> {
&'guard self tells the compiler to link 'guard to self.
If the guard should live longer than the struct then you have to move the Value or if you want to share the reference use Arc<Value> (Documentation)

Resources