<commit_before>use cairo;
use gdk::{self, WindowExt};
use gtk::{self, BoxExt, ContainerExt, DrawingArea, ScrolledWindowExt, StateFlags, WidgetExt};
use std::cell::RefCell;

use std::rc::Rc;
use std::time::Instant;

use color::Color;
use utils::RotateVec;

const LEFT_WIDTH: f64 = 31.;

pub struct Graph {
    elapsed: Instant,
    colors: Vec<Color>,
    pub data: Vec<RotateVec<f64>>,
    vertical_layout: gtk::Box,
    scroll_layout: gtk::ScrolledWindow,
    horizontal_layout: gtk::Box,
    pub area: DrawingArea,
    max: Option<RefCell<f64>>,
    keep_max: bool,
    display_labels: RefCell<bool>,
    initial_diff: Option<i32>,
    label_callbacks: Option<Box<dyn Fn(f64) -> [String; 4]>>,
    labels_layout_width: i32,
    /// `minimum` is used only if `max` is set: it'll be the minimum that the `max` value will
    /// be able to go down.
    minimum: Option<f64>,
    // In %, from 0 to whatever
    overhead: Option<f64>,
}

impl Graph {
    /// If `max` is `None`, the graph will expect values between 0 and 1.
    ///
    /// If `keep_max` is set to `true`, then this value will never go down, meaning that graphs
    /// won't rescale down. It is not taken into account if `max` is `None`.
    pub fn new(max: Option<f64>, keep_max: bool) -> Graph {
        let g = Graph {
            elapsed: Instant::now(),
            colors: vec![],
            data: vec![],
            vertical_layout: gtk::Box::new(gtk::Orientation::Vertical, 0),
            scroll_layout: gtk::ScrolledWindow::new(
                None::<&gtk::Adjustment>,
                None::<&gtk::Adjustment>,
            ),
            horizontal_layout: gtk::Box::new(gtk::Orientation::Horizontal, 0),
            area: DrawingArea::new(),
            max: if let Some(max) = max {
                Some(RefCell::new(max))
            } else {
                None
            },
            keep_max,
            display_labels: RefCell::new(true),
            initial_diff: None,
            label_callbacks: None,
            labels_layout_width: 80,
            minimum: None,
            overhead: None,
        };
        g.scroll_layout.set_min_content_width(g.labels_layout_width);
        g.scroll_layout.add(&g.vertical_layout);
        g.horizontal_layout.pack_start(&g.area, true, true, 0);
        g.horizontal_layout.pack_start(&g.scroll_layout, false, true, 10);
        g.horizontal_layout.set_margin_start(5);
        g
    }

    pub fn set_minimum(&mut self, minimum: Option<f64>) {
        self.minimum = minimum;
    }

    pub fn set_overhead(&mut self, overhead: Option<f64>) {
        if let Some(o) = overhead {
            assert!(o >= 0.);
        }
        self.overhead = overhead;
    }

    /// Changes the size of the layout containing labels (the one on the right).
    pub fn set_labels_width(&mut self, labels_layout_width: u32) {
        self.scroll_layout
            .set_min_content_width(labels_layout_width as i32);
        self.labels_layout_width = labels_layout_width as i32;
    }

    pub fn set_label_callbacks(
        &mut self,
        label_callbacks: Option<Box<dyn Fn(f64) -> [String; 4]>>,
    ) {
        self.label_callbacks = label_callbacks;
    }

    pub fn set_display_labels(&self, display_labels: bool) {
        *self.display_labels.borrow_mut() = display_labels;
        if display_labels {
            self.scroll_layout.show_all();
        } else {
            self.scroll_layout.hide();
        }
        self.invalidate();
    }

    pub fn hide(&self) {
        self.horizontal_layout.hide();
    }

    pub fn show_all(&self) {
        self.horizontal_layout.show_all();
        if !*self.display_labels.borrow() {
            self.scroll_layout.hide();
        }
    }

    pub fn attach_to(&self, to: &gtk::Box) {
        to.add(&self.horizontal_layout);
    }

    pub fn push(&mut self, d: RotateVec<f64>, s: &str, override_color: Option<usize>) {
        let c = if let Some(over) = override_color {
            Color::generate(over)
        } else {
            Color::generate(self.data.len() + 11)
        };
        let l = gtk::Label::new(Some(s));
        l.override_color(
            StateFlags::from_bits(0).expect("from_bits failed"),
            Some(&c.to_gdk()),
        );
        self.vertical_layout.add(&l);
        self.colors.push(c);
        self.data.push(d);
    }

    fn draw_labels(&self, c: &cairo::Context, max: f64, height: f64) {
        if let Some(ref call) = self.label_callbacks {
            let entries = call(max);
            let font_size = 8.;

            c.set_source_rgb(0., 0., 0.);
            c.set_font_size(font_size);

            c.move_to(LEFT_WIDTH - 4. - entries[0].len() as f64 * 4., font_size);
            c.show_text(entries[0].as_str());

            c.move_to(LEFT_WIDTH - 4. - entries[1].len() as f64 * 4., height / 2.);
            c.show_text(entries[1].as_str());

            c.move_to(LEFT_WIDTH - 4. - entries[2].len() as f64 * 4., height - 2.);
            c.show_text(entries[2].as_str());

            c.move_to(
                font_size - 1.,
                height / 2. + 4. * (entries[3].len() >> 1) as f64,
            );
            c.rotate(-::std::f64::consts::FRAC_PI_2);
            c.show_text(entries[3].as_str());
        }
    }

    pub fn draw(&self, c: &cairo::Context, width: f64, height: f64) {
        let x_start = if self.label_callbacks.is_some() {
            LEFT_WIDTH
        } else {
            1.0
        };

        c.set_source_rgb(0.95, 0.95, 0.95);
        c.rectangle(x_start, 1.0, width - 1.0, height - 2.0);
        c.fill();
        c.set_source_rgb(0.0, 0.0, 0.0);
        c.set_line_width(1.0);
        c.move_to(x_start, 0.0);
        c.line_to(x_start, height);
        c.move_to(width, 0.0);
        c.line_to(width, height);
        c.move_to(x_start, 0.0);
        c.line_to(width, 0.0);
        c.move_to(x_start, height);
        c.line_to(width, height);

        // For now it's always 60 seconds.
        let time = 60.;

        let elapsed = self.elapsed.elapsed().as_secs() % 5;
        let x_step = (width - 2.0 - x_start) * 5.0 / (time as f64);
        let mut current = width - elapsed as f64 * (x_step / 5.0) - 1.0;
        if x_step < 0.1 {
            c.stroke();
            return;
        }

        while current > x_start {
            c.move_to(current, 0.0);
            c.line_to(current, height);
            current -= x_step;
        }
        let step = height / 10.0;
        current = step - 1.0;
        while current < height - 1. {
            c.move_to(x_start, current);
            c.line_to(width - 1.0, current);
            current += step;
        }
        c.stroke();

        if let Some(ref self_max) = self.max {
            let mut max = if self.keep_max {
                *self_max.borrow()
            } else {
                1.
            };
            let len = self.data[0].len() - 1;
            for x in 0..len {
                for entry in &self.data {
                    if entry[x] > max {
                        max = entry[x];
                    }
                }
            }
            if let Some(min) = self.minimum {
                if min > max {
                    max = min;
                }
            } else if let Some(over) = self.overhead {
                max = max + max * over / 100.;
            }
            if !self.data.is_empty() && !self.data[0].is_empty() {
                let len = self.data[0].len() - 1;
                let step = (width - 2.0 - x_start) / len as f64;
                current = x_start + 1.0;
                let mut index = len;
                while current > x_start && index > 0 {
                    for (entry, color) in self.data.iter().zip(self.colors.iter()) {
                        c.set_source_rgb(color.r, color.g, color.b);
                        c.move_to(
                            current + step,
                            height - entry[index - 1] / max * (height - 1.0),
                        );
                        c.line_to(current, height - entry[index] / max * (height - 1.0));
                        c.stroke();
                    }
                    current += step;
                    index -= 1;
                }
            }
            if max > *self_max.borrow() || !self.keep_max {
                *self_max.borrow_mut() = max;
            }
            self.draw_labels(c, max, height);
        } else if !self.data.is_empty() && !self.data[0].is_empty() {
            let len = self.data[0].len() - 1;
            let step = (width - 2.0 - x_start) / (len as f64);
            current = x_start + 1.0;
            let mut index = len;
            while current > x_start && index > 0 {
                for (entry, color) in self.data.iter().zip(self.colors.iter()) {
                    c.set_source_rgb(color.r, color.g, color.b);
                    c.move_to(current + step, height - entry[index - 1] * (height - 1.0));
                    c.line_to(current, height - entry[index] * (height - 1.0));
                    c.stroke();
                }
                current += step;
                index -= 1;
            }
            // To be called in last to avoid having to restore state (rotation).
            self.draw_labels(c, 100., height);
        }
    }

    pub fn invalidate(&self) {
        if let Some(t_win) = self.area.get_window() {
            let (x, y) = self
                .area
                .translate_coordinates(&self.area, 0, 0)
                .expect("translate_coordinates failed");
            let rect = gdk::Rectangle {
                x,
                y,
                width: self.area.get_allocated_width(),
                height: self.area.get_allocated_height(),
            };
            t_win.invalidate_rect(Some(&rect), true);
        }
    }

    pub fn send_size_request(&self, width: Option<i32>) {
        let mut width = match width {
            Some(w) => w,
            None => {
                if let Some(parent) = self.area.get_parent() {
                    parent.get_allocation().width
                        - parent.get_margin_start()
                        - parent.get_margin_end()
                } else {
                    eprintln!(
                        "<Graph::send_size_request> A parent is required if no width is \
                               provided..."
                    );
                    return;
                }
            }
        };
        // This condition is to avoid having a graph with a bigger width than the window.
        if let Some(top) = self.area.get_toplevel() {
            let max_width = top.get_allocation().width;
            if width > max_width {
                width = max_width;
            }
        }
        self.area.set_size_request(
            if *self.display_labels.borrow() {
                width
                    - if width >= self.labels_layout_width {
                        self.labels_layout_width
                    } else {
                        width
                    }
            } else {
                width
            },
            200,
        );
    }
}

pub trait Connecter {
    fn connect_to_window_events(&self);
}

impl Connecter for Rc<RefCell<Graph>> {
    fn connect_to_window_events(&self) {
        let s = self.clone();
        if let Some(parent) = self.borrow().horizontal_layout.get_toplevel() {
            // TODO: ugly way to resize drawing area, I should find a better way
            parent.connect_configure_event(move |w, _| {
                let need_diff = s.borrow().initial_diff.is_none();
                if need_diff {
                    let mut s = s.borrow_mut();
                    let parent_width = if let Some(p) = s.area.get_parent() {
                        p.get_allocation().width
                    } else {
                        0
                    };
                    s.initial_diff = Some(w.get_allocation().width - parent_width);
                }
                s.borrow().send_size_request(None);
                false
            });
        } else {
            eprintln!("This method needs to be called *after* it has been put inside a window");
        }
    }
}
<commit_msg>Stop making graph lines move with time<commit_after>use cairo;
use gdk::{self, WindowExt};
use gtk::{self, BoxExt, ContainerExt, DrawingArea, ScrolledWindowExt, StateFlags, WidgetExt};
use std::cell::RefCell;

use std::rc::Rc;

use color::Color;
use utils::RotateVec;

const LEFT_WIDTH: f64 = 31.;

pub struct Graph {
    colors: Vec<Color>,
    pub data: Vec<RotateVec<f64>>,
    vertical_layout: gtk::Box,
    scroll_layout: gtk::ScrolledWindow,
    horizontal_layout: gtk::Box,
    pub area: DrawingArea,
    max: Option<RefCell<f64>>,
    keep_max: bool,
    display_labels: RefCell<bool>,
    initial_diff: Option<i32>,
    label_callbacks: Option<Box<dyn Fn(f64) -> [String; 4]>>,
    labels_layout_width: i32,
    /// `minimum` is used only if `max` is set: it'll be the minimum that the `max` value will
    /// be able to go down.
    minimum: Option<f64>,
    // In %, from 0 to whatever
    overhead: Option<f64>,
}

