<commit_before>use std::env;
use std::path::PathBuf;
#[cfg(windows)]
use kernel32::GetNativeSystemInfo;

pub fn obtain_groonga_versioned_path() -> PathBuf {
    let base_dir = env::home_dir().unwrap();
    base_dir.join(".groonga").join("versions")
}

pub fn obtain_install_base_path() -> PathBuf {
    let base_dir = env::home_dir().unwrap();
    base_dir.join(".groonga")
}

#[cfg(windows)]
pub fn obtain_arch() -> Option<String> {
    use std::mem;

    // Detect architectures
    const PROCESSOR_ARCHITECTURE_AMD64: u16 = 9;
    const PROCESSOR_ARCHITECTURE_INTEL: u16 = 0;
    let mut sys_info;
    unsafe {
        sys_info = mem::zeroed();
        GetNativeSystemInfo(&mut sys_info);
    }

    let arch = match sys_info.wProcessorArchitecture {
        PROCESSOR_ARCHITECTURE_AMD64 => "x64",
        PROCESSOR_ARCHITECTURE_INTEL => "x86",
        _ => return None,
    };
    Some(arch.to_string())
}

#[cfg(not(windows))]
pub fn obtain_arch() -> Option<String> {
    use libc;
    use std::mem;
    use std::ffi::CStr;

    let mut sys_info;
    let machine = unsafe {
        sys_info = mem::zeroed();
        if libc::uname(&mut sys_info) != 0 {
            return None;
        }

        CStr::from_ptr(sys_info.machine.as_ptr()).to_bytes()
    };
    Some(String::from_utf8_lossy(machine).into_owned())
}

#[cfg(test)]
mod test {
    use super::*;
    use std::env;
    use std::path::PathBuf;

    #[test]
    fn test_obtain_arch() {
        let arch = obtain_arch();
        assert!(arch.is_some());
    }

    #[test]
    fn test_obtain_groonga_versioned_path() {
        let home = env::home_dir().unwrap();
        let _ = env::set_var("HOME", "/home/grnenv");
        let path = obtain_groonga_versioned_path();
        let mut versioned = PathBuf::new();
        versioned.push("/home/grnenv/.groonga/versions");
        assert_eq!(versioned, path);
        let _ = env::set_var("HOME", home);
    }

    #[test]
    fn test_obtain_install_base_path() {
        let home = env::home_dir().unwrap();
        let _ = env::set_var("HOME", "/home/grnenv");
        let path = obtain_install_base_path();
        let mut versioned = PathBuf::new();
        versioned.push("/home/grnenv/.groonga");
        assert_eq!(versioned, path);
        let _ = env::set_var("HOME", home);
    }
}
<commit_msg>util :Use platform specific stub home<commit_after>use std::env;
use std::path::PathBuf;
#[cfg(windows)]
use kernel32::GetNativeSystemInfo;

pub fn obtain_groonga_versioned_path() -> PathBuf {
    let base_dir = env::home_dir().unwrap();
    base_dir.join(".groonga").join("versions")
}

pub fn obtain_install_base_path() -> PathBuf {
    let base_dir = env::home_dir().unwrap();
    base_dir.join(".groonga")
}

#[cfg(windows)]
pub fn obtain_arch() -> Option<String> {
    use std::mem;

    // Detect architectures
    const PROCESSOR_ARCHITECTURE_AMD64: u16 = 9;
    const PROCESSOR_ARCHITECTURE_INTEL: u16 = 0;
    let mut sys_info;
    unsafe {
        sys_info = mem::zeroed();
        GetNativeSystemInfo(&mut sys_info);
    }

    let arch = match sys_info.wProcessorArchitecture {
        PROCESSOR_ARCHITECTURE_AMD64 => "x64",
        PROCESSOR_ARCHITECTURE_INTEL => "x86",
        _ => return None,
    };
    Some(arch.to_string())
}

#[cfg(not(windows))]
pub fn obtain_arch() -> Option<String> {
    use libc;
    use std::mem;
    use std::ffi::CStr;

    let mut sys_info;
    let machine = unsafe {
        sys_info = mem::zeroed();
        if libc::uname(&mut sys_info) != 0 {
            return None;
        }

        CStr::from_ptr(sys_info.machine.as_ptr()).to_bytes()
    };
    Some(String::from_utf8_lossy(machine).into_owned())
}

#[cfg(test)]
mod test {
    use super::*;
    use std::env;
    use std::path::PathBuf;

    #[cfg(target_os = "linux")]
    fn stub_home() -> &'static str {
        "/home/grnenv"
    }
    #[cfg(target_os = "macos")]
    fn stub_home() -> &'static str {
        "/Users/grnenv"
    }
    #[cfg(target_os = "windows")]
    fn stub_home() -> &'static str {
        "C:\\Users\\grnenv"
    }

    #[test]
    fn test_obtain_arch() {
        let arch = obtain_arch();
        assert!(arch.is_some());
    }

    #[test]
    fn test_obtain_groonga_versioned_path() {
        let home = env::home_dir().unwrap();
        let stub_home = stub_home();
        let _ = env::set_var("HOME", stub_home.clone());
        let path = obtain_groonga_versioned_path();
        let versioned = PathBuf::from(stub_home.clone()).join(".groonga").join("versions");
        assert_eq!(versioned, path);
        let _ = env::set_var("HOME", home);
    }

    #[test]
    fn test_obtain_install_base_path() {
        let home = env::home_dir().unwrap();
        let stub_home = stub_home();
        let _ = env::set_var("HOME", stub_home.clone());
        let path = obtain_install_base_path();
        let versioned = PathBuf::from(stub_home.clone()).join(".groonga");
        assert_eq!(versioned, path);
        let _ = env::set_var("HOME", home);
    }
}
<|endoftext|>


<commit_before>//! Pixel iterators for `SharedImageSurface`.
use crate::rect::IRect;
use crate::util::clamp;

use super::shared_surface::SharedImageSurface;
use super::{EdgeMode, Pixel};

/// Iterator over pixels of a `SharedImageSurface`.
#[derive(Debug, Clone, Copy)]
pub struct Pixels<'a> {
    surface: &'a SharedImageSurface,
    bounds: IRect,
    x: u32,
    y: u32,
    offset: isize,
}

/// Iterator over a (potentially out of bounds) rectangle of pixels of a `SharedImageSurface`.
#[derive(Debug, Clone, Copy)]
pub struct PixelRectangle<'a> {
    surface: &'a SharedImageSurface,
    bounds: IRect,
    rectangle: IRect,
    edge_mode: EdgeMode,
    x: i32,
    y: i32,
}

impl<'a> Pixels<'a> {
    /// Creates an iterator over the image surface pixels
    #[inline]
    pub fn new(surface: &'a SharedImageSurface) -> Self {
        let bounds = IRect::from_size(surface.width(), surface.height());

        Self::within(surface, bounds)
    }

    /// Creates an iterator over the image surface pixels, constrained within the given bounds.
    #[inline]
    pub fn within(surface: &'a SharedImageSurface, bounds: IRect) -> Self {
        // Sanity checks.
        assert!(bounds.x0 >= 0);
        assert!(bounds.x0 <= surface.width());
        assert!(bounds.x1 >= bounds.x0);
        assert!(bounds.x1 <= surface.width());
        assert!(bounds.y0 >= 0);
        assert!(bounds.y0 <= surface.height());
        assert!(bounds.y1 >= bounds.y0);
        assert!(bounds.y1 <= surface.height());

        Self {
            surface,
            bounds,
            x: bounds.x0 as u32,
            y: bounds.y0 as u32,
            offset: bounds.y0 as isize * surface.stride() as isize + bounds.x0 as isize * 4,
        }
    }
}

impl<'a> PixelRectangle<'a> {
    /// Creates an iterator over the image surface pixels
    #[inline]
    pub fn new(surface: &'a SharedImageSurface, rectangle: IRect, edge_mode: EdgeMode) -> Self {
        let bounds = IRect::from_size(surface.width(), surface.height());

        Self::within(surface, bounds, rectangle, edge_mode)
    }

    /// Creates an iterator over the image surface pixels, constrained within the given bounds.
    #[inline]
    pub fn within(
        surface: &'a SharedImageSurface,
        bounds: IRect,
        rectangle: IRect,
        edge_mode: EdgeMode,
    ) -> Self {
        // Sanity checks.
        assert!(bounds.x0 >= 0);
        assert!(bounds.x0 <= surface.width());
        assert!(bounds.x1 >= bounds.x0);
        assert!(bounds.x1 <= surface.width());
        assert!(bounds.y0 >= 0);
        assert!(bounds.y0 <= surface.height());
        assert!(bounds.y1 >= bounds.y0);
        assert!(bounds.y1 <= surface.height());

        // Non-None EdgeMode values need at least one pixel available.
        if edge_mode != EdgeMode::None {
            assert!(bounds.x1 > bounds.x0);
            assert!(bounds.y1 > bounds.y0);
        }

        assert!(rectangle.x1 >= rectangle.x0);
        assert!(rectangle.y1 >= rectangle.y0);

        Self {
            surface,
            bounds,
            rectangle,
            edge_mode,
            x: rectangle.x0,
            y: rectangle.y0,
        }
    }
}

impl<'a> Iterator for Pixels<'a> {
    type Item = (u32, u32, Pixel);

    #[inline]
    fn next(&mut self) -> Option<Self::Item> {
        // This means we hit the end on the last iteration.
        if self.x == self.bounds.x1 as u32 || self.y == self.bounds.y1 as u32 {
            return None;
        }

        let rv = Some((
            self.x,
            self.y,
            self.surface.get_pixel_by_offset(self.offset),
        ));

        if self.x + 1 == self.bounds.x1 as u32 {
            self.x = self.bounds.x0 as u32;
            self.y += 1;
            self.offset += self.surface.stride() - (self.bounds.width() - 1) as isize * 4;
        } else {
            self.x += 1;
            self.offset += 4;
        }

        rv
    }
}

impl<'a> Iterator for PixelRectangle<'a> {
    type Item = (i32, i32, Pixel);

    #[inline(always)]
    fn next(&mut self) -> Option<Self::Item> {
        // This means we hit the end on the last iteration.
        if self.x == self.rectangle.x1 || self.y == self.rectangle.y1 {
            return None;
        }

        let rv = {
            let get_pixel = |x, y| {
                if !self.bounds.contains(x, y) {
                    match self.edge_mode {
                        EdgeMode::None => Pixel {
                            r: 0,
                            g: 0,
                            b: 0,
                            a: 0,
                        },
                        EdgeMode::Duplicate => {
                            let x = clamp(x, self.bounds.x0, self.bounds.x1 - 1);
                            let y = clamp(y, self.bounds.y0, self.bounds.y1 - 1);
                            self.surface.get_pixel(x as u32, y as u32)
                        }
                        EdgeMode::Wrap => {
                            let wrap = |mut x, v| {
                                while x < 0 {
                                    x += v;
                                }
                                x % v
                            };

                            let x = self.bounds.x0 + wrap(x - self.bounds.x0, self.bounds.width());
                            let y = self.bounds.y0 + wrap(y - self.bounds.y0, self.bounds.height());
                            self.surface.get_pixel(x as u32, y as u32)
                        }
                    }
                } else {
                    self.surface.get_pixel(x as u32, y as u32)
                }
            };

            Some((self.x, self.y, get_pixel(self.x, self.y)))
        };

        if self.x + 1 == self.rectangle.x1 {
            self.x = self.rectangle.x0;
            self.y += 1;
        } else {
            self.x += 1;
        }

        rv
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::surface_utils::shared_surface::SurfaceType;

    #[test]
    fn pixels_count() {
        const WIDTH: i32 = 32;
        const HEIGHT: i32 = 64;

        let surface = SharedImageSurface::wrap(
            cairo::ImageSurface::create(cairo::Format::ARgb32, WIDTH, HEIGHT).unwrap(),
            SurfaceType::SRgb,
        )
        .unwrap();

        // Full image.
        assert_eq!(Pixels::new(&surface).count(), (WIDTH * HEIGHT) as usize);

        // 1-wide column.
        let bounds = IRect::from_size(1, HEIGHT);
        assert_eq!(Pixels::within(&surface, bounds).count(), HEIGHT as usize);

        // 1-tall row.
        let bounds = IRect::from_size(WIDTH, 1);
        assert_eq!(Pixels::within(&surface, bounds).count(), WIDTH as usize);

        // 1×1.
        let bounds = IRect::from_size(1, 1);
        assert_eq!(Pixels::within(&surface, bounds).count(), 1);

        // Nothing (x0 == x1).
        let bounds = IRect::from_size(0, HEIGHT);
        assert_eq!(Pixels::within(&surface, bounds).count(), 0);

        // Nothing (y0 == y1).
        let bounds = IRect::from_size(WIDTH, 0);
        assert_eq!(Pixels::within(&surface, bounds).count(), 0);

        // Nothing (x0 == x1, y0 == y1).
        let bounds = IRect::new(0, 0, 0, 0);
        assert_eq!(Pixels::within(&surface, bounds).count(), 0);
    }

    #[test]
    fn pixel_rectangle() {
        const WIDTH: i32 = 32;
        const HEIGHT: i32 = 64;

        let surface = SharedImageSurface::wrap(
            cairo::ImageSurface::create(cairo::Format::ARgb32, WIDTH, HEIGHT).unwrap(),
            SurfaceType::SRgb,
        )
        .unwrap();

        let rect_bounds = IRect::new(-8, -8, 8, 8);
        assert_eq!(
            PixelRectangle::new(&surface, rect_bounds, EdgeMode::None).count(),
            (16 * 16) as usize
        );
    }
}
<commit_msg>surface_utils: shorten iterator test code<commit_after>//! Pixel iterators for `SharedImageSurface`.
use crate::rect::IRect;
use crate::util::clamp;

use super::shared_surface::SharedImageSurface;
use super::{EdgeMode, Pixel};

/// Iterator over pixels of a `SharedImageSurface`.
#[derive(Debug, Clone, Copy)]
pub struct Pixels<'a> {
    surface: &'a SharedImageSurface,
    bounds: IRect,
    x: u32,
    y: u32,
    offset: isize,
}

/// Iterator over a (potentially out of bounds) rectangle of pixels of a `SharedImageSurface`.
#[derive(Debug, Clone, Copy)]
pub struct PixelRectangle<'a> {
    surface: &'a SharedImageSurface,
    bounds: IRect,
    rectangle: IRect,
    edge_mode: EdgeMode,
    x: i32,
    y: i32,
}

impl<'a> Pixels<'a> {
    /// Creates an iterator over the image surface pixels
    #[inline]
    pub fn new(surface: &'a SharedImageSurface) -> Self {
        let bounds = IRect::from_size(surface.width(), surface.height());

        Self::within(surface, bounds)
    }

    /// Creates an iterator over the image surface pixels, constrained within the given bounds.
    #[inline]
    pub fn within(surface: &'a SharedImageSurface, bounds: IRect) -> Self {
        // Sanity checks.
        assert!(bounds.x0 >= 0);
        assert!(bounds.x0 <= surface.width());
        assert!(bounds.x1 >= bounds.x0);
        assert!(bounds.x1 <= surface.width());
        assert!(bounds.y0 >= 0);
        assert!(bounds.y0 <= surface.height());
        assert!(bounds.y1 >= bounds.y0);
        assert!(bounds.y1 <= surface.height());

        Self {
            surface,
            bounds,
            x: bounds.x0 as u32,
            y: bounds.y0 as u32,
            offset: bounds.y0 as isize * surface.stride() as isize + bounds.x0 as isize * 4,
        }
    }
}

impl<'a> PixelRectangle<'a> {
    /// Creates an iterator over the image surface pixels
    #[inline]
    pub fn new(surface: &'a SharedImageSurface, rectangle: IRect, edge_mode: EdgeMode) -> Self {
        let bounds = IRect::from_size(surface.width(), surface.height());

        Self::within(surface, bounds, rectangle, edge_mode)
    }

    /// Creates an iterator over the image surface pixels, constrained within the given bounds.
    #[inline]
    pub fn within(
        surface: &'a SharedImageSurface,
        bounds: IRect,
        rectangle: IRect,
        edge_mode: EdgeMode,
    ) -> Self {
        // Sanity checks.
        assert!(bounds.x0 >= 0);
        assert!(bounds.x0 <= surface.width());
        assert!(bounds.x1 >= bounds.x0);
        assert!(bounds.x1 <= surface.width());
        assert!(bounds.y0 >= 0);
        assert!(bounds.y0 <= surface.height());
        assert!(bounds.y1 >= bounds.y0);
        assert!(bounds.y1 <= surface.height());

        // Non-None EdgeMode values need at least one pixel available.
        if edge_mode != EdgeMode::None {
            assert!(bounds.x1 > bounds.x0);
            assert!(bounds.y1 > bounds.y0);
        }

        assert!(rectangle.x1 >= rectangle.x0);
        assert!(rectangle.y1 >= rectangle.y0);

        Self {
            surface,
            bounds,
            rectangle,
            edge_mode,
            x: rectangle.x0,
            y: rectangle.y0,
        }
    }
}

impl<'a> Iterator for Pixels<'a> {
    type Item = (u32, u32, Pixel);

    #[inline]
    fn next(&mut self) -> Option<Self::Item> {
        // This means we hit the end on the last iteration.
        if self.x == self.bounds.x1 as u32 || self.y == self.bounds.y1 as u32 {
            return None;
        }

        let rv = Some((
            self.x,
            self.y,
            self.surface.get_pixel_by_offset(self.offset),
        ));

        if self.x + 1 == self.bounds.x1 as u32 {
            self.x = self.bounds.x0 as u32;
            self.y += 1;
            self.offset += self.surface.stride() - (self.bounds.width() - 1) as isize * 4;
        } else {
            self.x += 1;
            self.offset += 4;
        }

        rv
    }
}

impl<'a> Iterator for PixelRectangle<'a> {
    type Item = (i32, i32, Pixel);

    #[inline(always)]
    fn next(&mut self) -> Option<Self::Item> {
        // This means we hit the end on the last iteration.
        if self.x == self.rectangle.x1 || self.y == self.rectangle.y1 {
            return None;
        }

        let rv = {
            let get_pixel = |x, y| {
                if !self.bounds.contains(x, y) {
                    match self.edge_mode {
                        EdgeMode::None => Pixel {
                            r: 0,
                            g: 0,
                            b: 0,
                            a: 0,
                        },
                        EdgeMode::Duplicate => {
                            let x = clamp(x, self.bounds.x0, self.bounds.x1 - 1);
                            let y = clamp(y, self.bounds.y0, self.bounds.y1 - 1);
                            self.surface.get_pixel(x as u32, y as u32)
                        }
                        EdgeMode::Wrap => {
                            let wrap = |mut x, v| {
                                while x < 0 {
                                    x += v;
                                }
                                x % v
                            };

                            let x = self.bounds.x0 + wrap(x - self.bounds.x0, self.bounds.width());
                            let y = self.bounds.y0 + wrap(y - self.bounds.y0, self.bounds.height());
                            self.surface.get_pixel(x as u32, y as u32)
                        }
                    }
                } else {
                    self.surface.get_pixel(x as u32, y as u32)
                }
            };

            Some((self.x, self.y, get_pixel(self.x, self.y)))
        };

        if self.x + 1 == self.rectangle.x1 {
            self.x = self.rectangle.x0;
            self.y += 1;
        } else {
            self.x += 1;
        }

        rv
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::surface_utils::shared_surface::SurfaceType;

    #[test]
    fn pixels_count() {
        const WIDTH: i32 = 32;
        const HEIGHT: i32 = 64;

        let surface = SharedImageSurface::empty(WIDTH, HEIGHT, SurfaceType::SRgb).unwrap();

        // Full image.
        assert_eq!(Pixels::new(&surface).count(), (WIDTH * HEIGHT) as usize);

        // 1-wide column.
        let bounds = IRect::from_size(1, HEIGHT);
        assert_eq!(Pixels::within(&surface, bounds).count(), HEIGHT as usize);

        // 1-tall row.
        let bounds = IRect::from_size(WIDTH, 1);
        assert_eq!(Pixels::within(&surface, bounds).count(), WIDTH as usize);

        // 1×1.
        let bounds = IRect::from_size(1, 1);
        assert_eq!(Pixels::within(&surface, bounds).count(), 1);

        // Nothing (x0 == x1).
        let bounds = IRect::from_size(0, HEIGHT);
        assert_eq!(Pixels::within(&surface, bounds).count(), 0);

        // Nothing (y0 == y1).
        let bounds = IRect::from_size(WIDTH, 0);
        assert_eq!(Pixels::within(&surface, bounds).count(), 0);

        // Nothing (x0 == x1, y0 == y1).
        let bounds = IRect::new(0, 0, 0, 0);
        assert_eq!(Pixels::within(&surface, bounds).count(), 0);
    }

    #[test]
    fn pixel_rectangle() {
        const WIDTH: i32 = 32;
        const HEIGHT: i32 = 64;

        let surface = SharedImageSurface::empty(WIDTH, HEIGHT, SurfaceType::SRgb).unwrap();

        let rect_bounds = IRect::new(-8, -8, 8, 8);
        assert_eq!(
            PixelRectangle::new(&surface, rect_bounds, EdgeMode::None).count(),
            (16 * 16) as usize
        );
    }
}
<|endoftext|>


<commit_before>
pub(crate) struct CartesianProductIterator<'a, I1, I2> {
  v1: &'a Vec<I1>,
  v2: &'a Vec<I2>,
  v1_idx: usize,
  v2_idx: usize
}

impl <'a, I1, I2> CartesianProductIterator<'a, I1, I2> {
  pub fn new(v1: &'a Vec<I1>, v2: &'a Vec<I2>) -> Self {
    CartesianProductIterator { v1, v2, v1_idx: 0, v2_idx: 0 }
  }
}

impl <'a, I1: 'a, I2> Iterator for CartesianProductIterator<'a, I1, I2> {
  type Item = (&'a I1, &'a I2);

  fn next(&mut self) -> Option<Self::Item> {
    if self.v1.is_empty() || self.v2.is_empty() {
      None
    } else if self.v1_idx == self.v1.len() && self.v2_idx == self.v2.len() {
      None
    } else if self.v2_idx == self.v2.len() {
      self.v2_idx = 1;
      self.v1_idx += 1;
      if self.v1_idx == self.v1.len() {
        None
      } else {
        Some((self.v1.get(self.v1_idx).unwrap(), self.v2.get(self.v2_idx - 1).unwrap()))
      }
    } else {
      self.v2_idx += 1;
      Some((self.v1.get(self.v1_idx).unwrap(), self.v2.get(self.v2_idx - 1).unwrap()))
    }
  }
}

#[cfg(test)]
mod tests {
  use expectest::prelude::*;
  use super::CartesianProductIterator;

