<commit_before>use std::fs::Metadata;
use std::path::{Path, PathBuf};

use log::warn;

pub fn walk<P: AsRef<Path>>(root: P) -> std::io::Result<Walk> {
    let iter = std::fs::read_dir(root)?;
    Ok(Walk {
        pending: vec!(WalkDir::from_read_dir(iter)),
    })
}

pub struct Walk {
    // TODO: Add support for stopping at device boundaries.
    pending: Vec<WalkDir>,
}

pub struct WalkEntry {
    path: PathBuf,
    metadata: Metadata,
}

impl Walk {

    fn push(&mut self, entry: &WalkEntry) {
        match std::fs::read_dir(&entry.path) {
            Ok(iter) => {
                self.pending.push(WalkDir::from_read_dir(iter));
            },
            Err(error) => {
                warn!("failed to read '{}': {}", entry.path.display(), error);
            },
        }
    }

    fn pop(&mut self) -> Option<WalkEntry> {
        while let Some(iter) = self.pending.last_mut() {
            for entry in iter {
                return Some(entry);
            }

            self.pending.pop();
        }

        None
    }
}

impl std::iter::Iterator for Walk {

    type Item = WalkEntry;

    fn next(&mut self) -> Option<WalkEntry> {
        let entry = self.pop()?;

        if entry.metadata.is_dir() {
            self.push(&entry);
        }

        Some(entry)
    }
}

struct WalkDir {
    iter: std::fs::ReadDir,
}

impl WalkDir {

    fn from_read_dir(iter: std::fs::ReadDir) -> WalkDir {
        WalkDir {
            iter: iter,
        }
    }
}

impl std::iter::Iterator for WalkDir {

    type Item = WalkEntry;

    fn next(&mut self) -> Option<WalkEntry> {
        for entry in &mut self.iter {
            let entry = match entry {
                Ok(entry) => entry,
                Err(error) => {
                    warn!("directory iteration error: {}", error);
                    continue
                },
            };

            let path = entry.path();
            let metadata = match entry.metadata() {
                Ok(metadata) => metadata,
                Err(error) => {
                    warn!("failed to stat '{}': {}", path.display(), error);
                    continue
                },
            };

            return Some(WalkEntry {
                path: path,
                metadata: metadata,
            });
        }

        None
    }
}
<commit_msg>Write tests for the directory iterator wrapper.<commit_after>use std::fs::Metadata;
use std::path::{Path, PathBuf};

use log::warn;

pub fn walk<P: AsRef<Path>>(root: P) -> std::io::Result<Walk> {
    let iter = std::fs::read_dir(root)?;
    Ok(Walk {
        pending: vec!(WalkDir::from_read_dir(iter)),
    })
}

pub struct Walk {
    // TODO: Add support for stopping at device boundaries.
    pending: Vec<WalkDir>,
}

pub struct WalkEntry {
    path: PathBuf,
    metadata: Metadata,
}

impl Walk {

    fn push(&mut self, entry: &WalkEntry) {
        match std::fs::read_dir(&entry.path) {
            Ok(iter) => {
                self.pending.push(WalkDir::from_read_dir(iter));
            },
            Err(error) => {
                warn!("failed to read '{}': {}", entry.path.display(), error);
            },
        }
    }

    fn pop(&mut self) -> Option<WalkEntry> {
        while let Some(iter) = self.pending.last_mut() {
            for entry in iter {
                return Some(entry);
            }

            self.pending.pop();
        }

        None
    }
}

impl std::iter::Iterator for Walk {

    type Item = WalkEntry;

    fn next(&mut self) -> Option<WalkEntry> {
        let entry = self.pop()?;

        if entry.metadata.is_dir() {
            self.push(&entry);
        }

        Some(entry)
    }
}

struct WalkDir {
    iter: std::fs::ReadDir,
}

impl WalkDir {

    fn from_read_dir(iter: std::fs::ReadDir) -> WalkDir {
        WalkDir {
            iter: iter,
        }
    }
}

impl std::iter::Iterator for WalkDir {

    type Item = WalkEntry;

    fn next(&mut self) -> Option<WalkEntry> {
        for entry in &mut self.iter {
            let entry = match entry {
                Ok(entry) => entry,
                Err(error) => {
                    warn!("directory iteration error: {}", error);
                    continue
                },
            };

            let path = entry.path();
            let metadata = match entry.metadata() {
                Ok(metadata) => metadata,
                Err(error) => {
                    warn!("failed to stat '{}': {}", path.display(), error);
                    continue
                },
            };

            return Some(WalkEntry {
                path: path,
                metadata: metadata,
            });
        }

        None
    }
}

#[cfg(test)]
mod tests {

    use std::fs::File;

    use super::*;

    #[test]
    fn test_walk_dir_empty() {
        let tempdir = tempfile::tempdir().unwrap();

        let iter = std::fs::read_dir(&tempdir).unwrap();
        let mut iter = WalkDir::from_read_dir(iter);

        assert!(iter.next().is_none());
    }

    #[test]
    fn test_walk_dir_with_files() {
        let tempdir = tempfile::tempdir().unwrap();
        File::create(tempdir.path().join("abc")).unwrap();
        File::create(tempdir.path().join("def")).unwrap();
        File::create(tempdir.path().join("ghi")).unwrap();

        let iter = std::fs::read_dir(&tempdir).unwrap();

        let mut results = WalkDir::from_read_dir(iter).collect::<Vec<_>>();
        results.sort_by_key(|entry| entry.path.clone());

        assert_eq!(results.len(), 3);

        assert_eq!(results[0].path, tempdir.path().join("abc"));
        assert!(results[0].metadata.is_file());

        assert_eq!(results[1].path, tempdir.path().join("def"));
        assert!(results[1].metadata.is_file());

        assert_eq!(results[2].path, tempdir.path().join("ghi"));
        assert!(results[2].metadata.is_file());
    }

    #[test]
    fn test_walk_dir_with_dirs() {
        let tempdir = tempfile::tempdir().unwrap();
        std::fs::create_dir(tempdir.path().join("abc")).unwrap();
        std::fs::create_dir(tempdir.path().join("def")).unwrap();

        let iter = std::fs::read_dir(&tempdir).unwrap();

        let mut results = WalkDir::from_read_dir(iter).collect::<Vec<_>>();
        results.sort_by_key(|entry| entry.path.clone());

        assert_eq!(results.len(), 2);

        assert_eq!(results[0].path, tempdir.path().join("abc"));
        assert!(results[0].metadata.is_dir());

        assert_eq!(results[1].path, tempdir.path().join("def"));
        assert!(results[1].metadata.is_dir());
    }

    #[cfg(target_family = "unix")]
    #[test]
    fn test_walk_dir_with_links() {
        let tempdir = tempfile::tempdir().unwrap();
        let source = tempdir.path().join("abc");
        let target = tempdir.path().join("def");

        File::create(&source).unwrap();
        std::os::unix::fs::symlink(&source, &target).unwrap();

        let iter = std::fs::read_dir(&tempdir).unwrap();

        let mut results = WalkDir::from_read_dir(iter).collect::<Vec<_>>();
        results.sort_by_key(|entry| entry.path.clone());

        assert_eq!(results.len(), 2);

        assert_eq!(results[0].path, source);
        assert!(results[0].metadata.file_type().is_file());

        assert_eq!(results[1].path, target);
        assert!(results[1].metadata.file_type().is_symlink());
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2018-2021, The rav1e contributors. All rights reserved
//
// This source code is subject to the terms of the BSD 2 Clause License and
// the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
// was not distributed with this source code in the LICENSE file, you can
// obtain it at www.aomedia.org/license/software. If the Alliance for Open
// Media Patent License 1.0 was not distributed with this source code in the
// PATENTS file, you can obtain it at www.aomedia.org/license/patent.

use crate::context::*;
use crate::header::PRIMARY_REF_NONE;
use crate::partition::BlockSize;
use crate::rdo::spatiotemporal_scale;
use crate::rdo::DistortionScale;
use crate::tiling::TileStateMut;
use crate::util::Pixel;
use crate::FrameInvariants;
use crate::FrameState;

pub const MAX_SEGMENTS: usize = 8;

pub fn segmentation_optimize<T: Pixel>(
  fi: &FrameInvariants<T>, fs: &mut FrameState<T>,
) {
  assert!(fi.enable_segmentation);
  fs.segmentation.enabled = true;

  if fs.segmentation.enabled {
    fs.segmentation.update_map = true;

    // We don't change the values between frames.
    fs.segmentation.update_data = fi.primary_ref_frame == PRIMARY_REF_NONE;

    // Avoid going into lossless mode by never bringing qidx below 1.
    // Because base_q_idx changes more frequently than the segmentation
    // data, it is still possible for a segment to enter lossless, so
    // enforcement elsewhere is needed.
    let offset_lower_limit = 1 - fi.base_q_idx as i16;

    if !fs.segmentation.update_data {
      let mut min_segment = MAX_SEGMENTS;
      for i in 0..MAX_SEGMENTS {
        if fs.segmentation.features[i][SegLvl::SEG_LVL_ALT_Q as usize]
          && fs.segmentation.data[i][SegLvl::SEG_LVL_ALT_Q as usize]
            >= offset_lower_limit
        {
          min_segment = i;
          break;
        }
      }
      assert_ne!(min_segment, MAX_SEGMENTS);
      fs.segmentation.min_segment = min_segment as u8;
      fs.segmentation.update_threshold(fi.base_q_idx, fi.config.bit_depth);
      return;
    }

    segmentation_optimize_inner(fi, fs, offset_lower_limit);

    /* Figure out parameters */
    fs.segmentation.preskip = false;
    fs.segmentation.last_active_segid = 0;
    for i in 0..MAX_SEGMENTS {
      for j in 0..SegLvl::SEG_LVL_MAX as usize {
        if fs.segmentation.features[i][j] {
          fs.segmentation.last_active_segid = i as u8;
          if j >= SegLvl::SEG_LVL_REF_FRAME as usize {
            fs.segmentation.preskip = true;
          }
        }
      }
    }
  }
}

// Select target quantizers for each segment by fitting to log(scale).
fn segmentation_optimize_inner<T: Pixel>(
  fi: &FrameInvariants<T>, fs: &mut FrameState<T>, offset_lower_limit: i16,
) {
  use crate::quantize::{ac_q, select_ac_qi};
  use crate::util::kmeans;
  use arrayvec::ArrayVec;

  // Minimize the total distance from a small set of values to all scales.
  // Find k-means of log(spatiotemporal scale), k in 3..=8
  let c: ([_; 8], [_; 7], [_; 6], [_; 5], [_; 4], [_; 3]) = {
    let coded_data = fi.coded_frame_data.as_ref().unwrap();
    let mut log2_scale_q24: Box<[i32]> =
      coded_data.spatiotemporal_scores.iter().map(|&s| s.blog32()).collect();
    log2_scale_q24.sort_unstable();
    let l = &log2_scale_q24;
    (kmeans(l), kmeans(l), kmeans(l), kmeans(l), kmeans(l), kmeans(l))
  };

  // Find variance in spacing between successive log(scale)
  let var = |c: &[i32]| {
    let delta = ArrayVec::<_, MAX_SEGMENTS>::from_iter(
      c.iter().skip(1).zip(c).map(|(&a, &b)| b as i64 - a as i64),
    );
    let mean = delta.iter().sum::<i64>() / delta.len() as i64;
    delta.iter().map(|&d| (d - mean).pow(2)).sum::<i64>() as u64
  };
  let variance =
    [var(&c.0), var(&c.1), var(&c.2), var(&c.3), var(&c.4), var(&c.5)];

  // Choose the k value with minimal variance in spacing
  let min_variance = *variance.iter().min().unwrap();
  let position = variance.iter().rposition(|&v| v == min_variance).unwrap();

  // For the selected centroids, derive a target quantizer:
  //   scale Q'^2 = Q^2
  // See `distortion_scale_for` for more information.
  let compute_delta = |centroids: &[i32]| {
    use crate::util::{bexp64, blog64};
    let log2_base_ac_q_q57 =
      blog64(ac_q(fi.base_q_idx, 0, fi.config.bit_depth).into());
    centroids
      .iter()
      .rev()
      // Rewrite in log form and exponentiate:
      //   scale Q'^2 = Q^2
      //           Q' = Q / sqrt(scale)
      //      log(Q') = log(Q) - 0.5 log(scale)
      .map(|&log2_scale_q24| {
        bexp64(log2_base_ac_q_q57 - ((log2_scale_q24 as i64) << (57 - 24 - 1)))
      })
      // Find the index of the nearest quantizer to the target,
      // and take the delta from the base quantizer index.
      .map(|q| {
        // Avoid going into lossless mode by never bringing qidx below 1.
        select_ac_qi(q, fi.config.bit_depth).max(1) as i16
          - fi.base_q_idx as i16
      })
      .collect::<ArrayVec<_, MAX_SEGMENTS>>()
  };

  // Compute segment deltas for best value of k
  let seg_delta = match position {
    0 => compute_delta(&c.0),
    1 => compute_delta(&c.1),
    2 => compute_delta(&c.2),
    3 => compute_delta(&c.3),
    4 => compute_delta(&c.4),
    _ => compute_delta(&c.5),
  };

  // Update the segmentation data
  fs.segmentation.max_segment = seg_delta.len() as u8 - 1;
  for (&delta, (features, data)) in seg_delta
    .iter()
    .zip(fs.segmentation.features.iter_mut().zip(&mut fs.segmentation.data))
  {
    features[SegLvl::SEG_LVL_ALT_Q as usize] = true;
    data[SegLvl::SEG_LVL_ALT_Q as usize] = delta.max(offset_lower_limit);
  }

  fs.segmentation.update_threshold(fi.base_q_idx, fi.config.bit_depth);
}

pub fn select_segment<T: Pixel>(
  fi: &FrameInvariants<T>, ts: &TileStateMut<'_, T>, tile_bo: TileBlockOffset,
  bsize: BlockSize, skip: bool,
) -> std::ops::RangeInclusive<u8> {
  // If skip is true or segmentation is turned off, sidx is not coded.
  if skip || !fi.enable_segmentation {
    return 0..=0;
  }

  use crate::api::SegmentationLevel;
  if fi.config.speed_settings.segmentation == SegmentationLevel::Full {
    return ts.segmentation.min_segment..=ts.segmentation.max_segment;
  }

  let frame_bo = ts.to_frame_block_offset(tile_bo);
  let scale = spatiotemporal_scale(fi, frame_bo, bsize);

  let sidx = segment_idx_from_distortion(&ts.segmentation.threshold, scale);

  // Avoid going into lossless mode by never bringing qidx below 1.
  let sidx = sidx.max(ts.segmentation.min_segment);

  sidx..=sidx
}

fn segment_idx_from_distortion(
  threshold: &[DistortionScale; MAX_SEGMENTS - 1], s: DistortionScale,
) -> u8 {
  threshold.partition_point(|&t| s.0 < t.0) as u8
}
<commit_msg>segmentation: Avoid reallocation in collect::<Box<[_]>>()<commit_after>// Copyright (c) 2018-2021, The rav1e contributors. All rights reserved
//
// This source code is subject to the terms of the BSD 2 Clause License and
// the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
// was not distributed with this source code in the LICENSE file, you can
// obtain it at www.aomedia.org/license/software. If the Alliance for Open
// Media Patent License 1.0 was not distributed with this source code in the
// PATENTS file, you can obtain it at www.aomedia.org/license/patent.

use crate::context::*;
use crate::header::PRIMARY_REF_NONE;
use crate::partition::BlockSize;
use crate::rdo::spatiotemporal_scale;
use crate::rdo::DistortionScale;
use crate::tiling::TileStateMut;
use crate::util::Pixel;
use crate::FrameInvariants;
use crate::FrameState;

pub const MAX_SEGMENTS: usize = 8;

pub fn segmentation_optimize<T: Pixel>(
  fi: &FrameInvariants<T>, fs: &mut FrameState<T>,
) {
  assert!(fi.enable_segmentation);
  fs.segmentation.enabled = true;

  if fs.segmentation.enabled {
    fs.segmentation.update_map = true;

    // We don't change the values between frames.
    fs.segmentation.update_data = fi.primary_ref_frame == PRIMARY_REF_NONE;

    // Avoid going into lossless mode by never bringing qidx below 1.
    // Because base_q_idx changes more frequently than the segmentation
    // data, it is still possible for a segment to enter lossless, so
    // enforcement elsewhere is needed.
    let offset_lower_limit = 1 - fi.base_q_idx as i16;

    if !fs.segmentation.update_data {
      let mut min_segment = MAX_SEGMENTS;
      for i in 0..MAX_SEGMENTS {
        if fs.segmentation.features[i][SegLvl::SEG_LVL_ALT_Q as usize]
          && fs.segmentation.data[i][SegLvl::SEG_LVL_ALT_Q as usize]
            >= offset_lower_limit
        {
          min_segment = i;
          break;
        }
      }
      assert_ne!(min_segment, MAX_SEGMENTS);
      fs.segmentation.min_segment = min_segment as u8;
      fs.segmentation.update_threshold(fi.base_q_idx, fi.config.bit_depth);
      return;
    }

    segmentation_optimize_inner(fi, fs, offset_lower_limit);

    /* Figure out parameters */
    fs.segmentation.preskip = false;
    fs.segmentation.last_active_segid = 0;
    for i in 0..MAX_SEGMENTS {
      for j in 0..SegLvl::SEG_LVL_MAX as usize {
        if fs.segmentation.features[i][j] {
          fs.segmentation.last_active_segid = i as u8;
          if j >= SegLvl::SEG_LVL_REF_FRAME as usize {
            fs.segmentation.preskip = true;
          }
        }
      }
    }
  }
}

// Select target quantizers for each segment by fitting to log(scale).
fn segmentation_optimize_inner<T: Pixel>(
  fi: &FrameInvariants<T>, fs: &mut FrameState<T>, offset_lower_limit: i16,
) {
  use crate::quantize::{ac_q, select_ac_qi};
  use crate::util::kmeans;
  use arrayvec::ArrayVec;

  // Minimize the total distance from a small set of values to all scales.
  // Find k-means of log(spatiotemporal scale), k in 3..=8
  let c: ([_; 8], [_; 7], [_; 6], [_; 5], [_; 4], [_; 3]) = {
    let spatiotemporal_scores =
      &fi.coded_frame_data.as_ref().unwrap().spatiotemporal_scores;
    let mut log2_scale_q24 = Vec::with_capacity(spatiotemporal_scores.len());
    log2_scale_q24.extend(spatiotemporal_scores.iter().map(|&s| s.blog32()));
    log2_scale_q24.sort_unstable();
    let l = &log2_scale_q24;
    (kmeans(l), kmeans(l), kmeans(l), kmeans(l), kmeans(l), kmeans(l))
  };

  // Find variance in spacing between successive log(scale)
  let var = |c: &[i32]| {
    let delta = ArrayVec::<_, MAX_SEGMENTS>::from_iter(
      c.iter().skip(1).zip(c).map(|(&a, &b)| b as i64 - a as i64),
    );
    let mean = delta.iter().sum::<i64>() / delta.len() as i64;
    delta.iter().map(|&d| (d - mean).pow(2)).sum::<i64>() as u64
  };
  let variance =
    [var(&c.0), var(&c.1), var(&c.2), var(&c.3), var(&c.4), var(&c.5)];

  // Choose the k value with minimal variance in spacing
  let min_variance = *variance.iter().min().unwrap();
  let position = variance.iter().rposition(|&v| v == min_variance).unwrap();

  // For the selected centroids, derive a target quantizer:
  //   scale Q'^2 = Q^2
  // See `distortion_scale_for` for more information.
  let compute_delta = |centroids: &[i32]| {
    use crate::util::{bexp64, blog64};
    let log2_base_ac_q_q57 =
      blog64(ac_q(fi.base_q_idx, 0, fi.config.bit_depth).into());
    centroids
      .iter()
      .rev()
      // Rewrite in log form and exponentiate:
      //   scale Q'^2 = Q^2
      //           Q' = Q / sqrt(scale)
      //      log(Q') = log(Q) - 0.5 log(scale)
      .map(|&log2_scale_q24| {
        bexp64(log2_base_ac_q_q57 - ((log2_scale_q24 as i64) << (57 - 24 - 1)))
      })
      // Find the index of the nearest quantizer to the target,
      // and take the delta from the base quantizer index.
      .map(|q| {
        // Avoid going into lossless mode by never bringing qidx below 1.
        select_ac_qi(q, fi.config.bit_depth).max(1) as i16
          - fi.base_q_idx as i16
      })
      .collect::<ArrayVec<_, MAX_SEGMENTS>>()
  };

  // Compute segment deltas for best value of k
  let seg_delta = match position {
    0 => compute_delta(&c.0),
    1 => compute_delta(&c.1),
    2 => compute_delta(&c.2),
    3 => compute_delta(&c.3),
    4 => compute_delta(&c.4),
    _ => compute_delta(&c.5),
  };

  // Update the segmentation data
  fs.segmentation.max_segment = seg_delta.len() as u8 - 1;
  for (&delta, (features, data)) in seg_delta
    .iter()
    .zip(fs.segmentation.features.iter_mut().zip(&mut fs.segmentation.data))
  {
    features[SegLvl::SEG_LVL_ALT_Q as usize] = true;
    data[SegLvl::SEG_LVL_ALT_Q as usize] = delta.max(offset_lower_limit);
  }

  fs.segmentation.update_threshold(fi.base_q_idx, fi.config.bit_depth);
}

pub fn select_segment<T: Pixel>(
  fi: &FrameInvariants<T>, ts: &TileStateMut<'_, T>, tile_bo: TileBlockOffset,
  bsize: BlockSize, skip: bool,
) -> std::ops::RangeInclusive<u8> {
  // If skip is true or segmentation is turned off, sidx is not coded.
  if skip || !fi.enable_segmentation {
    return 0..=0;
  }

  use crate::api::SegmentationLevel;
  if fi.config.speed_settings.segmentation == SegmentationLevel::Full {
    return ts.segmentation.min_segment..=ts.segmentation.max_segment;
  }

  let frame_bo = ts.to_frame_block_offset(tile_bo);
  let scale = spatiotemporal_scale(fi, frame_bo, bsize);

  let sidx = segment_idx_from_distortion(&ts.segmentation.threshold, scale);

  // Avoid going into lossless mode by never bringing qidx below 1.
  let sidx = sidx.max(ts.segmentation.min_segment);

  sidx..=sidx
}

fn segment_idx_from_distortion(
  threshold: &[DistortionScale; MAX_SEGMENTS - 1], s: DistortionScale,
) -> u8 {
  threshold.partition_point(|&t| s.0 < t.0) as u8
}
<|endoftext|>


<commit_before>//! An implementation of SipHash.

// ignore-tidy-undocumented-unsafe

#![allow(deprecated)] // the types in this module are deprecated

use crate::cmp;
use crate::marker::PhantomData;
use crate::mem;
use crate::ptr;

/// An implementation of SipHash 1-3.
///
/// This is currently the default hashing function used by standard library
/// (e.g., `collections::HashMap` uses it by default).
///
/// See: <https://131002.net/siphash>
#[unstable(feature = "hashmap_internals", issue = "none")]
#[rustc_deprecated(
    since = "1.13.0",
    reason = "use `std::collections::hash_map::DefaultHasher` instead"
)]
#[derive(Debug, Clone, Default)]
#[doc(hidden)]
pub struct SipHasher13 {
    hasher: Hasher<Sip13Rounds>,
}

/// An implementation of SipHash 2-4.
///
/// See: <https://131002.net/siphash/>
#[unstable(feature = "hashmap_internals", issue = "none")]
#[rustc_deprecated(
    since = "1.13.0",
    reason = "use `std::collections::hash_map::DefaultHasher` instead"
)]
#[derive(Debug, Clone, Default)]
struct SipHasher24 {
    hasher: Hasher<Sip24Rounds>,
}

/// An implementation of SipHash 2-4.
///
/// See: <https://131002.net/siphash/>
///
/// SipHash is a general-purpose hashing function: it runs at a good
/// speed (competitive with Spooky and City) and permits strong _keyed_
/// hashing. This lets you key your hashtables from a strong RNG, such as
/// [`rand::os::OsRng`](https://doc.rust-lang.org/rand/rand/os/struct.OsRng.html).
///
/// Although the SipHash algorithm is considered to be generally strong,
/// it is not intended for cryptographic purposes. As such, all
/// cryptographic uses of this implementation are _strongly discouraged_.
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_deprecated(
    since = "1.13.0",
    reason = "use `std::collections::hash_map::DefaultHasher` instead"
)]
#[derive(Debug, Clone, Default)]
pub struct SipHasher(SipHasher24);