impl Graph {
    /// If `max` is `None`, the graph will expect values between 0 and 1.
    ///
    /// If `keep_max` is set to `true`, then this value will never go down, meaning that graphs
    /// won't rescale down. It is not taken into account if `max` is `None`.
    pub fn new(max: Option<f64>, keep_max: bool) -> Graph {
        let g = Graph {
            colors: vec![],
            data: vec![],
            vertical_layout: gtk::Box::new(gtk::Orientation::Vertical, 0),
            scroll_layout: gtk::ScrolledWindow::new(
                None::<&gtk::Adjustment>,
                None::<&gtk::Adjustment>,
            ),
            horizontal_layout: gtk::Box::new(gtk::Orientation::Horizontal, 0),
            area: DrawingArea::new(),
            max: if let Some(max) = max {
                Some(RefCell::new(max))
            } else {
                None
            },
            keep_max,
            display_labels: RefCell::new(true),
            initial_diff: None,
            label_callbacks: None,
            labels_layout_width: 80,
            minimum: None,
            overhead: None,
        };
        g.scroll_layout.set_min_content_width(g.labels_layout_width);
        g.scroll_layout.add(&g.vertical_layout);
        g.horizontal_layout.pack_start(&g.area, true, true, 0);
        g.horizontal_layout.pack_start(&g.scroll_layout, false, true, 10);
        g.horizontal_layout.set_margin_start(5);
        g
    }

    pub fn set_minimum(&mut self, minimum: Option<f64>) {
        self.minimum = minimum;
    }

    pub fn set_overhead(&mut self, overhead: Option<f64>) {
        if let Some(o) = overhead {
            assert!(o >= 0.);
        }
        self.overhead = overhead;
    }

    /// Changes the size of the layout containing labels (the one on the right).
    pub fn set_labels_width(&mut self, labels_layout_width: u32) {
        self.scroll_layout
            .set_min_content_width(labels_layout_width as i32);
        self.labels_layout_width = labels_layout_width as i32;
    }

    pub fn set_label_callbacks(
        &mut self,
        label_callbacks: Option<Box<dyn Fn(f64) -> [String; 4]>>,
    ) {
        self.label_callbacks = label_callbacks;
    }

    pub fn set_display_labels(&self, display_labels: bool) {
        *self.display_labels.borrow_mut() = display_labels;
        if display_labels {
            self.scroll_layout.show_all();
        } else {
            self.scroll_layout.hide();
        }
        self.invalidate();
    }

    pub fn hide(&self) {
        self.horizontal_layout.hide();
    }

    pub fn show_all(&self) {
        self.horizontal_layout.show_all();
        if !*self.display_labels.borrow() {
            self.scroll_layout.hide();
        }
    }

    pub fn attach_to(&self, to: &gtk::Box) {
        to.add(&self.horizontal_layout);
    }

    pub fn push(&mut self, d: RotateVec<f64>, s: &str, override_color: Option<usize>) {
        let c = if let Some(over) = override_color {
            Color::generate(over)
        } else {
            Color::generate(self.data.len() + 11)
        };
        let l = gtk::Label::new(Some(s));
        l.override_color(
            StateFlags::from_bits(0).expect("from_bits failed"),
            Some(&c.to_gdk()),
        );
        self.vertical_layout.add(&l);
        self.colors.push(c);
        self.data.push(d);
    }

    fn draw_labels(&self, c: &cairo::Context, max: f64, height: f64) {
        if let Some(ref call) = self.label_callbacks {
            let entries = call(max);
            let font_size = 8.;

            c.set_source_rgb(0., 0., 0.);
            c.set_font_size(font_size);

            c.move_to(LEFT_WIDTH - 4. - entries[0].len() as f64 * 4., font_size);
            c.show_text(entries[0].as_str());

            c.move_to(LEFT_WIDTH - 4. - entries[1].len() as f64 * 4., height / 2.);
            c.show_text(entries[1].as_str());

            c.move_to(LEFT_WIDTH - 4. - entries[2].len() as f64 * 4., height - 2.);
            c.show_text(entries[2].as_str());

            c.move_to(
                font_size - 1.,
                height / 2. + 4. * (entries[3].len() >> 1) as f64,
            );
            c.rotate(-::std::f64::consts::FRAC_PI_2);
            c.show_text(entries[3].as_str());
        }
    }

    pub fn draw(&self, c: &cairo::Context, width: f64, height: f64) {
        let x_start = if self.label_callbacks.is_some() {
            LEFT_WIDTH
        } else {
            1.0
        };

        c.set_source_rgb(0.95, 0.95, 0.95);
        c.rectangle(x_start, 1.0, width - 1.0, height - 2.0);
        c.fill();
        c.set_source_rgb(0.0, 0.0, 0.0);
        c.set_line_width(1.0);
        c.move_to(x_start, 0.0);
        c.line_to(x_start, height);
        c.move_to(width, 0.0);
        c.line_to(width, height);
        c.move_to(x_start, 0.0);
        c.line_to(width, 0.0);
        c.move_to(x_start, height);
        c.line_to(width, height);

        // For now it's always 60 seconds.
        let time = 60.;
        let x_step = (width - 2.0 - x_start) * 5.0 / (time as f64);
        let mut current = width * (x_step / 5.0) - 1.0;
        if x_step < 0.1 {
            c.stroke();
            return;
        }

        while current > x_start {
            c.move_to(current, 0.0);
            c.line_to(current, height);
            current -= x_step;
        }
        let step = height / 10.0;
        current = step - 1.0;
        while current < height - 1. {
            c.move_to(x_start, current);
            c.line_to(width - 1.0, current);
            current += step;
        }
        c.stroke();

        if let Some(ref self_max) = self.max {
            let mut max = if self.keep_max {
                *self_max.borrow()
            } else {
                1.
            };
            let len = self.data[0].len() - 1;
            for x in 0..len {
                for entry in &self.data {
                    if entry[x] > max {
                        max = entry[x];
                    }
                }
            }
            if let Some(min) = self.minimum {
                if min > max {
                    max = min;
                }
            } else if let Some(over) = self.overhead {
                max = max + max * over / 100.;
            }
            if !self.data.is_empty() && !self.data[0].is_empty() {
                let len = self.data[0].len() - 1;
                let step = (width - 2.0 - x_start) / len as f64;
                current = x_start + 1.0;
                let mut index = len;
                while current > x_start && index > 0 {
                    for (entry, color) in self.data.iter().zip(self.colors.iter()) {
                        c.set_source_rgb(color.r, color.g, color.b);
                        c.move_to(
                            current + step,
                            height - entry[index - 1] / max * (height - 1.0),
                        );
                        c.line_to(current, height - entry[index] / max * (height - 1.0));
                        c.stroke();
                    }
                    current += step;
                    index -= 1;
                }
            }
            if max > *self_max.borrow() || !self.keep_max {
                *self_max.borrow_mut() = max;
            }
            self.draw_labels(c, max, height);
        } else if !self.data.is_empty() && !self.data[0].is_empty() {
            let len = self.data[0].len() - 1;
            let step = (width - 2.0 - x_start) / (len as f64);
            current = x_start + 1.0;
            let mut index = len;
            while current > x_start && index > 0 {
                for (entry, color) in self.data.iter().zip(self.colors.iter()) {
                    c.set_source_rgb(color.r, color.g, color.b);
                    c.move_to(current + step, height - entry[index - 1] * (height - 1.0));
                    c.line_to(current, height - entry[index] * (height - 1.0));
                    c.stroke();
                }
                current += step;
                index -= 1;
            }
            // To be called in last to avoid having to restore state (rotation).
            self.draw_labels(c, 100., height);
        }
    }

    pub fn invalidate(&self) {
        if let Some(t_win) = self.area.get_window() {
            let (x, y) = self
                .area
                .translate_coordinates(&self.area, 0, 0)
                .expect("translate_coordinates failed");
            let rect = gdk::Rectangle {
                x,
                y,
                width: self.area.get_allocated_width(),
                height: self.area.get_allocated_height(),
            };
            t_win.invalidate_rect(Some(&rect), true);
        }
    }

    pub fn send_size_request(&self, width: Option<i32>) {
        let mut width = match width {
            Some(w) => w,
            None => {
                if let Some(parent) = self.area.get_parent() {
                    parent.get_allocation().width
                        - parent.get_margin_start()
                        - parent.get_margin_end()
                } else {
                    eprintln!(
                        "<Graph::send_size_request> A parent is required if no width is \
                               provided..."
                    );
                    return;
                }
            }
        };
        // This condition is to avoid having a graph with a bigger width than the window.
        if let Some(top) = self.area.get_toplevel() {
            let max_width = top.get_allocation().width;
            if width > max_width {
                width = max_width;
            }
        }
        self.area.set_size_request(
            if *self.display_labels.borrow() {
                width
                    - if width >= self.labels_layout_width {
                        self.labels_layout_width
                    } else {
                        width
                    }
            } else {
                width
            },
            200,
        );
    }
}

pub trait Connecter {
    fn connect_to_window_events(&self);
}

impl Connecter for Rc<RefCell<Graph>> {
    fn connect_to_window_events(&self) {
        let s = self.clone();
        if let Some(parent) = self.borrow().horizontal_layout.get_toplevel() {
            // TODO: ugly way to resize drawing area, I should find a better way
            parent.connect_configure_event(move |w, _| {
                let need_diff = s.borrow().initial_diff.is_none();
                if need_diff {
                    let mut s = s.borrow_mut();
                    let parent_width = if let Some(p) = s.area.get_parent() {
                        p.get_allocation().width
                    } else {
                        0
                    };
                    s.initial_diff = Some(w.get_allocation().width - parent_width);
                }
                s.borrow().send_size_request(None);
                false
            });
        } else {
            eprintln!("This method needs to be called *after* it has been put inside a window");
        }
    }
}
<|endoftext|>


<commit_before>use super::{ArrayLength, GenericArray};
use core::borrow::{Borrow, BorrowMut};
use core::cmp::Ordering;
use core::fmt::{self, Debug};
use core::hash::{Hash, Hasher};

impl<T: Default, N> Default for GenericArray<T, N>
where
    N: ArrayLength<T>,
{
    #[inline]
    fn default() -> Self {
        Self::generate(|_| T::default())
    }
}

impl<T: Clone, N> Clone for GenericArray<T, N>
where
    N: ArrayLength<T>,
{
    fn clone(&self) -> GenericArray<T, N> {
        self.map_ref(|x| x.clone())
    }
}
impl<T: Copy, N> Copy for GenericArray<T, N>
where
    N: ArrayLength<T>,
    N::ArrayType: Copy,
{
}

impl<T: PartialEq, N> PartialEq for GenericArray<T, N>
where
    N: ArrayLength<T>,
{
    fn eq(&self, other: &Self) -> bool {
        **self == **other
    }
}
impl<T: Eq, N> Eq for GenericArray<T, N>
where
    N: ArrayLength<T>,
{
}

impl<T: PartialOrd, N> PartialOrd for GenericArray<T, N>
where
    N: ArrayLength<T>,
{
    fn partial_cmp(&self, other: &GenericArray<T, N>) -> Option<Ordering> {
        PartialOrd::partial_cmp(&self, &other)
    }
}

impl<T: Ord, N> Ord for GenericArray<T, N>
where
    N: ArrayLength<T>,
{
    fn cmp(&self, other: &GenericArray<T, N>) -> Ordering {
        Ord::cmp(&self, &other)
    }
}

impl<T: Debug, N> Debug for GenericArray<T, N>
where
    N: ArrayLength<T>,
{
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        self[..].fmt(fmt)
    }
}

impl<T, N> Borrow<[T]> for GenericArray<T, N>
where
    N: ArrayLength<T>,
{
    fn borrow(&self) -> &[T] {
        &self[..]
    }
}

impl<T, N> BorrowMut<[T]> for GenericArray<T, N>
where
    N: ArrayLength<T>,
{
    fn borrow_mut(&mut self) -> &mut [T] {
        &mut self[..]
    }
}

impl<T, N> AsRef<[T]> for GenericArray<T, N>
where
    N: ArrayLength<T>,
{
    fn as_ref(&self) -> &[T] {
        &self[..]
    }
}

impl<T, N> AsMut<[T]> for GenericArray<T, N>
where
    N: ArrayLength<T>,
{
    fn as_mut(&mut self) -> &mut [T] {
        &mut self[..]
    }
}

impl<T: Hash, N> Hash for GenericArray<T, N>
where
    N: ArrayLength<T>,
{
    fn hash<H>(&self, state: &mut H)
    where
        H: Hasher,
    {
        Hash::hash(&self[..], state)
    }
}
<commit_msg>Formatting and explicitely state slice comparisons.<commit_after>use super::{ArrayLength, GenericArray};
use core::borrow::{Borrow, BorrowMut};
use core::cmp::Ordering;
use core::fmt::{self, Debug};
use core::hash::{Hash, Hasher};

impl<T: Default, N> Default for GenericArray<T, N>
where
    N: ArrayLength<T>,
{
    #[inline]
    fn default() -> Self {
        Self::generate(|_| T::default())
    }
}

impl<T: Clone, N> Clone for GenericArray<T, N>
where
    N: ArrayLength<T>,
{
    fn clone(&self) -> GenericArray<T, N> {
        self.map_ref(|x| x.clone())
    }
}

impl<T: Copy, N> Copy for GenericArray<T, N>
where
    N: ArrayLength<T>,
    N::ArrayType: Copy,
{
}

impl<T: PartialEq, N> PartialEq for GenericArray<T, N>
where
    N: ArrayLength<T>,
{
    fn eq(&self, other: &Self) -> bool {
        **self == **other
    }
}

impl<T: Eq, N> Eq for GenericArray<T, N>
where
    N: ArrayLength<T>,
{
}

impl<T: PartialOrd, N> PartialOrd for GenericArray<T, N>
where
    N: ArrayLength<T>,
{
    fn partial_cmp(&self, other: &GenericArray<T, N>) -> Option<Ordering> {
        PartialOrd::partial_cmp(self.as_slice(), other.as_slice())
    }
}

impl<T: Ord, N> Ord for GenericArray<T, N>
where
    N: ArrayLength<T>,
{
    fn cmp(&self, other: &GenericArray<T, N>) -> Ordering {
        Ord::cmp(self.as_slice(), other.as_slice())
    }
}

impl<T: Debug, N> Debug for GenericArray<T, N>
where
    N: ArrayLength<T>,
{
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        self[..].fmt(fmt)
    }
}

impl<T, N> Borrow<[T]> for GenericArray<T, N>
where
    N: ArrayLength<T>,
{
    fn borrow(&self) -> &[T] {
        &self[..]
    }
}

impl<T, N> BorrowMut<[T]> for GenericArray<T, N>
where
    N: ArrayLength<T>,
{
    fn borrow_mut(&mut self) -> &mut [T] {
        &mut self[..]
    }
}

impl<T, N> AsRef<[T]> for GenericArray<T, N>
where
    N: ArrayLength<T>,
{
    fn as_ref(&self) -> &[T] {
        &self[..]
    }
}

impl<T, N> AsMut<[T]> for GenericArray<T, N>
where
    N: ArrayLength<T>,
{
    fn as_mut(&mut self) -> &mut [T] {
        &mut self[..]
    }
}

impl<T: Hash, N> Hash for GenericArray<T, N>
where
    N: ArrayLength<T>,
{
    fn hash<H>(&self, state: &mut H)
    where
        H: Hasher,
    {
        Hash::hash(&self[..], state)
    }
}
<|endoftext|>


<commit_before>use error::InputError;
use std::io;

pub fn read_line() -> io::Result<String> {
    let mut buffer = String::new();
    io::stdin().read_line(&mut buffer)?;

    // Trim the right side of the buffer to remove the newline character
    Ok(buffer.trim_right().to_string())
}

pub fn read_usize_range(min: usize, max: usize) -> Result<usize, InputError> {
    loop {
        let input = read_line()
            .map_err(InputError::ReadFailed)?
            .parse()
            .map_err(InputError::IntParseFailed)?;

        if input >= min && input <= max {
            return Ok(input);
        } else {
            println!("input must be between {}-{}", min, max);
        }
    }
}

#[derive(Debug)]
pub enum Answer {
    Yes,
    No,
}

impl Into<bool> for Answer {
    fn into(self) -> bool {
        match self {
            Answer::Yes => true,
            Answer::No => false,
        }
    }
}

pub fn read_yn(default: Answer) -> io::Result<bool> {
    let line = read_line()?;

    let answer = match line.as_str() {
        "y" | "Y" => true,
        "n" | "N" => false,
        _ => default.into(),
    };

    Ok(answer)
}
<commit_msg>Rename read_usize_range to read_range and make it generic<commit_after>use error::InputError;
use std::fmt::{Debug, Display};
use std::io;
use std::str::FromStr;

pub fn read_line() -> io::Result<String> {
    let mut buffer = String::new();
    io::stdin().read_line(&mut buffer)?;

    // Trim the right side of the buffer to remove the newline character
    Ok(buffer.trim_right().to_string())
}

pub fn read_range<T>(min: T, max: T) -> Result<T, InputError>
where
    T: Ord + FromStr + Debug + Display,
    <T as FromStr>::Err: Debug,
{
    loop {
        let input = read_line()
            .map_err(InputError::ReadFailed)?
            .parse()
            .map_err(|e| InputError::ParseFailed(format!("{:?}", e)))?;

        if input >= min && input <= max {
            return Ok(input);
        } else {
            println!("input must be between {}-{}", min, max);
        }
    }
}

#[derive(Debug)]
pub enum Answer {
    Yes,
    No,
}

impl Into<bool> for Answer {
    fn into(self) -> bool {
        match self {
            Answer::Yes => true,
            Answer::No => false,
        }
    }
}

pub fn read_yn(default: Answer) -> io::Result<bool> {
    let line = read_line()?;

    let answer = match line.as_str() {
        "y" | "Y" => true,
        "n" | "N" => false,
        _ => default.into(),
    };

    Ok(answer)
}
<|endoftext|>


<commit_before>/**
Katy Williamson kcw4sn
Ben Terner bt3ze
@virginia.edu

Final Project for CS4414 - Operating Systems
A parallel MST implementation on images in Rust

*/

extern mod extra;
use std::{os, num,hashmap,str} ;
use extra::{arc,priority_queue};

struct Pixel{
    r: int,
    b: int,
    g: int,
    color: int,
    x: int,
    y: int
}

impl Pixel {
    fn new(red: int, blue: int, green: int) -> Pixel {
        Pixel{
            r: red,
            b: blue,
            g: green,
            color: 0,
            x: 0,
            y: 0
        }
    }
}

struct Edge {
    source: Pixel,
    dest: Pixel,
    cost: float
}

impl Edge {
    fn new(s: Pixel, d: Pixel) -> Edge {
        Edge { // these need to be references to pixels, not copies.
            // for standard prim, it's alright for now
            source: s,
            dest: d,
            cost: edgeCost(s,d)
        }
    }
}

impl Ord for Edge {
    fn lt(&self, other: &Edge) -> bool {
        self.cost < other.cost
    }
}

fn edgeCost(a: Pixel, b: Pixel) -> float {
    num::sqrt( (
            a.r*a.r-b.r*b.r + a.g*a.g-b.g*b.g + a.b*a.b-b.b*b.b ) as float)
}

fn readImage( filename: &~str) -> ~ [ ~[Pixel]] {
    ~[~[]]
}

fn main(){
    let argv =  os::args();
    println(argv.to_str());
    let length = match from_str::<int>(argv[2]) {
        Some(x) => x,
        None() => 0
    };
    let width = match from_str::<int>(argv[3]) {
        Some(x) => x,
        None() => 0
    };

    let pixels: ~[ ~[Pixel] ] = readImage(&argv[1]);
    let mut find_arcs: ~[ ~[arc::RWArc<Pixel>] ] =  ~[ ~[]];
    let mut len = 0;
    let mut wid = 0;
    loop {
        loop {
            find_arcs[len][wid] = arc::RWArc::new(pixels[len][wid]);
                wid+=1;
            if(wid == width) {
                wid = 0;
                break;
            }
        }
        len+=1;
        if(len == length) {
            break;
        }
    }

    let arcs = find_arcs; // now we have an immutable array that can be shared

    let mut x= 0;
    let mut y= 0;
    let mut queue: priority_queue::PriorityQueue<Edge> =  priority_queue::PriorityQueue::new();
    let mut visited: hashmap::HashMap<(int,int),bool> = hashmap::HashMap::new();
    loop { // iterate through items in the queue, which contains all of the edges/vertices

        let edge = queue.maybe_pop();
        match edge {
            Some(e) => {
                if e.dest.color == 0 {
                    // not in any tree
                    let coord = (e.dest.x,e.dest.y);
                    if *visited.get(&coord) == false { // use visited hashmap to figure out if we're at a new vertex
                        visited.insert(coord,true);
                        x = e.dest.x;
                        y = e.dest.y;
                        let neighbors = [ (x,y-1),(x+1,y), (x,y+1), (x,y-1)];
                        for &coord in neighbors.iter() {
                            let (w,z) = coord;
                            if w >=0 && w < width && z >=0 && z <= length { // bounds checking
                                // if neighbor at coord has not been or colored
                                if pixels[w][z].color != 0 { // then we have a new vertex
                                    queue.push( Edge::new(pixels[x][y],pixels[w][z]) );
                                }
                            }
                        }
                    }

                    // use an arc to write the following
                    // e.dest.color = e.source.color;
                }
            }
            None => { break; } // this should really never execute
        }
    }

}
<commit_msg>commit before going to bed.<commit_after>/**
Katy Williamson kcw4sn
Ben Terner bt3ze
@virginia.edu

Final Project for CS4414 - Operating Systems
A parallel MST implementation on images in Rust

*/

extern mod extra;
use std::{os, num,hashmap,str} ;
use extra::{arc,priority_queue};

struct Pixel{
    r: int,
    b: int,
    g: int,
    color: int,
    x: int,
    y: int
}

impl Pixel {
    fn new(red: int, blue: int, green: int) -> Pixel {
        Pixel{
            r: red,
            b: blue,
            g: green,
            color: 0,
            x: 0,
            y: 0
        }
    }
}

struct Edge {
    source: Pixel,
    dest: Pixel,
    cost: float
}

impl Edge {
    fn new(s: Pixel, d: Pixel) -> Edge {
        Edge { // these need to be references to pixels, not copies.
            // for standard prim, it's alright for now
            source: s,
            dest: d,
            cost: edgeCost(s,d)
        }
    }
}

impl Ord for Edge {
    fn lt(&self, other: &Edge) -> bool {
        self.cost < other.cost
    }
}

fn edgeCost(a: Pixel, b: Pixel) -> float {
    num::sqrt( (
            a.r*a.r-b.r*b.r + a.g*a.g-b.g*b.g + a.b*a.b-b.b*b.b ) as float)
}

fn readImage( filename: &~str) -> ~ [ ~[Pixel]] {
    ~[~[]]
}

fn main(){
    let argv =  os::args();
    println(argv.to_str());
    let length = match from_str::<int>(argv[2]) {
        Some(x) => x,
        None() => 0
    };
    let width = match from_str::<int>(argv[3]) {
        Some(x) => x,
        None() => 0
    };

    let pixels: ~[ ~[Pixel] ] = readImage(&argv[1]);
    let mut find_arcs: ~[ ~[arc::RWArc<Pixel>] ] =  ~[ ~[]];
    let mut len = 0;
    let mut wid = 0;
    loop {
        loop {
            find_arcs[len][wid] = arc::RWArc::new(pixels[len][wid]);
                wid+=1;
            if(wid == width) {
                wid = 0;
                break;
            }
        }
        len+=1;
        if(len == length) {
            break;
        }
    }

    let arcs = find_arcs; // now we have an immutable array that can be shared

    let mut x= 0;
    let mut y= 0;
    let mut queue: priority_queue::PriorityQueue<Edge> =  priority_queue::PriorityQueue::new();
    let mut visited: hashmap::HashMap<(int,int),bool> = hashmap::HashMap::new();
    loop { // iterate through items in the queue, which contains all of the edges/vertices

        let edge = queue.maybe_pop();
        match edge {
            Some(e) => {
                if e.dest.color == 0 {
                    // not in any tree
                    let coord = (e.dest.x,e.dest.y);
                    if *visited.get(&coord) == false { // use visited hashmap to figure out if we're at a new vertex
                        visited.insert(coord,true);
                        x = e.dest.x;
                        y = e.dest.y;
                        let neighbors = [ (x,y-1),(x+1,y), (x,y+1), (x,y-1)];
                        for &coord in neighbors.iter() {
                            let (w,z) = coord;
                            if w >=0 && w < width && z >=0 && z <= length { // bounds checking
                                // if neighbor at coord has not been or colored
                                if pixels[w][z].color != 0 { // then we have a new vertex
                                    queue.push( Edge::new(pixels[x][y],pixels[w][z]) );
                                }
                            }
                        }
                    }

                    // use an arc to write the following
                    // e.dest.color = e.source.color;
                }
            }
            None => { break; } // this should really never execute till the end
        }
    }

}
<|endoftext|>


