Parsing command line arguments in Rust - parsing

I am working on a command line program where I need to parse the cli arguments. My problem is that there is an error when I try to parse elements from a vector of Strings
I have a function called ìnto_num_vec() which takes a vector of Strings and I should parse it into a new vector of integers.
Code from lib.rs
pub fn affirm_args(input: Vec<String>) {
if input.len() < 2 {
panic!("To few arguments");
} else {
let numbers = into_num_vec(input);
print_numbers(numbers);
}
}
fn into_num_vec(input: Vec<String>) -> Vec<i32> {
let mut collection: Vec<i32> = Vec::new();
for i in input {
match i.trim().parse() {
Ok(n) => collection.push(n),
Err(_) => panic!("Error parsing")
}
}
collection
}
pub fn print_numbers(input: Vec<i32>) {
for i in input {
println!("{}", i);
}
}
The function is panicking and I'am getting the custom panic msg "Error parsing".
Code in main.rs
use sort_program::*;
use std::env;
fn main() {
let args: Vec<String> = env::args().collect();
affirm_args(args);
}

The first argument to a program traditionally is the executable name. You should skip it:
fn main() {
let args: Vec<String> = env::args().skip(1).collect();
affirm_args(args);
}

Related

cannot move out of index of `Vec<Layer>`

use fastapprox::faster::sigmoid;
pub struct Neuron {
pub val: f32,
pub con: Vec<f32>
}
impl Neuron {
fn new(nextlaylen: u32) -> Neuron {
let mut con = Vec::new();
for _ in 0..nextlaylen {
con.push(0.0);
}
Neuron { val: 0.0, con: con }
}
pub fn add(&self, layer: &mut Layer) {
// loop through neurons and add values with weights
let mut counter = 0;
for i in 0..layer.neurons.len() {
counter += 1;
layer.neurons[i].val += self.val * self.con[counter];
}
}
}
pub struct Layer {
pub neurons: Vec<Neuron>
}
impl Layer {
pub fn new(size: u32, nextlaylen: u32) -> Layer {
let mut neurons = Vec::new();
for _ in 0..size {
neurons.push(Neuron::new(nextlaylen));
}
Layer { neurons: neurons }
}
pub fn add(self, layer: &mut Layer) {
// add neurons together
for i in 0..self.neurons.len() {
self.neurons[i].add(layer);
}
for i in 0..layer.neurons.len() {
layer.neurons[i].val = sigmoid(layer.neurons[i].val);
}
}
}
pub struct Model {
pub layers: Vec<Layer>
}
impl Model {
pub fn new(inputnodesamnt: u32, outputnodesamnt: u32, hiddenlayersamnt: u32, neuronsperlayer: u32) -> Model {
let mut layers = Vec::new();
layers.push(Layer::new(inputnodesamnt, neuronsperlayer)); // create input layer
// create hidden layers
for i in 0..hiddenlayersamnt {
if i != hiddenlayersamnt - 1 {
layers.push(Layer::new(neuronsperlayer, neuronsperlayer));
}
else {
layers.push(Layer::new(neuronsperlayer, outputnodesamnt));
}
}
layers.push(Layer::new(outputnodesamnt, 0)); // create output layer
Model { layers: layers }
}
pub fn process(self) {
for i in 0..self.layers.len() {
self.layers[i].add(&mut self.layers[i + 1]);
}
}
}
pub struct Output {
pub nodevaluearr: Vec<f32>
}
fn main() {
}
the error I get is this:
error[E0507]: cannot move out of index of `Vec<Layer>`
--> src/main.rs:83:13
|
83| self.layers[i].add(&mut self.layers[i + 1]);
| ^^^^^^^^^^^^^^ move occurs because value has type `Layer`, which does not implement the `Copy` trait
For more information about this error, try `rustc --explain E0507`.
error: could not compile `neuralnetrust` due to previous error
The terminal process "cargo 'run', '--package', 'neuralnetrust', '--bin', 'neuralnetrust'" failed to launch (exit code: 101).
I'm trying to make a simple neural net.
also, does anybody have any good resources for learning about the borrow checker?
Your add method takes ownership of self, when in reality you probably want to take &self. When you have a function which takes self instead of &self or &mut self, then when you call it on an object that object gets passed into the function and you cannot access it again (assuming it's not Copy) after that since Rust has move semantics by default. If you want to learn more about Rust's memory model then I'd spend some time with this chapter of the book.

using mem.eql - unable to evaluate constant expression

Can someone explain me why this piece of code can't be compiled?
const std = #import("std");
const ParseError = error { NotAValidField };
const TestEnum = enum {
field_1,
field_2,
pub fn fromString(str: []const u8) !TestEnum {
switch(true) {
std.mem.eql(u8, "field_1", str) => TestEnum.field_1,
std.mem.eql(u8, "field_2", str) => TestEnum.field_2,
else => ParseError.NotAValidField,
}
}
};
pub fn main() void {
const field = "field_1";
try TestEnum.fromString(field);
}
It results to an error:
./example.zig:11:40: error: unable to evaluate constant expression
std.mem.eql(u8, "field_1", str) => TestEnum.field_1,
Is the compiler trying to figure the str during the compile time while it is passed as an argument? Here's the code in godbolt: https://zig.godbolt.org/z/reK6xv7h5
P.S. I already know there is a std.meta.stringToEnum function.
The compiler sees str in mem.eql call as a runtime value, and thus the error. To specify that str is never used at run time, add a comptime keyword like so:
pub fn fromString(comptime str: []const u8) TestEnum {
return switch (true) {
std.mem.eql(u8, "field_1", str) => TestEnum.field_1,
std.mem.eql(u8, "field_2", str) => TestEnum.field_2,
};
}
Note that all of this comes from wanting to use the mem.eql results to match true. This limits the number of enum values to exactly two and requires the string to be known at compile time. What meta.stringToEnum does instead is to perform the operation at run time.

Handling streaming iterator as normal iterator by using PhantomData and unsafe

I know the code below is hacky, but could it be called safe and idiomatic Rust? Is there better way for this?
// needs to do 'rustup default nightly' to run under valgrind
// #![feature(alloc_system, global_allocator, allocator_api)]
// extern crate alloc_system;
// use alloc_system::System;
// #[global_allocator]
// static A: System = System;
struct Foo<'a> {
v: Vec<u8>,
pos: usize,
phantom: std::marker::PhantomData<&'a u8>,
}
impl<'a> Iterator for Foo<'a> {
type Item = &'a mut u8;
fn next(&mut self) -> Option<&'a mut u8> {
let r = self.v.get_mut(self.pos);
if r.is_some() {
self.pos += 1;
unsafe { Some(&mut *(r.unwrap() as *mut u8)) }
} else {
None
}
}
}
impl<'a> Foo<'a> {
fn reset(&mut self) {
self.pos = 0;
}
}
fn main() {
let mut x = Foo {
v: (1..10).collect(),
pos: 0,
phantom: std::marker::PhantomData,
};
let vp = x.v.as_ptr();
{
for i in &mut x {
println!("{}", i);
}
}
{
x.reset();
}
{
for i in &mut x {
*i *= *i;
}
}
{
x.reset();
}
{
for i in &mut x {
println!("{}", i);
}
}
assert!(vp == x.v.as_ptr());
}
Write a little bit in the comment, Valgrind told me no leak and the result is as expected under Rust 1.26.0-nightly and 1.25.0.
Related:
How do I write an iterator that returns references to itself?
Iterator returning items by reference, lifetime issue
This code is not safe. The user of the type may choose any lifetime, including 'static:
fn constructor() -> Foo<'static> {
Foo {
v: vec![42; 10],
pos: 0,
phantom: std::marker::PhantomData,
}
}
fn example() -> &'static u8 {
let mut f = constructor();
f.next().unwrap()
}
fn main() {
println!("example: {}", example());
}
Here, example returns a reference to a variable that is no longer in scope, accessing invalid memory and subverting the restrictions you must uphold.
There's an example of how you could write this code with no unsafe whatsoever in another Q&A.

"error: closure may outlive the current function" but it will not outlive it

When I try to compile the following code:
fn main() {
(...)
let mut should_end = false;
let mut input = Input::new(ctx);
input.add_handler(Box::new(|evt| {
match evt {
&Event::Quit{..} => {
should_end = true;
}
_ => {}
}
}));
while !should_end {
input.handle();
}
}
pub struct Input {
handlers: Vec<Box<FnMut(i32)>>,
}
impl Input {
pub fn new() -> Self {
Input {handlers: Vec::new()}
}
pub fn handle(&mut self) {
for a in vec![21,0,3,12,1] {
for handler in &mut self.handlers {
handler(a);
}
}
}
pub fn add_handler(&mut self, handler: Box<FnMut(i32)>) {
self.handlers.push(handler);
}
}
I get this error:
error: closure may outlive the current function, but it borrows `should_end`, which is owned by the current function
I can't simply add move to the closure, because I need to use should_end later in the main loop. I mean, I can, but since bool is Copy, it will only affect the should_end inside the closure, and thus the program loops forever.
As far as I understand, since input is created in the main function, and the closure is stored in input, it couldn't possibly outlive the current function. Is there a way to express to Rust that the closure won't outlive main? Or is there a possibility that I can't see that the closure will outlive main? In the latter case, it there a way to force it to live only as long as main?
Do I need to refactor the way I'm handling input, or is there some way I can make this work. If I need to refactor, where can I look to see a good example of this in Rust?
Here's a playpen of a simplified version. It is possible I made a mistake in it that could crash your browser. I happened to me once, so, beware.
In case it is needed, the rest of my code is available. All the relevant info should be in either main.rs or input.rs.
The problem is not your closure, but the add_handler method. Fully expanded it would look like this:
fn add_handler<'a>(&'a mut self, handler: Box<FnMut(i32) + 'static>)
As you can see, there's an implicit 'static bound on the trait object. Obviously we don't want that, so we introduce a second lifetime 'b:
fn add_handler<'a, 'b: 'a>(&'a mut self, handler: Box<FnMut(i32) + 'b>)
Since you are adding the handler object to the Input::handlers field, that field cannot outlive the scope of the handler object. Thus we also need to limit its lifetime:
pub struct Input<'a> {
handlers: Vec<Box<FnMut(i32) + 'a>>,
}
This again requires the impl to have a lifetime, which we can use in the add_handler method.
impl<'a> Input<'a> {
...
pub fn add_handler(&mut self, handler: Box<FnMut(i32) + 'a>) {
self.handlers.push(handler);
}
}
Now all that's left is using a Cell to control access to your should_end flag.
Here is an example of the fixed code:
use std::cell::Cell;
fn main() {
let should_end = Cell::new(false);
let mut input = Input::new();
input.add_handler(Box::new(|a| {
match a {
1 => {
should_end.set(true);
}
_ => {
println!("{} {}", a, should_end.get())
}
}
}));
let mut fail_safe = 0;
while !should_end.get() {
if fail_safe > 20 {break;}
input.handle();
fail_safe += 1;
}
}
pub struct Input<'a> {
handlers: Vec<Box<FnMut(i32) + 'a>>,
}
impl<'a> Input<'a> {
pub fn new() -> Self {
Input {handlers: Vec::new()}
}
pub fn handle(&mut self) {
for a in vec![21,0,3,12,1,2] {// it will print the 2, but it won't loop again
for handler in &mut self.handlers {
handler(a);
}
}
}
pub fn add_handler(&mut self, handler: Box<FnMut(i32) + 'a>) {
self.handlers.push(handler);
}
}

Does rust 0.10 have a rl package?

I'm starting to use rust to create a little toy command prompt applicationusing the gnu readline library. I started using the c foreign function interface but then came across this in rust 0.8.
The crate extra has a module extra::rl which appears to be a readline with all the tools that are needed. My question is, is this present in rust 0.10 and if so where is it? if not, is it packaged as an external module, and if so where can I find it?
Thanks in advance.
use std::c_str;
#[link(name = "readline")]
extern {
fn readline (p: *std::libc::c_char) -> * std::libc::c_char;
}
fn rust_readline (prompt: &str) -> Option<~str> {
let cprmt = prompt.to_c_str();
cprmt.with_ref(|c_buf| {
unsafe {
let ret = c_str::CString::new (readline (c_buf), true);
ret.as_str().map(|ret| ret.to_owned())
}
})
}
fn eval(input: &str)
{
println! ("{}", input);
}
fn main()
{
loop {
let val = rust_readline (">>> ");
match val {
None => { break }
_ => {
let input = val.unwrap ();
eval(input);
}
}
}
}
This is a sample REPL style interpreter that just prints instead of eval'ing. Based on code from http://redbrain.co.uk/2013/11/09/rust-and-readline-c-ffi/. His example no longer compiles.
This code is now on github here.
Sorry I really should have said, I came up with an answer to my own question, it includes a history for readline. I have put it here in case anyone else wants some of this functionality.
//! Readline FFI
//extern crate libc;
use std::libc;
use libc::c_char;
use std::c_str;
#[link(name = "readline")]
extern {
fn readline(p: *c_char) -> * c_char;
fn add_history(l: *c_char);
}
pub fn rust_readline(prompt: &str) -> Option<~str> {
let c_prompt = prompt.to_c_str();
c_prompt.with_ref(|c_buf| {
unsafe {
let ret = c_str::CString::new(readline(c_buf), true);
ret.as_str().map(|ret| ret.to_owned())
}
})
}
pub fn rust_add_history(line: &str) -> int {
// if line.len() == 0 { return Err("Empty string!") }
let c_line = line.to_c_str();
c_line.with_ref(|my_c_line| {
unsafe {
// println!("{}", my_c_line)
add_history(my_c_line);
}
});
0
}
fn main() {
loop {
let val = rust_readline("mikes_lisp> ");
match val {
None => { break }
_ => {
let input = val.unwrap();
rust_add_history(input);
println!("you said: '{}'", input);
}
}
}
}

Resources