Borrowed value does not live long enough when adding rustls::Stream to a vector - ssl

I want to create an Vec and add opened socket connection to it. When I run the code, I get borrowed value does not live long enough. I saw many Q&A on Stack Overflow for this error, but I couldn't figure it out how to solve it for rustls::Streams.
After creating array of rustls::Stream , I want to use another loop and send data with opened streams.
use rustls::{ClientConfig, ClientSession, Session, TLSError};
use std::env;
use std::fmt;
use std::sync::Arc;
use std::time::Instant;
use webpki;
use webpki_roots;
fn main() {
let mut config = rustls::ClientConfig::new();
config
.root_store
.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
let arc = std::sync::Arc::new(config);
let mut connectors = Vec::new();
let now = Instant::now();
{
for n in 1..=2 {
let mut socket = std::net::TcpStream::connect("X.X.X.X:443").unwrap();
let dns_name = webpki::DNSNameRef::try_from_ascii_str("X.com").unwrap();
let mut client = rustls::ClientSession::new(&arc, dns_name);
let mut stream = rustls::Stream::new(&mut client, &mut socket); // Create stream
connectors.push(stream);
}
}
let elapsed = now.elapsed();
println!("Elapsed: {:?}", elapsed);
//AND LATER I'M GONNA ITERATE THROUGH THE VECTOR AND USE IT TO SEND DATA.
}
The error:
error[E0597]: `client` does not live long enough
--> src/main.rs:38:50
|
38 | let mut stream = rustls::Stream::new(&mut client, &mut socket); // Create stream
| ^^^^^^^^^^^ borrowed value does not live long enough
39 | let data_ref = &mut stream;
40 | connectors.push(data_ref);
| ---------- borrow later used here
41 | }
| - `client` dropped here while still borrowed
error[E0597]: `socket` does not live long enough
--> src/main.rs:38:63
|
38 | let mut stream = rustls::Stream::new(&mut client, &mut socket); // Create stream
| ^^^^^^^^^^^ borrowed value does not live long enough
39 | let data_ref = &mut stream;
40 | connectors.push(data_ref);
| ---------- borrow later used here
41 | }
| - `socket` dropped here while still borrowed
error[E0597]: `stream` does not live long enough
--> src/main.rs:39:28
|
39 | let data_ref = &mut stream;
| ^^^^^^^^^^^ borrowed value does not live long enough
40 | connectors.push(data_ref);
| ---------- borrow later used here
41 | }
| - `stream` dropped here while still borrowed

Use StreamOwned instead:
use rustls::{ClientConfig, ClientSession, StreamOwned}; // 0.17.0
use std::{net::TcpStream, sync::Arc, time::Instant};
use webpki::DNSNameRef; // 0.21.2
use webpki_roots; // 0.19.0
fn main() {
let mut config = ClientConfig::new();
config
.root_store
.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
let arc = Arc::new(config);
let now = Instant::now();
let _connectors: Vec<_> = (0..2)
.map(|_| {
let socket = TcpStream::connect("X.X.X.X:443").unwrap();
let dns_name = DNSNameRef::try_from_ascii_str("X.com").unwrap();
let client = ClientSession::new(&arc, dns_name);
StreamOwned::new(client, socket)
})
.collect();
let elapsed = now.elapsed();
println!("Elapsed: {:?}", elapsed);
}

Related

How to change ledger's epoch during unit test?

I am trying to change epoch in a single unit test:
I run a method
I switch to next epoch
I run another method (on the same substate store)
It seems like I can not mutate substate store's epoch if I use a TransactionExecutor on it:
use radix_engine::ledger::*;
use radix_engine::transaction::*;
use scrypto::prelude::*;
#[test]
fn can_tick_from_scratch() {
let mut ledger = InMemorySubstateStore::with_bootstrap();
ledger.set_epoch(15);
let mut executor = TransactionExecutor::new(&mut ledger, false);
// Run transactions
// ...
ledger.set_epoch(16);
// Run other transactions
// ...
}
error[E0499]: cannot borrow `ledger` as mutable more than once at a time
--> tests/lib.rs:16:5
|
11 | let mut executor = TransactionExecutor::new(&mut ledger, false);
| ----------- first mutable borrow occurs here ...
16 | ledger.set_epoch(16);
| ^^^^^^^^^^^^^^^^^^^^ second mutable borrow occurs here
17 |
18 | let (pk, sk, oracle_owner) = executor.new_account();
| ---------------------- first borrow later used here
How can I change the epoch of the InMemorySubstateStore passed to the TransactionExecutor?
You indeed can not mutate the InMemorySubstateStore variable directly after passing it to the TransactionExecutor.
What you want to do is to change the executor's substate_store state:
use radix_engine::ledger::*;
use radix_engine::transaction::*;
use scrypto::prelude::*;
#[test]
fn can_tick_from_scratch() {
let mut ledger = InMemorySubstateStore::with_bootstrap();
ledger.set_epoch(15);
let mut executor = TransactionExecutor::new(&mut ledger, false);
// Run transactions
// ...
executor.substate_store_mut().set_epoch(16);
// Run other transactions
// ...
}