<commit_before>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//
// compile-flags: -C codegen-units=2
// error-pattern: build without -C codegen-units for more exact errors

#![feature(asm)]

fn main() {
    unsafe {
        asm!("nowayisthisavalidinstruction");
    }
}
<commit_msg>Don't test codegen-units errors on stage1 (c.f. #20184)<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//
// ignore-stage1 (#20184)
// compile-flags: -C codegen-units=2
// error-pattern: build without -C codegen-units for more exact errors

#![feature(asm)]

fn main() {
    unsafe {
        asm!("nowayisthisavalidinstruction");
    }
}
<|endoftext|>


<commit_before>//!
//! The **nodrop** crate has the following cargo feature flags:
//!
//! - `std`
//!   - Optional, enabled by default
//!   - Requires Rust 1.6 *to disable*
//!   - Use libstd
//! - `use_needs_drop`
//!   - Optional
//!   - Requires nightly channel.
//!   - Use `needs_drop` to skip overwriting if not necessary
//! - `use_union`
//!   - Optional
//!   - Requires nightly channel
//!   - Using untagged union, finally we have an implementation of `NoDrop` without hacks,
//!     for example the fact that `NoDrop<T>` never has a destructor anymore.
//!

#![cfg_attr(feature="use_needs_drop", feature(core_intrinsics))]

#![cfg_attr(not(any(test, feature="std")), no_std)]
#[cfg(not(any(test, feature="std")))]
extern crate core as std;

#[cfg(not(feature = "use_union"))]
extern crate odds;

#[cfg(feature = "use_union")]
extern crate nodrop_union as imp;

pub use imp::NoDrop;

#[cfg(not(feature = "use_union"))]
mod imp {
    use std;
    use odds::debug_assert_unreachable;
    use std::ptr;
    use std::mem;
    use std::ops::{Deref, DerefMut};

    /// repr(u8) - Make sure the non-nullable pointer optimization does not occur!
    #[repr(u8)]
    enum Flag<T> {
        Alive(T),
        Dropped,
    }

    /// A type holding **T** that will not call its destructor on drop
    pub struct NoDrop<T>(Flag<T>);

    impl<T> NoDrop<T> {
        /// Create a new **NoDrop**.
        #[inline]
        pub fn new(value: T) -> NoDrop<T> {
            NoDrop(Flag::Alive(value))
        }

        /// Extract the inner value.
        ///
        /// Once extracted, the value can of course drop again.
        #[inline]
        pub fn into_inner(mut self) -> T {
            let inner = unsafe {
                ptr::read(&mut *self)
            };
            // skip Drop, so we don't even have to overwrite
            mem::forget(self);
            inner
        }
    }

    #[cfg(not(feature = "use_needs_drop"))]
    #[inline]
    fn needs_drop<T>() -> bool {
        true
    }

    #[cfg(feature = "use_needs_drop")]
    #[inline]
    fn needs_drop<T>() -> bool {
        unsafe {
            std::intrinsics::needs_drop::<T>()
        }
    }

    impl<T> Drop for NoDrop<T> {
        fn drop(&mut self) {
            if needs_drop::<T>() {
                // inhibit drop
                unsafe {
                    ptr::write(&mut self.0, Flag::Dropped);
                }
            }
        }
    }

    impl<T> Deref for NoDrop<T> {
        type Target = T;

        // Use type invariant, always Flag::Alive.
        #[inline]
        fn deref(&self) -> &T {
            match self.0 {
                Flag::Alive(ref inner) => inner,
                _ => unsafe { debug_assert_unreachable() }
            }
        }
    }

    impl<T> DerefMut for NoDrop<T> {
        // Use type invariant, always Flag::Alive.
        #[inline]
        fn deref_mut(&mut self) -> &mut T {
            match self.0 {
                Flag::Alive(ref mut inner) => inner,
                _ => unsafe { debug_assert_unreachable() }
            }
        }
    }

    #[cfg(test)]
    #[test]
    fn test_no_nonnullable_opt() {
        // Make sure `Flag` does not apply the non-nullable pointer optimization
        // as Option would do.
        assert!(mem::size_of::<Flag<&i32>>() > mem::size_of::<&i32>());
        assert!(mem::size_of::<Flag<Vec<i32>>>() > mem::size_of::<Vec<i32>>());
        assert!(mem::size_of::<Option<Flag<&i32>>>() > mem::size_of::<Flag<&i32>>());
    }
}

#[cfg(test)]
mod tests {
    use super::NoDrop;

    #[test]
    fn test_drop() {
        use std::cell::Cell;

        let flag = &Cell::new(0);

        struct Bump<'a>(&'a Cell<i32>);

        impl<'a> Drop for Bump<'a> {
            fn drop(&mut self) {
                let n = self.0.get();
                self.0.set(n + 1);
            }
        }

        {
            let _ = NoDrop::new([Bump(flag), Bump(flag)]);
        }
        assert_eq!(flag.get(), 0);

        // test something with the nullable pointer optimization
        flag.set(0);

        {
            let mut array = NoDrop::new(Vec::new());
            array.push(vec![Bump(flag)]);
            array.push(vec![Bump(flag), Bump(flag)]);
            array.push(vec![]);
            array.push(vec![Bump(flag)]);
            drop(array.pop());
            assert_eq!(flag.get(), 1);
            drop(array.pop());
            assert_eq!(flag.get(), 1);
            drop(array.pop());
            assert_eq!(flag.get(), 3);
        }

        // last one didn't drop.
        assert_eq!(flag.get(), 3);

        flag.set(0);
        {
            let array = NoDrop::new(Bump(flag));
            array.into_inner();
            assert_eq!(flag.get(), 1);
        }
        assert_eq!(flag.get(), 1);
    }
}
<commit_msg>nodrop: Fix warning for unused import<commit_after>//!
//! The **nodrop** crate has the following cargo feature flags:
//!
//! - `std`
//!   - Optional, enabled by default
//!   - Requires Rust 1.6 *to disable*
//!   - Use libstd
//! - `use_needs_drop`
//!   - Optional
//!   - Requires nightly channel.
//!   - Use `needs_drop` to skip overwriting if not necessary
//! - `use_union`
//!   - Optional
//!   - Requires nightly channel
//!   - Using untagged union, finally we have an implementation of `NoDrop` without hacks,
//!     for example the fact that `NoDrop<T>` never has a destructor anymore.
//!

#![cfg_attr(feature="use_needs_drop", feature(core_intrinsics))]

#![cfg_attr(not(any(test, feature="std")), no_std)]
#[cfg(not(any(test, feature="std")))]
extern crate core as std;

#[cfg(not(feature = "use_union"))]
extern crate odds;

#[cfg(feature = "use_union")]
extern crate nodrop_union as imp;

pub use imp::NoDrop;

#[cfg(not(feature = "use_union"))]
mod imp {
    use odds::debug_assert_unreachable;
    use std::ptr;
    use std::mem;
    use std::ops::{Deref, DerefMut};

    /// repr(u8) - Make sure the non-nullable pointer optimization does not occur!
    #[repr(u8)]
    enum Flag<T> {
        Alive(T),
        Dropped,
    }

    /// A type holding **T** that will not call its destructor on drop
    pub struct NoDrop<T>(Flag<T>);

    impl<T> NoDrop<T> {
        /// Create a new **NoDrop**.
        #[inline]
        pub fn new(value: T) -> NoDrop<T> {
            NoDrop(Flag::Alive(value))
        }

        /// Extract the inner value.
        ///
        /// Once extracted, the value can of course drop again.
        #[inline]
        pub fn into_inner(mut self) -> T {
            let inner = unsafe {
                ptr::read(&mut *self)
            };
            // skip Drop, so we don't even have to overwrite
            mem::forget(self);
            inner
        }
    }

    #[cfg(not(feature = "use_needs_drop"))]
    #[inline]
    fn needs_drop<T>() -> bool {
        true
    }

    #[cfg(feature = "use_needs_drop")]
    #[inline]
    fn needs_drop<T>() -> bool {
        unsafe {
            ::std::intrinsics::needs_drop::<T>()
        }
    }

    impl<T> Drop for NoDrop<T> {
        fn drop(&mut self) {
            if needs_drop::<T>() {
                // inhibit drop
                unsafe {
                    ptr::write(&mut self.0, Flag::Dropped);
                }
            }
        }
    }

    impl<T> Deref for NoDrop<T> {
        type Target = T;

        // Use type invariant, always Flag::Alive.
        #[inline]
        fn deref(&self) -> &T {
            match self.0 {
                Flag::Alive(ref inner) => inner,
                _ => unsafe { debug_assert_unreachable() }
            }
        }
    }

    impl<T> DerefMut for NoDrop<T> {
        // Use type invariant, always Flag::Alive.
        #[inline]
        fn deref_mut(&mut self) -> &mut T {
            match self.0 {
                Flag::Alive(ref mut inner) => inner,
                _ => unsafe { debug_assert_unreachable() }
            }
        }
    }

    #[cfg(test)]
    #[test]
    fn test_no_nonnullable_opt() {
        // Make sure `Flag` does not apply the non-nullable pointer optimization
        // as Option would do.
        assert!(mem::size_of::<Flag<&i32>>() > mem::size_of::<&i32>());
        assert!(mem::size_of::<Flag<Vec<i32>>>() > mem::size_of::<Vec<i32>>());
        assert!(mem::size_of::<Option<Flag<&i32>>>() > mem::size_of::<Flag<&i32>>());
    }
}

#[cfg(test)]
mod tests {
    use super::NoDrop;

    #[test]
    fn test_drop() {
        use std::cell::Cell;

        let flag = &Cell::new(0);

        struct Bump<'a>(&'a Cell<i32>);

        impl<'a> Drop for Bump<'a> {
            fn drop(&mut self) {
                let n = self.0.get();
                self.0.set(n + 1);
            }
        }

        {
            let _ = NoDrop::new([Bump(flag), Bump(flag)]);
        }
        assert_eq!(flag.get(), 0);

        // test something with the nullable pointer optimization
        flag.set(0);

        {
            let mut array = NoDrop::new(Vec::new());
            array.push(vec![Bump(flag)]);
            array.push(vec![Bump(flag), Bump(flag)]);
            array.push(vec![]);
            array.push(vec![Bump(flag)]);
            drop(array.pop());
            assert_eq!(flag.get(), 1);
            drop(array.pop());
            assert_eq!(flag.get(), 1);
            drop(array.pop());
            assert_eq!(flag.get(), 3);
        }

        // last one didn't drop.
        assert_eq!(flag.get(), 3);

        flag.set(0);
        {
            let array = NoDrop::new(Bump(flag));
            array.into_inner();
            assert_eq!(flag.get(), 1);
        }
        assert_eq!(flag.get(), 1);
    }
}
<|endoftext|>


<commit_before>use std::fs::File;
use std::io::prelude::*;
use std::io::BufReader;
use std::io::{self, Error};
use std::mem;

use libc::{
    c_char, c_int, c_ulong, c_void, close, recvfrom, sendto, sockaddr, sockaddr_ll, socket,
    socklen_t, AF_AX25, AF_PACKET, SOCK_RAW,
};

const ETH_P_AX25: u16 = 0x0002; // from if_ether.h for SOCK_RAW
const SIOCGIFHWADDR: c_ulong = 0x8927; // from sockios.h in the linux kernel
const SIOCGIFINDEX: c_ulong = 0x8933;

/// An active AX.25 network interface, e.g. "ax0"
pub struct NetDev {
    pub name: String,
    pub ifindex: i32,
}

/// An open socket for sending and receiving AX.25 frames
pub struct Ax25RawSocket {
    fd: i32,
}

impl Ax25RawSocket {
    /// Create a new socket for sending and receiving raw AX.25 frames. This requires root or CAP_NET_ADMIN.
    pub fn new() -> io::Result<Ax25RawSocket> {
        match unsafe { socket(AF_PACKET, SOCK_RAW, ETH_P_AX25.to_be() as i32) } {
            -1 => Err(Error::last_os_error()),
            fd => Ok(Ax25RawSocket { fd: fd }),
        }
    }

    /// Close an open AX.25 socket.
    pub fn close(&mut self) -> io::Result<()> {
        match unsafe { close(self.fd) } {
            -1 => Err(Error::last_os_error()),
            _ => Ok(()),
        }
    }

