Using iter().map on a VecDeque of struct containing tuples - vector

I am new in Rust. I have the following problem:
pub struct Events {
pub ts: u64,
pub temperature_multiplier: (f64,f64), // (temperature,multiplier)
}
I have a VecDeque of this struct
elements_vec: VecDeque<Events>
I would like to be able to go through all the elements of VecDeque and compute the the sum of (temperature * multiplier).
What I have tried:
elements_vec.iter().map(|(_, (t,m))| t * m ).sum()
It returns an error saying "expected Struct Events".

Events is not a tuple but a struct. You need to go through Destructuring Structs section in rust book.
elements_vec.iter().map(|Events { temperature_multiplier: (t, m), .. }| t * m).sum::<f64>()

This is how I understood your question:
let mut elements_vec: VecDeque<Events> = VecDeque::with_capacity(10);
elements_vec.push_back(Events { ts: 0x0002, temperature_multiplier: (20.0, 2.0) });
elements_vec.push_back(Events { ts: 0x0003, temperature_multiplier: (30.0, 3.0) });
elements_vec.push_front(Events { ts: 0x0001, temperature_multiplier: (10.0, 1.0) });
println!("{:?}", &elements_vec);
let s : f64 = elements_vec.iter().map(|evnt| evnt.temperature_multiplier.0 * evnt.temperature_multiplier.1 ).sum();
println!("s: {}", s); // s: 140
The answer is in the compiler's message: map() needs struct Events, which we give it as map(|evnt| /* and use it here */). And it works!

Related

How can I pass mutable Vec<Something> variable to function and get item that is indexed

When I try the code below for the Vec<Ev> I get a [E0308]: mismatched type error.
use std::fmt::Error;
#[derive(Debug)]
struct Ev {
semt: String,
fiyat : i32,
}
impl Ev {
fn yeni (alan: &str,fiyat: i32) -> Ev {
Self {
semt: alan.to_string(),
fiyat
}
}
}
fn dizi_yap(boyut:usize) -> Result<Vec<Ev>,Error> {
let mut evler = Vec::<Ev>::with_capacity(boyut);
evler.push(Ev::yeni("melikgazi", 210));
evler.push(Ev::yeni("kocasinan", 120));
evler.push(Ev::yeni("hacılar", 410));
evler.push(Ev::yeni("bünyan", 90));
Ok(evler)
}
fn elemani_getir(&mut dizi:Vec<Ev>, sira:usize) -> Ev {
dizi[sira]
// dizi.get(sira).expect("hata")
}
fn main() {
let mut dizi = dizi_yap(1).expect("ulasmadi");
println!("eleman: {:?}",dizi[3]);
println!("eleman: {:?}",elemani_getir(dizi, 3))
}
How can I get Vec indexed item in this example?
The syntax in you function arguments is a little off. Mutable arguments can be a little confusing, as there are two different representations. Refer to this question for a more detailed explanation.
Here is the elemali_getit function corrected:
fn elemani_getir(mut dizi: &Vec<Ev>, sira: usize) -> &Ev {
&dizi[sira]
}
And you can call it like this:
println!("eleman: {:?}", elemani_getir(&dizi, 3))
Note that elemani_getir now returns a reference to Ev (&Ev). Returning Ev instead results in an error:
cannot move out of index of `std::vec::Vec<Ev>`
To get around this error, you can either return a reference to Ev as shown above, or return an exact duplicated of Ev my deriving the Clone trait:
#[derive(Debug, Clone)]
struct Ev {
semt: String,
fiyat: i32,
}
fn elemani_getir(mut dizi: &Vec<Ev>, sira: usize) -> Ev {
dizi[sira].clone()
}

Raw Pointers not producing desired effects

#![feature(ptr_internals)]
use core::ptr::Unique;
struct PtrWrapper {
id: usize,
self_reference: Unique<Self>
}
impl PtrWrapper {
fn new() -> Self {
let dummy = unsafe {Unique::new_unchecked(std::ptr::null_mut::<PtrWrapper>())};
let mut ret = Self {id:0, self_reference: dummy };
let new_ptr = &mut ret as *mut Self;
debug_print(new_ptr);
ret.self_reference = Unique::new(new_ptr).unwrap();
debug_print(ret.self_reference.as_ptr());
ret
}
fn get_id(&self) -> usize {
self.id.clone()
}
}
fn main() {
println!("START");
let mut wrapper = PtrWrapper::new();
wrapper.id = 10;
let ptr = wrapper.self_reference.as_ptr();
unsafe {
(*ptr).id += 30;
println!("The next print isn't 40? Garbage bytes");
debug_print(ptr);
let tmp = &mut wrapper as *mut PtrWrapper;
(*tmp).id += 500;
println!("The next print isn't 540?");
debug_print(tmp);
}
println!("Below debug_print is proof of undefined behavior! Garbage bytes\n");
debug_print(wrapper.self_reference.as_ptr());
debug_print(&mut wrapper as *mut PtrWrapper);
debug_print_move(wrapper);
println!("Why is the assertion below false?");
assert_eq!(unsafe{(*ptr).id}, 540);
}
fn debug_print_move(mut wrapper: PtrWrapper) {
debug_print(&mut wrapper as *mut PtrWrapper);
}
fn debug_print(ptr: *mut PtrWrapper) {
println!("Address: {:p}", ptr);
println!("ID: {}\n", unsafe {(*ptr).get_id()});
}
The above code should compile fine in rust playground with a nightly selected version. Pay attention to the console outputs.
My question is: Why are the intermittent results not equal to the value I expect them to equal? In the case below, there is no multiple access simultaneously (single threaded), so there aren't any data races. There are, however, implicitly multiple mutable version of the object existing on the stack.
As expected, the memory location of the pointer changes with the tmp variable as well as when the entire object is moved into debug_print_move. It appears that using the tmp pointer works as expected (i.e., adds 500), however, the pointers which are obtained from the Unique<PtrWrapper> object seems to point to irrelevant locations in memory.
As Stargateur recommended, in order to solve this problem we need to Pin the object which needs to be self-referential. I ended up using:
pin-api = "0.2.1"
In cargo.toml instead of std::pin::pin. Next, I set this up the struct and its implementation:
#![feature(ptr_internals, pin_into_inner, optin_builtin_traits)]
// not available on rust-playground
extern crate pin_api;
use pin_api::{boxed::PinBox, marker::Unpin, mem::Pin};
///test
pub struct PtrWrapper<T>
where
T: std::fmt::Debug,
{
///tmp
pub obj: T,
/// pinned object
pub self_reference: *mut Self,
}
impl<T> !Unpin for PtrWrapper<T> where T: std::fmt::Debug {}
impl<T> PtrWrapper<T>
where
T: std::fmt::Debug,
{
///test
pub fn new(obj: T) -> Self {
Self {
obj,
self_reference: std::ptr::null_mut(),
}
}
///test
pub fn init(mut self: Pin<PtrWrapper<T>>) {
let mut this: &mut PtrWrapper<T> = unsafe { Pin::get_mut(&mut self) };
this.self_reference = this as *mut Self;
}
/// Debug print
pub fn print_obj(&self) {
println!("Obj value: {:#?}", self.obj);
}
}
Finally, the test function:
fn main2() {
unsafe {
println!("START");
let mut wrapper = PinBox::new(PtrWrapper::new(10));
wrapper.as_pin().init();
let m = wrapper.as_pin().self_reference;
(*m).obj += 30;
println!("The next print is 40");
debug_print(m);
let tmp = wrapper.as_pin().self_reference;
(*tmp).obj += 500;
println!("The next print is 540?");
debug_print(tmp);
debug_print(wrapper.self_reference);
let cpy = PinBox::get_mut(&mut wrapper);
debug_print_move(cpy);
std::mem::drop(wrapper);
println!("Works!");
assert_eq!(unsafe { (*m).obj }, 540);
}
}
fn debug_print_move<T>(mut wrapper: &mut PtrWrapper<T>)
where
T: std::fmt::Debug,
{
debug_print(&mut *wrapper as *mut PtrWrapper<T>);
}
fn debug_print<T>(ptr: *mut PtrWrapper<T>)
where
T: std::fmt::Debug,
{
println!("Address: {:p}", ptr);
unsafe { (*ptr).print_obj() };
}
On a side note, pin-api does not exist on rust playground. You could still use std::pin::Pin, however it would require further customization.