How to pass a stm32f3discovery API into a function?

I am trying to create a separate file/module that has functions that can deal with the LEDs or gyro for the stm32f3discovery. I am trying to pass the stm32f3 API that holds all of the registers into a function to then use inside.
When I run this code, I get an error saying "there is no field '###' on type '##'". How can I do this?
main.rs
#![no_std]
#![no_main]
use stm32f3::stm32f303;
mod my_api;
#[entry]
fn main() -> ! {
let periph = stm32f303::Peripherals::take().unwrap();
let gpioe = periph.GPIOE;
let rcc = periph.RCC;
my_api::led::setup_led(&gpioe, &rcc);
loop {
my_api::led::all_led_on(&gpioe);
}
}
my_api.rs
pub mod led {
pub fn setup_led<G, R>(gpio: &G, rcc: &R) {
*rcc.ahbenr.modify(|_, w| w.iopeen().set_bit()); //enables clock
*gpio.moder.modify(|_, w| {
w.moder8().bits(0b01);
w.moder9().bits(0b01);
w.moder10().bits(0b01);
w.moder11().bits(0b01);
w.moder12().bits(0b01);
w.moder13().bits(0b01);
w.moder14().bits(0b01);
w.moder15().bits(0b01)
});
}
pub fn all_led_on<G>(gpio: &G) {
*gpio.odr.modify(|_, w| {
w.odr8().set_bit();
w.odr9().set_bit();
w.odr10().set_bit();
w.odr11().set_bit();
w.odr12().set_bit();
w.odr13().set_bit();
w.odr14().set_bit();
w.odr15().set_bit()
});
}
pub fn all_led_off<G>(gpio: &G) {
*gpio.odr.modify(|_, w| {
w.odr8().clear_bit();
w.odr9().clear_bit();
w.odr10().clear_bit();
w.odr11().clear_bit();
w.odr12().clear_bit();
w.odr13().clear_bit();
w.odr14().clear_bit();
w.odr15().clear_bit()
});
}
}
Error
error[E0609]: no field `odr` on type `&G`
--> src/my_api.rs:30:15
|
29 | pub fn all_led_off <G> (gpio: &G) {
| - type parameter 'G' declared here
30 | *gpio.odr.modify(|_,w| {
| ^^^
It has this error for all of the calls onto any of the registers
Instead of using a generic to try and force our way into passing in a type that you don't know use something like:
let my_name: () = 39.2;
It will give an error that will tell you what the value on the right is and you can use that to work out what data type you can pass into the function. As shown printing variable type in rust

How can I have multiple iterators to the same data pertaining to a file?

I have a file that I wish to read and filter the data into two different sets and determine the number of items in each set.
use std::io::{self, BufRead};
fn main() {
let cursor = io::Cursor::new(b"pillow\nbrick\r\nphone");
let lines = cursor.lines().map(|l| l.unwrap());
let soft_count = lines.filter(|line| line.contains("pillow")).count();
let hard_count = lines.filter(|line| !line.contains("pillow")).count();
}
Playground
GitHub
However, the borrow checker gives me an error:
error[E0382]: use of moved value: `lines`
--> src/main.rs:14:22
|
8 | let lines = cursor.lines().map(|l| l.unwrap());
| ----- move occurs because `lines` has type `std::iter::Map<std::io::Lines<std::io::Cursor<&[u8; 19]>>, [closure#src/main.rs:8:36: 8:50]>`, which does not implement the `Copy` trait
9 |
10 | let soft_count = lines
| ----- value moved here
...
14 | let hard_count = lines
| ^^^^^ value used here after move
I tried getting around this using reference counting to allow multiple ownership:
use std::io::{self, BufRead};
use std::rc::Rc;
fn main() {
let cursor = io::Cursor::new(b"pillow\nbrick\r\nphone");
let lines = Rc::new(cursor.lines().map(|l| l.unwrap()));
let soft_count = Rc::clone(&lines)
.filter(|line| line.contains("pillow"))
.count();
let hard_count = Rc::clone(&lines)
.filter(|line| !line.contains("pillow"))
.count();
}
Playground
Github
I get a similar error message:
error[E0507]: cannot move out of an `Rc`
--> src/main.rs:11:22
|
11 | let soft_count = Rc::clone(&lines)
| ^^^^^^^^^^^^^^^^^ move occurs because value has type `std::iter::Map<std::io::Lines<std::io::Cursor<&[u8; 19]>>, [closure#src/main.rs:9:44: 9:58]>`, which does not implement the `Copy` trait
error[E0507]: cannot move out of an `Rc`
--> src/main.rs:15:22
|
15 | let hard_count = Rc::clone(&lines)
| ^^^^^^^^^^^^^^^^^ move occurs because value has type `std::iter::Map<std::io::Lines<std::io::Cursor<&[u8; 19]>>, [closure#src/main.rs:9:44: 9:58]>`, which does not implement the `Copy` trait
You cannot. Instead, you will need to clone the iterator, or some building block of it. In this case, the highest thing you can clone is the Cursor:
use std::io::{self, BufRead};
fn main() {
let cursor = io::Cursor::new(b"pillow\nbrick\r\nphone");
let lines = cursor.clone().lines().map(|l| l.unwrap());
let lines2 = cursor.lines().map(|l| l.unwrap());
let soft_count = lines.filter(|line| line.contains("pillow")).count();
let hard_count = lines2.filter(|line| !line.contains("pillow")).count();
}
For an actual File, you will need to use try_clone as it might fail. In either case, you will be referring to the same data twice and only the iterator information will be kept.
For your specific case, you don't need any of this. In fact, iterating over the data twice is inefficient. The simplest built-in thing you can do is to partition the iterator:
let (softs, hards): (Vec<_>, Vec<_>) = lines.partition(|line| line.contains("pillow"));
let soft_count = softs.len();
let hard_count = hards.len();
This is still a bit inefficient as you don't need the actual values. You could create your own type that implements Extend and discards the values:
#[derive(Debug, Default)]
struct Count(usize);
impl<T> std::iter::Extend<T> for Count {
fn extend<I>(&mut self, iter: I)
where
I: IntoIterator,
{
self.0 += iter.into_iter().count();
}
}
let (softs, hards): (Count, Count) = lines.partition(|line| line.contains("pillow"));
let soft_count = softs.0;
let hard_count = hards.0;
You could also just use a for loop or build something on top of fold:
let (soft_count, hard_count) = lines.fold((0, 0), |mut state, line| {
if line.contains("pillow") {
state.0 += 1;
} else {
state.1 += 1;
}
state
});

What's the appropriate way to return a reference to the value from a generic associated function?

Imagine a tiny map that stores 3 values, the first two for known keys. I'd like to implement an iterator for this map, but I'm running into lifetime issues. What's the appropriate way to return a reference to the value from a generic associated function (K::zero() in the example below)?
FYI, I own the trait, so I tried changing it to the new RFC195 associated const, which didn't help.
I've boiled down my problem to the following code:
extern crate num;
use num::*;
pub struct TinyMap<K: Num, V> {
v0: Option<V>, // value for K::zero()
v1: Option<V>, // value for K::one()
k2: K, // arbitrary K
v2: Option<V>, // value for k2
}
pub struct Iter<'a, K: 'a + Num, V: 'a> {
k0: K,
v0: &'a Option<V>,
v1: &'a Option<V>,
k2: &'a K,
v2: &'a Option<V>,
}
impl<K: Num, V> TinyMap<K, V> {
pub fn iter(&self) -> Iter<K, V> {
Iter {
k0: K::zero(),
v0: &self.v0,
v1: &self.v1,
k2: &self.k2,
v2: &self.v2,
}
}
}
impl<'a, K: 'a + Num, V: 'a> Iterator for Iter<'a, K, V> {
type Item = (&'a K, &'a V);
fn next(&mut self) -> Option<(&'a K, &'a V)> {
if (*self.v0).is_some() {
// code removed that remembers we did this once.
return Some((&self.k0, ((*self.v0).as_ref()).unwrap()));
}
// if (*self.v1).is_some() {
// code removed that remembers we did this once.
// return Some((&K::one(), &((*self.v1).unwrap())));
// }
None
}
}
error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
--> src/lib.rs:38:26
|
38 | return Some((&self.k0, ((*self.v0).as_ref()).unwrap()));
| ^^^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 35:5...
--> src/lib.rs:35:5
|
35 | / fn next(&mut self) -> Option<(&'a K, &'a V)> {
36 | | if (*self.v0).is_some() {
37 | | // code removed that remembers we did this once.
38 | | return Some((&self.k0, ((*self.v0).as_ref()).unwrap()));
... |
44 | | None
45 | | }
| |_____^
note: ...so that reference does not outlive borrowed content
--> src/lib.rs:38:26
|
38 | return Some((&self.k0, ((*self.v0).as_ref()).unwrap()));
| ^^^^^^^^
note: but, the lifetime must be valid for the lifetime 'a as defined on the impl at 32:6...
--> src/lib.rs:32:6
|
32 | impl<'a, K: 'a + Num, V: 'a> Iterator for Iter<'a, K, V> {
| ^^
= note: ...so that the expression is assignable:
expected std::option::Option<(&'a K, &'a V)>
found std::option::Option<(&K, &V)>
It's not possible to do that with the Iterator trait, because of the lifetime of the self reference (which is elided away in your code, but can be explicitly written like this):
type Item = (&'a K, &'a V);
fn next<'s>(&'s mut self) -> Self::Item;
Since 's doesn't appear in the function's return value (and can't appear in there, because Self::Item can't use type parameters of the function), the output is not allowed to hold a reference to any of the iterator's member variables.
That's the mechanics of the mistake, now here's the why part:
Consider a function that does include a reference to a member of self, with all the lifetimes set up correctly:
struct SomeMember;
struct SomeObject {
some_member: SomeMember,
}
impl SomeObject {
fn some_function<'s>(&'s mut self) -> &'s SomeMember {
&self.some_member
}
}
The same way you're trying to return &self.k, but without any other things going on, and with the lifetimes fixed so that it's allowed. However, if I then try to do this:
fn main() {
let mut some_object = SomeObject{some_member: SomeMember};
let _item_1 = some_object.some_function();
let _item_2 = some_object.some_function();
}
error[E0499]: cannot borrow `some_object` as mutable more than once at a time
--> src/main.rs:15:23
|
14 | let _item_1 = some_object.some_function();
| ----------- first mutable borrow occurs here
15 | let _item_2 = some_object.some_function();
| ^^^^^^^^^^^ second mutable borrow occurs here
16 | }
| - first borrow ends here
The second call wasn't allowed, because it borrows some_object twice, mutably, a classic Rust no-no! But if I had tried to implement an iterator with an Item type that borrowed the iterator itself, then Iterator::collect() would be impossible, because it tries to pull more than one item out at once!
So, no, an iterator can't return an item that borrows its contents. That's an explicit, and intentional, part of the trait contract for iterators.
The consensus appears to be that as of this time (Rust 1.29), the only sensible way is to put K::zero() inside TinyMap. Thanks to #SvenMarnach for confirming my suspicions.