#[derive(Debug)]
struct Hasher<S: Sip> {
    k0: u64,
    k1: u64,
    length: usize, // how many bytes we've processed
    state: State,  // hash State
    tail: u64,     // unprocessed bytes le
    ntail: usize,  // how many bytes in tail are valid
    _marker: PhantomData<S>,
}

#[derive(Debug, Clone, Copy)]
#[repr(C)]
struct State {
    // v0, v2 and v1, v3 show up in pairs in the algorithm,
    // and simd implementations of SipHash will use vectors
    // of v02 and v13. By placing them in this order in the struct,
    // the compiler can pick up on just a few simd optimizations by itself.
    v0: u64,
    v2: u64,
    v1: u64,
    v3: u64,
}

macro_rules! compress {
    ($state:expr) => {{ compress!($state.v0, $state.v1, $state.v2, $state.v3) }};
    ($v0:expr, $v1:expr, $v2:expr, $v3:expr) => {{
        $v0 = $v0.wrapping_add($v1);
        $v1 = $v1.rotate_left(13);
        $v1 ^= $v0;
        $v0 = $v0.rotate_left(32);
        $v2 = $v2.wrapping_add($v3);
        $v3 = $v3.rotate_left(16);
        $v3 ^= $v2;
        $v0 = $v0.wrapping_add($v3);
        $v3 = $v3.rotate_left(21);
        $v3 ^= $v0;
        $v2 = $v2.wrapping_add($v1);
        $v1 = $v1.rotate_left(17);
        $v1 ^= $v2;
        $v2 = $v2.rotate_left(32);
    }};
}

/// Loads an integer of the desired type from a byte stream, in LE order. Uses
/// `copy_nonoverlapping` to let the compiler generate the most efficient way
/// to load it from a possibly unaligned address.
///
/// Unsafe because: unchecked indexing at i..i+size_of(int_ty)
macro_rules! load_int_le {
    ($buf:expr, $i:expr, $int_ty:ident) => {{
        debug_assert!($i + mem::size_of::<$int_ty>() <= $buf.len());
        let mut data = 0 as $int_ty;
        ptr::copy_nonoverlapping(
            $buf.get_unchecked($i),
            &mut data as *mut _ as *mut u8,
            mem::size_of::<$int_ty>(),
        );
        data.to_le()
    }};
}

/// Loads a u64 using up to 7 bytes of a byte slice. It looks clumsy but the
/// `copy_nonoverlapping` calls that occur (via `load_int_le!`) all have fixed
/// sizes and avoid calling `memcpy`, which is good for speed.
///
/// Unsafe because: unchecked indexing at start..start+len
#[inline]
unsafe fn u8to64_le(buf: &[u8], start: usize, len: usize) -> u64 {
    debug_assert!(len < 8);
    let mut i = 0; // current byte index (from LSB) in the output u64
    let mut out = 0;
    if i + 3 < len {
        out = load_int_le!(buf, start + i, u32) as u64;
        i += 4;
    }
    if i + 1 < len {
        out |= (load_int_le!(buf, start + i, u16) as u64) << (i * 8);
        i += 2
    }
    if i < len {
        out |= (*buf.get_unchecked(start + i) as u64) << (i * 8);
        i += 1;
    }
    debug_assert_eq!(i, len);
    out
}

impl SipHasher {
    /// Creates a new `SipHasher` with the two initial keys set to 0.
    #[inline]
    #[stable(feature = "rust1", since = "1.0.0")]
    #[rustc_deprecated(
        since = "1.13.0",
        reason = "use `std::collections::hash_map::DefaultHasher` instead"
    )]
    pub fn new() -> SipHasher {
        SipHasher::new_with_keys(0, 0)
    }

    /// Creates a `SipHasher` that is keyed off the provided keys.
    #[inline]
    #[stable(feature = "rust1", since = "1.0.0")]
    #[rustc_deprecated(
        since = "1.13.0",
        reason = "use `std::collections::hash_map::DefaultHasher` instead"
    )]
    pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher {
        SipHasher(SipHasher24 { hasher: Hasher::new_with_keys(key0, key1) })
    }
}

impl SipHasher13 {
    /// Creates a new `SipHasher13` with the two initial keys set to 0.
    #[inline]
    #[unstable(feature = "hashmap_internals", issue = "none")]
    #[rustc_deprecated(
        since = "1.13.0",
        reason = "use `std::collections::hash_map::DefaultHasher` instead"
    )]
    pub fn new() -> SipHasher13 {
        SipHasher13::new_with_keys(0, 0)
    }

    /// Creates a `SipHasher13` that is keyed off the provided keys.
    #[inline]
    #[unstable(feature = "hashmap_internals", issue = "none")]
    #[rustc_deprecated(
        since = "1.13.0",
        reason = "use `std::collections::hash_map::DefaultHasher` instead"
    )]
    pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher13 {
        SipHasher13 { hasher: Hasher::new_with_keys(key0, key1) }
    }
}

impl<S: Sip> Hasher<S> {
    #[inline]
    fn new_with_keys(key0: u64, key1: u64) -> Hasher<S> {
        let mut state = Hasher {
            k0: key0,
            k1: key1,
            length: 0,
            state: State { v0: 0, v1: 0, v2: 0, v3: 0 },
            tail: 0,
            ntail: 0,
            _marker: PhantomData,
        };
        state.reset();
        state
    }

    #[inline]
    fn reset(&mut self) {
        self.length = 0;
        self.state.v0 = self.k0 ^ 0x736f6d6570736575;
        self.state.v1 = self.k1 ^ 0x646f72616e646f6d;
        self.state.v2 = self.k0 ^ 0x6c7967656e657261;
        self.state.v3 = self.k1 ^ 0x7465646279746573;
        self.ntail = 0;
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl super::Hasher for SipHasher {
    #[inline]
    fn write(&mut self, msg: &[u8]) {
        self.0.hasher.write(msg)
    }

    #[inline]
    fn finish(&self) -> u64 {
        self.0.hasher.finish()
    }
}

#[unstable(feature = "hashmap_internals", issue = "none")]
impl super::Hasher for SipHasher13 {
    #[inline]
    fn write(&mut self, msg: &[u8]) {
        self.hasher.write(msg)
    }

    #[inline]
    fn finish(&self) -> u64 {
        self.hasher.finish()
    }
}

impl<S: Sip> super::Hasher for Hasher<S> {
    // Note: no integer hashing methods (`write_u*`, `write_i*`) are defined
    // for this type. We could add them, copy the `short_write` implementation
    // in librustc_data_structures/sip128.rs, and add `write_u*`/`write_i*`
    // methods to `SipHasher`, `SipHasher13`, and `DefaultHasher`. This would
    // greatly speed up integer hashing by those hashers, at the cost of
    // slightly slowing down compile speeds on some benchmarks. See #69152 for
    // details.
    #[inline]
    fn write(&mut self, msg: &[u8]) {
        let length = msg.len();
        self.length += length;

        let mut needed = 0;

        if self.ntail != 0 {
            needed = 8 - self.ntail;
            self.tail |= unsafe { u8to64_le(msg, 0, cmp::min(length, needed)) } << (8 * self.ntail);
            if length < needed {
                self.ntail += length;
                return;
            } else {
                self.state.v3 ^= self.tail;
                S::c_rounds(&mut self.state);
                self.state.v0 ^= self.tail;
                self.ntail = 0;
            }
        }

        // Buffered tail is now flushed, process new input.
        let len = length - needed;
        let left = len & 0x7;

        let mut i = needed;
        while i < len - left {
            let mi = unsafe { load_int_le!(msg, i, u64) };

            self.state.v3 ^= mi;
            S::c_rounds(&mut self.state);
            self.state.v0 ^= mi;

            i += 8;
        }

        self.tail = unsafe { u8to64_le(msg, i, left) };
        self.ntail = left;
    }

    #[inline]
    fn finish(&self) -> u64 {
        let mut state = self.state;

        let b: u64 = ((self.length as u64 & 0xff) << 56) | self.tail;

        state.v3 ^= b;
        S::c_rounds(&mut state);
        state.v0 ^= b;

        state.v2 ^= 0xff;
        S::d_rounds(&mut state);

        state.v0 ^ state.v1 ^ state.v2 ^ state.v3
    }
}

impl<S: Sip> Clone for Hasher<S> {
    #[inline]
    fn clone(&self) -> Hasher<S> {
        Hasher {
            k0: self.k0,
            k1: self.k1,
            length: self.length,
            state: self.state,
            tail: self.tail,
            ntail: self.ntail,
            _marker: self._marker,
        }
    }
}

impl<S: Sip> Default for Hasher<S> {
    /// Creates a `Hasher<S>` with the two initial keys set to 0.
    #[inline]
    fn default() -> Hasher<S> {
        Hasher::new_with_keys(0, 0)
    }
}

#[doc(hidden)]
trait Sip {
    fn c_rounds(_: &mut State);
    fn d_rounds(_: &mut State);
}

#[derive(Debug, Clone, Default)]
struct Sip13Rounds;

impl Sip for Sip13Rounds {
    #[inline]
    fn c_rounds(state: &mut State) {
        compress!(state);
    }

    #[inline]
    fn d_rounds(state: &mut State) {
        compress!(state);
        compress!(state);
        compress!(state);
    }
}

#[derive(Debug, Clone, Default)]
struct Sip24Rounds;

impl Sip for Sip24Rounds {
    #[inline]
    fn c_rounds(state: &mut State) {
        compress!(state);
        compress!(state);
    }

    #[inline]
    fn d_rounds(state: &mut State) {
        compress!(state);
        compress!(state);
        compress!(state);
        compress!(state);
    }
}
<commit_msg>Document unsafety in `src/libcore/hash/sip.rs`<commit_after>//! An implementation of SipHash.

#![allow(deprecated)] // the types in this module are deprecated

use crate::cmp;
use crate::marker::PhantomData;
use crate::mem;
use crate::ptr;

/// An implementation of SipHash 1-3.
///
/// This is currently the default hashing function used by standard library
/// (e.g., `collections::HashMap` uses it by default).
///
/// See: <https://131002.net/siphash>
#[unstable(feature = "hashmap_internals", issue = "none")]
#[rustc_deprecated(
    since = "1.13.0",
    reason = "use `std::collections::hash_map::DefaultHasher` instead"
)]
#[derive(Debug, Clone, Default)]
#[doc(hidden)]
pub struct SipHasher13 {
    hasher: Hasher<Sip13Rounds>,
}

/// An implementation of SipHash 2-4.
///
/// See: <https://131002.net/siphash/>
#[unstable(feature = "hashmap_internals", issue = "none")]
#[rustc_deprecated(
    since = "1.13.0",
    reason = "use `std::collections::hash_map::DefaultHasher` instead"
)]
#[derive(Debug, Clone, Default)]
struct SipHasher24 {
    hasher: Hasher<Sip24Rounds>,
}

/// An implementation of SipHash 2-4.
///
/// See: <https://131002.net/siphash/>
///
/// SipHash is a general-purpose hashing function: it runs at a good
/// speed (competitive with Spooky and City) and permits strong _keyed_
/// hashing. This lets you key your hashtables from a strong RNG, such as
/// [`rand::os::OsRng`](https://doc.rust-lang.org/rand/rand/os/struct.OsRng.html).
///
/// Although the SipHash algorithm is considered to be generally strong,
/// it is not intended for cryptographic purposes. As such, all
/// cryptographic uses of this implementation are _strongly discouraged_.
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_deprecated(
    since = "1.13.0",
    reason = "use `std::collections::hash_map::DefaultHasher` instead"
)]
#[derive(Debug, Clone, Default)]
pub struct SipHasher(SipHasher24);

#[derive(Debug)]
struct Hasher<S: Sip> {
    k0: u64,
    k1: u64,
    length: usize, // how many bytes we've processed
    state: State,  // hash State
    tail: u64,     // unprocessed bytes le
    ntail: usize,  // how many bytes in tail are valid
    _marker: PhantomData<S>,
}

#[derive(Debug, Clone, Copy)]
#[repr(C)]
struct State {
    // v0, v2 and v1, v3 show up in pairs in the algorithm,
    // and simd implementations of SipHash will use vectors
    // of v02 and v13. By placing them in this order in the struct,
    // the compiler can pick up on just a few simd optimizations by itself.
    v0: u64,
    v2: u64,
    v1: u64,
    v3: u64,
}

macro_rules! compress {
    ($state:expr) => {{ compress!($state.v0, $state.v1, $state.v2, $state.v3) }};
    ($v0:expr, $v1:expr, $v2:expr, $v3:expr) => {{
        $v0 = $v0.wrapping_add($v1);
        $v1 = $v1.rotate_left(13);
        $v1 ^= $v0;
        $v0 = $v0.rotate_left(32);
        $v2 = $v2.wrapping_add($v3);
        $v3 = $v3.rotate_left(16);
        $v3 ^= $v2;
        $v0 = $v0.wrapping_add($v3);
        $v3 = $v3.rotate_left(21);
        $v3 ^= $v0;
        $v2 = $v2.wrapping_add($v1);
        $v1 = $v1.rotate_left(17);
        $v1 ^= $v2;
        $v2 = $v2.rotate_left(32);
    }};
}

/// Loads an integer of the desired type from a byte stream, in LE order. Uses
/// `copy_nonoverlapping` to let the compiler generate the most efficient way
/// to load it from a possibly unaligned address.
///
/// Unsafe because: unchecked indexing at i..i+size_of(int_ty)
macro_rules! load_int_le {
    ($buf:expr, $i:expr, $int_ty:ident) => {{
        debug_assert!($i + mem::size_of::<$int_ty>() <= $buf.len());
        let mut data = 0 as $int_ty;
        ptr::copy_nonoverlapping(
            $buf.get_unchecked($i),
            &mut data as *mut _ as *mut u8,
            mem::size_of::<$int_ty>(),
        );
        data.to_le()
    }};
}

/// Loads a u64 using up to 7 bytes of a byte slice. It looks clumsy but the
/// `copy_nonoverlapping` calls that occur (via `load_int_le!`) all have fixed
/// sizes and avoid calling `memcpy`, which is good for speed.
///
/// Unsafe because: unchecked indexing at start..start+len
#[inline]
unsafe fn u8to64_le(buf: &[u8], start: usize, len: usize) -> u64 {
    debug_assert!(len < 8);
    let mut i = 0; // current byte index (from LSB) in the output u64
    let mut out = 0;
    if i + 3 < len {
        out = load_int_le!(buf, start + i, u32) as u64;
        i += 4;
    }
    if i + 1 < len {
        out |= (load_int_le!(buf, start + i, u16) as u64) << (i * 8);
        i += 2
    }
    if i < len {
        out |= (*buf.get_unchecked(start + i) as u64) << (i * 8);
        i += 1;
    }
    debug_assert_eq!(i, len);
    out
}

impl SipHasher {
    /// Creates a new `SipHasher` with the two initial keys set to 0.
    #[inline]
    #[stable(feature = "rust1", since = "1.0.0")]
    #[rustc_deprecated(
        since = "1.13.0",
        reason = "use `std::collections::hash_map::DefaultHasher` instead"
    )]
    pub fn new() -> SipHasher {
        SipHasher::new_with_keys(0, 0)
    }

    /// Creates a `SipHasher` that is keyed off the provided keys.
    #[inline]
    #[stable(feature = "rust1", since = "1.0.0")]
    #[rustc_deprecated(
        since = "1.13.0",
        reason = "use `std::collections::hash_map::DefaultHasher` instead"
    )]
    pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher {
        SipHasher(SipHasher24 { hasher: Hasher::new_with_keys(key0, key1) })
    }
}

impl SipHasher13 {
    /// Creates a new `SipHasher13` with the two initial keys set to 0.
    #[inline]
    #[unstable(feature = "hashmap_internals", issue = "none")]
    #[rustc_deprecated(
        since = "1.13.0",
        reason = "use `std::collections::hash_map::DefaultHasher` instead"
    )]
    pub fn new() -> SipHasher13 {
        SipHasher13::new_with_keys(0, 0)
    }

    /// Creates a `SipHasher13` that is keyed off the provided keys.
    #[inline]
    #[unstable(feature = "hashmap_internals", issue = "none")]
    #[rustc_deprecated(
        since = "1.13.0",
        reason = "use `std::collections::hash_map::DefaultHasher` instead"
    )]
    pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher13 {
        SipHasher13 { hasher: Hasher::new_with_keys(key0, key1) }
    }
}

impl<S: Sip> Hasher<S> {
    #[inline]
    fn new_with_keys(key0: u64, key1: u64) -> Hasher<S> {
        let mut state = Hasher {
            k0: key0,
            k1: key1,
            length: 0,
            state: State { v0: 0, v1: 0, v2: 0, v3: 0 },
            tail: 0,
            ntail: 0,
            _marker: PhantomData,
        };
        state.reset();
        state
    }

    #[inline]
    fn reset(&mut self) {
        self.length = 0;
        self.state.v0 = self.k0 ^ 0x736f6d6570736575;
        self.state.v1 = self.k1 ^ 0x646f72616e646f6d;
        self.state.v2 = self.k0 ^ 0x6c7967656e657261;
        self.state.v3 = self.k1 ^ 0x7465646279746573;
        self.ntail = 0;
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl super::Hasher for SipHasher {
    #[inline]
    fn write(&mut self, msg: &[u8]) {
        self.0.hasher.write(msg)
    }

    #[inline]
    fn finish(&self) -> u64 {
        self.0.hasher.finish()
    }
}

#[unstable(feature = "hashmap_internals", issue = "none")]
impl super::Hasher for SipHasher13 {
    #[inline]
    fn write(&mut self, msg: &[u8]) {
        self.hasher.write(msg)
    }

    #[inline]
    fn finish(&self) -> u64 {
        self.hasher.finish()
    }
}

impl<S: Sip> super::Hasher for Hasher<S> {
    // Note: no integer hashing methods (`write_u*`, `write_i*`) are defined
    // for this type. We could add them, copy the `short_write` implementation
    // in librustc_data_structures/sip128.rs, and add `write_u*`/`write_i*`
    // methods to `SipHasher`, `SipHasher13`, and `DefaultHasher`. This would
    // greatly speed up integer hashing by those hashers, at the cost of
    // slightly slowing down compile speeds on some benchmarks. See #69152 for
    // details.
    #[inline]
    fn write(&mut self, msg: &[u8]) {
        let length = msg.len();
        self.length += length;

        let mut needed = 0;

        if self.ntail != 0 {
            needed = 8 - self.ntail;
            // SAFETY: `cmp::min(length, needed)` is guaranteed to not be over `length`
            self.tail |= unsafe { u8to64_le(msg, 0, cmp::min(length, needed)) } << (8 * self.ntail);
            if length < needed {
                self.ntail += length;
                return;
            } else {
                self.state.v3 ^= self.tail;
                S::c_rounds(&mut self.state);
                self.state.v0 ^= self.tail;
                self.ntail = 0;
            }
        }

        // Buffered tail is now flushed, process new input.
        let len = length - needed;
        let left = len & 0x7; // len % 8

        let mut i = needed;
        while i < len - left {
            // SAFETY: because `len - left` is the biggest multiple of 8 under
            // `len`, and because `i` starts at `needed` where `len` is `length - needed`,
            // `i + 8` is guaranteed to be less than or equal to `length`.
            let mi = unsafe { load_int_le!(msg, i, u64) };

            self.state.v3 ^= mi;
            S::c_rounds(&mut self.state);
            self.state.v0 ^= mi;

            i += 8;
        }

        // SAFETY: `i` is now `needed + len.div_euclid(8) * 8`,
        // so `i + left` = `needed + len` = `length`, which is by
        // definition equal to `msg.len()`.
        self.tail = unsafe { u8to64_le(msg, i, left) };
        self.ntail = left;
    }

    #[inline]
    fn finish(&self) -> u64 {
        let mut state = self.state;

        let b: u64 = ((self.length as u64 & 0xff) << 56) | self.tail;

        state.v3 ^= b;
        S::c_rounds(&mut state);
        state.v0 ^= b;

        state.v2 ^= 0xff;
        S::d_rounds(&mut state);

        state.v0 ^ state.v1 ^ state.v2 ^ state.v3
    }
}

impl<S: Sip> Clone for Hasher<S> {
    #[inline]
    fn clone(&self) -> Hasher<S> {
        Hasher {
            k0: self.k0,
            k1: self.k1,
            length: self.length,
            state: self.state,
            tail: self.tail,
            ntail: self.ntail,
            _marker: self._marker,
        }
    }
}

impl<S: Sip> Default for Hasher<S> {
    /// Creates a `Hasher<S>` with the two initial keys set to 0.
    #[inline]
    fn default() -> Hasher<S> {
        Hasher::new_with_keys(0, 0)
    }
}

#[doc(hidden)]
trait Sip {
    fn c_rounds(_: &mut State);
    fn d_rounds(_: &mut State);
}

#[derive(Debug, Clone, Default)]
struct Sip13Rounds;

impl Sip for Sip13Rounds {
    #[inline]
    fn c_rounds(state: &mut State) {
        compress!(state);
    }

    #[inline]
    fn d_rounds(state: &mut State) {
        compress!(state);
        compress!(state);
        compress!(state);
    }
}

#[derive(Debug, Clone, Default)]
struct Sip24Rounds;

impl Sip for Sip24Rounds {
    #[inline]
    fn c_rounds(state: &mut State) {
        compress!(state);
        compress!(state);
    }

    #[inline]
    fn d_rounds(state: &mut State) {
        compress!(state);
        compress!(state);
        compress!(state);
        compress!(state);
    }
}
<|endoftext|>


<commit_before>use vector::{Vec2, Vec3, Vec4};

pub trait BooleanVector {
    pure fn any() -> bool;
    pure fn all() -> bool;
    pure fn not() -> self;
}

#[inline(always)] pub pure fn any<T:BooleanVector>(x: &T) -> bool { x.any() }
#[inline(always)] pub pure fn all<T:BooleanVector>(x: &T) -> bool { x.all() }
#[inline(always)] pub pure fn not<T:BooleanVector>(x: &T) -> T    { x.not() }

pub impl Vec2<bool>: BooleanVector {
    pure fn any() -> bool {
        self[0] || self[1]
    }

    pure fn all() -> bool {
        self[0] && self[1]
    }

    pure fn not() -> Vec2<bool> {
        Vec2::new(!self[0], !self[1])
    }
}

pub impl Vec3<bool>: BooleanVector {
    pure fn any() -> bool {
        self[0] || self[1] || self[2]
    }

    pure fn all() -> bool {
        self[0] && self[1] && self[2]
    }

    pure fn not() -> Vec3<bool> {
        Vec3::new(!self[0], !self[1], !self[2])
    }
}

pub impl Vec4<bool>: BooleanVector {
    pure fn any() -> bool {
        self[0] || self[1] || self[2] || self[3]
    }

    pure fn all() -> bool {
        self[0] && self[1] && self[2] && self[3]
    }

    pure fn not() -> Vec4<bool> {
        Vec4::new(!self[0], !self[1], !self[2], !self[3])
    }
}<commit_msg>Inherit Vector trait<commit_after>use vector::{Vector, Vec2, Vec3, Vec4};

pub trait BooleanVector: Vector<bool> {
    pure fn any() -> bool;
    pure fn all() -> bool;
    pure fn not() -> self;
}

#[inline(always)] pub pure fn any<T:BooleanVector>(x: &T) -> bool { x.any() }
#[inline(always)] pub pure fn all<T:BooleanVector>(x: &T) -> bool { x.all() }
#[inline(always)] pub pure fn not<T:BooleanVector>(x: &T) -> T    { x.not() }

pub impl Vec2<bool>: BooleanVector {
    pure fn any() -> bool {
        self[0] || self[1]
    }

    pure fn all() -> bool {
        self[0] && self[1]
    }

    pure fn not() -> Vec2<bool> {
        Vec2::new(!self[0], !self[1])
    }
}

pub impl Vec3<bool>: BooleanVector {
    pure fn any() -> bool {
        self[0] || self[1] || self[2]
    }

    pure fn all() -> bool {
        self[0] && self[1] && self[2]
    }

    pure fn not() -> Vec3<bool> {
        Vec3::new(!self[0], !self[1], !self[2])
    }
}

pub impl Vec4<bool>: BooleanVector {
    pure fn any() -> bool {
        self[0] || self[1] || self[2] || self[3]
    }

    pure fn all() -> bool {
        self[0] && self[1] && self[2] && self[3]
    }

    pure fn not() -> Vec4<bool> {
        Vec4::new(!self[0], !self[1], !self[2], !self[3])
    }
}<|endoftext|>


<commit_before>// Copyright 2013 The Lmath Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Coordinate vectors for positional data
//!
//! These types differ from the vector types implemented in `core::vec` because
//! they describe coordinates in geometric space and not a magnitude and a
//! direction. All positional data throughout the library uses these point
//! types, which allows for a clear, self-documenting API.

use std::cast;

use core::{Mat2, Mat3, Quat, Vec2, Vec3};

#[path = "../num_macros.rs"]
mod num_macros;

/// A geometric point
pub trait Point<T, Vec>: Eq
                       + Add<Vec, Self>
                       + Sub<Self, Vec>
                       + Mul<Vec, Self>
                       + ApproxEq<T>
                       + ToStr {
    pub fn as_vec<'a>(&'a self) -> &'a Vec;
    pub fn as_mut_vec<'a>(&'a mut self) -> &'a mut Vec;

    pub fn translate(&self, offset: &Vec) -> Self;
    pub fn scale(&self, factor: &Vec) -> Self;
    pub fn distance2(&self, other: &Self) -> T;
    pub fn distance(&self, other: &Self) -> T;
    pub fn direction(&self, other: &Self) -> Vec;
}

/// A two-dimensional point
#[deriving(Clone, Eq)]
pub struct Point2<T> { x: T, y: T }

impl<T:Num> Point2<T> {
    #[inline]
    pub fn new(x: T, y: T) -> Point2<T> {
        Point2 { x: x, y: y }
    }

    #[inline]
    pub fn from_vec(vec: Vec2<T>) -> Point2<T> {
        unsafe { cast::transmute(vec) }
    }

    #[inline]
    pub fn origin() -> Point2<T> {
        Point2::new(zero!(T), zero!(T))
    }
}

impl<T:Clone + Float> Point2<T> {
    #[inline]
    pub fn rotate_t(&self, radians: &T) -> Point2<T> {
        Point2::new((*self).x.cos() * (*radians),
                    (*self).y.sin() * (*radians))
    }

    #[inline]
    pub fn rotate_m(&self, mat: &Mat2<T>) -> Point2<T> {
        Point2::from_vec(mat.mul_v(self.as_vec()))
    }
}

impl<T:Clone + Float> Point<T, Vec2<T>> for Point2<T> {
    #[inline]
    pub fn as_vec<'a>(&'a self) -> &'a Vec2<T> {
        unsafe { cast::transmute(self) }
    }

    #[inline]
    pub fn as_mut_vec<'a>(&'a mut self) -> &'a mut Vec2<T> {
        unsafe { cast::transmute(self) }
    }

    #[inline]
    pub fn translate(&self, offset: &Vec2<T>) -> Point2<T> {
        (*self) + (*offset)
    }

    #[inline]
    pub fn scale(&self, factor: &Vec2<T>) -> Point2<T> {
        (*self) * (*factor)
    }

    #[inline]
    pub fn distance2(&self, other: &Point2<T>) -> T {
        ((*other) - (*self)).length2()
    }

    #[inline]
    pub fn distance(&self, other: &Point2<T>) -> T {
        other.distance2(self).sqrt()
    }

    #[inline]
    pub fn direction(&self, other: &Point2<T>) -> Vec2<T> {
        ((*other) - (*self)).normalize()
    }
}

impl<T:Num> Add<Vec2<T>, Point2<T>> for Point2<T> {
    fn add(&self, other: &Vec2<T>) -> Point2<T> {
        Point2::new((*self).x + (*other).x,
                    (*self).y + (*other).y)
    }
}

impl<T:Num> Sub<Point2<T>, Vec2<T>> for Point2<T> {
    fn sub(&self, other: &Point2<T>) -> Vec2<T> {
        Vec2::new((*self).x - (*other).x,
                  (*self).y - (*other).y)
    }
}

impl<T:Num> Mul<Vec2<T>, Point2<T>> for Point2<T> {
    fn mul(&self, scale: &Vec2<T>) -> Point2<T> {
        Point2::new((*self).x * (*scale).x,
                    (*self).y * (*scale).y)
    }
}

impl<T:Clone + Eq + ApproxEq<T>> ApproxEq<T> for Point2<T> {
    #[inline]
    pub fn approx_epsilon() -> T {
        ApproxEq::approx_epsilon::<T,T>()
    }

    #[inline]
    pub fn approx_eq(&self, other: &Point2<T>) -> bool {
        self.approx_eq_eps(other, &ApproxEq::approx_epsilon::<T,T>())
    }

    #[inline]
    pub fn approx_eq_eps(&self, other: &Point2<T>, epsilon: &T) -> bool {
        self.x.approx_eq_eps(&other.x, epsilon) &&
        self.y.approx_eq_eps(&other.y, epsilon)
    }
}

impl<T> ToStr for Point2<T> {
    pub fn to_str(&self) -> ~str {
        fmt!("[%?, %?]", self.x, self.y)
    }
}

#[cfg(test)]
mod test_point2 {
    use geom::point::*;

    #[test]
    fn test_to_str() {
        assert_eq!(Point2::new(1, 2).to_str(), ~"[1, 2]");
    }
}

/// A three-dimensional point
#[deriving(Clone, Eq)]
pub struct Point3<T> { x: T, y: T, z: T }

impl<T:Num> Point3<T> {
    #[inline]
    pub fn new(x: T, y: T, z: T) -> Point3<T> {
        Point3 { x: x, y: y, z: z }
    }

    #[inline]
    pub fn from_vec(vec: Vec3<T>) -> Point3<T> {
        unsafe { cast::transmute(vec) }
    }

    #[inline]
    pub fn origin() -> Point3<T> {
        Point3::new(zero!(T), zero!(T), zero!(T))
    }
}

impl<T:Clone + Float> Point3<T> {
    #[inline]
    pub fn rotate_q(&self, quat: &Quat<T>) -> Point3<T> {
        Point3::from_vec(quat.mul_v(self.as_vec()))
    }

    #[inline]
    pub fn rotate_m(&self, mat: &Mat3<T>) -> Point3<T> {
        Point3::from_vec(mat.mul_v(self.as_vec()))
    }
}

impl<T:Clone + Float> Point<T, Vec3<T>> for Point3<T> {
    #[inline]
    pub fn as_vec<'a>(&'a self) -> &'a Vec3<T> {
        unsafe { cast::transmute(self) }
    }

    #[inline]
    pub fn as_mut_vec<'a>(&'a mut self) -> &'a mut Vec3<T> {
        unsafe { cast::transmute(self) }
    }

    #[inline]
    pub fn translate(&self, offset: &Vec3<T>) -> Point3<T> {
        (*self) + (*offset)
    }

    #[inline]
    pub fn scale(&self, factor: &Vec3<T>) -> Point3<T> {
        (*self) * (*factor)
    }

    #[inline]
    pub fn distance2(&self, other: &Point3<T>) -> T {
        ((*other) - (*self)).length2()
    }

    #[inline]
    pub fn distance(&self, other: &Point3<T>) -> T {
        other.distance2(self).sqrt()
    }

    #[inline]
    pub fn direction(&self, other: &Point3<T>) -> Vec3<T> {
        ((*other) - (*self)).normalize()
    }
}

impl<T:Num> Add<Vec3<T>, Point3<T>> for Point3<T> {
    fn add(&self, other: &Vec3<T>) -> Point3<T> {
        Point3::new((*self).x + (*other).x,
                    (*self).y + (*other).y,
                    (*self).z + (*other).z)
    }
}

impl<T:Num> Sub<Point3<T>, Vec3<T>> for Point3<T> {
    fn sub(&self, other: &Point3<T>) -> Vec3<T> {
        Vec3::new((*self).x - (*other).x,
                  (*self).y - (*other).y,
                  (*self).z - (*other).z)
    }
}

impl<T:Num> Mul<Vec3<T>, Point3<T>> for Point3<T> {
    fn mul(&self, scale: &Vec3<T>) -> Point3<T> {
        Point3::new((*self).x * (*scale).x,
                    (*self).y * (*scale).y,
                    (*self).z * (*scale).z)
    }
}

impl<T:Clone + Eq + ApproxEq<T>> ApproxEq<T> for Point3<T> {
    #[inline]
    pub fn approx_epsilon() -> T {
        ApproxEq::approx_epsilon::<T,T>()
    }

    #[inline]
    pub fn approx_eq(&self, other: &Point3<T>) -> bool {
        self.approx_eq_eps(other, &ApproxEq::approx_epsilon::<T,T>())
    }

    #[inline]
    pub fn approx_eq_eps(&self, other: &Point3<T>, epsilon: &T) -> bool {
        self.x.approx_eq_eps(&other.x, epsilon) &&
        self.y.approx_eq_eps(&other.y, epsilon) &&
        self.z.approx_eq_eps(&other.z, epsilon)
    }
}

impl<T> ToStr for Point3<T> {
    pub fn to_str(&self) -> ~str {
        fmt!("[%?, %?, %?]", self.x, self.y, self.z)
    }
}

#[cfg(test)]
mod test_point3 {
    use geom::point::*;

    #[test]
    fn test_to_str() {
        assert_eq!(Point3::new(1, 2, 3).to_str(), ~"[1, 2, 3]");
    }
}
<commit_msg>Add conversions from points to homogenous coordinates<commit_after>// Copyright 2013 The Lmath Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Coordinate vectors for positional data
//!
//! These types differ from the vector types implemented in `core::vec` because
//! they describe coordinates in geometric space and not a magnitude and a
//! direction. All positional data throughout the library uses these point
//! types, which allows for a clear, self-documenting API.

use std::cast;

use core::{Mat2, Mat3, Quat, Vec2, Vec3, Vec4};

#[path = "../num_macros.rs"]
mod num_macros;

/// A geometric point
pub trait Point<T, Vec>: Eq
                       + Add<Vec, Self>
                       + Sub<Self, Vec>
                       + Mul<Vec, Self>
                       + ApproxEq<T>
                       + ToStr {
    pub fn as_vec<'a>(&'a self) -> &'a Vec;
    pub fn as_mut_vec<'a>(&'a mut self) -> &'a mut Vec;

    pub fn translate(&self, offset: &Vec) -> Self;
    pub fn scale(&self, factor: &Vec) -> Self;
    pub fn distance2(&self, other: &Self) -> T;
    pub fn distance(&self, other: &Self) -> T;
    pub fn direction(&self, other: &Self) -> Vec;
}

/// A two-dimensional point
#[deriving(Clone, Eq)]
pub struct Point2<T> { x: T, y: T }

impl<T:Num> Point2<T> {
    #[inline]
    pub fn new(x: T, y: T) -> Point2<T> {
        Point2 { x: x, y: y }
    }

    #[inline]
    pub fn from_vec(vec: Vec2<T>) -> Point2<T> {
        unsafe { cast::transmute(vec) }
    }

    #[inline]
    pub fn origin() -> Point2<T> {
        Point2::new(zero!(T), zero!(T))
    }
}

impl<T:Clone + Num> Point2<T> {
    /// Converts the point to a three-dimensional homogeneous vector:
    /// `[x, y] -> [x, y, 1]`
    #[inline]
    pub fn to_vec3(&self) -> Vec3<T> {
        Vec3::new((*self).x.clone(),
                  (*self).y.clone(),
                  one!(T))
    }
}

impl<T:Clone + Float> Point2<T> {
    #[inline]
    pub fn rotate_t(&self, radians: &T) -> Point2<T> {
        Point2::new((*self).x.cos() * (*radians),
                    (*self).y.sin() * (*radians))
    }

    #[inline]
    pub fn rotate_m(&self, mat: &Mat2<T>) -> Point2<T> {
        Point2::from_vec(mat.mul_v(self.as_vec()))
    }
}

impl<T:Clone + Float> Point<T, Vec2<T>> for Point2<T> {
    #[inline]
    pub fn as_vec<'a>(&'a self) -> &'a Vec2<T> {
        unsafe { cast::transmute(self) }
    }

    #[inline]
    pub fn as_mut_vec<'a>(&'a mut self) -> &'a mut Vec2<T> {
        unsafe { cast::transmute(self) }
    }

    #[inline]
    pub fn translate(&self, offset: &Vec2<T>) -> Point2<T> {
        (*self) + (*offset)
    }

    #[inline]
    pub fn scale(&self, factor: &Vec2<T>) -> Point2<T> {
        (*self) * (*factor)
    }

    #[inline]
    pub fn distance2(&self, other: &Point2<T>) -> T {
        ((*other) - (*self)).length2()
    }

    #[inline]
    pub fn distance(&self, other: &Point2<T>) -> T {
        other.distance2(self).sqrt()
    }

    #[inline]
    pub fn direction(&self, other: &Point2<T>) -> Vec2<T> {
        ((*other) - (*self)).normalize()
    }
}

impl<T:Num> Add<Vec2<T>, Point2<T>> for Point2<T> {
    fn add(&self, other: &Vec2<T>) -> Point2<T> {
        Point2::new((*self).x + (*other).x,
                    (*self).y + (*other).y)
    }
}

impl<T:Num> Sub<Point2<T>, Vec2<T>> for Point2<T> {
    fn sub(&self, other: &Point2<T>) -> Vec2<T> {
        Vec2::new((*self).x - (*other).x,
                  (*self).y - (*other).y)
    }
}

impl<T:Num> Mul<Vec2<T>, Point2<T>> for Point2<T> {
    fn mul(&self, scale: &Vec2<T>) -> Point2<T> {
        Point2::new((*self).x * (*scale).x,
                    (*self).y * (*scale).y)
    }
}

impl<T:Clone + Eq + ApproxEq<T>> ApproxEq<T> for Point2<T> {
    #[inline]
    pub fn approx_epsilon() -> T {
        ApproxEq::approx_epsilon::<T,T>()
    }

    #[inline]
    pub fn approx_eq(&self, other: &Point2<T>) -> bool {
        self.approx_eq_eps(other, &ApproxEq::approx_epsilon::<T,T>())
    }

    #[inline]
    pub fn approx_eq_eps(&self, other: &Point2<T>, epsilon: &T) -> bool {
        self.x.approx_eq_eps(&other.x, epsilon) &&
        self.y.approx_eq_eps(&other.y, epsilon)
    }
}

impl<T> ToStr for Point2<T> {
    pub fn to_str(&self) -> ~str {
        fmt!("[%?, %?]", self.x, self.y)
    }
}

#[cfg(test)]
mod test_point2 {
    use geom::point::*;

    #[test]
    fn test_to_str() {
        assert_eq!(Point2::new(1, 2).to_str(), ~"[1, 2]");
    }
}

/// A three-dimensional point
#[deriving(Clone, Eq)]
pub struct Point3<T> { x: T, y: T, z: T }

impl<T:Num> Point3<T> {
    #[inline]
    pub fn new(x: T, y: T, z: T) -> Point3<T> {
        Point3 { x: x, y: y, z: z }
    }

    #[inline]
    pub fn from_vec(vec: Vec3<T>) -> Point3<T> {
        unsafe { cast::transmute(vec) }
    }

    #[inline]
    pub fn origin() -> Point3<T> {
        Point3::new(zero!(T), zero!(T), zero!(T))
    }
}

impl<T:Clone + Num> Point3<T> {
    /// Converts the point to a four-dimensional homogeneous vector:
    /// `[x, y, z] -> [x, y, z, 1]`
    #[inline]
    pub fn to_vec4(&self) -> Vec4<T> {
        Vec4::new((*self).x.clone(),
                  (*self).y.clone(),
                  (*self).z.clone(),
                  one!(T))
    }
}

impl<T:Clone + Float> Point3<T> {
    #[inline]
    pub fn rotate_q(&self, quat: &Quat<T>) -> Point3<T> {
        Point3::from_vec(quat.mul_v(self.as_vec()))
    }

    #[inline]
    pub fn rotate_m(&self, mat: &Mat3<T>) -> Point3<T> {
        Point3::from_vec(mat.mul_v(self.as_vec()))
    }
}

impl<T:Clone + Float> Point<T, Vec3<T>> for Point3<T> {
    #[inline]
    pub fn as_vec<'a>(&'a self) -> &'a Vec3<T> {
        unsafe { cast::transmute(self) }
    }

    #[inline]
    pub fn as_mut_vec<'a>(&'a mut self) -> &'a mut Vec3<T> {
        unsafe { cast::transmute(self) }
    }

    #[inline]
    pub fn translate(&self, offset: &Vec3<T>) -> Point3<T> {
        (*self) + (*offset)
    }

    #[inline]
    pub fn scale(&self, factor: &Vec3<T>) -> Point3<T> {
        (*self) * (*factor)
    }

    #[inline]
    pub fn distance2(&self, other: &Point3<T>) -> T {
        ((*other) - (*self)).length2()
    }

    #[inline]
    pub fn distance(&self, other: &Point3<T>) -> T {
        other.distance2(self).sqrt()
    }

    #[inline]
    pub fn direction(&self, other: &Point3<T>) -> Vec3<T> {
        ((*other) - (*self)).normalize()
    }
}

impl<T:Num> Add<Vec3<T>, Point3<T>> for Point3<T> {
    fn add(&self, other: &Vec3<T>) -> Point3<T> {
        Point3::new((*self).x + (*other).x,
                    (*self).y + (*other).y,
                    (*self).z + (*other).z)
    }
}

impl<T:Num> Sub<Point3<T>, Vec3<T>> for Point3<T> {
    fn sub(&self, other: &Point3<T>) -> Vec3<T> {
        Vec3::new((*self).x - (*other).x,
                  (*self).y - (*other).y,
                  (*self).z - (*other).z)
    }
}

impl<T:Num> Mul<Vec3<T>, Point3<T>> for Point3<T> {
    fn mul(&self, scale: &Vec3<T>) -> Point3<T> {
        Point3::new((*self).x * (*scale).x,
                    (*self).y * (*scale).y,
                    (*self).z * (*scale).z)
    }
}

impl<T:Clone + Eq + ApproxEq<T>> ApproxEq<T> for Point3<T> {
    #[inline]
    pub fn approx_epsilon() -> T {
        ApproxEq::approx_epsilon::<T,T>()
    }

    #[inline]
    pub fn approx_eq(&self, other: &Point3<T>) -> bool {
        self.approx_eq_eps(other, &ApproxEq::approx_epsilon::<T,T>())
    }

    #[inline]
    pub fn approx_eq_eps(&self, other: &Point3<T>, epsilon: &T) -> bool {
        self.x.approx_eq_eps(&other.x, epsilon) &&
        self.y.approx_eq_eps(&other.y, epsilon) &&
        self.z.approx_eq_eps(&other.z, epsilon)
    }
}

impl<T> ToStr for Point3<T> {
    pub fn to_str(&self) -> ~str {
        fmt!("[%?, %?, %?]", self.x, self.y, self.z)
    }
}

#[cfg(test)]
mod test_point3 {
    use geom::point::*;

    #[test]
    fn test_to_str() {
        assert_eq!(Point3::new(1, 2, 3).to_str(), ~"[1, 2, 3]");
    }
}
<|endoftext|>


<commit_before>use dbus::arg::{Array};
use dbus::tree::MethodErr;
use dbus::MessageItem;

use super::utils::{parse_uuid, lock_tree_dbus};
use super::{DBusFactory, DBusObjPath};
use ::render::screen_scrape::{write_screen_scrape_lock, read_screen_scrape_lock,
                              scraped_pixels_lock, sync_scrape};

pub fn setup(f: &mut DBusFactory) -> DBusObjPath {
    f.object_path("/org/way_cooler/Screen", ()).introspectable().add(
        f.interface("org.way_cooler.Screen", ())
            .add_m(
                f.method("List", (), |m| {
                    let tree = lock_tree_dbus()?;
                    let outputs = tree.outputs().iter()
                        .map(|id|
                             MessageItem::Str(format!("{}", id.simple())))
                        .collect();
                    Ok(vec![m.msg.method_return()
                            .append((MessageItem::Array(outputs, "s".into())))
                    ])
                }).outarg::<Array<String, Vec<String>>, _>("success")
            )
            .add_m(
                f.method("Scrape", (), |m| {
                    *write_screen_scrape_lock() = true;
                    // ensure that no other threads can try to grab the pixels.
                    let _lock = read_screen_scrape_lock();
                    sync_scrape();
                    drop(_lock);
                    *write_screen_scrape_lock() = false;
                    let scraped_pixels = scraped_pixels_lock()
                        .expect("scraped_pixels lock was poisoned!");
                    let result = scraped_pixels.iter()
                        .map(|pixel| MessageItem::Byte(*pixel)).collect();
                    Ok(vec![m.msg.method_return()
                            .append((MessageItem::Array(result, "y".into())))])
                }).outarg::<Array<u8, Vec<u8>>, _>("success")
            )
            .add_m(
                f.method("Resolution", (), |m| {
                    let mut args_iter = m.msg.iter_init();
                    let output_id = args_iter.read::<String>()?;
                    let tree = lock_tree_dbus()?;
                    let uuid = parse_uuid("container_id", &output_id)?
                        .or_else(|| tree.active_id())
                        .ok_or(MethodErr::failed(&"No active container"))?;
                    let size = tree.output_resolution(uuid)
                        .map_err(|err| {
                            MethodErr::failed(&format!("{:?}", err))
                        })?;
                    Ok(vec![m.msg.method_return()
                            .append1((size.w, size.h))
                    ])
                })
                    .outarg::<(u32, u32), _>("success")
                    .inarg::<String, _>("output_id")
            )
    )
}
<commit_msg>Added todo for Scrape<commit_after>use dbus::arg::{Array};
use dbus::tree::MethodErr;
use dbus::MessageItem;

use super::utils::{parse_uuid, lock_tree_dbus};
use super::{DBusFactory, DBusObjPath};
use ::render::screen_scrape::{write_screen_scrape_lock, read_screen_scrape_lock,
                              scraped_pixels_lock, sync_scrape};

pub fn setup(f: &mut DBusFactory) -> DBusObjPath {
    f.object_path("/org/way_cooler/Screen", ()).introspectable().add(
        f.interface("org.way_cooler.Screen", ())
            .add_m(
                f.method("List", (), |m| {
                    let tree = lock_tree_dbus()?;
                    let outputs = tree.outputs().iter()
                        .map(|id|
                             MessageItem::Str(format!("{}", id.simple())))
                        .collect();
                    Ok(vec![m.msg.method_return()
                            .append((MessageItem::Array(outputs, "s".into())))
                    ])
                }).outarg::<Array<String, Vec<String>>, _>("success")
            )
            .add_m(
                // TODO Make this take in a:
                // * Output UUID
                // * Size (u32, u32) to scrape. For invalid ones, we throw error
                f.method("Scrape", (), |m| {
                    *write_screen_scrape_lock() = true;
                    // ensure that no other threads can try to grab the pixels.
                    let _lock = read_screen_scrape_lock();
                    sync_scrape();
                    drop(_lock);
                    *write_screen_scrape_lock() = false;
                    let scraped_pixels = scraped_pixels_lock()
                        .expect("scraped_pixels lock was poisoned!");
                    let result = scraped_pixels.iter()
                        .map(|pixel| MessageItem::Byte(*pixel)).collect();
                    Ok(vec![m.msg.method_return()
                            .append((MessageItem::Array(result, "y".into())))])
                }).outarg::<Array<u8, Vec<u8>>, _>("success")
            )
            .add_m(
                f.method("Resolution", (), |m| {
                    let mut args_iter = m.msg.iter_init();
                    let output_id = args_iter.read::<String>()?;
                    let tree = lock_tree_dbus()?;
                    let uuid = parse_uuid("container_id", &output_id)?
                        .or_else(|| tree.active_id())
                        .ok_or(MethodErr::failed(&"No active container"))?;
                    let size = tree.output_resolution(uuid)
                        .map_err(|err| {
                            MethodErr::failed(&format!("{:?}", err))
                        })?;
                    Ok(vec![m.msg.method_return()
                            .append1((size.w, size.h))
                    ])
                })
                    .outarg::<(u32, u32), _>("success")
                    .inarg::<String, _>("output_id")
            )
    )
}
<|endoftext|>


<commit_before>use {CrateList, GoodCrate};

use cargo_registry::owner::EncodableOwner;
use cargo_registry::user::EncodablePublicUser;
use cargo_registry::crate_owner_invitation::{EncodableCrateOwnerInvitation,
                                             NewCrateOwnerInvitation};
use cargo_registry::schema::crate_owner_invitations;

use conduit::{Handler, Method};
use diesel;
use diesel::prelude::*;

#[derive(Deserialize)]
struct TeamResponse {
    teams: Vec<EncodableOwner>,
}
#[derive(Deserialize)]
struct UserResponse {
    users: Vec<EncodableOwner>,
}

#[test]
fn new_crate_owner() {
    #[derive(Deserialize)]
    struct O {
        ok: bool,
    }

    let (_b, app, middle) = ::app();

    // Create a crate under one user
    let mut req = ::new_req(app.clone(), "foo_owner", "1.0.0");
    ::sign_in(&mut req, &app);
    let u2;
    {
        let conn = app.diesel_database.get().unwrap();
        u2 = ::new_user("bar").create_or_update(&conn).unwrap();
    }
    let mut response = ok_resp!(middle.call(&mut req));
    ::json::<GoodCrate>(&mut response);

    // Flag the second user as an owner
    let body = r#"{"users":["bar"]}"#;
    let mut response = ok_resp!(
        middle.call(
            req.with_path("/api/v1/crates/foo_owner/owners")
                .with_method(Method::Put)
                .with_body(body.as_bytes()),
        )
    );
    assert!(::json::<O>(&mut response).ok);
    bad_resp!(
        middle.call(
            req.with_path("/api/v1/crates/foo_owner/owners")
                .with_method(Method::Put)
                .with_body(body.as_bytes()),
        )
    );

    // Make sure this shows up as one of their crates.
    let query = format!("user_id={}", u2.id);
    let mut response = ok_resp!(
        middle.call(
            req.with_path("/api/v1/crates")
                .with_method(Method::Get)
                .with_query(&query),
        )
    );
    assert_eq!(::json::<CrateList>(&mut response).crates.len(), 1);

    // And upload a new crate as the first user
    let body = ::new_req_body_version_2(::krate("foo_owner"));
    ::sign_in_as(&mut req, &u2);
    let mut response = ok_resp!(
        middle.call(
            req.with_path("/api/v1/crates/new")
                .with_method(Method::Put)
                .with_body(&body),
        )
    );
    ::json::<GoodCrate>(&mut response);
}

// Ensures that so long as at least one owner remains associated with the crate,
// a user can still remove their own login as an owner
#[test]
fn owners_can_remove_self() {
    #[derive(Deserialize)]
    struct R {
        users: Vec<EncodablePublicUser>,
    }
    #[derive(Deserialize)]
    struct O {
        ok: bool,
    }

    let (_b, app, middle) = ::app();
    let mut req = ::req(
        app.clone(),
        Method::Get,
        "/api/v1/crates/owners_selfremove/owners",
    );
    {
        let conn = app.diesel_database.get().unwrap();
        ::new_user("secondowner").create_or_update(&conn).unwrap();
        let user = ::new_user("firstowner").create_or_update(&conn).unwrap();
        ::sign_in_as(&mut req, &user);
        ::CrateBuilder::new("owners_selfremove", user.id).expect_build(&conn);
    }

    let mut response = ok_resp!(middle.call(&mut req));
    let r: R = ::json(&mut response);
    assert_eq!(r.users.len(), 1);

    // Deleting yourself when you're the only owner isn't allowed.
    let body = r#"{"users":["firstowner"]}"#;
    let mut response = ok_resp!(middle.call(req.with_method(Method::Delete).with_body(
        body.as_bytes(),
    )));
    let json = ::json::<::Bad>(&mut response);
    assert!(json.errors[0].detail.contains(
        "cannot remove the sole owner of a crate",
    ));

    let body = r#"{"users":["secondowner"]}"#;
    let mut response = ok_resp!(middle.call(req.with_method(Method::Put).with_body(
        body.as_bytes(),
    )));
    assert!(::json::<O>(&mut response).ok);

    // Deleting yourself when there are other owners is allowed.
    let body = r#"{"users":["firstowner"]}"#;
    let mut response = ok_resp!(middle.call(req.with_method(Method::Delete).with_body(
        body.as_bytes(),
    )));
    assert!(::json::<O>(&mut response).ok);

    // After you delete yourself, you no longer have permisions to manage the crate.
    let body = r#"{"users":["secondowner"]}"#;
    let mut response = ok_resp!(middle.call(req.with_method(Method::Delete).with_body(
        body.as_bytes(),
    )));
    let json = ::json::<::Bad>(&mut response);
    assert!(json.errors[0].detail.contains(
        "only owners have permission to modify owners",
    ));
}

#[test]
fn owners() {
    #[derive(Deserialize)]
    struct R {
        users: Vec<EncodablePublicUser>,
    }
    #[derive(Deserialize)]
    struct O {
        ok: bool,
    }

    let (_b, app, middle) = ::app();
    let mut req = ::req(app.clone(), Method::Get, "/api/v1/crates/foo_owners/owners");
    {
        let conn = app.diesel_database.get().unwrap();
        ::new_user("foobar").create_or_update(&conn).unwrap();
        let user = ::new_user("foo").create_or_update(&conn).unwrap();
        ::sign_in_as(&mut req, &user);
        ::CrateBuilder::new("foo_owners", user.id).expect_build(&conn);
    }

    let mut response = ok_resp!(middle.call(&mut req));
    let r: R = ::json(&mut response);
    assert_eq!(r.users.len(), 1);

    let mut response = ok_resp!(middle.call(req.with_method(Method::Get)));
    let r: R = ::json(&mut response);
    assert_eq!(r.users.len(), 1);

    let body = r#"{"users":["foobar"]}"#;
    let mut response = ok_resp!(middle.call(req.with_method(Method::Put).with_body(
        body.as_bytes(),
    )));
    assert!(::json::<O>(&mut response).ok);

    let mut response = ok_resp!(middle.call(req.with_method(Method::Get)));
    let r: R = ::json(&mut response);
    assert_eq!(r.users.len(), 2);

    let body = r#"{"users":["foobar"]}"#;
    let mut response = ok_resp!(middle.call(req.with_method(Method::Delete).with_body(
        body.as_bytes(),
    )));
    assert!(::json::<O>(&mut response).ok);

    let mut response = ok_resp!(middle.call(req.with_method(Method::Get)));
    let r: R = ::json(&mut response);
    assert_eq!(r.users.len(), 1);

    let body = r#"{"users":["foo"]}"#;
    let mut response = ok_resp!(middle.call(req.with_method(Method::Delete).with_body(
        body.as_bytes(),
    )));
    ::json::<::Bad>(&mut response);

    let body = r#"{"users":["foobar"]}"#;
    let mut response = ok_resp!(middle.call(req.with_method(Method::Put).with_body(
        body.as_bytes(),
    )));
    assert!(::json::<O>(&mut response).ok);
}

/*  Testing the crate ownership between two crates and one team.
    Given two crates, one crate owned by both a team and a user,
    one only owned by a user, check that the CrateList returned
    for the user_id contains only the crates owned by that user,
    and that the CrateList returned for the team_id contains
    only crates owned by that team.
*/
#[test]
fn check_ownership_two_crates() {
    let (_b, app, middle) = ::app();

    let (krate_owned_by_team, team) = {
        let conn = app.diesel_database.get().unwrap();
        let u = ::new_user("user_foo").create_or_update(&conn).unwrap();
        let t = ::new_team("team_foo").create_or_update(&conn).unwrap();
        let krate = ::CrateBuilder::new("foo", u.id).expect_build(&conn);
        ::add_team_to_crate(&t, &krate, &u, &conn).unwrap();
        (krate, t)
    };

    let (krate_not_owned_by_team, user) = {
        let conn = app.diesel_database.get().unwrap();
        let u = ::new_user("user_bar").create_or_update(&conn).unwrap();
        (::CrateBuilder::new("bar", u.id).expect_build(&conn), u)
    };

    let mut req = ::req(app.clone(), Method::Get, "/api/v1/crates");

    let query = format!("user_id={}", user.id);
    let mut response = ok_resp!(middle.call(req.with_query(&query)));
    let json: CrateList = ::json(&mut response);

    assert_eq!(json.crates[0].name, krate_not_owned_by_team.name);
    assert_eq!(json.crates.len(), 1);

    let query = format!("team_id={}", team.id);
    let mut response = ok_resp!(middle.call(req.with_query(&query)));

    let json: CrateList = ::json(&mut response);
    assert_eq!(json.crates.len(), 1);
    assert_eq!(json.crates[0].name, krate_owned_by_team.name);
}

/*  Given a crate owned by both a team and a user, check that the
    JSON returned by the /owner_team route and /owner_user route
    contains the correct kind of owner

    Note that in this case function new_team must take a team name
    of form github:org_name:team_name as that is the format
    EncodableOwner::encodable is expecting
*/
#[test]
fn check_ownership_one_crate() {
    let (_b, app, middle) = ::app();

    let (team, user) = {
        let conn = app.diesel_database.get().unwrap();
        let u = ::new_user("user_cat").create_or_update(&conn).unwrap();
        let t = ::new_team("github:test_org:team_sloth")
            .create_or_update(&conn)
            .unwrap();
        let krate = ::CrateBuilder::new("best_crate", u.id).expect_build(&conn);
        ::add_team_to_crate(&t, &krate, &u, &conn).unwrap();
        (t, u)
    };

    let mut req = ::req(
        app.clone(),
        Method::Get,
        "/api/v1/crates/best_crate/owner_team",
    );
    let mut response = ok_resp!(middle.call(&mut req));
    let json: TeamResponse = ::json(&mut response);

    assert_eq!(json.teams[0].kind, "team");
    assert_eq!(json.teams[0].name, team.name);

    let mut req = ::req(
        app.clone(),
        Method::Get,
        "/api/v1/crates/best_crate/owner_user",
    );
    let mut response = ok_resp!(middle.call(&mut req));
    let json: UserResponse = ::json(&mut response);

    assert_eq!(json.users[0].kind, "user");
    assert_eq!(json.users[0].name, user.name);
}

#[test]
fn invitations_are_empty_by_default() {
    #[derive(Deserialize)]
    struct R {
        crate_owner_invitations: Vec<EncodableCrateOwnerInvitation>,
    }

    let (_b, app, middle) = ::app();
    let mut req = ::req(
        app.clone(),
        Method::Get,
        "/api/v1/me/crate_owner_invitations",
    );

    let user = {
        let conn = app.diesel_database.get().unwrap();
        ::new_user("user_no_invites")
            .create_or_update(&conn)
            .unwrap()
    };
    ::sign_in_as(&mut req, &user);

    let mut response = ok_resp!(middle.call(&mut req));
    let json: R = ::json(&mut response);

    assert_eq!(json.crate_owner_invitations.len(), 0);
}

#[test]
fn invitations_list() {
    #[derive(Deserialize)]
    struct R {
        crate_owner_invitations: Vec<EncodableCrateOwnerInvitation>,
    }

    let (_b, app, middle) = ::app();
    let mut req = ::req(
        app.clone(),
        Method::Get,
        "/api/v1/me/crate_owner_invitations",
    );
    let (krate, user) = {
        let conn = app.diesel_database.get().unwrap();
        let owner = ::new_user("inviting_user").create_or_update(&conn).unwrap();
        let user = ::new_user("invited_user").create_or_update(&conn).unwrap();
        let krate = ::CrateBuilder::new("invited_crate", owner.id).expect_build(&conn);

        // This should be replaced by an actual call to the route that `owner --add` hits once
        // that route creates an invitation.
        let invitation = NewCrateOwnerInvitation {
            invited_by_user_id: owner.id,
            invited_user_id: user.id,
            crate_id: krate.id,
        };
        diesel::insert(&invitation)
            .into(crate_owner_invitations::table)
            .execute(&*conn)
            .unwrap();
        (krate, user)
    };
    ::sign_in_as(&mut req, &user);

    let mut response = ok_resp!(middle.call(&mut req));
    let json: R = ::json(&mut response);

    assert_eq!(json.crate_owner_invitations.len(), 1);
    assert_eq!(json.crate_owner_invitations[0].invited_by_username, "inviting_user");
    assert_eq!(json.crate_owner_invitations[0].crate_name, "invited_crate");
    assert_eq!(json.crate_owner_invitations[0].crate_id, krate.id);
}
<commit_msg>cargo fmt<commit_after>use {CrateList, GoodCrate};

use cargo_registry::owner::EncodableOwner;
use cargo_registry::user::EncodablePublicUser;
use cargo_registry::crate_owner_invitation::{EncodableCrateOwnerInvitation,
                                             NewCrateOwnerInvitation};
use cargo_registry::schema::crate_owner_invitations;

use conduit::{Handler, Method};
use diesel;
use diesel::prelude::*;

#[derive(Deserialize)]
struct TeamResponse {
    teams: Vec<EncodableOwner>,
}
#[derive(Deserialize)]
struct UserResponse {
    users: Vec<EncodableOwner>,
}

#[test]
fn new_crate_owner() {
    #[derive(Deserialize)]
    struct O {
        ok: bool,
    }

    let (_b, app, middle) = ::app();

    // Create a crate under one user
    let mut req = ::new_req(app.clone(), "foo_owner", "1.0.0");
    ::sign_in(&mut req, &app);
    let u2;
    {
        let conn = app.diesel_database.get().unwrap();
        u2 = ::new_user("bar").create_or_update(&conn).unwrap();
    }
    let mut response = ok_resp!(middle.call(&mut req));
    ::json::<GoodCrate>(&mut response);

    // Flag the second user as an owner
    let body = r#"{"users":["bar"]}"#;
    let mut response = ok_resp!(
        middle.call(
            req.with_path("/api/v1/crates/foo_owner/owners")
                .with_method(Method::Put)
                .with_body(body.as_bytes()),
        )
    );
    assert!(::json::<O>(&mut response).ok);
    bad_resp!(
        middle.call(
            req.with_path("/api/v1/crates/foo_owner/owners")
                .with_method(Method::Put)
                .with_body(body.as_bytes()),
        )
    );

    // Make sure this shows up as one of their crates.
    let query = format!("user_id={}", u2.id);
    let mut response = ok_resp!(
        middle.call(
            req.with_path("/api/v1/crates")
                .with_method(Method::Get)
                .with_query(&query),
        )
    );
    assert_eq!(::json::<CrateList>(&mut response).crates.len(), 1);

    // And upload a new crate as the first user
    let body = ::new_req_body_version_2(::krate("foo_owner"));
    ::sign_in_as(&mut req, &u2);
    let mut response = ok_resp!(
        middle.call(
            req.with_path("/api/v1/crates/new")
                .with_method(Method::Put)
                .with_body(&body),
        )
    );
    ::json::<GoodCrate>(&mut response);
}

// Ensures that so long as at least one owner remains associated with the crate,
// a user can still remove their own login as an owner
#[test]
fn owners_can_remove_self() {
    #[derive(Deserialize)]
    struct R {
        users: Vec<EncodablePublicUser>,
    }
    #[derive(Deserialize)]
    struct O {
        ok: bool,
    }

    let (_b, app, middle) = ::app();
    let mut req = ::req(
        app.clone(),
        Method::Get,
        "/api/v1/crates/owners_selfremove/owners",
    );
    {
        let conn = app.diesel_database.get().unwrap();
        ::new_user("secondowner").create_or_update(&conn).unwrap();
        let user = ::new_user("firstowner").create_or_update(&conn).unwrap();
        ::sign_in_as(&mut req, &user);
        ::CrateBuilder::new("owners_selfremove", user.id).expect_build(&conn);
    }

    let mut response = ok_resp!(middle.call(&mut req));
    let r: R = ::json(&mut response);
    assert_eq!(r.users.len(), 1);

    // Deleting yourself when you're the only owner isn't allowed.
    let body = r#"{"users":["firstowner"]}"#;
    let mut response = ok_resp!(middle.call(req.with_method(Method::Delete).with_body(
        body.as_bytes(),
    )));
    let json = ::json::<::Bad>(&mut response);
    assert!(json.errors[0].detail.contains(
        "cannot remove the sole owner of a crate",
    ));

    let body = r#"{"users":["secondowner"]}"#;
    let mut response = ok_resp!(middle.call(req.with_method(Method::Put).with_body(
        body.as_bytes(),
    )));
    assert!(::json::<O>(&mut response).ok);

    // Deleting yourself when there are other owners is allowed.
    let body = r#"{"users":["firstowner"]}"#;
    let mut response = ok_resp!(middle.call(req.with_method(Method::Delete).with_body(
        body.as_bytes(),
    )));
    assert!(::json::<O>(&mut response).ok);

    // After you delete yourself, you no longer have permisions to manage the crate.
    let body = r#"{"users":["secondowner"]}"#;
    let mut response = ok_resp!(middle.call(req.with_method(Method::Delete).with_body(
        body.as_bytes(),
    )));
    let json = ::json::<::Bad>(&mut response);
    assert!(json.errors[0].detail.contains(
        "only owners have permission to modify owners",
    ));
}

#[test]
fn owners() {
    #[derive(Deserialize)]
    struct R {
        users: Vec<EncodablePublicUser>,
    }
    #[derive(Deserialize)]
    struct O {
        ok: bool,
    }

    let (_b, app, middle) = ::app();
    let mut req = ::req(app.clone(), Method::Get, "/api/v1/crates/foo_owners/owners");
    {
        let conn = app.diesel_database.get().unwrap();
        ::new_user("foobar").create_or_update(&conn).unwrap();
        let user = ::new_user("foo").create_or_update(&conn).unwrap();
        ::sign_in_as(&mut req, &user);
        ::CrateBuilder::new("foo_owners", user.id).expect_build(&conn);
    }

    let mut response = ok_resp!(middle.call(&mut req));
    let r: R = ::json(&mut response);
    assert_eq!(r.users.len(), 1);

    let mut response = ok_resp!(middle.call(req.with_method(Method::Get)));
    let r: R = ::json(&mut response);
    assert_eq!(r.users.len(), 1);

    let body = r#"{"users":["foobar"]}"#;
    let mut response = ok_resp!(middle.call(req.with_method(Method::Put).with_body(
        body.as_bytes(),
    )));
    assert!(::json::<O>(&mut response).ok);

    let mut response = ok_resp!(middle.call(req.with_method(Method::Get)));
    let r: R = ::json(&mut response);
    assert_eq!(r.users.len(), 2);

    let body = r#"{"users":["foobar"]}"#;
    let mut response = ok_resp!(middle.call(req.with_method(Method::Delete).with_body(
        body.as_bytes(),
    )));
    assert!(::json::<O>(&mut response).ok);

    let mut response = ok_resp!(middle.call(req.with_method(Method::Get)));
    let r: R = ::json(&mut response);
    assert_eq!(r.users.len(), 1);

    let body = r#"{"users":["foo"]}"#;
    let mut response = ok_resp!(middle.call(req.with_method(Method::Delete).with_body(
        body.as_bytes(),
    )));
    ::json::<::Bad>(&mut response);

    let body = r#"{"users":["foobar"]}"#;
    let mut response = ok_resp!(middle.call(req.with_method(Method::Put).with_body(
        body.as_bytes(),
    )));
    assert!(::json::<O>(&mut response).ok);
}

/*  Testing the crate ownership between two crates and one team.
    Given two crates, one crate owned by both a team and a user,
    one only owned by a user, check that the CrateList returned
    for the user_id contains only the crates owned by that user,
    and that the CrateList returned for the team_id contains
    only crates owned by that team.
*/
#[test]
fn check_ownership_two_crates() {
    let (_b, app, middle) = ::app();

    let (krate_owned_by_team, team) = {
        let conn = app.diesel_database.get().unwrap();
        let u = ::new_user("user_foo").create_or_update(&conn).unwrap();
        let t = ::new_team("team_foo").create_or_update(&conn).unwrap();
        let krate = ::CrateBuilder::new("foo", u.id).expect_build(&conn);
        ::add_team_to_crate(&t, &krate, &u, &conn).unwrap();
        (krate, t)
    };

    let (krate_not_owned_by_team, user) = {
        let conn = app.diesel_database.get().unwrap();
        let u = ::new_user("user_bar").create_or_update(&conn).unwrap();
        (::CrateBuilder::new("bar", u.id).expect_build(&conn), u)
    };

    let mut req = ::req(app.clone(), Method::Get, "/api/v1/crates");

    let query = format!("user_id={}", user.id);
    let mut response = ok_resp!(middle.call(req.with_query(&query)));
    let json: CrateList = ::json(&mut response);

    assert_eq!(json.crates[0].name, krate_not_owned_by_team.name);
    assert_eq!(json.crates.len(), 1);

    let query = format!("team_id={}", team.id);
    let mut response = ok_resp!(middle.call(req.with_query(&query)));

    let json: CrateList = ::json(&mut response);
    assert_eq!(json.crates.len(), 1);
    assert_eq!(json.crates[0].name, krate_owned_by_team.name);
}

/*  Given a crate owned by both a team and a user, check that the
    JSON returned by the /owner_team route and /owner_user route
    contains the correct kind of owner

    Note that in this case function new_team must take a team name
    of form github:org_name:team_name as that is the format
    EncodableOwner::encodable is expecting
*/
#[test]
fn check_ownership_one_crate() {
    let (_b, app, middle) = ::app();

    let (team, user) = {
        let conn = app.diesel_database.get().unwrap();
        let u = ::new_user("user_cat").create_or_update(&conn).unwrap();
        let t = ::new_team("github:test_org:team_sloth")
            .create_or_update(&conn)
            .unwrap();
        let krate = ::CrateBuilder::new("best_crate", u.id).expect_build(&conn);
        ::add_team_to_crate(&t, &krate, &u, &conn).unwrap();
        (t, u)
    };

    let mut req = ::req(
        app.clone(),
        Method::Get,
        "/api/v1/crates/best_crate/owner_team",
    );
    let mut response = ok_resp!(middle.call(&mut req));
    let json: TeamResponse = ::json(&mut response);

    assert_eq!(json.teams[0].kind, "team");
    assert_eq!(json.teams[0].name, team.name);

    let mut req = ::req(
        app.clone(),
        Method::Get,
        "/api/v1/crates/best_crate/owner_user",
    );
    let mut response = ok_resp!(middle.call(&mut req));
    let json: UserResponse = ::json(&mut response);

    assert_eq!(json.users[0].kind, "user");
    assert_eq!(json.users[0].name, user.name);
}

#[test]
fn invitations_are_empty_by_default() {
    #[derive(Deserialize)]
    struct R {
        crate_owner_invitations: Vec<EncodableCrateOwnerInvitation>,
    }

    let (_b, app, middle) = ::app();
    let mut req = ::req(
        app.clone(),
        Method::Get,
        "/api/v1/me/crate_owner_invitations",
    );

    let user = {
        let conn = app.diesel_database.get().unwrap();
        ::new_user("user_no_invites")
            .create_or_update(&conn)
            .unwrap()
    };
    ::sign_in_as(&mut req, &user);

    let mut response = ok_resp!(middle.call(&mut req));
    let json: R = ::json(&mut response);

    assert_eq!(json.crate_owner_invitations.len(), 0);
}

#[test]
fn invitations_list() {
    #[derive(Deserialize)]
    struct R {
        crate_owner_invitations: Vec<EncodableCrateOwnerInvitation>,
    }

    let (_b, app, middle) = ::app();
    let mut req = ::req(
        app.clone(),
        Method::Get,
        "/api/v1/me/crate_owner_invitations",
    );
    let (krate, user) = {
        let conn = app.diesel_database.get().unwrap();
        let owner = ::new_user("inviting_user").create_or_update(&conn).unwrap();
        let user = ::new_user("invited_user").create_or_update(&conn).unwrap();
        let krate = ::CrateBuilder::new("invited_crate", owner.id).expect_build(&conn);

        // This should be replaced by an actual call to the route that `owner --add` hits once
        // that route creates an invitation.
        let invitation = NewCrateOwnerInvitation {
            invited_by_user_id: owner.id,
            invited_user_id: user.id,
            crate_id: krate.id,
        };
        diesel::insert(&invitation)
            .into(crate_owner_invitations::table)
            .execute(&*conn)
            .unwrap();
        (krate, user)
    };
    ::sign_in_as(&mut req, &user);

    let mut response = ok_resp!(middle.call(&mut req));
    let json: R = ::json(&mut response);

    assert_eq!(json.crate_owner_invitations.len(), 1);
    assert_eq!(
        json.crate_owner_invitations[0].invited_by_username,
        "inviting_user"
    );
    assert_eq!(json.crate_owner_invitations[0].crate_name, "invited_crate");
    assert_eq!(json.crate_owner_invitations[0].crate_id, krate.id);
}
<|endoftext|>