Using the type system to enforce coordinate boundaries in Rust [duplicate]

I have a function that takes an argument of type u16. Is there an elegant way to define a custom data type that behaves exactly like a u16 but only has values between 0 and 100?
As I understand it, that requires dependent types, which Rust does not have. This doesn't require dependent types (see comments) but Rust still doesn't have the support needed.
As a workaround, you could create a newtype that you verify yourself:
#[derive(Debug)]
struct Age(u16);
impl Age {
fn new(age: u16) -> Option<Age> {
if age <= 100 {
Some(Age(age))
} else {
None
}
}
}
fn main() {
let age1 = Age::new(30);
let age2 = Age::new(500);
println!("{:?}, {:?}", age1, age2);
assert_eq!(
std::mem::size_of::<Age>(),
std::mem::size_of::<u16>()
);
}
Of course, it doesn't behave exactly like a u16, but you don't want it to, either! For example, a u16 can go beyond 100... You'd have to reason out if it makes sense to add/subtract/multiply/divide etc your new type as well.
For maximum safeguarding, you should move your type and any associated functions into a module. This leverages Rust's visibility rules to prevent people from accidentally accessing the value inside the newtype and invalidating the constraints.
You may also want to implement TryFrom (from u16 to your type) or From (from your type to u16) to better integrate with generic code.
An important thing to note is that this newtype takes the same amount of space as a u16 - the wrapper type is effectively erased when the code is compiled. The type checker makes sure everything meshes before that point.
Unfortunately, there is no such a thing inside the std crate.
However, you can do it yourself in an optimized manner with the nightly generic consts, scheduled to be stabilized in Rust 1.51. Example:
// 1.51.0-nightly (2020-12-30)
pub struct BoundedI32<const LOW: i32, const HIGH: i32>(i32);
impl<const LOW: i32, const HIGH: i32> BoundedI32<{ LOW }, { HIGH }> {
pub const LOW: i32 = LOW;
pub const HIGH: i32 = HIGH;
pub fn new(n: i32) -> Self {
BoundedI32(n.min(Self::HIGH).max(Self::LOW))
}
pub fn fallible_new(n: i32) -> Result<Self, &'static str> {
match n {
n if n < Self::LOW => Err("Value too low"),
n if n > Self::HIGH => Err("Value too high"),
n => Ok(BoundedI32(n)),
}
}
pub fn set(&mut self, n: i32) {
*self = BoundedI32(n.min(Self::HIGH).max(Self::LOW))
}
}
impl<const LOW: i32, const HIGH: i32> std::ops::Deref for BoundedI32<{ LOW }, { HIGH }> {
type Target = i32;
fn deref(&self) -> &Self::Target {
&self.0
}
}
fn main() {
let dice = BoundedI32::<1, 6>::fallible_new(0);
assert!(dice.is_err());
let mut dice = BoundedI32::<1, 6>::new(0);
assert_eq!(*dice, 1);
dice.set(123);
assert_eq!(*dice, 6);
}
And then you can implement the maths, etc.
If you want to chose the bound at runtime, you don't need this feature, and you just need to do something like that:
pub struct BoundedI32 {
n: i32,
low: i32,
high: i32,
}
You can also use a crate like bounded-integer that allows to generate a bounded integer on-the-fly with a macro.
With the nightly feature generic_const_exprs, it is possible to verify this at compile time:
#![feature(generic_const_exprs)]
struct If<const COND: bool>;
trait True {}
impl True for If<true> {}
const fn in_bounds(n: usize, low: usize, high: usize) -> bool {
n > low && n < high
}
struct BoundedInteger<const LOW: usize, const HIGH: usize>(usize);
impl<const LOW: usize, const HIGH: usize> BoundedInteger<LOW, HIGH>
where
If<{ LOW < HIGH }>: True,
{
fn new<const N: usize>() -> Self
where
If<{ in_bounds(N, LOW, HIGH) }>: True,
{
Self(N)
}
}
The error messages aren't the best, but it works!
fn main() {
let a = BoundedInteger::<1, 10>::new::<5>();
let b = BoundedInteger::<10, 1>::new::<5>(); // ERROR: doesn't satisfy `If<{ LOW < HIGH }>: True`
let c = BoundedInteger::<2, 5>::new::<6>(); // ERROR: expected `false`, found `true`
}
Not exactly, to my knowledge. But you can use a trait to get close. Example, where tonnage is a unsigned 8 bit integer that is expected to be 20-100 and a multiple of 5:
pub trait Validator{
fn isvalid(&self) -> bool;
}
pub struct TotalRobotTonnage{
pub tonnage: u8,
}
impl Validator for TotalRobotTonnage{
//is in range 20-100 and a multiple of 5
fn isvalid(&self) -> bool{
if self.tonnage < 20 || self.tonnage > 100 || self.tonnage % 5 != 0{
false
}else{
true
}
}
}
fn main() {
let validtonnage = TotalRobotTonnage{tonnage: 100};
let invalidtonnage_outofrange = TotalRobotTonnage{tonnage: 10};
let invalidtonnage_notmultipleof5 = TotalRobotTonnage{tonnage: 21};
println!("value {} [{}] value {} [{}] value {} [{}]",
validtonnage.tonnage,
validtonnage.isvalid(),
invalidtonnage_outofrange.tonnage,
invalidtonnage_outofrange.isvalid(),
invalidtonnage_notmultipleof5.tonnage,
invalidtonnage_notmultipleof5.isvalid()
);
}

Implementing 2D vector syntax for accessing a 1D vector?

I'm making a toy roguelike and have a Level structure for storing the game map, for which the most naive implementation is a 2D vector.
I'm following this tutorial which uses a Vector of Vectors, but states that for performance gains it's also possible to use a single Vector of size MAP_HEIGHT * MAP_WIDTH, and to access a tile at (x, y) one can simply access map[y * MAP_WIDTH + x].
I'm trying to implement this faster method but using getters and setters is clunky, and public fields aren't that great either. I'd much prefer it to feel like a 2D vector.
In order to do that I need to implement the Index trait for my class, but I'm not sure how to get the result I want. Maybe by nesting the impls? I really no idea.
Here is my code with a terrible attempt at implementing Index for my structure, which obviously won't work for my purposes because it's one dimensional:
const MAP_WIDTH: i32 = 80;
const MAP_HEIGHT: i32 = 45;
pub struct Level {
map: Vec<Tile>,
}
impl Level {
pub fn new() -> Self {
Level { map: vec![Tile::empty(); (MAP_HEIGHT * MAP_WIDTH) as usize] }
}
}
impl std::ops::Index<i32> for Level {
type Output = Tile;
fn index(&self, x: i32) -> &Self::Output {
self[MAP_WIDTH + x]; // We have x and y values; how do we make this work?
}
}
Make your struct indexible over objects of type (i32, i32).
type Pos = (i32, i32);
impl std::ops::Index<Pos> for Level {
type Output = Tile;
fn index(&self, (x, y): Pos) -> &Self::Output {
&self.map[(y * MAP_WIDTH + x) as usize]
}
}
Which you can then access with, for example:
let tile = level[(3, 4)];
Since you are using i32, you need to make sure that the values are within range, and can be coerced to usize, which is what Vecs are indexed over. Probably you should just stick with u32 or usize values from the start. Otherwise, you'll need to keep track of the minimum x and y values, and subtract them, to keep the position in range. It's definitely simpler to deal with positive coordinates and make the assumption that the corner of your map is (0, 0).
It is possible, though not obvious.
First of all, I suggest having the MAP_WIDTH and MAP_HEIGHT in usize, as they are positive integers:
const MAP_WIDTH: usize = 80;
const MAP_HEIGHT: usize = 45;
Then you need to implement Index (and possibly IndexMut) to return a slice; in this case I'm assuming that you want the first coordinate to be the row:
impl std::ops::Index<usize> for Level {
type Output = [Tile];
fn index(&self, row: usize) -> &[Tile] {
let start = MAP_WIDTH * row;
&self.map[start .. start + MAP_WIDTH]
}
}
impl std::ops::IndexMut<usize> for Level {
fn index_mut(&mut self, row: usize) -> &mut [Tile] {
let start = MAP_WIDTH * row;
&mut self.map[start .. start + MAP_WIDTH]
}
}
Then, when you index a Level, it first returns a slice with the applicable row; then you can index that slice with the column number.
Below is an example implementation with a substitute Tile:
const MAP_WIDTH: usize = 80;
const MAP_HEIGHT: usize = 45;
#[derive(Clone, Debug)]
pub struct Tile {
x: u32,
y: u32
}
pub struct Level {
map: Vec<Tile>,
}
impl Level {
pub fn new() -> Self {
Level { map: vec![Tile { x: 0, y: 0 }; (MAP_HEIGHT * MAP_WIDTH) as usize] }
}
}
impl std::ops::Index<usize> for Level {
type Output = [Tile];
fn index(&self, row: usize) -> &[Tile] {
let start = MAP_WIDTH * row;
&self.map[start .. start + MAP_WIDTH]
}
}
impl std::ops::IndexMut<usize> for Level {
fn index_mut(&mut self, row: usize) -> &mut [Tile] {
let start = MAP_WIDTH * row;
&mut self.map[start .. start + MAP_WIDTH]
}
}
fn main() {
let mut lvl = Level::new();
lvl[5][2] = Tile { x: 5, y: 2 };
println!("{:?}", lvl[5][2]); // Tile { x: 5, y: 2 }
}
You cannot do this without exposing internal details about your implementation. Index is defined as:
pub trait Index<Idx>
where
Idx: ?Sized,
{
type Output: ?Sized;
fn index(&self, index: Idx) -> &Self::Output;
}
In order to support game[x][y], the return value of game[x] would need to:
Be a reference to something. (&Self::Output)
Implement Index itself.
There's no value to return a reference to other than self, and self would already implement Index for a usize so you can't reuse it.
Instead, you can implement indexing for a tuple:
impl std::ops::Index<(usize, usize)> for Level {
type Output = Tile;
fn index(&self, (x, y): (usize, usize)) -> &Self::Output {
&self.map[MAP_WIDTH as usize * y + x]
}
}
This can be used as level[(43, 12)].
If you implement Index to return a slice, you should be aware that you are forever requiring that your internal data structure be something that is based on slices. For example, you cannot use a "sparse" structure like a HashMap because it cannot return a &[Tile]. The ability to return a &[Tile] is now a part of the public API of the struct. It's certainly a possibility that the representation will change, especially since it's already changed once.

Show u8 slice in hex representation

I need to convert &[u8] to a hex representation. For example [ A9, 45, FF, 00 ... ].
The trait std::fmt::UpperHex is not implemented for slices (so I can't use std::fmt::format). Rust has the serialize::hex::ToHex trait, which converts &[u8] to a hex String, but I need a representation with separate bytes.
I can implement trait UpperHex for &[u8] myself, but I'm not sure how canonical this would be. What is the most canonical way to do this?
Rust 1.26.0 and up
The :x? "debug with hexadecimal integers" formatter can be used:
let data = b"hello";
// lower case
println!("{:x?}", data);
// upper case
println!("{:X?}", data);
let data = [0x0, 0x1, 0xe, 0xf, 0xff];
// print the leading zero
println!("{:02X?}", data);
// It can be combined with the pretty modifier as well
println!("{:#04X?}", data);
Output:
[68, 65, 6c, 6c, 6f]
[68, 65, 6C, 6C, 6F]
[00, 01, 0E, 0F, FF]
[
0x00,
0x01,
0x0E,
0x0F,
0xFF,
]
If you need more control or need to support older versions of Rust, keep reading.
Rust 1.0 and up
use std::fmt::Write;
fn main() {
let mut s = String::new();
for &byte in "Hello".as_bytes() {
write!(&mut s, "{:X} ", byte).expect("Unable to write");
}
println!("{}", s);
}
This can be fancied up by implementing one of the formatting traits (fmt::Debug, fmt::Display, fmt::LowerHex, fmt::UpperHex, etc.) on a wrapper struct and having a little constructor:
use std::fmt;
struct HexSlice<'a>(&'a [u8]);
impl<'a> HexSlice<'a> {
fn new<T>(data: &'a T) -> HexSlice<'a>
where
T: ?Sized + AsRef<[u8]> + 'a,
{
HexSlice(data.as_ref())
}
}
// You can choose to implement multiple traits, like Lower and UpperHex
impl fmt::Display for HexSlice<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for byte in self.0 {
// Decide if you want to pad the value or have spaces inbetween, etc.
write!(f, "{:X} ", byte)?;
}
Ok(())
}
}
fn main() {
// To get a `String`
let s = format!("{}", HexSlice::new("Hello"));
// Or print it directly
println!("{}", HexSlice::new("world"));
// Works with
HexSlice::new("Hello"); // string slices (&str)
HexSlice::new(b"Hello"); // byte slices (&[u8])
HexSlice::new(&"World".to_string()); // References to String
HexSlice::new(&vec![0x00, 0x01]); // References to Vec<u8>
}
You can be even fancier and create an extension trait:
trait HexDisplayExt {
fn hex_display(&self) -> HexSlice<'_>;
}
impl<T> HexDisplayExt for T
where
T: ?Sized + AsRef<[u8]>,
{
fn hex_display(&self) -> HexSlice<'_> {
HexSlice::new(self)
}
}
fn main() {
println!("{}", "world".hex_display());
}
use hex::encode:
let a: [u8;4] = [1, 3, 3, 7];
assert_eq!(hex::encode(&a), "01030307");
[dependencies]
hex = "0.4"
Since the accepted answer doesn't work on Rust 1.0 stable, here's my attempt. Should be allocationless and thus reasonably fast. This is basically a formatter for [u8], but because of the coherence rules, we must wrap [u8] to a self-defined type ByteBuf(&[u8]) to use it:
struct ByteBuf<'a>(&'a [u8]);
impl<'a> std::fmt::LowerHex for ByteBuf<'a> {
fn fmt(&self, fmtr: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
for byte in self.0 {
try!( fmtr.write_fmt(format_args!("{:02x}", byte)));
}
Ok(())
}
}
Usage:
let buff = [0_u8; 24];
println!("{:x}", ByteBuf(&buff));
There's a crate for this: hex-slice.
For example:
extern crate hex_slice;
use hex_slice::AsHex;
fn main() {
let foo = vec![0u32, 1, 2 ,3];
println!("{:02x}", foo.as_hex());
}
I'm doing it this way:
let bytes : Vec<u8> = "привет".to_string().as_bytes().to_vec();
let hex : String = bytes.iter()
.map(|b| format!("{:02x}", b).to_string())
.collect::<Vec<String>>()
.join(" ");

Resources