    /// Find all AX.25 interfaces on the system
    pub fn list_ax25_interfaces(&self) -> io::Result<Vec<NetDev>> {
        let dev_file = File::open("/proc/net/dev")?;
        let mut devices: Vec<NetDev> = Vec::new();
        let reader = BufReader::new(dev_file);
        let lines = reader.lines();
        for l in lines.skip(2) {
            match l {
                Ok(line) => {
                    let device_name = line.trim().split(":").next().unwrap();
                    if let Some(net_dev) = get_ax25_netdev(&device_name, self.fd) {
                        devices.push(net_dev);
                    }
                }
                Err(_) => (),
            }
        }
        Ok(devices)
    }

    /// Send a frame to a particular interface, specified by its index
    pub fn send_frame(&self, frame: &[u8], ifindex: i32) -> io::Result<()> {
        // The Linux interface demands a single null byte prefix on the actual packet
        let mut prefixed_frame: Vec<u8> = Vec::with_capacity(frame.len() + 1);
        prefixed_frame.push(0);
        prefixed_frame.extend(frame.iter().cloned());

        let sa = sockaddr_ll {
            sll_family: AF_PACKET as u16,
            sll_protocol: ETH_P_AX25.to_be(),
            sll_ifindex: ifindex,
            sll_hatype: 0,
            sll_pkttype: 0,
            sll_halen: 0,
            sll_addr: [0; 8],
        };

        match unsafe {
            let sa_ptr = mem::transmute::<*const sockaddr_ll, *const sockaddr>(&sa);
            sendto(
                self.fd,
                prefixed_frame.as_ptr() as *const c_void,
                prefixed_frame.len(),
                0,
                sa_ptr,
                mem::size_of_val(&sa) as socklen_t,
            )
        } {
            -1 => Err(Error::last_os_error()),
            _ => Ok(()),
        }
    }

    /// Block to receive an incoming AX.25 frame from any interface
    pub fn receive_frame(&self) -> io::Result<Vec<u8>> {
        let mut buf: [u8; 1024] = [0; 1024];
        // Not sure we need the address but it might come in handy someday
        let mut addr_struct: sockaddr_ll = unsafe { mem::zeroed() };
        let len: usize;
        unsafe {
            let sa_ptr = mem::transmute::<*mut sockaddr_ll, *mut sockaddr>(&mut addr_struct);
            let mut sa_in_sz: socklen_t = mem::size_of::<sockaddr_ll>() as socklen_t;
            len = match recvfrom(
                self.fd,
                buf.as_mut_ptr() as *mut c_void,
                buf.len(),
                0,
                sa_ptr,
                &mut sa_in_sz,
            ) {
                -1 => return Err(Error::last_os_error()),
                len => len as usize,
            };
        }
        let ref valid_buf = buf[0..len];

        // In practice AF_PACKET gives us one leading one null byte
        // These are unhelpful so we will skip all leading null bytes
        let filtered: Vec<u8> = valid_buf
            .into_iter()
            .skip_while(|&c| *c == 0)
            .cloned()
            .collect();
        Ok(filtered)
    }
}

fn get_ax25_netdev(name: &str, fd: i32) -> Option<NetDev> {
    let mut req = ifreq::default();
    let if_name = name.to_owned();
    for (d, s) in req.ifr_name.iter_mut().zip(if_name.as_bytes()) {
        *d = *s as c_char;
    }

    if unsafe { ioctl(fd, SIOCGIFHWADDR, &mut req) } == -1 {
        return None;
    }
    if req.data.address_family() as i32 != AF_AX25 {
        return None;
    }
    let hw_addr = match req.data.ax25_address() {
        Some(addr) => addr,
        None => return None,
    };

    if unsafe { ioctl(fd, SIOCGIFINDEX, &mut req) } == -1 {
        return None;
    }
    let ifindex = req.data.ifindex();

    Some(NetDev {
        name: hw_addr,
        ifindex: ifindex,
    })
}

extern "C" {
    fn ioctl(fd: c_int, request: c_ulong, ifreq: *mut ifreq) -> c_int;
}

#[repr(C)]
struct ifreq {
    ifr_name: [c_char; 16],
    data: ifreq_union,
}

impl Default for ifreq {
    fn default() -> ifreq {
        ifreq {
            ifr_name: [0; 16],
            data: ifreq_union::default(),
        }
    }
}

#[repr(C)]
struct ifreq_union {
    data: [u8; 24],
}

impl Default for ifreq_union {
    fn default() -> ifreq_union {
        ifreq_union { data: [0; 24] }
    }
}

impl ifreq_union {
    fn ifindex(&self) -> c_int {
        c_int::from_be(
            ((self.data[0] as c_int) << 24)
                + ((self.data[1] as c_int) << 16)
                + ((self.data[2] as c_int) << 8)
                + (self.data[3] as c_int),
        )
    }

    fn address_family(&self) -> u16 {
        u16::from_be(((self.data[0] as u16) << 8) + (self.data[1] as u16))
    }

    fn ax25_address(&self) -> Option<String> {
        let mut addr_utf8: Vec<u8> = self.data[2..8]
            .iter()
            .rev()
            .map(|&c| c >> 1)
            .skip_while(|&c| c == 0)
            .collect::<Vec<u8>>();
        addr_utf8.reverse();
        let ssid = (self.data[8] >> 1) & 0x0f;
        if let Some(addr) = String::from_utf8(addr_utf8).ok() {
            return Some(format!("{}-{}", addr, ssid));
        }
        None
    }
}
<commit_msg>Fix some more lints in the linux feature<commit_after>use std::fs::File;
use std::io::prelude::*;
use std::io::BufReader;
use std::io::{self, Error};
use std::mem;

use libc::{
    c_char, c_int, c_ulong, c_void, close, recvfrom, sendto, sockaddr, sockaddr_ll, socket,
    socklen_t, AF_AX25, AF_PACKET, SOCK_RAW,
};

const ETH_P_AX25: u16 = 0x0002; // from if_ether.h for SOCK_RAW
const SIOCGIFHWADDR: c_ulong = 0x8927; // from sockios.h in the linux kernel
const SIOCGIFINDEX: c_ulong = 0x8933;

/// An active AX.25 network interface, e.g. "ax0"
pub struct NetDev {
    pub name: String,
    pub ifindex: i32,
}

/// An open socket for sending and receiving AX.25 frames
pub struct Ax25RawSocket {
    fd: i32,
}

impl Ax25RawSocket {
    /// Create a new socket for sending and receiving raw AX.25 frames. This requires root or CAP_NET_ADMIN.
    pub fn new() -> io::Result<Ax25RawSocket> {
        match unsafe { socket(AF_PACKET, SOCK_RAW, ETH_P_AX25.to_be() as i32) } {
            -1 => Err(Error::last_os_error()),
            fd => Ok(Ax25RawSocket { fd }),
        }
    }

    /// Close an open AX.25 socket.
    pub fn close(&mut self) -> io::Result<()> {
        match unsafe { close(self.fd) } {
            -1 => Err(Error::last_os_error()),
            _ => Ok(()),
        }
    }

    /// Find all AX.25 interfaces on the system
    pub fn list_ax25_interfaces(&self) -> io::Result<Vec<NetDev>> {
        let dev_file = File::open("/proc/net/dev")?;
        let mut devices: Vec<NetDev> = Vec::new();
        let reader = BufReader::new(dev_file);
        let lines = reader.lines();
        for l in lines.skip(2) {
            match l {
                Ok(line) => {
                    let device_name = line.trim().split(":").next().unwrap();
                    if let Some(net_dev) = get_ax25_netdev(&device_name, self.fd) {
                        devices.push(net_dev);
                    }
                }
                Err(_) => (),
            }
        }
        Ok(devices)
    }

    /// Send a frame to a particular interface, specified by its index
    pub fn send_frame(&self, frame: &[u8], ifindex: i32) -> io::Result<()> {
        // The Linux interface demands a single null byte prefix on the actual packet
        let mut prefixed_frame: Vec<u8> = Vec::with_capacity(frame.len() + 1);
        prefixed_frame.push(0);
        prefixed_frame.extend(frame.iter().cloned());

        let sa = sockaddr_ll {
            sll_family: AF_PACKET as u16,
            sll_protocol: ETH_P_AX25.to_be(),
            sll_ifindex: ifindex,
            sll_hatype: 0,
            sll_pkttype: 0,
            sll_halen: 0,
            sll_addr: [0; 8],
        };

        match unsafe {
            let sa_ptr = mem::transmute::<*const sockaddr_ll, *const sockaddr>(&sa);
            sendto(
                self.fd,
                prefixed_frame.as_ptr() as *const c_void,
                prefixed_frame.len(),
                0,
                sa_ptr,
                mem::size_of_val(&sa) as socklen_t,
            )
        } {
            -1 => Err(Error::last_os_error()),
            _ => Ok(()),
        }
    }

    /// Block to receive an incoming AX.25 frame from any interface
    pub fn receive_frame(&self) -> io::Result<Vec<u8>> {
        let mut buf: [u8; 1024] = [0; 1024];
        // Not sure we need the address but it might come in handy someday
        let mut addr_struct: sockaddr_ll = unsafe { mem::zeroed() };
        let len: usize;
        unsafe {
            let sa_ptr = mem::transmute::<*mut sockaddr_ll, *mut sockaddr>(&mut addr_struct);
            let mut sa_in_sz: socklen_t = mem::size_of::<sockaddr_ll>() as socklen_t;
            len = match recvfrom(
                self.fd,
                buf.as_mut_ptr() as *mut c_void,
                buf.len(),
                0,
                sa_ptr,
                &mut sa_in_sz,
            ) {
                -1 => return Err(Error::last_os_error()),
                len => len as usize,
            };
        }
        let ref valid_buf = buf[0..len];

        // In practice AF_PACKET gives us one leading one null byte
        // These are unhelpful so we will skip all leading null bytes
        let filtered: Vec<u8> = valid_buf
            .into_iter()
            .skip_while(|&c| *c == 0)
            .cloned()
            .collect();
        Ok(filtered)
    }
}

fn get_ax25_netdev(name: &str, fd: i32) -> Option<NetDev> {
    let mut req = ifreq::default();
    let if_name = name.to_owned();
    for (d, s) in req.ifr_name.iter_mut().zip(if_name.as_bytes()) {
        *d = *s as c_char;
    }

    if unsafe { ioctl(fd, SIOCGIFHWADDR, &mut req) } == -1 {
        return None;
    }
    if req.data.address_family() as i32 != AF_AX25 {
        return None;
    }
    let hw_addr = match req.data.ax25_address() {
        Some(addr) => addr,
        None => return None,
    };

    if unsafe { ioctl(fd, SIOCGIFINDEX, &mut req) } == -1 {
        return None;
    }
    let ifindex = req.data.ifindex();

    Some(NetDev {
        name: hw_addr,
        ifindex,
    })
}

extern "C" {
    fn ioctl(fd: c_int, request: c_ulong, ifreq: *mut ifreq) -> c_int;
}

#[repr(C)]
struct ifreq {
    ifr_name: [c_char; 16],
    data: ifreq_union,
}

impl Default for ifreq {
    fn default() -> ifreq {
        ifreq {
            ifr_name: [0; 16],
            data: ifreq_union::default(),
        }
    }
}

#[repr(C)]
struct ifreq_union {
    data: [u8; 24],
}

impl Default for ifreq_union {
    fn default() -> ifreq_union {
        ifreq_union { data: [0; 24] }
    }
}

impl ifreq_union {
    fn ifindex(&self) -> c_int {
        c_int::from_be(
            ((self.data[0] as c_int) << 24)
                + ((self.data[1] as c_int) << 16)
                + ((self.data[2] as c_int) << 8)
                + (self.data[3] as c_int),
        )
    }

    fn address_family(&self) -> u16 {
        u16::from_be(((self.data[0] as u16) << 8) + (self.data[1] as u16))
    }

    fn ax25_address(&self) -> Option<String> {
        let mut addr_utf8: Vec<u8> = self.data[2..8]
            .iter()
            .rev()
            .map(|&c| c >> 1)
            .skip_while(|&c| c == 0)
            .collect::<Vec<u8>>();
        addr_utf8.reverse();
        let ssid = (self.data[8] >> 1) & 0x0f;
        if let Some(addr) = String::from_utf8(addr_utf8).ok() {
            return Some(format!("{}-{}", addr, ssid));
        }
        None
    }
}
<|endoftext|>


