Method not found in `regex::Captures<'_>` - rust

When I run this code in playground:
use regex::Regex;
fn main() {
let re = Regex::new(r#"regex(group)"#).unwrap();
println!("{:?}", re.captures(r#"regexgroup"#).unwrap().get(1).unwrap().as_str());
}
the code snippet works. However, running this code locally I get the error:
error[E0599]: no method named `get` found for struct `regex::Captures` in the current scope
|
| println!("{:?}", re.captures(r#"regexgroup"#).unwrap().get(1).unwrap().as_str());
| ^^^ method not found in `regex::Captures<'_>`
In both cases I am using the 2018 edition of Rust and import regex::Regex (and nothing else from the regex crate).
I tried using cargo clean and importing the mentioned Struct but nothing works. In the regex doc they basically do the above thing and it definitely implements the get method.

You got an old version of regex. Up until v0.1.80 (and including), it did not have get(). Upgrade your regex version (change Cargo.toml to at least regex = "1"), or use the pos() method - the name of the early get(), or just use indexing since you unwrap() anyway.

Related

can't find gen_range method on rand::thread_rng [duplicate]

This question already has an answer here:
Why do I need to import a trait to use the methods it defines for a type?
(1 answer)
Closed 2 years ago.
I'm stuck on the first example given in the Rust book, the guessing game. I just cannot find the gen_range method on thread_rng() to generate the number. The only methods that show up are fill_bytes, next_u32, next_u64 and try_fill_bytes, and if I try to write it anyway I get an error saying the method doesn't exist. However, when I tried the random function, which according to the documentation is simply a shortcut for thread_rng().gen(), it works. I've tried other functions, updating and reinstalling everything but it still doesn't work and I really don't know what to do.
Welcome to Stack Overflow. In the future, please try to add more information to your question, including relevant links (which doc are you talking about), source code and error messages. This will make it easier for us to give relevant and useful answers.
I'm assuming you're doing something like this:
use rand::thread_rng;
fn main() {
let x = thread_rng().gen_range(0, 10);
println!("{}", x);
}
Playground
Which gives the following error:
error[E0599]: no method named `gen_range` found for struct `rand::rngs::thread::ThreadRng` in the current scope
--> src/main.rs:4:26
|
4 | let x = thread_rng().gen_range(0, 10);
| ^^^^^^^^^ method not found in `rand::rngs::thread::ThreadRng`
|
::: /playground/.cargo/registry/src/github.com-1ecc6299db9ec823/rand-0.7.3/src/lib.rs:212:8
|
212 | fn gen_range<T: SampleUniform, B1, B2>(&mut self, low: B1, high: B2) -> T
| ---------
| |
| the method is available for `std::boxed::Box<rand::rngs::thread::ThreadRng>` here
| the method is available for `std::sync::Arc<rand::rngs::thread::ThreadRng>` here
| the method is available for `std::rc::Rc<rand::rngs::thread::ThreadRng>` here
|
= help: items from traits can only be used if the trait is in scope
help: the following trait is implemented but not in scope; perhaps add a `use` for it:
|
1 | use rand::Rng;
|
Note that the Rust compiler is very good in giving suggestions for ways to fix your code. In this case, the last line from the error suggests adding use rand::Rng;, and now it works:
use rand::Rng;
use rand::thread_rng;
fn main() {
let x = thread_rng().gen_range(0, 10);
println!("{}", x);
}
Playground
This is because the gen_range method is not implemented directly on the ThreadRng struct, but instead it is implemented in the general Rng trait, which makes it automatically available for all random number generators. However methods from traits are only available if the trait itself is available, hence the need to import rand::Rng first.
You can try installing the the following version, works for me in this version.
Add this to your Cargo.toml dependencies:
rand = "0.7.3"
Import:
use rand::Rng;
Usage:
rand::thread_rng().gen_range(0, 10);

Why the result of `Regex::new` cannot be assigned to a constant?

I have many repeated constants in the form of:
pub const FOO_REGEX: Regex = Regex::new(r"foo.*").unwrap();
pub const BAR_REGEX: Regex = Regex::new(r"bar.*").unwrap();
I'd like to simply this by using a macro_rules! macro.
I tried:
macro_rules! pattern {
($value:literal) => {
Regex::new($value).unwrap()
}
}
pub const FOO_REGEX: Regex = pattern!(r"foo.*");
But the compiler complains with:
error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants
--> lib.rs:7:9
|
7 | Regex::new($value).unwrap()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
11 | pub const FOO_REGEX: Regex = pattern!(r"foo.*");
| ------------------ in this macro invocation
Per this guide I tried many of the available designators options, like expr, ident, but I'm still not able to get macro to compile.
Why does the literal designator not work for this macro expression?
This has nothing to do with macros: you get the same error if you write the code directly (playground). The problem here is that calling Regex::new is not a literal (1) and cannot be evaluated at compile-time (yet?). You will need to use something like the lazy_static crate to ensure that Regex::new is called at run-time to compile the regular expression:
use regex::Regex;
use lazy_static::lazy_static;
lazy_static!{
pub static ref FOO_REGEX: Regex = Regex::new(r"foo.*").unwrap();
}
Playground
(1) Quoting from this answer:
A literal is a value written as-is in the code: true, 1, "hello"; the result of an expression [like Regex::new] cannot be a literal (by definition). The resulting types may look similar (or even be identical) but types are irrelevant here.

How to print the contents of a syn::Expr with println?

I am trying to output the contents of a syn::Expr to the console, but get the following error:
error[E0599]: no method named `to_string` found for type `&syn::Expr` in the current scope
--> derive/src/lib.rs:165:40
|
165 | println!("Expression: {:#?}", expr.to_string());
| ^^^^^^^^^
|
= note: the method `to_string` exists but the following trait bounds were not satisfied:
`syn::Expr : std::string::ToString`
`&syn::Expr : std::string::ToString`
`syn::Expr : std::string::ToString`
It is not clear to me what "trait bounds" are or how to satisfy them. Are there any easy ways to output the contents of this variable?
syn::Expr is documented as implementing the Debug trait, so you use the Debug formatter:
extern crate syn; // 0.15.4
fn example(expr: syn::Expr) {
println!("{:#?}", expr);
}
However, all Debug implementations in syn are guarded by the Cargo feature extra-traits. So in order to use those Debug impls, you have to specifically enable that feature in your Cargo.toml:
[dependencies]
syn = { version = "0.15", features = ["extra-traits"] }
You can read more about syn's optional Cargo features in their README.
See also:
How do I print variables in Rust and have it show everything about that variable, like Ruby's .inspect?
What is the difference between println's format styles?
Should I implement Display or ToString to render a type as a string?
Does println! borrow or own the variable?

Is there any straightforward way for Clap to display help when no command is provided?

I'm using the Clap crate for parsing command line parameters. I've defined a subcommand ls that should list files. Clap also defines a help subcommand that displays information about the application and its usage.
If no command is provided, nothing gets displayed at all, but I want the app to display help in that case.
I've tried this code, which looks pretty straightforward, but it doesn't work:
extern crate clap;
use clap::{App, SubCommand};
fn main() {
let mut app = App::new("myapp")
.version("0.0.1")
.about("My first CLI APP")
.subcommand(SubCommand::with_name("ls").about("List anything"));
let matches = app.get_matches();
if let Some(cmd) = matches.subcommand_name() {
match cmd {
"ls" => println!("List something here"),
_ => eprintln!("unknown command"),
}
} else {
app.print_long_help();
}
}
I get an error that app is used after move:
error[E0382]: use of moved value: `app`
--> src/main.rs:18:9
|
10 | let matches = app.get_matches();
| --- value moved here
...
18 | app.print_long_help();
| ^^^ value used here after move
|
= note: move occurs because `app` has type `clap::App<'_, '_>`, which does not implement the `Copy` trait
Reading through the documentation of Clap, I've found that the clap::ArgMatches that's returned in get_matches() has a method usage that returns the string for usage part, but, unfortunately, only this part and nothing else.
Use clap::AppSettings::ArgRequiredElseHelp:
App::new("myprog")
.setting(AppSettings::ArgRequiredElseHelp)
See also:
Method call on clap::App moving ownership more than once
You can also use Command::arg_required_else_help as a bool on the command itself.
Command::new("rule").arg_required_else_help(true)

How are mod & use supposed to work for traits in rust?

Consider the following contrived situation:
mod imported {
pub trait Imported {
fn hello(&self, x:int) -> int;
}
}
struct Hi;
impl imported::Imported for Hi {
fn hello(&self, x:int) -> int {
return x;
}
}
#[test]
fn test_thing() {
let value = Hi;
println!("{:?}", value.hello(10));
}
This won't compile, because the trait Imported is not in scope, so the method hello() cannot be invoked:
imports.rs:20:18: 20:33 error: type `imports::Hi` does not implement any method in scope named `hello`
imports.rs:20 println!("{:?}", value.hello(10));
^~~~~~~~~~~~~~~
If we put Imported in the current scope (ie. get rid of mod imported) this works fine, but like this, it does not.
Normally for this purpose you would use 'use' to bring the 'Imported' symbol into the local scope:
use imported::Imported;
However, in this case you cannot, because the symbol 'imported' does not yet exist at the beginning of the file:
imports.rs:2:5: 2:13 error: unresolved import. maybe a missing `extern crate imported`?
imports.rs:2 use imported::Imported;
^~~~~~~~
imports.rs:2:5: 2:23 error: failed to resolve import `imported::Imported`
imports.rs:2 use imported::Imported;
^~~~~~~~~~~~~~~~~~
And you cannot do it after the mod imported call, because:
imports.rs:8:1: 8:24 error: `use` and `extern crate` declarations must precede items
imports.rs:8 use imported::Imported;
^~~~~~~~~~~~~~~~~~~~~~~
To be fair this only occurs when you are implementing a trait and then trying to use that impl in the safe file, but it seems like this would actually be quite a common use case for testing.
You can work around it by structuring your code slightly differently and importing modules from some common parent, but this seems like an inherent limitation of the current system.
Am I missing something?
I think you have indeed missed something. Adding use imported::Imported; at the top of the file does work—I presume that this is not precisely what you tried to compile.
use statements, although written before the mod statements, are resolved after the mod, so there is no source order problem.
I presume that your error is in fact that your file imports.rs was not the crate root. Remember that a use statement takes an absolute path if you don't use super or self in it. To make it work in any place, you would need to write use self::imported::Imported;; assuming you were compiling a lib.rs containing mod imports;, you would have needed to use imports::imported::Imported, the absolute path to the trait.
(BTW, you can replace return x; at the end of the function with just x. Remember Rust's block value doctrine, whereby the last expression in a block is the value of the block.)

Resources