Extract chain of iterator calls to a helper function [duplicate]

This question already has answers here:
What is the correct way to return an Iterator (or any other trait)?
(2 answers)
Closed 5 years ago.
I'm trying to write a function that will encapsulate a series of chained iterator method calls (.lines().map(...).filter(...)) which I currently have duplicated. I can't figure out the type signatures to get this to compile. If this is impossible or highly unidiomatic for Rust, I'm open to suggestions for an idiomatic approach.
use std::fs;
use std::io;
use std::io::prelude::*;
use std::iter;
const WORDS_PATH: &str = "/usr/share/dict/words";
fn is_short(word: &String) -> bool {
word.len() < 7
}
fn unwrap(result: Result<String, io::Error>) -> String {
result.unwrap()
}
fn main_works_but_code_dupe() {
let file = fs::File::open(WORDS_PATH).unwrap();
let reader = io::BufReader::new(&file);
let count = reader.lines().map(unwrap).filter(is_short).count();
println!("{:?}", count);
let mut reader = io::BufReader::new(&file);
reader.seek(io::SeekFrom::Start(0));
let sample_size = (0.05 * count as f32) as usize; // 5% sample
// This chain of iterator logic is duplicated
for line in reader.lines().map(unwrap).filter(is_short).take(sample_size) {
println!("{}", line);
}
}
fn short_lines<'a, T>
(reader: &'a T)
-> iter::Filter<std::iter::Map<std::io::Lines<T>, &FnMut(&str, bool)>, &FnMut(&str, bool)>
where T: io::BufRead
{
reader.lines().map(unwrap).filter(is_short)
}
fn main_dry() {
let file = fs::File::open(WORDS_PATH).unwrap();
let reader = io::BufReader::new(&file);
let count = short_lines(reader).count();
println!("{:?}", count);
// Would like to do this instead:
let mut reader = io::BufReader::new(&file);
reader.seek(io::SeekFrom::Start(0));
let sample_size = (0.05 * count as f32) as usize; // 5% sample
for line in short_lines(reader).take(sample_size) {
println!("{}", line);
}
}
fn main() {
main_works_but_code_dupe();
}
I can't figure out the type signatures to get this to compile.
The compiler told you what it was.
error[E0308]: mismatched types
--> src/main.rs:35:5
|
35 | reader.lines().map(unwrap).filter(is_short)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found fn item
|
= note: expected type `std::iter::Filter<std::iter::Map<_, &'a for<'r> std::ops::FnMut(&'r str, bool) + 'a>, &'a for<'r> std::ops::FnMut(&'r str, bool) + 'a>`
found type `std::iter::Filter<std::iter::Map<_, fn(std::result::Result<std::string::String, std::io::Error>) -> std::string::String {unwrap}>, for<'r> fn(&'r std::string::String) -> bool {is_short}>`
Now, granted, you can't just copy+paste this directly. You have to replace the _ type with the actual one you already had (it left it out because it was already correct). Secondly, you need to delete the {unwrap} and {is_short} bits; those are because function items have unique types, and that's how the compiler annotates them. Sadly, you can't actually write these types out.
Recompile and...
error[E0308]: mismatched types
--> src/main.rs:35:5
|
32 | -> std::iter::Filter<std::iter::Map<std::io::Lines<T>, fn(std::result::Result<std::string::String, std::io::Error>) -> std::string::String>, for<'r> fn(&'r std::string::String) -> bool>
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- expected `std::iter::Filter<std::iter::Map<std::io::Lines<T>, fn(std::result::Result<std::string::String, std::io::Error>) -> std::string::String>, for<'r> fn(&'r std::string::String) -> bool>` because of return type
...
35 | reader.lines().map(unwrap).filter(is_short)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected fn pointer, found fn item
|
= note: expected type `std::iter::Filter<std::iter::Map<_, fn(std::result::Result<std::string::String, std::io::Error>) -> std::string::String>, for<'r> fn(&'r std::string::String) -> bool>`
found type `std::iter::Filter<std::iter::Map<_, fn(std::result::Result<std::string::String, std::io::Error>) -> std::string::String {unwrap}>, for<'r> fn(&'r std::string::String) -> bool {is_short}>`
Remember what I said about function items have unique types? Yeah, that. To fix that, we cast from a function item to a function pointer. We don't even need to specify what we're casting to, we just have to let the compiler know we want it to do a cast.
fn short_lines<'a, T>
(reader: &'a T)
-> std::iter::Filter<std::iter::Map<std::io::Lines<T>, fn(std::result::Result<std::string::String, std::io::Error>) -> std::string::String>, for<'r> fn(&'r std::string::String) -> bool>
where T: io::BufRead
{
reader.lines().map(unwrap as _).filter(is_short as _)
}
error[E0308]: mismatched types
--> src/main.rs:41:29
|
41 | let count = short_lines(reader).count();
| ^^^^^^ expected reference, found struct `std::io::BufReader`
|
= note: expected type `&_`
found type `std::io::BufReader<&std::fs::File>`
= help: try with `&reader`
Again, the compiler tells you exactly what to do. Make the change and...
error[E0507]: cannot move out of borrowed content
--> src/main.rs:35:5
|
35 | reader.lines().map(unwrap as _).filter(is_short as _)
| ^^^^^^ cannot move out of borrowed content
Right, that's because you got the input of short_lines wrong. One more change:
fn short_lines<T>
(reader: T)
-> std::iter::Filter<std::iter::Map<std::io::Lines<T>, fn(std::result::Result<std::string::String, std::io::Error>) -> std::string::String>, for<'r> fn(&'r std::string::String) -> bool>
where T: io::BufRead
{
reader.lines().map(unwrap as _).filter(is_short as _)
}
And now all you have to deal with are warnings.
In short: read the compiler messages. They're useful.
I'd suggest doing it the simple way - collecting the iterator into a vector:
use std::fs;
use std::io;
use std::io::prelude::*;
const WORDS_PATH: &str = "/usr/share/dict/words";
fn main() {
let file = fs::File::open(WORDS_PATH).unwrap();
let reader = io::BufReader::new(&file);
let short_lines = reader.lines()
.map(|l| l.unwrap())
.filter(|l| l.len() < 7)
.collect::<Vec<_>>(); // the element type can just be inferred
let count = short_lines.len();
println!("{:?}", count);
let sample_size = (0.05 * count as f32) as usize; // 5% sample
for line in &short_lines[0..sample_size] {
println!("{}", line);
}
}