How to concatenate static strings in Rust

Since I was essentially trying to emulate C macros, I tried to solve the problem with Rust macros and succeeded: macro_rules! description { () => ( “my program” ) } macro_rules! version { () => ( env!(“CARGO_PKG_VERSION”) ) } macro_rules! version_string { () => ( concat!(description!(), ” v”, version!()) ) } It feels a bit … Read more

Is there a trait supplying `iter()`?

No, there is no trait that provides iter(). However, IntoIterator is implemented on references to some containers. For example, Vec<T>, &Vec<T> and &mut Vec<T> are three separate types that implement IntoIterator, and you’ll notice that they all map to different iterators. In fact, Vec::iter() and Vec::iter_mut() are just convenience methods equivalent to &Vec::into_iter() and &mut … Read more

Is it possible to declare variables procedurally using Rust macros?

Yes however this is only available as a nightly-only experimental API which may be removed. You can pass arbitrary identifier into a macro and yes, you can concatenate identifiers into a new identifier using concat_idents!() macro: #![feature(concat_idents)] macro_rules! test { ($x:ident) => ({ let z = concat_idents!(hello_, $x); z(); }) } fn hello_world() { } … Read more

Why do proc-macros have to be defined in proc-macro crate?

Procedural macros are fundamentally different from normal dependencies in your code. A normal library is just linked into your code, but a procedural macro is actually a compiler plugin. Consider the case of cross-compiling: you are working on a Linux machine, but building a WASM project. A normal crate will be cross-compiled, generate WASM code … Read more

What is the ..= (dot dot equals) operator in Rust?

This is the inclusive range operator. The range x..=y contains all values >= x and <= y, i.e. “from x up to and including y”. This is in contrast to the non-inclusive range operator x..y, which doesn’t include y itself. fn main() { println!(“{:?}”, (10..20) .collect::<Vec<_>>()); println!(“{:?}”, (10..=20).collect::<Vec<_>>()); } // Output: // // [10, 11, … Read more

How can I insert all values of one HashSet into another HashSet?

You don’t want union — as you said, it will create a new HashSet. Instead you can use Extend::extend: use std::collections::HashSet; fn main() { let mut a: HashSet<u16> = [1, 2, 3].iter().copied().collect(); let b: HashSet<u16> = [1, 3, 7, 8, 9].iter().copied().collect(); a.extend(&b); println!(“{:?}”, a); // {8, 3, 2, 1, 7, 9} } (Playground) Extend::extend is … Read more

How to expose a Rust `Vec` to FFI?

If you just want some C function to mutably borrow the Vec, you can do it like this: extern “C” { fn some_c_function(ptr: *mut i32, len: ffi::size_t); } fn safe_wrapper(a: &mut [i32]) { unsafe { some_c_function(a.as_mut_ptr(), a.len() as ffi::size_t); } } Of course, the C function shouldn’t store this pointer somewhere else because that would … Read more