Re: [rust-dev] Some help needed in Vector of enum conversion

2014-04-07 Thread Rodrigo Rivas
On Sun, Apr 6, 2014 at 7:50 PM, Philippe Delrieu
philippe.delr...@free.fr wrote:
 I need some more help.

 The impl Iteratormut  ~Base for Container declaration generate the error:
 error: missing lifetime specifier
 So I had it but I can't manage to return the next value with the specified
 life time.
 The code :
 impl'a Iterator'a mut  ~Base for Container {
 /// Advance the iterator and return the next value. Return `None` when
 the end is reached.
 fn next(mut self) - Option'a mut ~Base{
 if self.iter_counter == self.nodeList.len()   {
 None
 } else  {
 self.iter_counter += 1;
 Some('a mut match **self.nodeList.get(self.iter_counter){
 FirstThinkImpl(first) = first as ~Base,
 SecondThinkImpl(second)= second as ~Base,
 })
 }
 }
 }

 Generate these errors :
 test_enum.rs:58:18: 61:14 error: borrowed value does not live long enough
 test/test_enum.rs:58 Some('a mut match

Oh, I think I may have misleaded you... You cannot implement the
iterator directly in Container, because the iterator must handle the
current position, while the Container just holds the values. You need
a intermediate struct that implements the Iterator traits. That's what
the `iter()` and ' move_iter()` functions do for vectors and other
standard containers. So you'll need something along the lines of this
(disclaimer: totally untested!!):

struct Container {
//
fn iter('a self) - BaseItems'a {
   let iter = nodeList.iter();
   BaseItems{ iter : iter }
}
}

struct BaseItems'a {
iter : Items'a, ~Base
}

impl'a Iterator'a mut  ~Base for BaseItems'a {
//
}

BTW, why all the double pointer in all the mut ~Base instead of
just mut Base?

-- 
Rodrigo
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Some help needed in Vector of enum conversion

2014-04-05 Thread Rodrigo Rivas
On Fri, Apr 4, 2014 at 10:41 PM, Philippe Delrieu
philippe.delr...@free.fr wrote:
 Hello,

 I've some problem to find a solution for something I want to do with a
 vector of enum. This is an example of what I want to do:

 trait Base{
   fn set_something(mut self);
 }

 struct FirstThink;

 impl Base for FirstThink{
   fn set_something(mut self){}
 }

 struct SecondThink;
 impl Base for SecondThink{
   fn set_something(mut self){}
 }

 enum BaseImpl{
 FirstThinkImpl(~FirstThink),
 SecondThinkImpl(~SecondThink),
 }

 fn some_process(list: mut Vecmut ~Base){
 for think in list.mut_iter()   {
 think.set_something();
 }
 }

 struct Container{
 nodeList: Vec~BaseImpl,
 }

 impl Container{
 fn add_FirstThink(mut self, think: ~FirstThink){
 self.nodeList.push(~FirstThinkImpl(think));
 }
 fn add_SecondThink(mut self, think: ~SecondThink){
 self.nodeList.push(~SecondThinkImpl(think));
 }

 fn do_some_process(mut self, fct: fn(mut Vecmut ~Base)){
  I didn't find a simple  way to convert the Vec~BaseImpl to a mut
 Vecmut ~Base
  to do the call
fct(self.nodeList);

 }
 }

 I use the enum pattern to have only one collection of object that impl Base
 but sometime I have to do specific processing depending if the Base is a
 FirstThink or SecondThink (not in the example). I use the match as follow

 match think {
 FirstThinkImpl(first) = do specific first,
 SecondThinkImpl(second)= do specific second,
 });

 Perhaps there is a better way to do. Any suggestions would  be appreciated.

I think that would be better if the `fct` function take an
`std::iter::Iteratormut ~Base` instead of a `Vec`. Naturally, you
will not be able to modify the vector, only to iterate through it. But
if `fct` is allowed to modify the vector your requirements are
impossible in the first place!

Then you can write a simple adaptor:

impl std::iter::Iteratormut ~Base for Container {
// left as an exercise to the reader ;-)
}

-- 
Rodrigo
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] How to end a task blocked doing IO

2014-03-07 Thread Rodrigo Rivas
Hello!

I'm writing my first non trivial program in Rust and I'm facing now a
blocking issue (pun intended): I have to read/write data from/to a
TcpStream, so I create a task for reading and a task for writing.

fn do_tcp_stuff(sck : TcpStream) {
let mut wtr = ~BufferedWriter::new(sck.clone());
let mut rdr = ~BufferedReader::new(sck);

let (inport, inchan) = Chan::new();
let (outport, outchan) = Chan::new();

spawn(proc() { do_tcp_write(wtr, outport); });
spawn(proc() { do_tcp_read(rdr, inchan); });

loop {
   // do interesting things, select!() and such
}

}

fn do_tcp_write(mut wtr : ~Writer, port : Port~[u8]) - IoResult() {
loop {
let data = port.recv();
try!(wtr.write(data));
wtr.flush();
}
Ok(())
}

fn do_tcp_read(mut rdr : ~Reader, chan : Chan~[u8]) - IoResult() {
loop {
let block = try!(rdr.read_bytes(1024));
chan.send(block);
}
Ok(())
}

And all works perfectly... until I want to close the connection and
kill the tasks:

- The do_tcp_write() function is blocked in port.recv(), so if I
close the outchan it will finish automatically. Nice!
- But the do_tcp_read() function is blocked in rdr.read_bytes() so
closing inport will not affect it, unless it happens to receive some
data.

I've read that in older iterations of the library I could use linked
tasks or something like that. But in master that seems to have
disappeared. I tried also closing the connection, but I couldn't find
how.

Is there any way to do what I want? Or am I doing something fundamentally wrong?

Thank you in advance for your help!
-- 
Rodrigo
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev