view rust/src/main.rs @ 589:f2508125adf1 rust

Try using traits for periodic stream
author Matt Johnston <matt@ucc.asn.au>
date Wed, 21 Dec 2016 08:16:13 +0800
parents 038734052b20
children dccd8504aa38
line wrap: on
line source

#![feature(conservative_impl_trait)]
extern crate tokio_core;
extern crate futures;

use std::time::Duration;
use std::cell::RefCell;
use std::io::{self, Read, Write};

use tokio_core::reactor::Interval;
use tokio_core::reactor::Core;
use tokio_core::reactor::Handle;
use futures::{Future, failed, Poll, Async, Stream};

pub struct Reading {
    name: String,
    value: Option<f32>,
}

pub type Readings = Vec<Reading>;

pub struct Sensor {
    current: f32,
}

struct Periodic<T> {
    interval: Interval,
}

trait Ticker {
    type TickItem;
    fn tick(&self) -> Self::TickItem;
}

impl<T: Ticker> Stream for Periodic<T> {
    type Item = T::TickItem;
    type Error = io::Error;

    fn poll(&mut self) -> Poll<Option<Self::Item>, io::Error> {
        self.interval.poll().map(|a| {
            if let Async::Ready(t) = a {
                Async::Ready(self.tick())
            } else {
                a
            }
        })
    }
}

impl Sensor {

    fn step(&mut self) -> Readings {
        let mut r = Vec::new();
        self.current = self.current + 0.1;
        r.push(Reading { name: "aaa".to_string(), value: Some(self.current) });
        r
    }

    pub fn new() -> Sensor {
        Sensor { current: 22.0 }
    }

    pub fn run(handle: &Handle) -> Box<Stream<Item=Readings, Error=io::Error>> {
        let mut s = Sensor::new();

        let dur = Duration::from_millis(400);
        Interval::new(dur, handle).unwrap().map(move |()| {
            println!("each one");
            // TODO read the sensor here
            s.step()
        }   )
    }
}

fn main() {
    println!("Wort Templog");

    let mut core = Core::new().unwrap();
    let handle = core.handle();

    let s = Sensor::run(&handle);

    let mut re = Readings::new();

    let h = s.for_each(|r| {
        re = r;
        for rx in &re {
            match rx.value {
                Some(x) => println!("re is {} {}", rx.name, x),
                None => println!("re is {} broken", rx.name),
            }
        };
        Ok(())
    });

    core.run(h);
}