<commit_before>// http://rosettacode.org/wiki/Ludic_numbers

const ARRAY_MAX: usize = 25000;
const LUDIC_MAX: usize = 2100;

fn main() {

    // Variable that will hold all the ludic numbers
    let mut result: Vec<usize> = vec![];

    // Array that will hold the first array with 25.000 numbers starting with number 2
    let mut array = (2..(ARRAY_MAX+2)).collect::<Vec<_>>();

    // Calculate LUDIC_MAX Ludic numbers
    // First Ludic numbers is '1'
    result.push(1);

    for _ in 0..LUDIC_MAX {
        let next_ludic = array[0];
        result.push(next_ludic);
        let mut counter = 0;
        for i in 0..array.len() {
            // modulo operation:
            // ((a % b) + b) % b
            let modulo = ((i as usize % next_ludic) + next_ludic) % next_ludic;

            if modulo != 0 {
                array[counter] = array[i];
                counter += 1;
            }
        }
    }

    print!("First 25: ");
    print_n_ludics(&result, 25);
    println!("");
    print!("Number of Ludics below 1000: ");
    print_num_ludics_upto(&result, 1000);
    println!("");
    print!("Ludics from 2000 to 2005: ");
    print_ludics_from_to(&result, 2000, 2005);
    println!("");
    println!("Triplets below 250: ");
    print_tiples_until(&result, 250);

}

//Function that prints the first 'n' Ludic numbers
fn print_n_ludics(x: &Vec<usize>, n: usize) {
    for i in 0..n {
        print!("{} ", x[i]);
    }
    println!("");
}

//Function that calculates how many Ludic numbers are below 'max_num'
fn print_num_ludics_upto(x: &Vec<usize>, max_num: usize) {
    let mut num: i32 = 0;
    for i in 0..x.len() {
        if x[i] < max_num {
            num = num + 1;
        }
    }
    println!("{}", num);
}

//Function that prints Ludic numbers between to numbers
fn print_ludics_from_to(x: &Vec<usize>, from: usize, to: usize) {
    for i in from - 1..to - 1 {
        print!("{} ", x[i]);
    }
    println!("");
}

//Function that calculates triplets until certain Ludic number
fn print_tiples_until(x: &Vec<usize>, limit: usize) {
    let mut counter: usize = 0;

    while x[counter] < limit {
        let triplet2 = x[counter] + 2;
        let triplet3 = x[counter] + 6;

        let res_triplet2 = x.binary_search(&triplet2);
        let res_triplet3 = x.binary_search(&triplet3);

        if res_triplet2.is_ok() && res_triplet3.is_ok() {
            println!("{} {} {}", x[counter], triplet2, triplet3);
        }
        counter = counter + 1;
    }
}
<commit_msg>modified comment to check if it builds now<commit_after>// http://rosettacode.org/wiki/Ludic_numbers

const ARRAY_MAX: usize = 25000;
const LUDIC_MAX: usize = 2100;

fn main() {

    // Vector that will hold all the ludic numbers
    let mut result: Vec<usize> = vec![];

    // Array that will hold the first array with 25.000 numbers starting with number 2
    let mut array = (2..(ARRAY_MAX+2)).collect::<Vec<_>>();

    // Calculate LUDIC_MAX Ludic numbers
    // First Ludic numbers is '1'
    result.push(1);

    for _ in 0..LUDIC_MAX {
        let next_ludic = array[0];
        result.push(next_ludic);
        let mut counter = 0;
        for i in 0..array.len() {
            // modulo operation:
            // ((a % b) + b) % b
            let modulo = ((i as usize % next_ludic) + next_ludic) % next_ludic;

            if modulo != 0 {
                array[counter] = array[i];
                counter += 1;
            }
        }
    }

    print!("First 25: ");
    print_n_ludics(&result, 25);
    println!("");
    print!("Number of Ludics below 1000: ");
    print_num_ludics_upto(&result, 1000);
    println!("");
    print!("Ludics from 2000 to 2005: ");
    print_ludics_from_to(&result, 2000, 2005);
    println!("");
    println!("Triplets below 250: ");
    print_tiples_until(&result, 250);

}

//Function that prints the first 'n' Ludic numbers
fn print_n_ludics(x: &Vec<usize>, n: usize) {
    for i in 0..n {
        print!("{} ", x[i]);
    }
    println!("");
}

//Function that calculates how many Ludic numbers are below 'max_num'
fn print_num_ludics_upto(x: &Vec<usize>, max_num: usize) {
    let mut num: i32 = 0;
    for i in 0..x.len() {
        if x[i] < max_num {
            num = num + 1;
        }
    }
    println!("{}", num);
}

//Function that prints Ludic numbers between to numbers
fn print_ludics_from_to(x: &Vec<usize>, from: usize, to: usize) {
    for i in from - 1..to - 1 {
        print!("{} ", x[i]);
    }
    println!("");
}

//Function that calculates triplets until certain Ludic number
fn print_tiples_until(x: &Vec<usize>, limit: usize) {
    let mut counter: usize = 0;

    while x[counter] < limit {
        let triplet2 = x[counter] + 2;
        let triplet3 = x[counter] + 6;

        let res_triplet2 = x.binary_search(&triplet2);
        let res_triplet3 = x.binary_search(&triplet3);

        if res_triplet2.is_ok() && res_triplet3.is_ok() {
            println!("{} {} {}", x[counter], triplet2, triplet3);
        }
        counter = counter + 1;
    }
}
<|endoftext|>


<commit_before>use std::ops::DerefMut;

use toml::Value;

use std::collections::BTreeMap;
use std::fmt;
use std::fmt::Display;

use libimagstore::store::Store;
use libimagstore::storeid::StoreIdIterator;
use libimagstore::store::FileLockEntry;
use libimagstore::storeid::StoreId;
use libimagstore::storeid::IntoStoreId;

use module_path::ModuleEntryPath;
use result::Result;
use error::CounterError as CE;
use error::CounterErrorKind as CEK;

pub type CounterName = String;

#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub struct CounterUnit(String);

impl Display for CounterUnit {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "({})", self.0)
    }
}

impl CounterUnit {
    pub fn new<S: Into<String>>(unit: S) -> CounterUnit {
        CounterUnit(unit.into())
    }
}

pub struct Counter<'a> {
    fle: FileLockEntry<'a>,
    unit: Option<CounterUnit>,
}

impl<'a> Counter<'a> {

    pub fn new(store: &Store, name: CounterName, init: i64) -> Result<Counter> {
        use std::ops::DerefMut;

        debug!("Creating new counter: '{}' with value: {}", name, init);
        let fle = {
            let lockentry = store.create(ModuleEntryPath::new(name.clone()).into_storeid());
            if lockentry.is_err() {
                return Err(CE::new(CEK::StoreWriteError, Some(Box::new(lockentry.err().unwrap()))));
            }
            let mut lockentry = lockentry.unwrap();

            {
                let mut entry  = lockentry.deref_mut();
                let mut header = entry.get_header_mut();
                let setres = header.set("counter", Value::Table(BTreeMap::new()));
                if setres.is_err() {
                    return Err(CE::new(CEK::StoreWriteError, Some(Box::new(setres.unwrap_err()))));
                }

                let setres = header.set("counter.name", Value::String(name));
                if setres.is_err() {
                    return Err(CE::new(CEK::StoreWriteError, Some(Box::new(setres.unwrap_err()))));
                }

                let setres = header.set("counter.value", Value::Integer(init));
                if setres.is_err() {
                    return Err(CE::new(CEK::StoreWriteError, Some(Box::new(setres.unwrap_err()))));
                }
            }

            lockentry
        };

        Ok(Counter { fle: fle, unit: None })
    }

    pub fn with_unit(mut self, unit: Option<CounterUnit>) -> Result<Counter<'a>> {
        self.unit = unit;

        if let Some(u) = self.unit.clone() {
            let mut header = self.fle.deref_mut().get_header_mut();
            let setres = header.set("counter.unit", Value::String(u.0));
            if setres.is_err() {
                return Err(CE::new(CEK::StoreWriteError, Some(Box::new(setres.unwrap_err()))));
            }
        };
        Ok(self)
    }

    pub fn inc(&mut self) -> Result<()> {
        let mut header = self.fle.deref_mut().get_header_mut();
        match header.read("counter.value") {
            Ok(Some(Value::Integer(i))) => {
                header.set("counter.value", Value::Integer(i + 1))
                    .map_err(|e| CE::new(CEK::StoreWriteError, Some(Box::new(e))))
                    .map(|_| ())
            },
            Err(e) => Err(CE::new(CEK::StoreReadError, Some(Box::new(e)))),
            _ => Err(CE::new(CEK::StoreReadError, None)),
        }
    }

    pub fn dec(&mut self) -> Result<()> {
        let mut header = self.fle.deref_mut().get_header_mut();
        match header.read("counter.value") {
            Ok(Some(Value::Integer(i))) => {
                header.set("counter.value", Value::Integer(i - 1))
                    .map_err(|e| CE::new(CEK::StoreWriteError, Some(Box::new(e))))
                    .map(|_| ())
            },
            Err(e) => Err(CE::new(CEK::StoreReadError, Some(Box::new(e)))),
            _ => Err(CE::new(CEK::StoreReadError, None)),
        }
    }

    pub fn reset(&mut self) -> Result<()> {
        let mut header = self.fle.deref_mut().get_header_mut();
        header.set("counter.value", Value::Integer(0))
            .map_err(|e| CE::new(CEK::StoreWriteError, Some(Box::new(e))))
            .map(|_| ())
    }

    pub fn set(&mut self, v: i64) -> Result<()> {
        let mut header = self.fle.deref_mut().get_header_mut();
        header.set("counter.value", Value::Integer(v))
            .map_err(|e| CE::new(CEK::StoreWriteError, Some(Box::new(e))))
            .map(|_| ())
    }

    pub fn name(&self) -> Result<CounterName> {
        self.fle.get_header().read("counter.name")
            .map_err(|e| CE::new(CEK::StoreWriteError, Some(Box::new(e))))
            .and_then(|v| {
                match v {
                    Some(Value::String(s)) => Ok(s),
                    _ => Err(CE::new(CEK::HeaderTypeError, None)),
                }
            })
    }

    pub fn value(&self) -> Result<i64> {
        self.fle.get_header().read("counter.value")
            .map_err(|e| CE::new(CEK::StoreWriteError, Some(Box::new(e))))
            .and_then(|v| {
                match v {
                    Some(Value::Integer(i)) => Ok(i),
                    _ => Err(CE::new(CEK::HeaderTypeError, None)),
                }
            })
    }

    pub fn unit(&self) -> Option<CounterUnit> {
        self.fle.get_header().read("counter.unit")
            .ok()
            .and_then(|s| match s {
                Some(Value::String(s)) => Some(CounterUnit::new(s)),
                _ => None,
            })
    }

    pub fn load(name: CounterName, store: &Store) -> Result<Counter> {
        debug!("Loading counter: '{}'", name);
        let id = ModuleEntryPath::new(name).into_storeid();
        Counter::from_storeid(store, id)
    }

    pub fn delete(name: CounterName, store: &Store) -> Result<()> {
        debug!("Deleting counter: '{}'", name);
        store.delete(ModuleEntryPath::new(name).into_storeid())
            .map_err(|e| CE::new(CEK::StoreWriteError, Some(Box::new(e))))
    }

    pub fn all_counters(store: &Store) -> Result<CounterIterator> {
        store.retrieve_for_module("counter")
            .map(|iter| CounterIterator::new(store, iter))
            .map_err(|e| CE::new(CEK::StoreReadError, Some(Box::new(e))))
    }

}

trait FromStoreId {
    fn from_storeid(&Store, StoreId) -> Result<Counter>;
}

impl<'a> FromStoreId for Counter<'a> {

    fn from_storeid(store: &Store, id: StoreId) -> Result<Counter> {
        debug!("Loading counter from storeid: '{:?}'", id);
        match store.retrieve(id) {
            Err(e) => Err(CE::new(CEK::StoreReadError, Some(Box::new(e)))),
            Ok(c)  => {
                let mut counter = Counter { fle: c, unit: None };
                counter.unit = counter.unit();
                Ok(counter)
            }
        }
    }

}

pub struct CounterIterator<'a> {
    store: &'a Store,
    iditer: StoreIdIterator,
}

impl<'a> CounterIterator<'a> {

    pub fn new(store: &'a Store, iditer: StoreIdIterator) -> CounterIterator<'a> {
        CounterIterator {
            store: store,
            iditer: iditer,
        }
    }

}

impl<'a> Iterator for CounterIterator<'a> {
    type Item = Result<Counter<'a>>;

    fn next(&mut self) -> Option<Result<Counter<'a>>> {
        self.iditer
            .next()
            .map(|id| Counter::from_storeid(self.store, id))
    }

}

<commit_msg>better error-handling when reading the unit<commit_after>use std::ops::DerefMut;

use toml::Value;

use std::collections::BTreeMap;
use std::fmt;
use std::fmt::Display;

use libimagstore::store::Store;
use libimagstore::storeid::StoreIdIterator;
use libimagstore::store::FileLockEntry;
use libimagstore::storeid::StoreId;
use libimagstore::storeid::IntoStoreId;

use module_path::ModuleEntryPath;
use result::Result;
use error::CounterError as CE;
use error::CounterErrorKind as CEK;
use error::error::MapErrInto;

pub type CounterName = String;

#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub struct CounterUnit(String);

impl Display for CounterUnit {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "({})", self.0)
    }
}

impl CounterUnit {
    pub fn new<S: Into<String>>(unit: S) -> CounterUnit {
        CounterUnit(unit.into())
    }
}

pub struct Counter<'a> {
    fle: FileLockEntry<'a>,
    unit: Option<CounterUnit>,
}

impl<'a> Counter<'a> {

    pub fn new(store: &Store, name: CounterName, init: i64) -> Result<Counter> {
        use std::ops::DerefMut;

        debug!("Creating new counter: '{}' with value: {}", name, init);
        let fle = {
            let lockentry = store.create(ModuleEntryPath::new(name.clone()).into_storeid());
            if lockentry.is_err() {
                return Err(CE::new(CEK::StoreWriteError, Some(Box::new(lockentry.err().unwrap()))));
            }
            let mut lockentry = lockentry.unwrap();

            {
                let mut entry  = lockentry.deref_mut();
                let mut header = entry.get_header_mut();
                let setres = header.set("counter", Value::Table(BTreeMap::new()));
                if setres.is_err() {
                    return Err(CE::new(CEK::StoreWriteError, Some(Box::new(setres.unwrap_err()))));
                }

                let setres = header.set("counter.name", Value::String(name));
                if setres.is_err() {
                    return Err(CE::new(CEK::StoreWriteError, Some(Box::new(setres.unwrap_err()))));
                }

                let setres = header.set("counter.value", Value::Integer(init));
                if setres.is_err() {
                    return Err(CE::new(CEK::StoreWriteError, Some(Box::new(setres.unwrap_err()))));
                }
            }

            lockentry
        };

        Ok(Counter { fle: fle, unit: None })
    }

    pub fn with_unit(mut self, unit: Option<CounterUnit>) -> Result<Counter<'a>> {
        self.unit = unit;

        if let Some(u) = self.unit.clone() {
            let mut header = self.fle.deref_mut().get_header_mut();
            let setres = header.set("counter.unit", Value::String(u.0));
            if setres.is_err() {
                self.unit = None;
                return Err(CE::new(CEK::StoreWriteError, Some(Box::new(setres.unwrap_err()))));
            }
        };
        Ok(self)
    }

    pub fn inc(&mut self) -> Result<()> {
        let mut header = self.fle.deref_mut().get_header_mut();
        match header.read("counter.value") {
            Ok(Some(Value::Integer(i))) => {
                header.set("counter.value", Value::Integer(i + 1))
                    .map_err(|e| CE::new(CEK::StoreWriteError, Some(Box::new(e))))
                    .map(|_| ())
            },
            Err(e) => Err(CE::new(CEK::StoreReadError, Some(Box::new(e)))),
            _ => Err(CE::new(CEK::StoreReadError, None)),
        }
    }

    pub fn dec(&mut self) -> Result<()> {
        let mut header = self.fle.deref_mut().get_header_mut();
        match header.read("counter.value") {
            Ok(Some(Value::Integer(i))) => {
                header.set("counter.value", Value::Integer(i - 1))
                    .map_err(|e| CE::new(CEK::StoreWriteError, Some(Box::new(e))))
                    .map(|_| ())
            },
            Err(e) => Err(CE::new(CEK::StoreReadError, Some(Box::new(e)))),
            _ => Err(CE::new(CEK::StoreReadError, None)),
        }
    }

    pub fn reset(&mut self) -> Result<()> {
        let mut header = self.fle.deref_mut().get_header_mut();
        header.set("counter.value", Value::Integer(0))
            .map_err(|e| CE::new(CEK::StoreWriteError, Some(Box::new(e))))
            .map(|_| ())
    }

    pub fn set(&mut self, v: i64) -> Result<()> {
        let mut header = self.fle.deref_mut().get_header_mut();
        header.set("counter.value", Value::Integer(v))
            .map_err(|e| CE::new(CEK::StoreWriteError, Some(Box::new(e))))
            .map(|_| ())
    }

    pub fn name(&self) -> Result<CounterName> {
        self.fle.get_header().read("counter.name")
            .map_err(|e| CE::new(CEK::StoreWriteError, Some(Box::new(e))))
            .and_then(|v| {
                match v {
                    Some(Value::String(s)) => Ok(s),
                    _ => Err(CE::new(CEK::HeaderTypeError, None)),
                }
            })
    }

    pub fn value(&self) -> Result<i64> {
        self.fle.get_header().read("counter.value")
            .map_err(|e| CE::new(CEK::StoreWriteError, Some(Box::new(e))))
            .and_then(|v| {
                match v {
                    Some(Value::Integer(i)) => Ok(i),
                    _ => Err(CE::new(CEK::HeaderTypeError, None)),
                }
            })
    }

    pub fn unit(&self) -> Option<&CounterUnit> {
        self.unit.as_ref()
    }

    pub fn read_unit(&self) -> Result<Option<CounterUnit>> {
        self.fle.get_header().read("counter.unit")
            .map_err_into(CEK::StoreReadError)
            .and_then(|s| match s {
                Some(Value::String(s)) => Ok(Some(CounterUnit::new(s))),
                Some(_) => Err(CE::new(CEK::HeaderTypeError, None)),
                None => Ok(None),
            })
    }

    pub fn load(name: CounterName, store: &Store) -> Result<Counter> {
        debug!("Loading counter: '{}'", name);
        let id = ModuleEntryPath::new(name).into_storeid();
        Counter::from_storeid(store, id)
    }

    pub fn delete(name: CounterName, store: &Store) -> Result<()> {
        debug!("Deleting counter: '{}'", name);
        store.delete(ModuleEntryPath::new(name).into_storeid())
            .map_err(|e| CE::new(CEK::StoreWriteError, Some(Box::new(e))))
    }

    pub fn all_counters(store: &Store) -> Result<CounterIterator> {
        store.retrieve_for_module("counter")
            .map(|iter| CounterIterator::new(store, iter))
            .map_err(|e| CE::new(CEK::StoreReadError, Some(Box::new(e))))
    }

}

trait FromStoreId {
    fn from_storeid(&Store, StoreId) -> Result<Counter>;
}

impl<'a> FromStoreId for Counter<'a> {

    fn from_storeid(store: &Store, id: StoreId) -> Result<Counter> {
        debug!("Loading counter from storeid: '{:?}'", id);
        match store.retrieve(id) {
            Err(e) => Err(CE::new(CEK::StoreReadError, Some(Box::new(e)))),
            Ok(c)  => {
                let mut counter = Counter { fle: c, unit: None };
                counter.read_unit()
                    .map_err_into(CEK::StoreReadError)
                    .and_then(|u| {
                        counter.unit = u;
                        Ok(counter)
                    })
            }
        }
    }

}

pub struct CounterIterator<'a> {
    store: &'a Store,
    iditer: StoreIdIterator,
}

impl<'a> CounterIterator<'a> {

    pub fn new(store: &'a Store, iditer: StoreIdIterator) -> CounterIterator<'a> {
        CounterIterator {
            store: store,
            iditer: iditer,
        }
    }

}

impl<'a> Iterator for CounterIterator<'a> {
    type Item = Result<Counter<'a>>;

    fn next(&mut self) -> Option<Result<Counter<'a>>> {
        self.iditer
            .next()
            .map(|id| Counter::from_storeid(self.store, id))
    }

}

<|endoftext|>


<commit_before>extern crate libc;

#[phase(plugin)]
extern crate gl_generator;

extern crate glutin;

use self::glutin::{Event, VirtualKeyCode}; // TODO: why 'self'?

mod gl {
    generate_gl_bindings! {
        api: "gles2",
        profile: "core",
        version: "2.0",
        generator: "static_struct",
    }
}

static mut COLOR_COUNTER: i32 = 0; // TODO

pub struct Visualizer {
    gl: gl::Gles2,
    window: glutin::Window,
    should_close: bool,
}

impl Visualizer {
    pub fn new() -> Visualizer {
        let window = glutin::Window::new().unwrap();
        unsafe {
            window.make_current();
        };
        let gl = gl::Gles2::load_with(|s| window.get_proc_address(s));
        Visualizer {
            gl: gl,
            window: window,
            should_close: false,
        }
    }

    pub fn is_running(&self) -> bool {
        !self.should_close
    }

    fn handle_events(&mut self) {
        let events = self.window.poll_events().collect::<Vec<_>>();
        if !events.is_empty() {
            println!("{}", events);
        }
        for event in events.iter() {
            match *event {
                Event::KeyboardInput(_, _, Some(VirtualKeyCode::Escape))
                    | Event::Closed =>
                {
                    self.should_close = true;
                },
                _ => {},
            }
        }
    }

    fn draw(&self) {
        unsafe {
            match COLOR_COUNTER {
                0 => self.gl.ClearColor(0.3, 0.0, 0.0, 1.0),
                30 => self.gl.ClearColor(0.0, 0.3, 0.0, 1.0),
                60 => self.gl.ClearColor(0.0, 0.0, 0.3, 1.0),
                _ => if COLOR_COUNTER > 90 { COLOR_COUNTER = -1; }
            }
            COLOR_COUNTER += 1;
            assert!(self.gl.GetError() == 0);
            self.gl.Clear(gl::COLOR_BUFFER_BIT);
        }
        self.window.swap_buffers();
    }

    pub fn tick(&mut self) {
        self.handle_events();
        // self.logic();
        self.draw();
        // self.update_time();
    }
}

// vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab:
<commit_msg>Removed 'extern crate libc;'<commit_after>#[phase(plugin)]
extern crate gl_generator;

extern crate glutin;

use self::glutin::{Event, VirtualKeyCode}; // TODO: why 'self'?

mod gl {
    generate_gl_bindings! {
        api: "gles2",
        profile: "core",
        version: "2.0",
        generator: "static_struct",
    }
}

static mut COLOR_COUNTER: i32 = 0; // TODO

pub struct Visualizer {
    gl: gl::Gles2,
    window: glutin::Window,
    should_close: bool,
}

impl Visualizer {
    pub fn new() -> Visualizer {
        let window = glutin::Window::new().unwrap();
        unsafe {
            window.make_current();
        };
        let gl = gl::Gles2::load_with(|s| window.get_proc_address(s));
        Visualizer {
            gl: gl,
            window: window,
            should_close: false,
        }
    }

    pub fn is_running(&self) -> bool {
        !self.should_close
    }

    fn handle_events(&mut self) {
        let events = self.window.poll_events().collect::<Vec<_>>();
        if !events.is_empty() {
            println!("{}", events);
        }
        for event in events.iter() {
            match *event {
                Event::KeyboardInput(_, _, Some(VirtualKeyCode::Escape))
                    | Event::Closed =>
                {
                    self.should_close = true;
                },
                _ => {},
            }
        }
    }

    fn draw(&self) {
        unsafe {
            match COLOR_COUNTER {
                0 => self.gl.ClearColor(0.3, 0.0, 0.0, 1.0),
                30 => self.gl.ClearColor(0.0, 0.3, 0.0, 1.0),
                60 => self.gl.ClearColor(0.0, 0.0, 0.3, 1.0),
                _ => if COLOR_COUNTER > 90 { COLOR_COUNTER = -1; }
            }
            COLOR_COUNTER += 1;
            assert!(self.gl.GetError() == 0);
            self.gl.Clear(gl::COLOR_BUFFER_BIT);
        }
        self.window.swap_buffers();
    }