  #[test]
  fn cartesian_product_iterator_empty_array_tests() {
    expect!(CartesianProductIterator::new(&Vec::<usize>::new(), &Vec::<usize>::new()).next()).to(be_none());
    expect!(CartesianProductIterator::new(&vec![1], &Vec::<usize>::new()).next()).to(be_none());
    expect!(CartesianProductIterator::new(&Vec::<usize>::new(), &vec![1]).next()).to(be_none());
  }

  #[test]
  fn cartesian_product_iterator_tests() {
    let vec1 = vec![1];
    let vec2 = vec![2];
    let mut i1 = CartesianProductIterator::new(&vec1, &vec2);
    expect!(i1.next()).to(be_some().value((&1, &2)));
    expect!(i1.next()).to(be_none());

    let vec3 = vec![1, 2];
    let mut i2 = CartesianProductIterator::new(&vec3, &vec2);
    expect!(i2.next()).to(be_some().value((&1, &2)));
    expect!(i2.next()).to(be_some().value((&2, &2)));
    expect!(i2.next()).to(be_none());

    let mut i3 = CartesianProductIterator::new(&vec1, &vec3);
    expect!(i3.next()).to(be_some().value((&1, &1)));
    expect!(i3.next()).to(be_some().value((&1, &2)));
    expect!(i3.next()).to(be_none());

    let vec4 = vec![2, 3];
    let mut i4 = CartesianProductIterator::new(&vec3, &vec4);
    expect!(i4.next()).to(be_some().value((&1, &2)));
    expect!(i4.next()).to(be_some().value((&1, &3)));
    expect!(i4.next()).to(be_some().value((&2, &2)));
    expect!(i4.next()).to(be_some().value((&2, &3)));
    expect!(i4.next()).to(be_none());
  }
}
<commit_msg>chore: fix clippy violation<commit_after>
pub(crate) struct CartesianProductIterator<'a, I1, I2> {
  v1: &'a Vec<I1>,
  v2: &'a Vec<I2>,
  v1_idx: usize,
  v2_idx: usize
}

impl <'a, I1, I2> CartesianProductIterator<'a, I1, I2> {
  pub fn new(v1: &'a Vec<I1>, v2: &'a Vec<I2>) -> Self {
    CartesianProductIterator { v1, v2, v1_idx: 0, v2_idx: 0 }
  }
}

impl <'a, I1: 'a, I2> Iterator for CartesianProductIterator<'a, I1, I2> {
  type Item = (&'a I1, &'a I2);

  fn next(&mut self) -> Option<Self::Item> {
    if self.v1.is_empty() || self.v2.is_empty() || self.v1_idx == self.v1.len() &&
      self.v2_idx == self.v2.len() {
      None
    } else if self.v2_idx == self.v2.len() {
      self.v2_idx = 1;
      self.v1_idx += 1;
      if self.v1_idx == self.v1.len() {
        None
      } else {
        Some((self.v1.get(self.v1_idx).unwrap(), self.v2.get(self.v2_idx - 1).unwrap()))
      }
    } else {
      self.v2_idx += 1;
      Some((self.v1.get(self.v1_idx).unwrap(), self.v2.get(self.v2_idx - 1).unwrap()))
    }
  }
}

#[cfg(test)]
mod tests {
  use expectest::prelude::*;
  use super::CartesianProductIterator;

  #[test]
  fn cartesian_product_iterator_empty_array_tests() {
    expect!(CartesianProductIterator::new(&Vec::<usize>::new(), &Vec::<usize>::new()).next()).to(be_none());
    expect!(CartesianProductIterator::new(&vec![1], &Vec::<usize>::new()).next()).to(be_none());
    expect!(CartesianProductIterator::new(&Vec::<usize>::new(), &vec![1]).next()).to(be_none());
  }

  #[test]
  fn cartesian_product_iterator_tests() {
    let vec1 = vec![1];
    let vec2 = vec![2];
    let mut i1 = CartesianProductIterator::new(&vec1, &vec2);
    expect!(i1.next()).to(be_some().value((&1, &2)));
    expect!(i1.next()).to(be_none());

    let vec3 = vec![1, 2];
    let mut i2 = CartesianProductIterator::new(&vec3, &vec2);
    expect!(i2.next()).to(be_some().value((&1, &2)));
    expect!(i2.next()).to(be_some().value((&2, &2)));
    expect!(i2.next()).to(be_none());

    let mut i3 = CartesianProductIterator::new(&vec1, &vec3);
    expect!(i3.next()).to(be_some().value((&1, &1)));
    expect!(i3.next()).to(be_some().value((&1, &2)));
    expect!(i3.next()).to(be_none());

    let vec4 = vec![2, 3];
    let mut i4 = CartesianProductIterator::new(&vec3, &vec4);
    expect!(i4.next()).to(be_some().value((&1, &2)));
    expect!(i4.next()).to(be_some().value((&1, &3)));
    expect!(i4.next()).to(be_some().value((&2, &2)));
    expect!(i4.next()).to(be_some().value((&2, &3)));
    expect!(i4.next()).to(be_none());
  }
}
<|endoftext|>


<commit_before>/// This modules specifies the input to rust-analyzer. In some sense, this is
/// **the** most important module, because all other fancy stuff is strickly
/// derived from this input.
use std::sync::Arc;

use rustc_hash::{FxHashMap};
use relative_path::RelativePathBuf;
use ra_syntax::SmolStr;
use salsa;

/// `FileId` is an integer which uniquely identifies a file. File paths are
/// messy and system-dependent, so most of the code should work directly with
/// `FileId`, without inspecting the path. The mapping between `FileId` and path
/// and `SourceRoot` is constant. File rename is represented as a pair of
/// deletion/creation.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct FileId(pub u32);

/// Files are grouped into source roots. A source root is a directory on the
/// file systems which is watched for changes. Typically it corresponds to a
/// Cargo package. Source roots *might* be nested: in this case, file belongs to
/// the nearest enclosing source root. Path to files are always relative to a
/// source root, and analyzer does not know the root path of the source root at
/// all. So, a file from one source root can't refere a file in another source
/// root by path.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct SourceRootId(pub u32);

#[derive(Default, Clone, Debug, PartialEq, Eq)]
pub struct SourceRoot {
    pub files: FxHashMap<RelativePathBuf, FileId>,
}

/// `CrateGraph` is a bit of information which turns a set of text files into a
/// number of Rust crates. Each Crate is the `FileId` of it's root module, the
/// set of cfg flags (not yet implemented) and the set of dependencies. Note
/// that, due to cfg's, there might be several crates for a single `FileId`! As
/// in the rust-lang proper, a crate does not have a name. Instead, names are
/// specified on dependency edges. That is, a crate might be known under
/// different names in different dependant crates.
///
/// Note that `CrateGraph` is build-system agnostic: it's a concept of the Rust
/// langauge proper, not a concept of the build system. In practice, we get
/// `CrateGraph` by lowering `cargo metadata` output.
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct CrateGraph {
    arena: FxHashMap<CrateId, CrateData>,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct CrateId(pub u32);

#[derive(Debug, Clone, PartialEq, Eq)]
struct CrateData {
    file_id: FileId,
    dependencies: Vec<Dependency>,
}

impl CrateData {
    fn new(file_id: FileId) -> CrateData {
        CrateData {
            file_id,
            dependencies: Vec::new(),
        }
    }

    fn add_dep(&mut self, name: SmolStr, crate_id: CrateId) {
        self.dependencies.push(Dependency { name, crate_id })
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Dependency {
    pub crate_id: CrateId,
    pub name: SmolStr,
}

impl Dependency {
    pub fn crate_id(&self) -> CrateId {
        self.crate_id
    }
}

impl CrateGraph {
    pub fn add_crate_root(&mut self, file_id: FileId) -> CrateId {
        let crate_id = CrateId(self.arena.len() as u32);
        let prev = self.arena.insert(crate_id, CrateData::new(file_id));
        assert!(prev.is_none());
        crate_id
    }
    // FIXME: check that we don't have cycles here.
    // Just a simple depth first search from `to` should work,
    // the graph is small.
    pub fn add_dep(&mut self, from: CrateId, name: SmolStr, to: CrateId) {
        self.arena.get_mut(&from).unwrap().add_dep(name, to)
    }
    pub fn crate_root(&self, crate_id: CrateId) -> FileId {
        self.arena[&crate_id].file_id
    }
    pub fn crate_id_for_crate_root(&self, file_id: FileId) -> Option<CrateId> {
        let (&crate_id, _) = self
            .arena
            .iter()
            .find(|(_crate_id, data)| data.file_id == file_id)?;
        Some(crate_id)
    }
    pub fn dependencies<'a>(
        &'a self,
        crate_id: CrateId,
    ) -> impl Iterator<Item = &'a Dependency> + 'a {
        self.arena[&crate_id].dependencies.iter()
    }
}

salsa::query_group! {
    pub trait FilesDatabase: salsa::Database {
        /// Text of the file.
        fn file_text(file_id: FileId) -> Arc<String> {
            type FileTextQuery;
            storage input;
        }
        /// Path to a file, relative to the root of its source root.
        fn file_relative_path(file_id: FileId) -> RelativePathBuf {
            type FileRelativePathQuery;
            storage input;
        }
        /// Source root of the file.
        fn file_source_root(file_id: FileId) -> SourceRootId {
            type FileSourceRootQuery;
            storage input;
        }
        /// Contents of the source root.
        fn source_root(id: SourceRootId) -> Arc<SourceRoot> {
            type SourceRootQuery;
            storage input;
        }
        /// The set of "local" (that is, from the current workspace) roots.
        /// Files in local roots are assumed to change frequently.
        fn local_roots() -> Arc<Vec<SourceRootId>> {
            type LocalRootsQuery;
            storage input;
        }
        /// The set of roots for crates.io libraries.
        /// Files in libraries are assumed to never change.
        fn library_roots() -> Arc<Vec<SourceRootId>> {
            type LibraryRootsQuery;
            storage input;
        }
        /// The crate graph.
        fn crate_graph() -> Arc<CrateGraph> {
            type CrateGraphQuery;
            storage input;
        }
    }
}
<commit_msg>extend comment<commit_after>/// This modules specifies the input to rust-analyzer. In some sense, this is
/// **the** most important module, because all other fancy stuff is strictly
/// derived from this input.
///
/// Note that neither this module, nor any other part of the analyzer's core do
/// actual IO. See `vfs` and `project_model` in `ra_lsp_server` crate for how
/// actual IO is done and lowered to input.
use std::sync::Arc;

use rustc_hash::{FxHashMap};
use relative_path::RelativePathBuf;
use ra_syntax::SmolStr;
use salsa;

/// `FileId` is an integer which uniquely identifies a file. File paths are
/// messy and system-dependent, so most of the code should work directly with
/// `FileId`, without inspecting the path. The mapping between `FileId` and path
/// and `SourceRoot` is constant. File rename is represented as a pair of
/// deletion/creation.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct FileId(pub u32);

/// Files are grouped into source roots. A source root is a directory on the
/// file systems which is watched for changes. Typically it corresponds to a
/// Cargo package. Source roots *might* be nested: in this case, file belongs to
/// the nearest enclosing source root. Path to files are always relative to a
/// source root, and analyzer does not know the root path of the source root at
/// all. So, a file from one source root can't refere a file in another source
/// root by path.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct SourceRootId(pub u32);

#[derive(Default, Clone, Debug, PartialEq, Eq)]
pub struct SourceRoot {
    pub files: FxHashMap<RelativePathBuf, FileId>,
}

/// `CrateGraph` is a bit of information which turns a set of text files into a
/// number of Rust crates. Each Crate is the `FileId` of it's root module, the
/// set of cfg flags (not yet implemented) and the set of dependencies. Note
/// that, due to cfg's, there might be several crates for a single `FileId`! As
/// in the rust-lang proper, a crate does not have a name. Instead, names are
/// specified on dependency edges. That is, a crate might be known under
/// different names in different dependant crates.
///
/// Note that `CrateGraph` is build-system agnostic: it's a concept of the Rust
/// langauge proper, not a concept of the build system. In practice, we get
/// `CrateGraph` by lowering `cargo metadata` output.
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct CrateGraph {
    arena: FxHashMap<CrateId, CrateData>,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct CrateId(pub u32);

#[derive(Debug, Clone, PartialEq, Eq)]
struct CrateData {
    file_id: FileId,
    dependencies: Vec<Dependency>,
}

impl CrateData {
    fn new(file_id: FileId) -> CrateData {
        CrateData {
            file_id,
            dependencies: Vec::new(),
        }
    }

    fn add_dep(&mut self, name: SmolStr, crate_id: CrateId) {
        self.dependencies.push(Dependency { name, crate_id })
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Dependency {
    pub crate_id: CrateId,
    pub name: SmolStr,
}

impl Dependency {
    pub fn crate_id(&self) -> CrateId {
        self.crate_id
    }
}

impl CrateGraph {
    pub fn add_crate_root(&mut self, file_id: FileId) -> CrateId {
        let crate_id = CrateId(self.arena.len() as u32);
        let prev = self.arena.insert(crate_id, CrateData::new(file_id));
        assert!(prev.is_none());
        crate_id
    }
    // FIXME: check that we don't have cycles here.
    // Just a simple depth first search from `to` should work,
    // the graph is small.
    pub fn add_dep(&mut self, from: CrateId, name: SmolStr, to: CrateId) {
        self.arena.get_mut(&from).unwrap().add_dep(name, to)
    }
    pub fn crate_root(&self, crate_id: CrateId) -> FileId {
        self.arena[&crate_id].file_id
    }
    pub fn crate_id_for_crate_root(&self, file_id: FileId) -> Option<CrateId> {
        let (&crate_id, _) = self
            .arena
            .iter()
            .find(|(_crate_id, data)| data.file_id == file_id)?;
        Some(crate_id)
    }
    pub fn dependencies<'a>(
        &'a self,
        crate_id: CrateId,
    ) -> impl Iterator<Item = &'a Dependency> + 'a {
        self.arena[&crate_id].dependencies.iter()
    }
}

salsa::query_group! {
    pub trait FilesDatabase: salsa::Database {
        /// Text of the file.
        fn file_text(file_id: FileId) -> Arc<String> {
            type FileTextQuery;
            storage input;
        }
        /// Path to a file, relative to the root of its source root.
        fn file_relative_path(file_id: FileId) -> RelativePathBuf {
            type FileRelativePathQuery;
            storage input;
        }
        /// Source root of the file.
        fn file_source_root(file_id: FileId) -> SourceRootId {
            type FileSourceRootQuery;
            storage input;
        }
        /// Contents of the source root.
        fn source_root(id: SourceRootId) -> Arc<SourceRoot> {
            type SourceRootQuery;
            storage input;
        }
        /// The set of "local" (that is, from the current workspace) roots.
        /// Files in local roots are assumed to change frequently.
        fn local_roots() -> Arc<Vec<SourceRootId>> {
            type LocalRootsQuery;
            storage input;
        }
        /// The set of roots for crates.io libraries.
        /// Files in libraries are assumed to never change.
        fn library_roots() -> Arc<Vec<SourceRootId>> {
            type LibraryRootsQuery;
            storage input;
        }
        /// The crate graph.
        fn crate_graph() -> Arc<CrateGraph> {
            type CrateGraphQuery;
            storage input;
        }
    }
}
<|endoftext|>


<commit_before>extern crate rustc_serialize;

use std::cmp::Ordering;
use std::collections::HashMap;
use std::hash::Hash;
use std::io::prelude::*;
use std::fs::File;

use self::rustc_serialize::json;

use ngrams::ngrams;

pub type StringCountPair = (String, usize);
pub struct Profile {
    pub ngram_ranks: HashMap<String, usize>,
}

impl Profile {
    pub fn build_from_text(text: &str) -> Profile {
        let mut ngram_counts = HashMap::new();
        for n in 1..6 {
            for ngram in ngrams(text, n) {
                *ngram_counts.entry(ngram).or_insert(0usize) += 1;
            }
        }

        let mut ngrams_and_counts = vec_from_hashmap(&ngram_counts);
        ngrams_and_counts.sort_by(cmp_counts_reverse);

        let mut ngram_ranks = HashMap::new();
        for (index, item) in ngrams_and_counts.iter().enumerate() {
            ngram_ranks.insert((*item).clone().0, index);
        }

        Profile { ngram_ranks: ngram_ranks }
    }

    pub fn load_from_file(path: &str) -> Profile {
        let mut f = File::open(path).unwrap();
        let mut encoded_profile = String::new();
        f.read_to_string(&mut encoded_profile);
        let ngram_ranks = json::decode(&encoded_profile).unwrap();
        Profile { ngram_ranks: ngram_ranks }
    }

    pub fn save_to_file(&self, path: &str) {
        let encoded_profile = json::encode(&self.ngram_ranks).unwrap();
        let mut f = File::create(path).unwrap();
        f.write_all(encoded_profile.as_bytes()).unwrap();
    }

    pub fn compare(&self, other: &Profile) -> usize {
        let max_difference = other.ngram_ranks.len();
        let mut difference = 0;
        for (ngram, index) in self.ngram_ranks.iter() {
            difference += match other.ngram_ranks.get(ngram) {
                Some(other_index) => get_difference(*index, *other_index),
                None => max_difference,
            }
        }
        difference
    }
}

// useful utils

fn get_difference(a: usize, b: usize) -> usize {
    if a > b { a - b } else { b - a }
}

fn vec_from_hashmap<K, V> (hashmap: &HashMap<K, V>) -> Vec<(K, V)>
         where K: Eq + Hash + Clone, V: Clone {
    let mut vec: Vec<(K, V)> = Vec::new();
    for (key, value) in hashmap.iter() {
        let item = ((*key).clone(), (*value).clone());
        vec.push(item);
    }
    vec
}

fn cmp_counts_reverse(a: &StringCountPair, b: &StringCountPair) -> Ordering {
    b.1.cmp(&a.1)
}
<commit_msg>Limit the profile size to top 300 grams<commit_after>extern crate rustc_serialize;

use std::cmp::min;
use std::cmp::Ordering;
use std::collections::HashMap;
use std::hash::Hash;
use std::io::prelude::*;
use std::fs::File;

use self::rustc_serialize::json;

use ngrams::ngrams;

pub type StringCountPair = (String, usize);
pub struct Profile {
    pub ngram_ranks: HashMap<String, usize>,
}

impl Profile {
    pub fn build_from_text(text: &str) -> Profile {
        let mut ngram_counts = HashMap::new();
        for n in 1..6 {
            for ngram in ngrams(text, n) {
                *ngram_counts.entry(ngram).or_insert(0usize) += 1;
            }
        }

        let mut ngrams_and_counts = vec_from_hashmap(&ngram_counts);
        ngrams_and_counts.sort_by(cmp_counts_reverse);

        let mut ngram_ranks = HashMap::new();
        let size = min(ngrams_and_counts.len(), 300);
        for (index, item) in ngrams_and_counts[..size].iter().enumerate() {
            ngram_ranks.insert((*item).clone().0, index);
        }

        Profile { ngram_ranks: ngram_ranks }
    }

    pub fn load_from_file(path: &str) -> Profile {
        let mut f = File::open(path).unwrap();
        let mut encoded_profile = String::new();
        f.read_to_string(&mut encoded_profile);
        let ngram_ranks = json::decode(&encoded_profile).unwrap();
        Profile { ngram_ranks: ngram_ranks }
    }

    pub fn save_to_file(&self, path: &str) {
        let encoded_profile = json::encode(&self.ngram_ranks).unwrap();
        let mut f = File::create(path).unwrap();
        f.write_all(encoded_profile.as_bytes()).unwrap();
    }

    pub fn compare(&self, other: &Profile) -> usize {
        let max_difference = other.ngram_ranks.len();
        let mut difference = 0;
        for (ngram, index) in self.ngram_ranks.iter() {
            difference += match other.ngram_ranks.get(ngram) {
                Some(other_index) => get_difference(*index, *other_index),
                None => max_difference,
            }
        }
        difference
    }
}

// useful utils

fn get_difference(a: usize, b: usize) -> usize {
    if a > b { a - b } else { b - a }
}

fn vec_from_hashmap<K, V> (hashmap: &HashMap<K, V>) -> Vec<(K, V)>
         where K: Eq + Hash + Clone, V: Clone {
    let mut vec: Vec<(K, V)> = Vec::new();
    for (key, value) in hashmap.iter() {
        let item = ((*key).clone(), (*value).clone());
        vec.push(item);
    }
    vec
}

fn cmp_counts_reverse(a: &StringCountPair, b: &StringCountPair) -> Ordering {
    b.1.cmp(&a.1)
}
<|endoftext|>


<commit_before>use std::collections::HashMap;

use toml::Value;

use dep::{DeclaredDep, DepKind};
use graph::DepGraph;
use error::{CliErrorKind, CliResult};
use config::Config;
use util;

#[derive(Debug)]
pub struct Project<'c, 'o>
    where 'o: 'c
{
    cfg: &'c Config<'o>,
}

impl<'c, 'o> Project<'c, 'o> {
    pub fn with_config(cfg: &'c Config<'o>) -> CliResult<Self> {
        Ok(Project { cfg: cfg })
    }

    pub fn graph(mut self) -> CliResult<DepGraph<'c, 'o>> {
        let root_deps = try!(self.parse_root_deps());
        let mut dg = try!(self.parse_lock_file());
        self.set_resolved_kind(&root_deps, &mut dg);
        if !self.cfg.include_vers {
            Project::show_version_on_duplicates(&mut dg);
        }
        Ok(dg)
    }

    /// Forces the version to be displayed on dependencies
    /// that have the same name (but a different version) as another dependency.
    fn show_version_on_duplicates(dg: &mut DepGraph<'c, 'o>) {
        // Build a list of node IDs, sorted by the name of the dependency on that node.
        let dep_ids_sorted_by_name = {
            let mut deps = dg.nodes.iter().enumerate().collect::<Vec<_>>();
            deps.sort_by_key(|dep| &*dep.1.name);
            deps.iter().map(|dep| dep.0).collect::<Vec<_>>()
        };

        for (i, &dep_id_i) in dep_ids_sorted_by_name.iter().enumerate().take(dep_ids_sorted_by_name.len() - 1) {
            // Find other nodes with the same name
            // We need to iterate one more time after the last node to handle the break.
            for (j, &dep) in dep_ids_sorted_by_name.iter().enumerate().take(dep_ids_sorted_by_name.len() + 1).skip(i + 1) {
                // Stop once we've found a node with a different name
                // or reached the end of the list.
                if j >= dep_ids_sorted_by_name.len() ||
                   dg.nodes[dep_id_i].name != dg.nodes[dep].name {
                    // If there are at least two nodes with the same name
                    if j >= i + 2 {
                        // Set force_write_ver = true on all nodes
                        // from dep_ids_sorted_by_name[i] to dep_ids_sorted_by_name[j - 1].
                        // Remember: j is pointing on the next node with a *different* name!
                        // Remember also: i..j includes i but excludes j.
						for &dep_id_k in dep_ids_sorted_by_name.iter().take(j).skip(i) {
                            dg.nodes[dep_id_k].force_write_ver = true;
                        }
                    }

                    break;
                }
            }
        }
    }

    /// Sets the kind of dependency on each dependency
    /// based on how the dependencies are declared in the manifest.
    fn set_resolved_kind(&mut self, declared_deps: &[DeclaredDep], dg: &mut DepGraph<'c, 'o>) {
        let declared_deps_map =
            declared_deps.iter().map(|dd| (&*dd.name, dd.kind)).collect::<HashMap<_, _>>();

        dg.nodes[0].is_build = true;

        dg.edges.sort(); // make sure to process edges from the root node first
        for ed in dg.edges.iter() {
            if ed.0 == 0 {
                // If this is an edge from the root node,
                // set the kind based on how the dependency is declared in the manifest file.
                if let Some(kind) = declared_deps_map.get(&*dg.nodes[ed.1].name) {
                    match *kind {
                        DepKind::Build => dg.nodes[ed.1].is_build = true,
                        DepKind::Dev => dg.nodes[ed.1].is_dev = true,
                        DepKind::Optional => dg.nodes[ed.1].is_optional = true,
                        _ => (),
                    }
                }
            } else {
                // If this is an edge from a dependency node, propagate the kind.
                // This is a set of flags because a dependency can appear several times in the graph,
                // and the kind of dependency may vary based on the path to that dependency.
                // The flags start at false, and once they become true, they stay true.
                // ResolvedDep::kind() will pick a kind based on their priority.
                if dg.nodes[ed.0].is_build {
                    dg.nodes[ed.1].is_build = true;
                }

                if dg.nodes[ed.0].is_dev {
                    dg.nodes[ed.1].is_dev = true;
                }

                if dg.nodes[ed.0].is_optional {
                    dg.nodes[ed.1].is_optional = true;
                }
            }
        }

        // Remove the nodes that the user doesn't want.
        // Start at 1 to keep the root node.
        for id in (1..dg.nodes.len()).rev() {
            let kind = dg.nodes[id].kind();
            if (kind == DepKind::Build && !self.cfg.build_deps) ||
               (kind == DepKind::Dev && !self.cfg.dev_deps) ||
               (kind == DepKind::Optional && !self.cfg.optional_deps) {
                dg.remove(id);
            }
        }

        dg.remove_orphans();
    }

    /// Builds a graph of the resolved dependencies declared in the lock file.
    fn parse_lock_file(&mut self) -> CliResult<DepGraph<'c, 'o>> {
        fn parse_package<'c, 'o>(dg: &mut DepGraph<'c, 'o>, pkg: &Value) {
            let name = pkg.lookup("name")
                          .expect("no 'name' field in Cargo.lock [package] or [root] table")
                          .as_str()
                          .expect("'name' field of [package] or [root] table in Cargo.lock was not a \
                                   valid string")
                          .to_owned();
            let ver = pkg.lookup("version")
                         .expect("no 'version' field in Cargo.lock [package] or [root] table")
                         .as_str()
                         .expect("'version' field of [package] or [root] table in Cargo.lock was not a \
                                  valid string")
                         .to_owned();

            let id = dg.find_or_add(&*name, &*ver);

            if let Some(&Value::Array(ref deps)) = pkg.lookup("dependencies") {
                for dep in deps {
                    let dep_vec = dep.as_str().unwrap_or("").split(' ').collect::<Vec<_>>();
                    let dep_string = dep_vec[0].to_owned();
                    let ver = dep_vec[1];
                    dg.add_child(id, &*dep_string, ver);
                }
            }
        }

        let lock_path = try!(util::find_manifest_file(self.cfg.lock_file));
        let lock_toml = try!(util::toml_from_file(lock_path));

        let mut dg = DepGraph::new(self.cfg);

        if let Some(root) = lock_toml.get("root") {
            parse_package(&mut dg, root);
        } else {
            return Err(From::from(CliErrorKind::TomlTableRoot));
        }

        if let Some(&Value::Array(ref packages)) = lock_toml.get("package") {
            for pkg in packages {
                parse_package(&mut dg, pkg);
            }
        }

        debugln!("return=parse_lock_file; self={:#?}", self);
        Ok(dg)
    }

    /// Builds a list of the dependencies declared in the manifest file.
    pub fn parse_root_deps(&mut self) -> CliResult<Vec<DeclaredDep>> {
        debugln!("executing; parse_root_deps;");
        let manifest_path = try!(util::find_manifest_file(self.cfg.manifest_file));
        let manifest_toml = try!(util::toml_from_file(manifest_path));

        let mut declared_deps = vec![];
        let mut v = vec![];

        if let Some(table) = manifest_toml.get("dependencies") {
            if let Some(table) = table.as_table() {
                for (name, dep_table) in table.into_iter() {
                    if let Some(&Value::Boolean(true)) = dep_table.lookup("optional") {
                        declared_deps.push(DeclaredDep::with_kind(name.clone(), DepKind::Optional));
                    } else {
                        declared_deps.push(DeclaredDep::with_kind(name.clone(), DepKind::Build));
                    }
                    v.push(name.clone());
                }
            }
        }

        if let Some(table) = manifest_toml.get("dev-dependencies") {
            if let Some(table) = table.as_table() {
                for (name, _) in table.into_iter() {
                    declared_deps.push(DeclaredDep::with_kind(name.clone(), DepKind::Dev));
                    v.push(name.clone());
                }
            }
        }

        debugln!("return=parse_root_deps; self={:#?}", self);
        debugln!("return=parse_root_deps; declared_deps={:#?}", declared_deps);
        Ok(declared_deps)
    }
}
<commit_msg>Add missing debug output<commit_after>use std::collections::HashMap;

use toml::Value;

use dep::{DeclaredDep, DepKind};
use graph::DepGraph;
use error::{CliErrorKind, CliResult};
use config::Config;
use util;

#[derive(Debug)]
pub struct Project<'c, 'o>
    where 'o: 'c
{
    cfg: &'c Config<'o>,
}

impl<'c, 'o> Project<'c, 'o> {
    pub fn with_config(cfg: &'c Config<'o>) -> CliResult<Self> {
        Ok(Project { cfg: cfg })
    }

    pub fn graph(mut self) -> CliResult<DepGraph<'c, 'o>> {
        let root_deps = try!(self.parse_root_deps());
        let mut dg = try!(self.parse_lock_file());
        self.set_resolved_kind(&root_deps, &mut dg);
        if !self.cfg.include_vers {
            Project::show_version_on_duplicates(&mut dg);
        }
        Ok(dg)
    }

    /// Forces the version to be displayed on dependencies
    /// that have the same name (but a different version) as another dependency.
    fn show_version_on_duplicates(dg: &mut DepGraph<'c, 'o>) {
        // Build a list of node IDs, sorted by the name of the dependency on that node.
        let dep_ids_sorted_by_name = {
            let mut deps = dg.nodes.iter().enumerate().collect::<Vec<_>>();
            deps.sort_by_key(|dep| &*dep.1.name);
            deps.iter().map(|dep| dep.0).collect::<Vec<_>>()
        };

        for (i, &dep_id_i) in dep_ids_sorted_by_name.iter().enumerate().take(dep_ids_sorted_by_name.len() - 1) {
            // Find other nodes with the same name
            // We need to iterate one more time after the last node to handle the break.
            for (j, &dep) in dep_ids_sorted_by_name.iter().enumerate().take(dep_ids_sorted_by_name.len() + 1).skip(i + 1) {
                // Stop once we've found a node with a different name
                // or reached the end of the list.
                if j >= dep_ids_sorted_by_name.len() ||
                   dg.nodes[dep_id_i].name != dg.nodes[dep].name {
                    // If there are at least two nodes with the same name
                    if j >= i + 2 {
                        // Set force_write_ver = true on all nodes
                        // from dep_ids_sorted_by_name[i] to dep_ids_sorted_by_name[j - 1].
                        // Remember: j is pointing on the next node with a *different* name!
                        // Remember also: i..j includes i but excludes j.
						for &dep_id_k in dep_ids_sorted_by_name.iter().take(j).skip(i) {
                            dg.nodes[dep_id_k].force_write_ver = true;
                        }
                    }

                    break;
                }
            }
        }
    }

    /// Sets the kind of dependency on each dependency
    /// based on how the dependencies are declared in the manifest.
    fn set_resolved_kind(&mut self, declared_deps: &[DeclaredDep], dg: &mut DepGraph<'c, 'o>) {
        let declared_deps_map =
            declared_deps.iter().map(|dd| (&*dd.name, dd.kind)).collect::<HashMap<_, _>>();

        dg.nodes[0].is_build = true;

        dg.edges.sort(); // make sure to process edges from the root node first
        for ed in dg.edges.iter() {
            if ed.0 == 0 {
                // If this is an edge from the root node,
                // set the kind based on how the dependency is declared in the manifest file.
                if let Some(kind) = declared_deps_map.get(&*dg.nodes[ed.1].name) {
                    match *kind {
                        DepKind::Build => dg.nodes[ed.1].is_build = true,
                        DepKind::Dev => dg.nodes[ed.1].is_dev = true,
                        DepKind::Optional => dg.nodes[ed.1].is_optional = true,
                        _ => (),
                    }
                }
            } else {
                // If this is an edge from a dependency node, propagate the kind.
                // This is a set of flags because a dependency can appear several times in the graph,
                // and the kind of dependency may vary based on the path to that dependency.
                // The flags start at false, and once they become true, they stay true.
                // ResolvedDep::kind() will pick a kind based on their priority.
                if dg.nodes[ed.0].is_build {
                    dg.nodes[ed.1].is_build = true;
                }

                if dg.nodes[ed.0].is_dev {
                    dg.nodes[ed.1].is_dev = true;
                }

                if dg.nodes[ed.0].is_optional {
                    dg.nodes[ed.1].is_optional = true;
                }
            }
        }

        // Remove the nodes that the user doesn't want.
        // Start at 1 to keep the root node.
        for id in (1..dg.nodes.len()).rev() {
            let kind = dg.nodes[id].kind();
            if (kind == DepKind::Build && !self.cfg.build_deps) ||
               (kind == DepKind::Dev && !self.cfg.dev_deps) ||
               (kind == DepKind::Optional && !self.cfg.optional_deps) {
                dg.remove(id);
            }
        }

        dg.remove_orphans();
    }

    /// Builds a graph of the resolved dependencies declared in the lock file.
    fn parse_lock_file(&mut self) -> CliResult<DepGraph<'c, 'o>> {
        fn parse_package<'c, 'o>(dg: &mut DepGraph<'c, 'o>, pkg: &Value) {
            let name = pkg.lookup("name")
                          .expect("no 'name' field in Cargo.lock [package] or [root] table")
                          .as_str()
                          .expect("'name' field of [package] or [root] table in Cargo.lock was not a \
                                   valid string")
                          .to_owned();
            let ver = pkg.lookup("version")
                         .expect("no 'version' field in Cargo.lock [package] or [root] table")
                         .as_str()
                         .expect("'version' field of [package] or [root] table in Cargo.lock was not a \
                                  valid string")
                         .to_owned();

            let id = dg.find_or_add(&*name, &*ver);

            if let Some(&Value::Array(ref deps)) = pkg.lookup("dependencies") {
                for dep in deps {
                    let dep_vec = dep.as_str().unwrap_or("").split(' ').collect::<Vec<_>>();
                    let dep_string = dep_vec[0].to_owned();
                    let ver = dep_vec[1];
                    dg.add_child(id, &*dep_string, ver);
                }
            }
        }

        let lock_path = try!(util::find_manifest_file(self.cfg.lock_file));
        let lock_toml = try!(util::toml_from_file(lock_path));

        let mut dg = DepGraph::new(self.cfg);

        if let Some(root) = lock_toml.get("root") {
            parse_package(&mut dg, root);
        } else {
            return Err(From::from(CliErrorKind::TomlTableRoot));
        }

        if let Some(&Value::Array(ref packages)) = lock_toml.get("package") {
            for pkg in packages {
                parse_package(&mut dg, pkg);
            }
        }

        debugln!("return=parse_lock_file; self={:#?}", self);
        debugln!("return=parse_lock_file; dg={:#?}", dg);
        Ok(dg)
    }

    /// Builds a list of the dependencies declared in the manifest file.
    pub fn parse_root_deps(&mut self) -> CliResult<Vec<DeclaredDep>> {
        debugln!("executing; parse_root_deps;");
        let manifest_path = try!(util::find_manifest_file(self.cfg.manifest_file));
        let manifest_toml = try!(util::toml_from_file(manifest_path));

        let mut declared_deps = vec![];
        let mut v = vec![];

        if let Some(table) = manifest_toml.get("dependencies") {
            if let Some(table) = table.as_table() {
                for (name, dep_table) in table.into_iter() {
                    if let Some(&Value::Boolean(true)) = dep_table.lookup("optional") {
                        declared_deps.push(DeclaredDep::with_kind(name.clone(), DepKind::Optional));
                    } else {
                        declared_deps.push(DeclaredDep::with_kind(name.clone(), DepKind::Build));
                    }
                    v.push(name.clone());
                }
            }
        }

        if let Some(table) = manifest_toml.get("dev-dependencies") {
            if let Some(table) = table.as_table() {
                for (name, _) in table.into_iter() {
                    declared_deps.push(DeclaredDep::with_kind(name.clone(), DepKind::Dev));
                    v.push(name.clone());
                }
            }
        }

        debugln!("return=parse_root_deps; self={:#?}", self);
        debugln!("return=parse_root_deps; declared_deps={:#?}", declared_deps);
        Ok(declared_deps)
    }
}
<|endoftext|>


<commit_before>#![no_std]

#[macro_use]
extern crate array_macro;

/// Enum map constructor.
///
/// This macro allows to create a new enum map in a type safe way. It takes
/// a list of `,` separated pairs separated by `=>`. Left side is `|`
/// separated list of enum keys, or `_` to match all unmatched enum keys,
/// while right side is a value.
///
/// # Examples
///
/// ```
/// # extern crate enum_map;
/// use enum_map::{enum_map, Enum};
///
/// #[derive(Enum)]
/// enum Example {
///     A,
///     B,
///     C,
///     D,
/// }
///
/// fn main() {
///     let enum_map = enum_map! {
///         Example::A | Example::B => 1,
///         Example::C => 2,
///         _ => 3,
///     };
///     assert_eq!(enum_map[Example::A], 1);
///     assert_eq!(enum_map[Example::B], 1);
///     assert_eq!(enum_map[Example::C], 2);
///     assert_eq!(enum_map[Example::D], 3);
/// }
/// ```
#[macro_export]
macro_rules! enum_map {
    {$($t:tt)*} => {
        $crate::from_fn(|k| match k { $($t)* })
    };
}

mod enum_map_impls;
mod internal;
mod iter;
mod serde;

pub use internal::Enum;
pub use iter::{IntoIter, Iter, IterMut, Values, ValuesMut};

/// An enum mapping.
///
/// This internally uses an array which stores a value for each possible
/// enum value. To work, it requires implementation of internal (private,
/// although public due to macro limitations) trait which allows extracting
/// information about an enum, which can be automatically generated using
/// `#[derive(EnumMap)]` macro.
///
/// Additionally, `bool` and `u8` automatically derives from `EnumMap`. While
/// `u8` is not technically an enum, it's convenient to consider it like one.
/// In particular, [reverse-complement in benchmark game] could be using `u8`
/// as an enum.
///
/// # Examples
///
/// ```
/// # extern crate enum_map;
/// use enum_map::{enum_map, Enum, EnumMap};
///
/// #[derive(Enum)]
/// enum Example {
///     A,
///     B,
///     C,
/// }
///
/// fn main() {
///     let mut map = EnumMap::new();
///     // new initializes map with default values
///     assert_eq!(map[Example::A], 0);
///     map[Example::A] = 3;
///     assert_eq!(map[Example::A], 3);
/// }
/// ```
///
/// [reverse-complement in benchmark game]:
///     http://benchmarksgame.alioth.debian.org/u64q/program.php?test=revcomp&lang=rust&id=2
pub struct EnumMap<K: Enum<V>, V> {
    array: K::Array,
}

impl<K: Enum<V>, V: Default> EnumMap<K, V> {
    /// Creates an enum map with default values.
    ///
    /// # Examples
    ///
    /// ```
    /// # extern crate enum_map;
    /// use enum_map::{Enum, EnumMap};
    ///
    /// #[derive(Enum)]
    /// enum Example {
    ///     A,
    /// }
    ///
    /// fn main() {
    ///     let enum_map = EnumMap::<_, i32>::new();
    ///     assert_eq!(enum_map[Example::A], 0);
    /// }
    /// ```
    #[inline]
    pub fn new() -> Self {
        EnumMap::default()
    }
}

impl<K: Enum<V>, V> EnumMap<K, V> {
    /// Returns an iterator over enum map.
    #[inline]
    pub fn iter(&self) -> Iter<K, V> {
        self.into_iter()
    }

    /// Returns a mutable iterator over enum map.
    #[inline]
    pub fn iter_mut(&mut self) -> IterMut<K, V> {
        self.into_iter()
    }

    /// Returns number of elements in enum map.
    #[inline]
    pub fn len(&self) -> usize {
        self.as_slice().len()
    }

    /// Returns whether the enum variant set is empty.
    ///
    /// This isn't particularly useful, as there is no real reason to use
    /// enum map for enums without variants. However, it is provided for
    /// consistency with data structures providing len method (and I will
    /// admit, to avoid clippy warnings).
    ///
    /// # Examples
    ///
    /// ```
    /// extern crate enum_map;
    ///
    /// use enum_map::{Enum, EnumMap};
    ///
    /// #[derive(Enum)]
    /// enum Void {}
    ///
    /// #[derive(Enum)]
    /// enum SingleVariant {
    ///     Variant,
    /// }
    ///
    /// fn main() {
    ///     assert!(EnumMap::<Void, ()>::new().is_empty());
    ///     assert!(!EnumMap::<SingleVariant, ()>::new().is_empty());
    /// }
    #[inline]
    pub fn is_empty(&self) -> bool {
        self.as_slice().is_empty()
    }

    /// Swaps two indexes.
    ///
    /// # Examples
    ///
    /// ```
    /// # extern crate enum_map;
    /// use enum_map::enum_map;
    ///
    /// fn main() {
    ///     let mut map = enum_map! { false => 0, true => 1 };
    ///     map.swap(false, true);
    ///     assert_eq!(map[false], 1);
    ///     assert_eq!(map[true], 0);
    /// }
    /// ```
    #[inline]
    pub fn swap(&mut self, a: K, b: K) {
        self.as_mut_slice().swap(a.to_usize(), b.to_usize())
    }

    /// Converts an enum map to a slice representing values.
    #[inline]
    pub fn as_slice(&self) -> &[V] {
        K::slice(&self.array)
    }

    /// Converts a mutable enum map to a mutable slice representing values.
    #[inline]
    pub fn as_mut_slice(&mut self) -> &mut [V] {
        K::slice_mut(&mut self.array)
    }

    /// Returns a raw pointer to the enum map's slice.
    ///
    /// The caller must ensure that the slice outlives the pointer this
    /// function returns, or else it will end up pointing to garbage.
    ///
    /// # Examples
    ///
    /// ```
    /// #[macro_use]
    /// extern crate enum_map;
    ///
    /// use enum_map::EnumMap;
    ///
    /// fn main() {
    ///     let map = enum_map! { 5 => 42, _ => 0 };
    ///     assert_eq!(unsafe { *map.as_ptr().offset(5) }, 42);
    /// }
    /// ```
    #[inline]
    pub fn as_ptr(&self) -> *const V {
        self.as_slice().as_ptr()
    }

    /// Returns an unsafe mutable pointer to the enum map's slice.
    ///
    /// The caller must ensure that the slice outlives the pointer this
    /// function returns, or else it will end up pointing to garbage.
    ///
    /// # Examples
    ///
    /// ```
    /// #[macro_use]
    /// extern crate enum_map;
    ///
    /// use enum_map::EnumMap;
    ///
    /// fn main() {
    ///     let mut map = enum_map! { _ => 0 };
    ///     unsafe {
    ///         *map.as_mut_ptr().offset(11) = 23
    ///     };
    ///     assert_eq!(map[11], 23);
    /// }
    /// ```
    #[inline]
    pub fn as_mut_ptr(&mut self) -> *mut V {
        self.as_mut_slice().as_mut_ptr()
    }
}

impl<F: FnMut(K) -> V, K: Enum<V>, V> From<F> for EnumMap<K, V> {
    #[inline]
    fn from(f: F) -> Self {
        EnumMap {
            array: K::from_function(f),
        }
    }
}

pub fn from_fn<K, V>(f: impl FnMut(K) -> V) -> EnumMap<K, V>
where
    K: Enum<V>,
{
    f.into()
}
<commit_msg>Use Rust 2018's use instead of extern crate<commit_after>#![no_std]

#[macro_use]
extern crate array_macro;

/// Enum map constructor.
///
/// This macro allows to create a new enum map in a type safe way. It takes
/// a list of `,` separated pairs separated by `=>`. Left side is `|`
/// separated list of enum keys, or `_` to match all unmatched enum keys,
/// while right side is a value.
///
/// # Examples
///
/// ```
/// # extern crate enum_map;
/// use enum_map::{enum_map, Enum};
///
/// #[derive(Enum)]
/// enum Example {
///     A,
///     B,
///     C,
///     D,
/// }
///
/// fn main() {
///     let enum_map = enum_map! {
///         Example::A | Example::B => 1,
///         Example::C => 2,
///         _ => 3,
///     };
///     assert_eq!(enum_map[Example::A], 1);
///     assert_eq!(enum_map[Example::B], 1);
///     assert_eq!(enum_map[Example::C], 2);
///     assert_eq!(enum_map[Example::D], 3);
/// }
/// ```
#[macro_export]
macro_rules! enum_map {
    {$($t:tt)*} => {
        $crate::from_fn(|k| match k { $($t)* })
    };
}

mod enum_map_impls;
mod internal;
mod iter;
mod serde;

pub use internal::Enum;
pub use iter::{IntoIter, Iter, IterMut, Values, ValuesMut};

/// An enum mapping.
///
/// This internally uses an array which stores a value for each possible
/// enum value. To work, it requires implementation of internal (private,
/// although public due to macro limitations) trait which allows extracting
/// information about an enum, which can be automatically generated using
/// `#[derive(EnumMap)]` macro.
///
/// Additionally, `bool` and `u8` automatically derives from `EnumMap`. While
/// `u8` is not technically an enum, it's convenient to consider it like one.
/// In particular, [reverse-complement in benchmark game] could be using `u8`
/// as an enum.
///
/// # Examples
///
/// ```
/// # extern crate enum_map;
/// use enum_map::{enum_map, Enum, EnumMap};
///
/// #[derive(Enum)]
/// enum Example {
///     A,
///     B,
///     C,
/// }
///
/// fn main() {
///     let mut map = EnumMap::new();
///     // new initializes map with default values
///     assert_eq!(map[Example::A], 0);
///     map[Example::A] = 3;
///     assert_eq!(map[Example::A], 3);
/// }
/// ```
///
/// [reverse-complement in benchmark game]:
///     http://benchmarksgame.alioth.debian.org/u64q/program.php?test=revcomp&lang=rust&id=2
pub struct EnumMap<K: Enum<V>, V> {
    array: K::Array,
}

impl<K: Enum<V>, V: Default> EnumMap<K, V> {
    /// Creates an enum map with default values.
    ///
    /// # Examples
    ///
    /// ```
    /// # extern crate enum_map;
    /// use enum_map::{Enum, EnumMap};
    ///
    /// #[derive(Enum)]
    /// enum Example {
    ///     A,
    /// }
    ///
    /// fn main() {
    ///     let enum_map = EnumMap::<_, i32>::new();
    ///     assert_eq!(enum_map[Example::A], 0);
    /// }
    /// ```
    #[inline]
    pub fn new() -> Self {
        EnumMap::default()
    }
}

impl<K: Enum<V>, V> EnumMap<K, V> {
    /// Returns an iterator over enum map.
    #[inline]
    pub fn iter(&self) -> Iter<K, V> {
        self.into_iter()
    }

    /// Returns a mutable iterator over enum map.
    #[inline]
    pub fn iter_mut(&mut self) -> IterMut<K, V> {
        self.into_iter()
    }

    /// Returns number of elements in enum map.
    #[inline]
    pub fn len(&self) -> usize {
        self.as_slice().len()
    }

    /// Returns whether the enum variant set is empty.
    ///
    /// This isn't particularly useful, as there is no real reason to use
    /// enum map for enums without variants. However, it is provided for
    /// consistency with data structures providing len method (and I will
    /// admit, to avoid clippy warnings).
    ///
    /// # Examples
    ///
    /// ```
    /// # extern crate enum_map;
    /// use enum_map::{Enum, EnumMap};
    ///
    /// #[derive(Enum)]
    /// enum Void {}
    ///
    /// #[derive(Enum)]
    /// enum SingleVariant {
    ///     Variant,
    /// }
    ///
    /// fn main() {
    ///     assert!(EnumMap::<Void, ()>::new().is_empty());
    ///     assert!(!EnumMap::<SingleVariant, ()>::new().is_empty());
    /// }
    #[inline]
    pub fn is_empty(&self) -> bool {
        self.as_slice().is_empty()
    }

    /// Swaps two indexes.
    ///
    /// # Examples
    ///
    /// ```
    /// # extern crate enum_map;
    /// use enum_map::enum_map;
    ///
    /// fn main() {
    ///     let mut map = enum_map! { false => 0, true => 1 };
    ///     map.swap(false, true);
    ///     assert_eq!(map[false], 1);
    ///     assert_eq!(map[true], 0);
    /// }
    /// ```
    #[inline]
    pub fn swap(&mut self, a: K, b: K) {
        self.as_mut_slice().swap(a.to_usize(), b.to_usize())
    }

    /// Converts an enum map to a slice representing values.
    #[inline]
    pub fn as_slice(&self) -> &[V] {
        K::slice(&self.array)
    }

    /// Converts a mutable enum map to a mutable slice representing values.
    #[inline]
    pub fn as_mut_slice(&mut self) -> &mut [V] {
        K::slice_mut(&mut self.array)
    }

    /// Returns a raw pointer to the enum map's slice.
    ///
    /// The caller must ensure that the slice outlives the pointer this
    /// function returns, or else it will end up pointing to garbage.
    ///
    /// # Examples
    ///
    /// ```
    /// # extern crate enum_map;
    /// use enum_map::{enum_map, EnumMap};
    ///
    /// fn main() {
    ///     let map = enum_map! { 5 => 42, _ => 0 };
    ///     assert_eq!(unsafe { *map.as_ptr().offset(5) }, 42);
    /// }
    /// ```
    #[inline]
    pub fn as_ptr(&self) -> *const V {
        self.as_slice().as_ptr()
    }

    /// Returns an unsafe mutable pointer to the enum map's slice.
    ///
    /// The caller must ensure that the slice outlives the pointer this
    /// function returns, or else it will end up pointing to garbage.
    ///
    /// # Examples
    ///
    /// ```
    /// # extern crate enum_map;
    /// use enum_map::{enum_map, EnumMap};
    ///
    /// fn main() {
    ///     let mut map = enum_map! { _ => 0 };
    ///     unsafe {
    ///         *map.as_mut_ptr().offset(11) = 23
    ///     };
    ///     assert_eq!(map[11], 23);
    /// }
    /// ```
    #[inline]
    pub fn as_mut_ptr(&mut self) -> *mut V {
        self.as_mut_slice().as_mut_ptr()
    }
}

impl<F: FnMut(K) -> V, K: Enum<V>, V> From<F> for EnumMap<K, V> {
    #[inline]
    fn from(f: F) -> Self {
        EnumMap {
            array: K::from_function(f),
        }
    }
}

pub fn from_fn<K, V>(f: impl FnMut(K) -> V) -> EnumMap<K, V>
where
    K: Enum<V>,
{
    f.into()
}
<|endoftext|>


<commit_before>//! Falcon Intermediate Language.
//!
//! # An Introduction
//!
//! Falcon IL is a simple, expression-based, well-defined, semantically-accurate
//! intermediate language for the analysis of Binary Programs.
//!
//! * **Simple** - Falcon IL has 21 expression types (including terminals), and
//! 5 operation types, minimizing the work required to implement analyses.
//! * **Expression-based** - Falcon IL operates over expressions, as opposed to
//! a [three-address form](https://en.wikipedia.org/wiki/Three-address_code)
//! like REIL/RREIL.
//! * **Well-defined** - Falcon IL is specified with rust's enumerated types,
//! leaving no ambiguity in the IL.
//! * **Semantically accurate** - Falcon IL accurately captures the semantics of
//! underlying architectures. This is mainly a function of the lifters.  A
//! divergence in the lifted semantics and the target architecture is a bug.
//! This makes Falcon IL suitable for analyses which require precision in the
//! semantics.
//!
//! ## Limitations
//!
//! * Falcon IL does not support floating point operations.
//!
//! ## Position and Semantics
//!
//! You should think of components of the Falcon IL as belonging to two groups:
//!
//! * Components which provide program semantics
//! * Components which provide location within a binary.
//!
//! The following components provide semantics:
//!
//! * `Block`
//! * `Constant `
//! * `ControlFlowGraph`
//! * `Edge`
//! * `Expression`
//! * `Operation`
//! * `Scalar`
//!
//! The following components provide location within a binary:
//!
//! * `Function`
//! * `Instruction`
//! * `ProgramLocation` / `FunctionLocation`
//! * `RefProgramLocation` / `RefFunctionLocation`
//! * `Program`
//!
//! While this construct may seem verbose at first, in practice it is not. There
//! are several convenience functions which allow for quickly gathering the
//! necessary information from different components of the IL, and the
//! IL is easily iterable.
//!
//! # Components of the IL
//!
//! ## `Constant`, and `Scalar`.
//!
//! The terminals in Falcon IL are `Constant` and `Scalar`.
//!
//! Constant is a valid, and Scalar is an identifier/variable.
//!
//! ## `Expression`
//!
//! Expressions implement basic arithemtic operations, comparison
//! operations, and bit extension/truncation operations over the terminals
//! `Scalar` and `Constant`
//!
//! * Terminals: `Scalar`, `Constant`.
//! * Arithmetic: `Add`, `Sub`, `Mul`, `Divu`, `Modu`, `Divs`, `Mods`, `And`,
//! `Or`, `Xor`, `Shl`, `Shr`.
//! * Comparison: `Cmpeq`, `Cmpneq`, `Cmplts`, `Cmpltu`.
//! * Extension: `Zext`, `Sext`, `Trun`.
//!
//! Comparison expressions evaluate to a 1-bit expression with the value `1`
//! representing `True`, and the value `0` representing `False`.
//!
//! It is an error to create an expresison which operates over expressions of
//! differing bitness. This is checked dynamically at runtime, and a `Sort`
//! error wil be emitted if expressions have operands of differing bitness. It
//! is a bug if a lifter generates an expression with operands of differing
//! bitness. `Zext`, `Sext`, and `Trun` should be used to ensure expressions
//! are of the same bitness.
//!
//! ## `Operation`
//!
//! An `Operation` applies a transformation over some state. There are five
//! types of `Operation` in Falcon:
//!
//! * `Assign`: Assigns an `Expression` to a `Scalar`.
//! * `Store`: Stores an `Expression` indexed by an `Expression`. The size of
//! the store will be determined by the size of the expression being stored.
//! * `Load`: Loads an `Expression` indexed by an `Expression`, and places the
//! result into a `Scalar`. The size of the load will be determined by the size
//! of the Scalar being loaded into.
//! * `Branch`: Branch to the address in the given `Expression`.
//! * `Intrinsic`: The `Intrinsic` operation is used when a Falcon lifter cannot
//! capture the semantics of a lifted instruction. Dealing with intrinsic
//! instructions is left to the user.
//! * `Nop`: The nop instruction is used to provide an instruction, which has a
//! location, when no operation needs take place at that location. For example,
//! Intra-precedural direct branches lifted as edges in the `ControlFlowGraph`,
//! and `Nop` is emitted in case a follow-on analysis needs to find the address
//! where that branching instruction was originally located.
//!
//! When lifting, direct conditional branches such as X86 `je` or MIPS `be` do
//! not result in an `Operation::Branch`. Instead, the instruction will be
//! omitted and edges will be emitted in the `ControlFlowGraph` with expressions
//! which guard those edges. `Branch` will only be emitted for indirect
//! branches.
//!
//! `Load` and `Store` are obviously dependent on the endianness of the target
//! architecture. Endianness is specified in the memory model, not in the IL.
//!
//! ## `Instruction`
//!
//! An instruction provides position to an `Operation` within a `Block`, and
//! also carries an optional `address`. When an `Instruction` is lifted from a
//! program, this `address` field will be filled in.
//!
//! You should not create an `Instruction` explicitly, but instead call the
//! various methods over `Block` corresponding to the `Operation` you wish to
//! emit, and this will create the `Instruction` implicitly.
//!
//! ## `Block`
//!
//! A `Block` is a basic block, or a sequence of `Instruction`.
//!
//! A `Block` does not carry an `address` field like `Instruction`. Instead, a
//! `Block` has an `index` field, which is an arbitray location within a
//! `ControlFlowGraph`.
//!
//! ## `Edge`
//!
//! An `Edge` connects two `Block`s in a `ControlFlowGraph`. An edge has an
//! optional field `condition`, which guards the edge. When direct conditional
//! branches are lifted from a program, this field will be filled in with the
//! condition that guards traversal of the edge.
//!
//! We create a new `Edge` by calling the `conditional_edge` and
//! `unconditional_edge` methods on a `ControlFlowGraph`.
//!
//! ## `ControlFlowGraph`
//!
//! A `ControlFlowGraph` is a directed graph with vertices of type `Block` and
//! edges of type `Edge`.
//!
//! A perhaps interesting property of `ControlFlowGraph` is the
//! optional `entry` and `exit` index. Falcon lifters lift individual
//! instructions to `ControlFlowGraph`, allowing them to capture semantics of
//! instructions which loop, such as X86's `repne scasb` instruction.
//! Since all instructions have clearly defined entry and exit points, we can
//! use these to append their lifted graphs together. This is how Falcon's
//! lifters construct basic blocks.
//!
//! ## `Function`
//!
//! A function holds an address, and a `ControlFlowGraph`, applying location to
//! the `ControlFlowGraph`. A function also has an optional `name`, which will
//! be filled in by a `Loader` when a corresponding symbol is available, as well
//! as an optional `index` for when this function belongs to an `il::Program`.
//!
//! ## `Program`
//!
//! A program holds multiple instances of `Function`.
//!
//! # That's it!
//!
//! Falcon IL may seem verbose, because of the many components, but in practice
//! it is relatively simple and straight forward, with a minimal set of
//! expressions and operations. Influenced by RREIL and Binary Ninja's IL,
//! Falcon IL is my 3rd IL for binary program analysis, and strikes a good
//! balance between simplicity and readability.
//!
//! Unless writing a lifter, you should never have to create elements of the IL
//! yourself, and can use the accessor methods to gather the information
//! required.

use error::*;
use graph;

mod block;
mod constant;
mod control_flow_graph;
mod edge;
mod expression;
mod function;
mod intrinsic;
mod instruction;
mod location;
mod operation;
mod scalar;
mod program;

pub use self::block::*;
pub use self::constant::*;
pub use self::control_flow_graph::*;
pub use self::edge::*;
pub use self::expression::*;
pub use self::function::*;
pub use self::intrinsic::*;
pub use self::instruction::*;
pub use self::location::*;
pub use self::operation::*;
pub use self::scalar::*;
pub use self::program::*;

/// A convenience function to create a new constant.
///
/// This is the preferred way to create a `Constant`.
pub fn const_(value: u64, bits: usize) -> Constant {
    Constant::new(value, bits)
}

/// A convenience function to create a new constant expression.
///
/// This is the preferred way to create an `Expression::Constant`.
pub fn expr_const(value: u64, bits: usize) -> Expression {
    Expression::constant(Constant::new(value, bits))
}

/// A convenience function to create a new scalar.
///
/// This is the preferred way to create a `Scalar`.
pub fn scalar<S>(name: S, bits: usize) -> Scalar where S: Into<String> {
    Scalar::new(name, bits)
}

/// A convenience function to create a new scalar expression.
///
/// This is the preferred way to create an `Expression::Scalar`.
pub fn expr_scalar<S>(name: S, bits: usize) -> Expression where S: Into<String> {
    Expression::scalar(Scalar::new(name, bits))
}<commit_msg>Add `ite` to `il` documentation<commit_after>//! Falcon Intermediate Language.
//!
//! # An Introduction
//!
//! Falcon IL is a simple, expression-based, well-defined, semantically-accurate
//! intermediate language for the analysis of Binary Programs.
//!
//! * **Simple** - Falcon IL has 21 expression types (including terminals), and
//! 5 operation types, minimizing the work required to implement analyses.
//! * **Expression-based** - Falcon IL operates over expressions, as opposed to
//! a [three-address form](https://en.wikipedia.org/wiki/Three-address_code)
//! like REIL/RREIL.
//! * **Well-defined** - Falcon IL is specified with rust's enumerated types,
//! leaving no ambiguity in the IL.
//! * **Semantically accurate** - Falcon IL accurately captures the semantics of
//! underlying architectures. This is mainly a function of the lifters.  A
//! divergence in the lifted semantics and the target architecture is a bug.
//! This makes Falcon IL suitable for analyses which require precision in the
//! semantics.
//!
//! ## Limitations
//!
//! * Falcon IL does not support floating point operations.
//!
//! ## Position and Semantics
//!
//! You should think of components of the Falcon IL as belonging to two groups:
//!
//! * Components which provide program semantics
//! * Components which provide location within a binary.
//!
//! The following components provide semantics:
//!
//! * `Block`
//! * `Constant `
//! * `ControlFlowGraph`
//! * `Edge`
//! * `Expression`
//! * `Operation`
//! * `Scalar`
//!
//! The following components provide location within a binary:
//!
//! * `Function`
//! * `Instruction`
//! * `ProgramLocation` / `FunctionLocation`
//! * `RefProgramLocation` / `RefFunctionLocation`
//! * `Program`
//!
//! While this construct may seem verbose at first, in practice it is not. There
//! are several convenience functions which allow for quickly gathering the
//! necessary information from different components of the IL, and the
//! IL is easily iterable.
//!
//! # Components of the IL
//!
//! ## `Constant`, and `Scalar`.
//!
//! The terminals in Falcon IL are `Constant` and `Scalar`.
//!
//! Constant is a valid, and Scalar is an identifier/variable.
//!
//! ## `Expression`
//!
//! Expressions implement basic arithemtic operations, comparison
//! operations, and bit extension/truncation operations over the terminals
//! `Scalar` and `Constant`
//!
//! * Terminals: `Scalar`, `Constant`.
//! * Arithmetic: `Add`, `Sub`, `Mul`, `Divu`, `Modu`, `Divs`, `Mods`, `And`,
//! `Or`, `Xor`, `Shl`, `Shr`.
//! * Comparison: `Cmpeq`, `Cmpneq`, `Cmplts`, `Cmpltu`.
//! * Extension: `Zext`, `Sext`, `Trun`.
//! * Ternary: `Ite`
//!
//! Comparison expressions evaluate to a 1-bit expression with the value `1`
//! representing `True`, and the value `0` representing `False`.
//!
//! It is an error to create an expresison which operates over expressions of
//! differing bitness. This is checked dynamically at runtime, and a `Sort`
//! error wil be emitted if expressions have operands of differing bitness. It
//! is a bug if a lifter generates an expression with operands of differing
//! bitness. `Zext`, `Sext`, and `Trun` should be used to ensure expressions
//! are of the same bitness.
//!
//! ## `Operation`
//!
//! An `Operation` applies a transformation over some state. There are five
//! types of `Operation` in Falcon:
//!
//! * `Assign`: Assigns an `Expression` to a `Scalar`.
//! * `Store`: Stores an `Expression` indexed by an `Expression`. The size of
//! the store will be determined by the size of the expression being stored.
//! * `Load`: Loads an `Expression` indexed by an `Expression`, and places the
//! result into a `Scalar`. The size of the load will be determined by the size
//! of the Scalar being loaded into.
//! * `Branch`: Branch to the address in the given `Expression`.
//! * `Intrinsic`: The `Intrinsic` operation is used when a Falcon lifter cannot
//! capture the semantics of a lifted instruction. Dealing with intrinsic
//! instructions is left to the user.
//! * `Nop`: The nop instruction is used to provide an instruction, which has a
//! location, when no operation needs take place at that location. For example,
//! Intra-precedural direct branches lifted as edges in the `ControlFlowGraph`,
//! and `Nop` is emitted in case a follow-on analysis needs to find the address
//! where that branching instruction was originally located.
//!
//! When lifting, direct conditional branches such as X86 `je` or MIPS `be` do
//! not result in an `Operation::Branch`. Instead, the instruction will be
//! omitted and edges will be emitted in the `ControlFlowGraph` with expressions
//! which guard those edges. `Branch` will only be emitted for indirect
//! branches.
//!
//! `Load` and `Store` are obviously dependent on the endianness of the target
//! architecture. Endianness is specified in the memory model, not in the IL.
//!
//! ## `Instruction`
//!
//! An instruction provides position to an `Operation` within a `Block`, and
//! also carries an optional `address`. When an `Instruction` is lifted from a
//! program, this `address` field will be filled in.
//!
//! You should not create an `Instruction` explicitly, but instead call the
//! various methods over `Block` corresponding to the `Operation` you wish to
//! emit, and this will create the `Instruction` implicitly.
//!
//! ## `Block`
//!
//! A `Block` is a basic block, or a sequence of `Instruction`.
//!
//! A `Block` does not carry an `address` field like `Instruction`. Instead, a
//! `Block` has an `index` field, which is an arbitray location within a
//! `ControlFlowGraph`.
//!
//! ## `Edge`
//!
//! An `Edge` connects two `Block`s in a `ControlFlowGraph`. An edge has an
//! optional field `condition`, which guards the edge. When direct conditional
//! branches are lifted from a program, this field will be filled in with the
//! condition that guards traversal of the edge.
//!
//! We create a new `Edge` by calling the `conditional_edge` and
//! `unconditional_edge` methods on a `ControlFlowGraph`.
//!
//! ## `ControlFlowGraph`
//!
//! A `ControlFlowGraph` is a directed graph with vertices of type `Block` and
//! edges of type `Edge`.
//!
//! A perhaps interesting property of `ControlFlowGraph` is the
//! optional `entry` and `exit` index. Falcon lifters lift individual
//! instructions to `ControlFlowGraph`, allowing them to capture semantics of
//! instructions which loop, such as X86's `repne scasb` instruction.
//! Since all instructions have clearly defined entry and exit points, we can
//! use these to append their lifted graphs together. This is how Falcon's
//! lifters construct basic blocks.
//!
//! ## `Function`
//!
//! A function holds an address, and a `ControlFlowGraph`, applying location to
//! the `ControlFlowGraph`. A function also has an optional `name`, which will
//! be filled in by a `Loader` when a corresponding symbol is available, as well
//! as an optional `index` for when this function belongs to an `il::Program`.
//!
//! ## `Program`
//!
//! A program holds multiple instances of `Function`.
//!
//! # That's it!
//!
//! Falcon IL may seem verbose, because of the many components, but in practice
//! it is relatively simple and straight forward, with a minimal set of
//! expressions and operations. Influenced by RREIL and Binary Ninja's IL,
//! Falcon IL is my 3rd IL for binary program analysis, and strikes a good
//! balance between simplicity and readability.
//!
//! Unless writing a lifter, you should never have to create elements of the IL
//! yourself, and can use the accessor methods to gather the information
//! required.

use error::*;
use graph;

mod block;
mod constant;
mod control_flow_graph;
mod edge;
mod expression;
mod function;
mod intrinsic;
mod instruction;
mod location;
mod operation;
mod scalar;
mod program;

pub use self::block::*;
pub use self::constant::*;
pub use self::control_flow_graph::*;
pub use self::edge::*;
pub use self::expression::*;
pub use self::function::*;
pub use self::intrinsic::*;
pub use self::instruction::*;
pub use self::location::*;
pub use self::operation::*;
pub use self::scalar::*;
pub use self::program::*;

/// A convenience function to create a new constant.
///
/// This is the preferred way to create a `Constant`.
pub fn const_(value: u64, bits: usize) -> Constant {
    Constant::new(value, bits)
}

/// A convenience function to create a new constant expression.
///
/// This is the preferred way to create an `Expression::Constant`.
pub fn expr_const(value: u64, bits: usize) -> Expression {
    Expression::constant(Constant::new(value, bits))
}

/// A convenience function to create a new scalar.
///
/// This is the preferred way to create a `Scalar`.
pub fn scalar<S>(name: S, bits: usize) -> Scalar where S: Into<String> {
    Scalar::new(name, bits)
}

/// A convenience function to create a new scalar expression.
///
/// This is the preferred way to create an `Expression::Scalar`.
pub fn expr_scalar<S>(name: S, bits: usize) -> Expression where S: Into<String> {
    Expression::scalar(Scalar::new(name, bits))
}<|endoftext|>


<commit_before>
pub fn raindrops(num: i32) -> String
{

}
<commit_msg>raindrops<commit_after>use std::str;

pub fn raindrops() {
    println!("Finding factors of x!");

	let x = 120;
	let mut mul = 1;
    let mut done = false;
    let mut j = 0;
    let pling = "Pling";
    while !done{
        if (x%mul == 0) && !(j == mul)
        {
            j = x/mul;
            println!("{}",mul );
            println!("{}",j );
            mul = mul + 1;
        }
        else if j == mul
        {
            done = true;
        }
        else{
            mul = mul + 1;
        }
    }
}
<|endoftext|>