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);
}
}
}
}
Related
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);
}
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.
I am trying to extract messages (which are futures themselves) from an unbounded queue every N seconds and spawn them into the Tokio handler.
I’ve tried dozens of variations but I cannot seem to find the right approach. It looks like it should be possible, but I always hit a future type mismatch or end up with borrow issues.
This is the code that shows more or less what I want:
let fut = Interval::new_interval(Duration::from_secs(1))
.for_each(|num| vantage_dequeuer.into_future() )
.for_each(|message:VantageMessage |{
handle.spawn(message);
return Ok(());
})
.map_err(|e| panic!("delay errored; err={:?}", e));
core.run(fut);
Complete code:
extern crate futures; // 0.1.24
extern crate tokio; // 0.1.8
extern crate tokio_core; // 0.1.17
use futures::future::ok;
use futures::sync::mpsc;
use futures::{Future, Stream};
use std::thread;
use std::time::Duration;
use tokio::timer::Interval;
use tokio_core::reactor::Core;
type VantageMessage = Box<Future<Item = (), Error = ()> + Send>;
fn main() {
let (enqueuer, dequeuer) = mpsc::unbounded();
let new_fut: VantageMessage = Box::new(ok(()).and_then(|_| {
println!("Message!");
return Ok(());
}));
enqueuer.unbounded_send(new_fut);
let joinHandle = worker(Some(dequeuer));
joinHandle.join();
}
/*
Every second extract one message from dequeuer (or wait if not available)
and spawn it in the core
*/
fn worker(
mut vantage_dequeuer: Option<mpsc::UnboundedReceiver<VantageMessage>>,
) -> thread::JoinHandle<()> {
let dequeuer = dequeuer.take().unwrap();
let joinHandle = thread::spawn(|| {
let mut core = Core::new().unwrap();
let handle = core.handle();
let fut = Interval::new_interval(Duration::from_secs(1))
.for_each(|num| vantage_dequeuer.into_future())
.for_each(|message: VantageMessage| {
handle.spawn(message);
return Ok(());
})
.map_err(|e| panic!("delay errored; err={:?}", e));
core.run(fut);
println!("Returned!");
});
return joinHandle;
}
Playground
error[E0425]: cannot find value `dequeuer` in this scope
--> src/main.rs:33:20
|
33 | let dequeuer = dequeuer.take().unwrap();
| ^^^^^^^^ not found in this scope
error[E0599]: no method named `into_future` found for type `std::option::Option<futures::sync::mpsc::UnboundedReceiver<std::boxed::Box<(dyn futures::Future<Item=(), Error=()> + std::marker::Send + 'static)>>>` in the current scope
--> src/main.rs:38:46
|
38 | .for_each(|num| vantage_dequeuer.into_future())
| ^^^^^^^^^^^
|
= note: the method `into_future` exists but the following trait bounds were not satisfied:
`&mut std::option::Option<futures::sync::mpsc::UnboundedReceiver<std::boxed::Box<(dyn futures::Future<Item=(), Error=()> + std::marker::Send + 'static)>>> : futures::Stream`
Interval and UnboundedReceiver are both streams, so I'd use Stream::zip to combine them:
The zipped stream waits for both streams to produce an item, and then returns that pair. If an error happens, then that error will be returned immediately. If either stream ends then the zipped stream will also end.
extern crate futures; // 0.1.24
extern crate tokio; // 0.1.8
extern crate tokio_core; // 0.1.17
use futures::{
future::ok,
sync::mpsc,
{Future, Stream},
};
use std::{thread, time::Duration};
use tokio::timer::Interval;
use tokio_core::reactor::Core;
type VantageMessage = Box<Future<Item = (), Error = ()> + Send>;
pub fn main() {
let (tx, rx) = mpsc::unbounded();
let new_fut: VantageMessage = Box::new(ok(()).and_then(|_| {
println!("Message!");
Ok(())
}));
tx.unbounded_send(new_fut).expect("Unable to send");
drop(tx); // Close the sending side
worker(rx).join().expect("Thread had a panic");
}
fn worker(queue: mpsc::UnboundedReceiver<VantageMessage>) -> thread::JoinHandle<()> {
thread::spawn(|| {
let mut core = Core::new().unwrap();
let handle = core.handle();
core.run({
Interval::new_interval(Duration::from_secs(1))
.map_err(|e| panic!("delay errored; err={}", e))
.zip(queue)
.for_each(|(_, message)| {
handle.spawn(message);
Ok(())
})
})
.expect("Unable to run reactor");
println!("Returned!");
})
}
Note that this doesn't actually wait for any of the spawned futures to complete before the reactor shuts down. If you want that, I'd switch to tokio::run and tokio::spawn:
fn worker(queue: mpsc::UnboundedReceiver<VantageMessage>) -> thread::JoinHandle<()> {
thread::spawn(|| {
tokio::run({
Interval::new_interval(Duration::from_secs(1))
.map_err(|e| panic!("delay errored; err={}", e))
.zip(queue)
.for_each(|(_, message)| {
tokio::spawn(message);
Ok(())
})
});
println!("Returned!");
})
}
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.
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);
}
}