    pub fn tick(&mut self) {
        self.handle_events();
        // self.logic();
        self.draw();
        // self.update_time();
    }
}

// vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab:
<|endoftext|>


<commit_before>//! Array Virtual Table
//! Port of [carray](http://www.sqlite.org/cgi/src/finfo?name=ext/misc/carray.c) C extension.
use std::default::Default;
use std::os::raw::{c_char, c_int, c_void};
use std::rc::Rc;

use ffi;
use types::{ToSql, ToSqlOutput, Value};
use vtab::{self, declare_vtab, Context, IndexInfo, VTab, VTabCursor, Values};
use {Connection, Error, Result};

// http://sqlite.org/bindptr.html

pub(crate) const ARRAY_TYPE: *const c_char = b"rarray\0" as *const u8 as *const c_char;

pub(crate) unsafe extern "C" fn free_array(p: *mut c_void) {
    let _: Array = Rc::from_raw(p as *const Vec<Value>);
}

pub type Array = Rc<Vec<Value>>;

impl ToSql for Array {
    fn to_sql(&self) -> Result<ToSqlOutput> {
        Ok(ToSqlOutput::Array(self.clone()))
    }
}

/// Register the "rarray" module.
pub fn load_module(conn: &Connection) -> Result<()> {
    let aux: Option<()> = None;
    conn.create_module("rarray", &ARRAY_MODULE, aux)
}

eponymous_module!(
    ARRAY_MODULE,
    ArrayTab,
    (),
    ArrayTabCursor,
    None,
    array_connect,
    array_best_index,
    array_disconnect,
    None,
    array_open,
    array_close,
    array_filter,
    array_next,
    array_eof,
    array_column,
    array_rowid
);

// Column numbers
// const CARRAY_COLUMN_VALUE : c_int = 0;
const CARRAY_COLUMN_POINTER: c_int = 1;

/// An instance of the Array virtual table
#[repr(C)]
struct ArrayTab {
    /// Base class. Must be first
    base: ffi::sqlite3_vtab,
}

impl VTab for ArrayTab {
    type Aux = ();
    type Cursor = ArrayTabCursor;

    unsafe fn connect(db: *mut ffi::sqlite3, _aux: *mut (), _args: &[&[u8]]) -> Result<ArrayTab> {
        let vtab = ArrayTab {
            base: Default::default(),
        };
        try!(declare_vtab(db, "CREATE TABLE x(value,pointer hidden)"));
        Ok(vtab)
    }

    fn best_index(&self, info: &mut IndexInfo) -> Result<()> {
        // Index of the pointer= constraint
        let mut ptr_idx = None;
        for (i, constraint) in info.constraints().enumerate() {
            if !constraint.is_usable() {
                continue;
            }
            if constraint.operator() != vtab::IndexConstraintOp::SQLITE_INDEX_CONSTRAINT_EQ {
                continue;
            }
            match constraint.column() {
                CARRAY_COLUMN_POINTER => {
                    ptr_idx = Some(i);
                }
                _ => {}
            }
        }
        if let Some(ptr_idx) = ptr_idx {
            {
                let mut constraint_usage = info.constraint_usage(ptr_idx);
                constraint_usage.set_argv_index(1);
                constraint_usage.set_omit(true);
            }
            info.set_estimated_cost(1f64);
            info.set_estimated_rows(100);
            info.set_idx_num(1);
        } else {
            info.set_estimated_cost(2_147_483_647f64);
            info.set_estimated_rows(2_147_483_647);
            info.set_idx_num(0);
        }
        Ok(())
    }

    fn open(&self) -> Result<ArrayTabCursor> {
        Ok(ArrayTabCursor::new())
    }
}

/// A cursor for the Array virtual table
#[repr(C)]
struct ArrayTabCursor {
    /// Base class. Must be first
    base: ffi::sqlite3_vtab_cursor,
    /// The rowid
    row_id: i64,
    /// Pointer to the array of values ("pointer")
    ptr: Option<Array>,
}

impl ArrayTabCursor {
    fn new() -> ArrayTabCursor {
        ArrayTabCursor {
            base: Default::default(),
            row_id: 0,
            ptr: None,
        }
    }
    fn len(&self) -> i64 {
        match self.ptr {
            Some(ref a) => a.len() as i64,
            _ => 0,
        }
    }
}
impl VTabCursor for ArrayTabCursor {
    type Table = ArrayTab;

    fn vtab(&self) -> &ArrayTab {
        unsafe { &*(self.base.pVtab as *const ArrayTab) }
    }
    fn filter(&mut self, idx_num: c_int, _idx_str: Option<&str>, args: &Values) -> Result<()> {
        if idx_num > 0 {
            self.ptr = try!(args.get_array(0));
        } else {
            self.ptr = None;
        }
        self.row_id = 1;
        Ok(())
    }
    fn next(&mut self) -> Result<()> {
        self.row_id += 1;
        Ok(())
    }
    fn eof(&self) -> bool {
        self.row_id > self.len()
    }
    fn column(&self, ctx: &mut Context, i: c_int) -> Result<()> {
        match i {
            CARRAY_COLUMN_POINTER => Ok(()),
            _ => {
                if let Some(ref array) = self.ptr {
                    let value = &array[(self.row_id - 1) as usize];
                    ctx.set_result(&value)
                } else {
                    Ok(())
                }
            }
        }
    }
    fn rowid(&self) -> Result<i64> {
        Ok(self.row_id)
    }
}

#[cfg(test)]
mod test {
    use std::rc::Rc;
    use types::Value;
    use vtab::array;
    use Connection;

    #[test]
    #[cfg_attr(rustfmt, rustfmt_skip)]
    fn test_array_module() {
        let db = Connection::open_in_memory().unwrap();
        array::load_module(&db).unwrap();

        let v = vec![1i64, 2, 3, 4];
        let values = v.into_iter().map(|i| Value::from(i)).collect();
        let ptr = Rc::new(values);
        let mut stmt = db.prepare("SELECT value from rarray(?);").unwrap();

        let rows = stmt.query_map(&[&ptr], |row| row.get::<_, i64>(0)).unwrap();
        let mut count = 0;
        for (i, value) in rows.enumerate() {
            assert_eq!(i as i64, value.unwrap()-1);
            count += 1;
        }
        assert_eq!(4, count);
    }
}
<commit_msg>Minalist check that there is no memory leak.<commit_after>//! Array Virtual Table
//! Port of [carray](http://www.sqlite.org/cgi/src/finfo?name=ext/misc/carray.c) C extension.
use std::default::Default;
use std::os::raw::{c_char, c_int, c_void};
use std::rc::Rc;

use ffi;
use types::{ToSql, ToSqlOutput, Value};
use vtab::{self, declare_vtab, Context, IndexInfo, VTab, VTabCursor, Values};
use {Connection, Error, Result};

// http://sqlite.org/bindptr.html

pub(crate) const ARRAY_TYPE: *const c_char = b"rarray\0" as *const u8 as *const c_char;

pub(crate) unsafe extern "C" fn free_array(p: *mut c_void) {
    let _: Array = Rc::from_raw(p as *const Vec<Value>);
}

pub type Array = Rc<Vec<Value>>;

impl ToSql for Array {
    fn to_sql(&self) -> Result<ToSqlOutput> {
        Ok(ToSqlOutput::Array(self.clone()))
    }
}

/// Register the "rarray" module.
pub fn load_module(conn: &Connection) -> Result<()> {
    let aux: Option<()> = None;
    conn.create_module("rarray", &ARRAY_MODULE, aux)
}

eponymous_module!(
    ARRAY_MODULE,
    ArrayTab,
    (),
    ArrayTabCursor,
    None,
    array_connect,
    array_best_index,
    array_disconnect,
    None,
    array_open,
    array_close,
    array_filter,
    array_next,
    array_eof,
    array_column,
    array_rowid
);

// Column numbers
// const CARRAY_COLUMN_VALUE : c_int = 0;
const CARRAY_COLUMN_POINTER: c_int = 1;

/// An instance of the Array virtual table
#[repr(C)]
struct ArrayTab {
    /// Base class. Must be first
    base: ffi::sqlite3_vtab,
}

impl VTab for ArrayTab {
    type Aux = ();
    type Cursor = ArrayTabCursor;

    unsafe fn connect(db: *mut ffi::sqlite3, _aux: *mut (), _args: &[&[u8]]) -> Result<ArrayTab> {
        let vtab = ArrayTab {
            base: Default::default(),
        };
        try!(declare_vtab(db, "CREATE TABLE x(value,pointer hidden)"));
        Ok(vtab)
    }

    fn best_index(&self, info: &mut IndexInfo) -> Result<()> {
        // Index of the pointer= constraint
        let mut ptr_idx = None;
        for (i, constraint) in info.constraints().enumerate() {
            if !constraint.is_usable() {
                continue;
            }
            if constraint.operator() != vtab::IndexConstraintOp::SQLITE_INDEX_CONSTRAINT_EQ {
                continue;
            }
            match constraint.column() {
                CARRAY_COLUMN_POINTER => {
                    ptr_idx = Some(i);
                }
                _ => {}
            }
        }
        if let Some(ptr_idx) = ptr_idx {
            {
                let mut constraint_usage = info.constraint_usage(ptr_idx);
                constraint_usage.set_argv_index(1);
                constraint_usage.set_omit(true);
            }
            info.set_estimated_cost(1f64);
            info.set_estimated_rows(100);
            info.set_idx_num(1);
        } else {
            info.set_estimated_cost(2_147_483_647f64);
            info.set_estimated_rows(2_147_483_647);
            info.set_idx_num(0);
        }
        Ok(())
    }

    fn open(&self) -> Result<ArrayTabCursor> {
        Ok(ArrayTabCursor::new())
    }
}

/// A cursor for the Array virtual table
#[repr(C)]
struct ArrayTabCursor {
    /// Base class. Must be first
    base: ffi::sqlite3_vtab_cursor,
    /// The rowid
    row_id: i64,
    /// Pointer to the array of values ("pointer")
    ptr: Option<Array>,
}

impl ArrayTabCursor {
    fn new() -> ArrayTabCursor {
        ArrayTabCursor {
            base: Default::default(),
            row_id: 0,
            ptr: None,
        }
    }
    fn len(&self) -> i64 {
        match self.ptr {
            Some(ref a) => a.len() as i64,
            _ => 0,
        }
    }
}
impl VTabCursor for ArrayTabCursor {
    type Table = ArrayTab;

    fn vtab(&self) -> &ArrayTab {
        unsafe { &*(self.base.pVtab as *const ArrayTab) }
    }
    fn filter(&mut self, idx_num: c_int, _idx_str: Option<&str>, args: &Values) -> Result<()> {
        if idx_num > 0 {
            self.ptr = try!(args.get_array(0));
        } else {
            self.ptr = None;
        }
        self.row_id = 1;
        Ok(())
    }
    fn next(&mut self) -> Result<()> {
        self.row_id += 1;
        Ok(())
    }
    fn eof(&self) -> bool {
        self.row_id > self.len()
    }
    fn column(&self, ctx: &mut Context, i: c_int) -> Result<()> {
        match i {
            CARRAY_COLUMN_POINTER => Ok(()),
            _ => {
                if let Some(ref array) = self.ptr {
                    let value = &array[(self.row_id - 1) as usize];
                    ctx.set_result(&value)
                } else {
                    Ok(())
                }
            }
        }
    }
    fn rowid(&self) -> Result<i64> {
        Ok(self.row_id)
    }
}

#[cfg(test)]
mod test {
    use std::rc::Rc;
    use types::Value;
    use vtab::array;
    use Connection;

    #[test]
    #[cfg_attr(rustfmt, rustfmt_skip)]
    fn test_array_module() {
        let db = Connection::open_in_memory().unwrap();
        array::load_module(&db).unwrap();

        let v = vec![1i64, 2, 3, 4];
        let values = v.into_iter().map(|i| Value::from(i)).collect();
        let ptr = Rc::new(values);
        let mut stmt = db.prepare("SELECT value from rarray(?);").unwrap();

        let rows = stmt.query_map(&[&ptr], |row| row.get::<_, i64>(0)).unwrap();
        assert_eq!(2, Rc::strong_count(&ptr));
        let mut count = 0;
        for (i, value) in rows.enumerate() {
            assert_eq!(i as i64, value.unwrap()-1);
            count += 1;
        }
        assert_eq!(4, count);
        assert_eq!(1, Rc::strong_count(&ptr));
    }
}
<|endoftext|>