<commit_before>use boxdraw;

use SimpleSearch;

// EXERCISE 1: Can you make an undraw implementation that can handle
// the case below?

#[test]
fn three_by_three() {
    boxdraw::check_undraw(".............\n\
                           ..+--+--+--+.\n\
                           ..|aa|bb|cc|.\n\
                           ..|aa|bb|cc|.\n\
                           ..+--+--+--+.\n\
                           ..|dd|ee|ff|.\n\
                           ..|dd|ee|ff|.\n\
                           ..+--+--+--+.\n\
                           ..|gg|hh|ii|.\n\
                           ..|gg|hh|ii|.\n\
                           ..+--+--+--+.\n\
                           .............\n\
                          ",
                          &SimpleSearch).unwrap();

}

// EXERCISE 2: One might think that once you generate a working
// Script, there's no further way to improve upon it. However,
// consider a case like this:
//
//
//                  ....................
//                  ......+------+......
//                  ......|bbbbbb|......
//                  ......|bbbbbb|......
//                  .+----|bbbbbb|----+.
//                  .|aaaa|bbbbbb|aaaa|.
//                  .|aaaa|bbbbbb|aaaa|.
//                  .+----|bbbbbb|----+.
//                  ......|bbbbbb|......
//                  ......+------+......
//                  ....................
//
// There are two "obvious" relatively short scripts that generate the
// above picture: one that draws two 'a' rectangles and then the
// single 'b' rectangle (thus requiring three commands in the script).
//
//  ....................       ....................
//  ....................       ......+------+......
//  ....................       ......|bbbbbb|......
//  ....................       ......|bbbbbb|......
//  .+----+......+----+.       ......|bbbbbb|......
//  .|aaaa|......|aaaa|. then  ......|bbbbbb|......
//  .|aaaa|......|aaaa|.       ......|bbbbbb|......
//  .+----+......+----+.       ......|bbbbbb|......
//  ....................       ......|bbbbbb|......
//  ....................       ......+------+......
//  ....................       ....................
//
//
// But there is also this approach, which requires only two commands:
//
//  ....................       ....................
//  ....................       ......+------+......
//  ....................       ......|bbbbbb|......
//  ....................       ......|bbbbbb|......
//  .+----------------+.       ......|bbbbbb|......
//  .|aaaaaaaaaaaaaaaa|. then  ......|bbbbbb|......
//  .|aaaaaaaaaaaaaaaa|.       ......|bbbbbb|......
//  .+----------------+.       ......|bbbbbb|......
//  ....................       ......|bbbbbb|......
//  ....................       ......+------+......
//  ....................       ....................
//
// The undraw strategy of the code above will tend to generate the
// three-command script. What ideas do you have to try to make it
// generate "optimal" scripts (where "optimal" here means "minimal
// number of commands."

// EXERCISE 3: Up until now, we have assumed that all boxes are at
// least width and height >= 2.  So for example `test::narrow_lines()`
// shows boxes of width == 2, so narrow that they have no interior.
//
// BUT: The boxdraw-rs library supports boxes of width or height == 1
// as well, and it has *very* different behavior for them. Find out
// what that behavior is (perhaps by looking at the tests in the
// boxdraw library).
//
// Consider what a box with both width and height equal to 1 would
// look like. What implications does this have? For example, what kind
// of pictures can you make with *just* boxes width and height 1?
//
// Try to solve the undraw problem even for such cases.
//
// Note 1: to do this, you may want to start from scratch; or maybe
// some of the code here could be of use.
//
// Note 2: You may want to play around first with approaches that are
// not anywhere close to optimal.

// EXERCISE 4: Like exercise 2 above: Again, solve the generalized
// undraw problem (that is, including boxes of width and/or height 1),
// but this time, try to generate relatively small scripts.
//
// Note that you can make short scripts that first draw large boxes
// (which will then have borders) and then write over the borders with
// boxes of width or height 1, like so:
//
//  ....................       ....................   ....................
//  ....................       ....................   ....................
//  ....................       ....................   ....................
//  ....................       ....................   ....................
//  .+----------------+.       .aaaaaaaaaaaaaaaaaa.   .a................a.
//  .|aaaaaaaaaaaaaaaa|. then  .................... ; .a................a.
//  .|aaaaaaaaaaaaaaaa|.       ....................   .a................a.
//  .+----------------+.       .aaaaaaaaaaaaaaaaaa.   .a................a.
//  ....................       ....................   ....................
//  ....................       ....................   ....................
//  ....................       ....................   ....................
//
// and this generates a picture with a borderless box:
//
//  ....................
//  ....................
//  ....................
//  ....................
//  .aaaaaaaaaaaaaaaaaa.
//  .aaaaaaaaaaaaaaaaaa.
//  .aaaaaaaaaaaaaaaaaa.
//  .aaaaaaaaaaaaaaaaaa.
//  ....................
//  ....................
//  ....................
<commit_msg>Try to clarify scenario being described.<commit_after>use boxdraw;

use SimpleSearch;

// EXERCISE 1: Can you make an undraw implementation that can handle
// the case below?

#[test]
fn three_by_three() {
    boxdraw::check_undraw(".............\n\
                           ..+--+--+--+.\n\
                           ..|aa|bb|cc|.\n\
                           ..|aa|bb|cc|.\n\
                           ..+--+--+--+.\n\
                           ..|dd|ee|ff|.\n\
                           ..|dd|ee|ff|.\n\
                           ..+--+--+--+.\n\
                           ..|gg|hh|ii|.\n\
                           ..|gg|hh|ii|.\n\
                           ..+--+--+--+.\n\
                           .............\n\
                          ",
                          &SimpleSearch).unwrap();

}

// EXERCISE 2: One might think that once you generate a working
// Script, there's no further way to improve upon it. However,
// consider a case like this:
//
//
//                  ....................
//                  ......+------+......
//                  ......|bbbbbb|......
//                  ......|bbbbbb|......
//                  .+----|bbbbbb|----+.
//                  .|aaaa|bbbbbb|aaaa|.
//                  .|aaaa|bbbbbb|aaaa|.
//                  .+----|bbbbbb|----+.
//                  ......|bbbbbb|......
//                  ......+------+......
//                  ....................
//
// There are two "obvious" relatively short scripts that generate the
// above picture: one that draws two 'a' rectangles and then the
// single 'b' rectangle (thus requiring three commands in the script).
//
//  ....................       ....................
//  ....................       ......+------+......
//  ....................       ......|bbbbbb|......
//  ....................       ......|bbbbbb|......
//  .+----+......+----+.       ......|bbbbbb|......
//  .|aaaa|......|aaaa|. then  ......|bbbbbb|......
//  .|aaaa|......|aaaa|.       ......|bbbbbb|......
//  .+----+......+----+.       ......|bbbbbb|......
//  ....................       ......|bbbbbb|......
//  ....................       ......+------+......
//  ....................       ....................
//
//
// But there is also this approach, which requires only two commands:
//
//  ....................       ....................
//  ....................       ......+------+......
//  ....................       ......|bbbbbb|......
//  ....................       ......|bbbbbb|......
//  .+----------------+.       ......|bbbbbb|......
//  .|aaaaaaaaaaaaaaaa|. then  ......|bbbbbb|......
//  .|aaaaaaaaaaaaaaaa|.       ......|bbbbbb|......
//  .+----------------+.       ......|bbbbbb|......
//  ....................       ......|bbbbbb|......
//  ....................       ......+------+......
//  ....................       ....................
//
// The undraw strategy of the code above will tend to generate the
// three-command script. What ideas do you have to try to make it
// generate "optimal" scripts (where "optimal" here means "minimal
// number of commands."

// EXERCISE 3: Up until now, we have assumed that all boxes are at
// least width and height >= 2.  So for example `test::narrow_lines()`
// shows boxes of width == 2, so narrow that they have no interior.
//
// BUT: The boxdraw-rs library supports boxes of width or height == 1
// as well, and it has *very* different behavior for them. Find out
// what that behavior is (perhaps by looking at the tests in the
// boxdraw library).
//
// Consider what a box with both width and height equal to 1 would
// look like. What implications does this have? For example, what kind
// of pictures can you make with just boxes of *both* width and height 1?
//
// Try to solve the undraw problem even for such cases.
//
// Note 1: to do this, you may want to start from scratch; or maybe
// some of the code here could be of use.
//
// Note 2: You may want to play around first with approaches that are
// not anywhere close to optimal.

// EXERCISE 4: Like exercise 2 above: Again, solve the generalized
// undraw problem (that is, including boxes of width and/or height 1),
// but this time, try to generate relatively small scripts.
//
// Note that you can make short scripts that first draw large boxes
// (which will then have borders) and then write over the borders with
// boxes of width or height 1, like so:
//
//  ....................       ....................   ....................
//  ....................       ....................   ....................
//  ....................       ....................   ....................
//  ....................       ....................   ....................
//  .+----------------+.       .aaaaaaaaaaaaaaaaaa.   .a................a.
//  .|aaaaaaaaaaaaaaaa|. then  .................... ; .a................a.
//  .|aaaaaaaaaaaaaaaa|.       ....................   .a................a.
//  .+----------------+.       .aaaaaaaaaaaaaaaaaa.   .a................a.
//  ....................       ....................   ....................
//  ....................       ....................   ....................
//  ....................       ....................   ....................
//
// and this generates a picture with a borderless box:
//
//  ....................
//  ....................
//  ....................
//  ....................
//  .aaaaaaaaaaaaaaaaaa.
//  .aaaaaaaaaaaaaaaaaa.
//  .aaaaaaaaaaaaaaaaaa.
//  .aaaaaaaaaaaaaaaaaa.
//  ....................
//  ....................
//  ....................
<|endoftext|>


<commit_before>//! Implementation of the SPECK block cipher.
//!
//! SPECK is a really simple block cipher designed by the NSA. It is famous for its simple
//! structure and code size, which can fit in just a couple of lines, while still preserving
//! security.

#![feature(i128_type)]

#![no_std]
#![forbid(unsafe_code)]

/// The number of rounds.
const ROUNDS: u64 = 32;

/// A single round of SPECK.
///
/// This is a keyed ARX transformation.
macro_rules! round {
    ($x:ident, $y:ident, $k:ident) => {
        $x = $x.rotate_right(8);
        $x = $x.wrapping_add($y);
        $x ^= $k;
        $y = $y.rotate_left(3);
        $y ^= $x;
    }
}

/// Revert a SPECK round given some subkey.
macro_rules! inv_round {
    ($x:ident, $y:ident, $k:ident) => {
        $y ^= $x;
        $y = $y.rotate_right(3);
        $x ^= $k;
        $x = $x.wrapping_sub($y);
        $x = $x.rotate_left(8);
    }
}

/// Encrypt a block with key schedule generated on-the-go.
///
/// This works great for one-time use of a key (such as usages other than encryption), because it
/// should never read from memory (both the message and the keys are stored in the registers). As
/// such, this should be really fast for such usage.
///
/// If you want to reuse the key, however, it is recommended that you use the precomputed schedule
/// provided by the `Key` struct.
pub fn encrypt_block(m: u128, k: u128) -> u128 {
    let mut m1 = (m >> 64) as u64;
    let mut m2 = m as u64;
    let mut k1 = (k >> 64) as u64;
    let mut k2 = k as u64;

    // Run the initial round (similar to the loop below, but doesn't update the key schedule).
    round!(m1, m2, k2);

    for i in 0..ROUNDS - 1 {
        // Progress the key schedule.
        round!(k1, k2, i);
        // Run a round over the message.
        round!(m1, m2, k2);
    }

    m2 as u128 | (m1 as u128) << 64
}

/// A precomputed key.
///
/// This precomputes a key schedule, which can then be used for both encrypting and decrypting
/// messages.
pub struct Key {
    /// The computed schedule.
    ///
    /// Each of these subkeys are used in a round of the cipher. The first subkey is used in the
    /// first round of the cipher and so on.
    schedule: [u64; ROUNDS as usize],
}

impl Key {
    /// Generate a new key from some seed.
    pub fn new(k: u128) -> Key {
        let mut k1 = (k >> 64) as u64;
        let mut k2 = k as u64;

        let mut ret = Key {
            schedule: [0; ROUNDS as usize],
        };

        // Run `ROUNDS - 1` rounds to generate the key's endpoint (the last key in the schedule).
        for i in 0..ROUNDS {
            // Insert the key into the schedule.
            ret.schedule[i as usize] = k2;

            // The beautiful thing about SPECK is that it reuses its round function to generate the
            // key schedule.
            round!(k1, k2, i);
        }

        ret
    }

    /// Encrypt a 128-bit block with this key.
    pub fn encrypt_block(&self, m: u128) -> u128 {
        let mut m1 = (m >> 64) as u64;
        let mut m2 = m as u64;

        // We run a round for every subkey in the generated key schedule.
        for &k in &self.schedule {
            // Run a round on the message.
            round!(m1, m2, k);
        }

        m2 as u128 | (m1 as u128) << 64
    }

    /// Decrypt a 128-bit block with this key.
    pub fn decrypt_block(&self, c: u128) -> u128 {
        let mut c1 = (c >> 64) as u64;
        let mut c2 = c as u64;

        // We run a round for every subkey in the generated key schedule.
        for &k in self.schedule.iter().rev() {
            // Run a round on the message.
            inv_round!(c1, c2, k);
        }

        c2 as u128 | (c1 as u128) << 64
    }
}

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

    #[test]
    fn encrypt_decrypt() {
        for mut x in 0u128..90000 {
            // <3
            x = x.wrapping_mul(0x6eed0e9da4d94a4f6eed0e9da4d94a4f);
            x ^= (x >> 6) >> (x >> 122);
            x = x.wrapping_mul(0x6eed0e9da4d94a4f6eed0e9da4d94a4f);

            let key = Key::new(!x);

            assert_eq!(key.decrypt_block(key.encrypt_block(x)), x);
            assert_eq!(key.encrypt_block(x), encrypt_block(x, !x));
        }
    }

    #[test]
    fn test_vectors() {
        // These test vectors are taken from the SPECK paper.
        assert_eq!(
            encrypt_block(
                0x6c617669757165207469206564616d20,
                0x0f0e0d0c0b0a09080706050403020100
            ),
            0xa65d9851797832657860fedf5c570d18
        );
    }
}
<commit_msg>Added trait derivation for `Key`.<commit_after>//! Implementation of the SPECK block cipher.
//!
//! SPECK is a really simple block cipher designed by the NSA. It is famous for its simple
//! structure and code size, which can fit in just a couple of lines, while still preserving
//! security.
#![feature(i128_type)]
#![no_std]
#![forbid(unsafe_code)]

/// The number of rounds.
const ROUNDS: u64 = 32;

/// A single round of SPECK.
///
/// This is a keyed ARX transformation.
macro_rules! round {
    ($x:ident, $y:ident, $k:ident) => {
        $x = $x.rotate_right(8);
        $x = $x.wrapping_add($y);
        $x ^= $k;
        $y = $y.rotate_left(3);
        $y ^= $x;
    }
}

/// Revert a SPECK round given some subkey.
macro_rules! inv_round {
    ($x:ident, $y:ident, $k:ident) => {
        $y ^= $x;
        $y = $y.rotate_right(3);
        $x ^= $k;
        $x = $x.wrapping_sub($y);
        $x = $x.rotate_left(8);
    }
}

/// Encrypt a block with key schedule generated on-the-go.
///
/// This works great for one-time use of a key (such as usages other than encryption), because it
/// should never read from memory (both the message and the keys are stored in the registers). As
/// such, this should be really fast for such usage.
///
/// If you want to reuse the key, however, it is recommended that you use the precomputed schedule
/// provided by the `Key` struct.
pub fn encrypt_block(m: u128, k: u128) -> u128 {
    let mut m1 = (m >> 64) as u64;
    let mut m2 = m as u64;
    let mut k1 = (k >> 64) as u64;
    let mut k2 = k as u64;

    // Run the initial round (similar to the loop below, but doesn't update the key schedule).
    round!(m1, m2, k2);

    for i in 0..ROUNDS - 1 {
        // Progress the key schedule.
        round!(k1, k2, i);
        // Run a round over the message.
        round!(m1, m2, k2);
    }

    m2 as u128 | (m1 as u128) << 64
}

/// A precomputed key.
///
/// This precomputes a key schedule, which can then be used for both encrypting and decrypting
/// messages.
#[derive(Debug, Copy, Clone)]
pub struct Key {
    /// The computed schedule.
    ///
    /// Each of these subkeys are used in a round of the cipher. The first subkey is used in the
    /// first round of the cipher and so on.
    schedule: [u64; ROUNDS as usize],
}

impl Key {
    /// Generate a new key from some seed.
    pub fn new(k: u128) -> Key {
        let mut k1 = (k >> 64) as u64;
        let mut k2 = k as u64;

        let mut ret = Key {
            schedule: [0; ROUNDS as usize],
        };

        // Run `ROUNDS - 1` rounds to generate the key's endpoint (the last key in the schedule).
        for i in 0..ROUNDS {
            // Insert the key into the schedule.
            ret.schedule[i as usize] = k2;

            // The beautiful thing about SPECK is that it reuses its round function to generate the
            // key schedule.
            round!(k1, k2, i);
        }

        ret
    }

    /// Encrypt a 128-bit block with this key.
    pub fn encrypt_block(&self, m: u128) -> u128 {
        let mut m1 = (m >> 64) as u64;
        let mut m2 = m as u64;

        // We run a round for every subkey in the generated key schedule.
        for &k in &self.schedule {
            // Run a round on the message.
            round!(m1, m2, k);
        }

        m2 as u128 | (m1 as u128) << 64
    }

    /// Decrypt a 128-bit block with this key.
    pub fn decrypt_block(&self, c: u128) -> u128 {
        let mut c1 = (c >> 64) as u64;
        let mut c2 = c as u64;

        // We run a round for every subkey in the generated key schedule.
        for &k in self.schedule.iter().rev() {
            // Run a round on the message.
            inv_round!(c1, c2, k);
        }

        c2 as u128 | (c1 as u128) << 64
    }
}

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

    #[test]
    fn encrypt_decrypt() {
        for mut x in 0u128..90000 {
            // <3
            x = x.wrapping_mul(0x6eed0e9da4d94a4f6eed0e9da4d94a4f);
            x ^= (x >> 6) >> (x >> 122);
            x = x.wrapping_mul(0x6eed0e9da4d94a4f6eed0e9da4d94a4f);

            let key = Key::new(!x);

            assert_eq!(key.decrypt_block(key.encrypt_block(x)), x);
            assert_eq!(key.encrypt_block(x), encrypt_block(x, !x));
        }
    }

    #[test]
    fn test_vectors() {
        // These test vectors are taken from the SPECK paper.
        assert_eq!(
            encrypt_block(
                0x6c617669757165207469206564616d20,
                0x0f0e0d0c0b0a09080706050403020100
            ),
            0xa65d9851797832657860fedf5c570d18
        );
    }
}
<|endoftext|>


<commit_before>

use std::num::abs;
use self::calculator::*;
use self::constants::*;

/// Frequency related constants.
pub mod constants {
    pub static HIGHEST_HZ: f32 = 20000f32;
    pub static LOWEST_HZ: f32 = 20f32;
    pub static DEFAULT_WEIGHT: f32 = 4f32;
}

/// Frequency struct! Capable of scaling
/// frequency weight via a power function
/// applied to a percentage.
#[deriving(Show, Clone)]
pub struct Frequency {
    hz: f32,
    perc: f64,
    scaled_perc: f64, // For weighting lower frequencies.
    scale_weight: f32 // For adjusting the scale weighting (default 4).
}

/// Frequency calculator for converting between
/// scale percentage and frequency. in all
/// possible directions.
pub mod calculator {

    use super::constants::*;

    pub fn get_hz_from_perc(perc: f64) -> f32 {
        perc as f32 * (HIGHEST_HZ - LOWEST_HZ) + LOWEST_HZ
    }

    pub fn get_hz_from_scaled_perc(scaled: f64, weight: f32) -> f32 {
        get_hz_from_perc(get_perc_from_scaled_perc(scaled, weight))
    }

    pub fn get_perc_from_hz(hz: f32) -> f64 {
        (hz - LOWEST_HZ) as f64 / (HIGHEST_HZ - LOWEST_HZ) as f64
    }

    pub fn get_perc_from_scaled_perc(scaled: f64, weight: f32) -> f64 {
        scaled.powf(weight as f64)
    }

    pub fn get_scaled_perc_from_hz(hz: f32, weight: f32) -> f64 {
        get_scaled_perc_from_perc(get_perc_from_hz(hz), weight)
    }

    pub fn get_scaled_perc_from_perc(perc: f64, weight: f32) -> f64 {
        perc.powf(1f64 / weight as f64)
    }

}

/// A HasFrequency for easy implementation
/// for those types that revolve around frequency.
/// This is also the base trait for the more
/// musically orientated `HasPitch` trait.
pub trait HasFrequency {

    /// Getters
    fn get_freq<'a>(&'a self) -> &'a Frequency;
    fn get_freq_mut<'a>(&'a mut self) -> &'a mut Frequency;
    fn get_hz(&self) -> f32 { self.get_freq().hz }
    fn get_perc(&self) -> f64 { self.get_freq().perc }
    fn get_scaled_perc(&self) -> f64 { self.get_freq().scaled_perc }
    fn get_scale_weight(&self) -> f32 { self.get_freq().scale_weight }

    /// Setters
    fn set_freq_hz(&mut self, hz: f32) {
        assert!(hz >= LOWEST_HZ && hz <= HIGHEST_HZ);
        let weight = self.get_freq().scale_weight;
        self.get_freq_mut().hz = hz;
        self.get_freq_mut().perc = get_perc_from_hz(hz);
        self.get_freq_mut().scaled_perc = get_scaled_perc_from_hz(hz, weight);
    }
    fn set_freq_perc(&mut self, perc: f64) {
        assert!(perc >= 0f64 && perc <= 1f64);
        let weight = self.get_freq().scale_weight;
        self.get_freq_mut().hz = get_hz_from_perc(perc);
        self.get_freq_mut().perc = perc;
        self.get_freq_mut().scaled_perc = get_scaled_perc_from_perc(perc, weight);
    }
    fn set_freq_scaled_perc(&mut self, scaled_perc: f64) {
        assert!(scaled_perc >= 0f64 && scaled_perc <= 1f64);
        let weight = self.get_freq().scale_weight;
        self.get_freq_mut().hz = get_hz_from_scaled_perc(scaled_perc, weight);
        self.get_freq_mut().perc = get_perc_from_scaled_perc(scaled_perc, weight);
        self.get_freq_mut().scaled_perc = scaled_perc;
    }
    fn set_scale_weight(&mut self, scale_weight: f32) {
        self.get_freq_mut().scale_weight = scale_weight;
    }

    /// Determine difference as another Frequency object.
    fn find_difference(&self, freq: &Frequency) -> Frequency {
        Frequency::new_from_scaled_perc_and_weight(abs(self.get_scaled_perc() - freq.get_scaled_perc()), self.get_scale_weight())
    }

}

/// Only methods returning a reference to
/// Frequency both mutably and immutably
/// are required to impl HasFrequency.
impl HasFrequency for Frequency {
    fn get_freq<'a>(&'a self) -> &'a Frequency { self }
    fn get_freq_mut<'a>(&'a mut self) -> &'a mut Frequency { self }
}

impl Frequency {

    /// Default constructor.
    pub fn new() -> Frequency {
        Frequency {
            hz: LOWEST_HZ,
            perc: 0f64,
            scaled_perc: 0f64,
            scale_weight: DEFAULT_WEIGHT
        }
    }

    /// Construct from hz.
    pub fn new_from_hz(hz: f32) -> Frequency {
        Frequency {
            hz: hz,
            perc: get_perc_from_hz(hz),
            scaled_perc: get_scaled_perc_from_hz(hz, DEFAULT_WEIGHT),
            scale_weight: DEFAULT_WEIGHT
        }
    }

    /// Construct from hz percentage.
    pub fn new_from_perc(perc: f64) -> Frequency {
        Frequency {
            hz: get_hz_from_perc(perc),
            perc: perc,
            scaled_perc: get_scaled_perc_from_perc(perc, DEFAULT_WEIGHT),
            scale_weight: DEFAULT_WEIGHT
        }
    }

    /// Construct from scaled percentage. (Weighted
    /// towards the lowever end of the spectrum).
    pub fn new_from_scaled_perc(scaled_perc: f64) -> Frequency {
        Frequency {
            hz: get_hz_from_scaled_perc(scaled_perc, DEFAULT_WEIGHT),
            perc: get_perc_from_scaled_perc(scaled_perc, DEFAULT_WEIGHT),
            scaled_perc: scaled_perc,
            scale_weight: DEFAULT_WEIGHT
        }
    }

    /// Construct from scaled percentage. (Weighted
    /// towards the lowever end of the spectrum).
    /// The low-end weight can be defined here.
    pub fn new_from_scaled_perc_and_weight(scaled_perc: f64, weight: f32) -> Frequency {
        Frequency {
            hz: get_hz_from_scaled_perc(scaled_perc, weight),
            perc: get_perc_from_scaled_perc(scaled_perc, weight),
            scaled_perc: scaled_perc,
            scale_weight: weight
        }
    }

}

// Tests
//------------------------------
/*
pub fn test() {

    println!("Frequency Tests!");
    let mut freq = Frequency::new();
    println!("Initialised freq: {}", freq);

    freq.set_freq_hz(1000f32);
    println!("freq set to 1,000 hz: {}", freq);

    freq.set_freq_perc(0.8f64);
    println!("freq set to 0.8 perc: {}", freq);

    freq.set_freq_scaled_perc(0.5f64);
    println!("freq set to 0.5 scaled perc: {}", freq);

    freq = Frequency::new_from_scaled_perc_and_weight(0.5f64, 2f32);
    println!("freq initialised to 0.5 scaled perc with 2.0 weight: {}", freq);

    freq = Frequency::new_from_hz(440f32);
    println!("freq initialised to 440 hz: {}", freq);

    freq = Frequency::new_from_perc(0.5f64);
    println!("freq initialised to 0.5 perc: {}", freq);

    freq = Frequency::new_from_scaled_perc(0.5f64);
    println!("freq initialised to 0.5 scaled perc: {}", freq);

}
*/
//------------------------------
<commit_msg>Added Frequency struct, HasFrequency trait and frequency related calculator functions.<commit_after>

use std::num::abs;
use self::calculator::*;
use self::constants::*;

/// Frequency related constants.
pub mod constants {
    pub static HIGHEST_HZ: f32 = 20000f32;
    pub static LOWEST_HZ: f32 = 20f32;
    pub static DEFAULT_WEIGHT: f32 = 4f32;
}

/// Frequency struct! Capable of scaling
/// frequency weight via a power function
/// applied to a percentage.
#[deriving(Show, Clone)]
pub struct Frequency {
    hz: f32,
    perc: f64,        // Represents hz as a percentage.
    scaled_perc: f64, // For weighting lower frequencies.
    scale_weight: f32 // For adjusting the scale weighting (default 4).
}

/// Frequency calculator for converting between
/// scale percentage and frequency. in all
/// possible directions.
pub mod calculator {

    use super::constants::*;

    /// Calculate frequency in hz from percentage.
    pub fn get_hz_from_perc(perc: f64) -> f32 {
        perc as f32 * (HIGHEST_HZ - LOWEST_HZ) + LOWEST_HZ
    }

    /// Calculate hz from scaled percentage.
    pub fn get_hz_from_scaled_perc(scaled: f64, weight: f32) -> f32 {
        get_hz_from_perc(get_perc_from_scaled_perc(scaled, weight))
    }

    /// Calculate percentage from hz.
    pub fn get_perc_from_hz(hz: f32) -> f64 {
        (hz - LOWEST_HZ) as f64 / (HIGHEST_HZ - LOWEST_HZ) as f64
    }

    /// Calculate percentage from scaled percentage.
    pub fn get_perc_from_scaled_perc(scaled: f64, weight: f32) -> f64 {
        scaled.powf(weight as f64)
    }

    /// Calculate scaled percentage from hz.
    pub fn get_scaled_perc_from_hz(hz: f32, weight: f32) -> f64 {
        get_scaled_perc_from_perc(get_perc_from_hz(hz), weight)
    }

    /// Calculate scaled percentage from percentage.
    pub fn get_scaled_perc_from_perc(perc: f64, weight: f32) -> f64 {
        perc.powf(1f64 / weight as f64)
    }

}

/// A HasFrequency for easy implementation
/// for those types that revolve around frequency.
/// This is also the base trait for the more
/// musically orientated `HasPitch` trait.
pub trait HasFrequency {

    /// Get Frequency struct as an immutable reference.
    fn get_freq<'a>(&'a self) -> &'a Frequency;
    /// Get Frequency struct as a mutable reference.
    fn get_freq_mut<'a>(&'a mut self) -> &'a mut Frequency;
    /// Return the frequency in hz.
    fn get_hz(&self) -> f32 { self.get_freq().hz }
    /// Return the frequency as a percentage between LOWEST_HZ & HIGHEST_HZ.
    fn get_perc(&self) -> f64 { self.get_freq().perc }
    /// Return the frequency as a scaled percentage between LOWEST_HZ & HIGHEST_HZ.
    fn get_scaled_perc(&self) -> f64 { self.get_freq().scaled_perc }
    /// Return the scale weighting (higher the weight, the more lower frequencies).
    fn get_scale_weight(&self) -> f32 { self.get_freq().scale_weight }

    /// Set the frequency via hz.
    fn set_freq_hz(&mut self, hz: f32) {
        assert!(hz >= LOWEST_HZ && hz <= HIGHEST_HZ);
        let weight = self.get_freq().scale_weight;
        self.get_freq_mut().hz = hz;
        self.get_freq_mut().perc = get_perc_from_hz(hz);
        self.get_freq_mut().scaled_perc = get_scaled_perc_from_hz(hz, weight);
    }
    /// Set the frequency via a percentage.
    fn set_freq_perc(&mut self, perc: f64) {
        assert!(perc >= 0f64 && perc <= 1f64);
        let weight = self.get_freq().scale_weight;
        self.get_freq_mut().hz = get_hz_from_perc(perc);
        self.get_freq_mut().perc = perc;
        self.get_freq_mut().scaled_perc = get_scaled_perc_from_perc(perc, weight);
    }
    /// Set the frequency via a scaled percentage.
    fn set_freq_scaled_perc(&mut self, scaled_perc: f64) {
        assert!(scaled_perc >= 0f64 && scaled_perc <= 1f64);
        let weight = self.get_freq().scale_weight;
        self.get_freq_mut().hz = get_hz_from_scaled_perc(scaled_perc, weight);
        self.get_freq_mut().perc = get_perc_from_scaled_perc(scaled_perc, weight);
        self.get_freq_mut().scaled_perc = scaled_perc;
    }
    /// Set the scale weighting (higher the weight, the lower the frequencies).
    fn set_scale_weight(&mut self, scale_weight: f32) {
        self.get_freq_mut().scale_weight = scale_weight;
    }

    /// Determine the difference between two frequencies
    /// and return the result as another Frequency object.
    fn find_difference(&self, freq: &Frequency) -> Frequency {
        Frequency::new_from_scaled_perc_and_weight(
            abs(self.get_scaled_perc() - freq.get_scaled_perc()), self.get_scale_weight())
    }

}

/// Only methods returning a reference to
/// Frequency both mutably and immutably
/// are required to impl HasFrequency.
impl HasFrequency for Frequency {

    /// Get Frequency struct as an immutable reference.
    fn get_freq<'a>(&'a self) -> &'a Frequency { self }
    /// Get Frequency struct as a mutable reference.
    fn get_freq_mut<'a>(&'a mut self) -> &'a mut Frequency { self }
}

impl Frequency {

    /// Default constructor.
    pub fn new() -> Frequency {
        Frequency {
            hz: LOWEST_HZ,
            perc: 0f64,
            scaled_perc: 0f64,
            scale_weight: DEFAULT_WEIGHT
        }
    }

    /// Construct from hz.
    pub fn new_from_hz(hz: f32) -> Frequency {
        Frequency {
            hz: hz,
            perc: get_perc_from_hz(hz),
            scaled_perc: get_scaled_perc_from_hz(hz, DEFAULT_WEIGHT),
            scale_weight: DEFAULT_WEIGHT
        }
    }

    /// Construct from hz percentage.
    pub fn new_from_perc(perc: f64) -> Frequency {
        Frequency {
            hz: get_hz_from_perc(perc),
            perc: perc,
            scaled_perc: get_scaled_perc_from_perc(perc, DEFAULT_WEIGHT),
            scale_weight: DEFAULT_WEIGHT
        }
    }

    /// Construct from scaled percentage. (Weighted
    /// towards the lowever end of the spectrum).
    pub fn new_from_scaled_perc(scaled_perc: f64) -> Frequency {
        Frequency {
            hz: get_hz_from_scaled_perc(scaled_perc, DEFAULT_WEIGHT),
            perc: get_perc_from_scaled_perc(scaled_perc, DEFAULT_WEIGHT),
            scaled_perc: scaled_perc,
            scale_weight: DEFAULT_WEIGHT
        }
    }

    /// Construct from scaled percentage. (Weighted
    /// towards the lowever end of the spectrum).
    /// The low-end weight can be defined here.
    pub fn new_from_scaled_perc_and_weight(scaled_perc: f64, weight: f32) -> Frequency {
        Frequency {
            hz: get_hz_from_scaled_perc(scaled_perc, weight),
            perc: get_perc_from_scaled_perc(scaled_perc, weight),
            scaled_perc: scaled_perc,
            scale_weight: weight
        }
    }

}

// Tests
//------------------------------
/*
pub fn test() {

    println!("Frequency Tests!");
    let mut freq = Frequency::new();
    println!("Initialised freq: {}", freq);

    freq.set_freq_hz(1000f32);
    println!("freq set to 1,000 hz: {}", freq);

    freq.set_freq_perc(0.8f64);
    println!("freq set to 0.8 perc: {}", freq);

    freq.set_freq_scaled_perc(0.5f64);
    println!("freq set to 0.5 scaled perc: {}", freq);

    freq = Frequency::new_from_scaled_perc_and_weight(0.5f64, 2f32);
    println!("freq initialised to 0.5 scaled perc with 2.0 weight: {}", freq);

    freq = Frequency::new_from_hz(440f32);
    println!("freq initialised to 440 hz: {}", freq);

    freq = Frequency::new_from_perc(0.5f64);
    println!("freq initialised to 0.5 perc: {}", freq);

    freq = Frequency::new_from_scaled_perc(0.5f64);
    println!("freq initialised to 0.5 scaled perc: {}", freq);

}
*/
//------------------------------
<|endoftext|>


<commit_before>use std::io::File;
use std::io::fs::PathExtensions;

use calx::color;
use calx::Context;
use calx::event;
use calx::key;
use calx::{Fonter, V2};
use world;
use world::action;
use world::action::{Step, Melee};
use world::dir6::*;
use worldview;
use sprite::{WorldSprites, GibSprite};

pub struct GameState {
    world_spr: WorldSprites,
}

impl GameState {
    pub fn new(seed: Option<u32>) -> GameState {
        world::init_world(seed);
        GameState {
            world_spr: WorldSprites::new(),
        }
    }

    /// Repaint view, update game world if needed.
    pub fn update(&mut self, ctx: &mut Context) {
        ctx.clear(&color::BLACK);
        let camera = world::camera();

        // Process events
        loop {
            match world::pop_msg() {
                Some(world::Gib(loc)) => {
                    self.world_spr.add(box GibSprite::new(loc));
                }
                Some(x) => {
                    println!("Unhandled Msg type {}", x);
                }
                None => break
            }
        }

        worldview::draw_world(&camera, ctx);

        // TODO use FOV for sprite draw.
        self.world_spr.draw(|_| true, &camera, ctx);
        self.world_spr.update();

        let fps = 1.0 / ctx.render_duration;
        let _ = write!(&mut ctx.text_writer(V2(0, 8), 0.1, color::LIGHTGREEN)
                       .set_border(color::BLACK),
                       "FPS {:.0}", fps);

        if action::control_state() == action::ReadyToUpdate {
            action::update();
        }
    }

    pub fn save_game(&self) {
        let save_data = world::save();
        let mut file = File::create(&Path::new("/tmp/magog_save.json"));
        file.write_str(save_data.as_slice()).unwrap();
    }

    pub fn load_game(&mut self) {
        let path = Path::new("/tmp/magog_save.json");
        if !path.exists() { return; }
        let save_data = File::open(&path).read_to_string().unwrap();
        // TODO: Handle failed load nicely.
        world::load(save_data.as_slice()).unwrap();
    }

    fn smart_move(&mut self, dir: Dir6) {
        let player = action::player().unwrap();
        let target_loc = player.location().unwrap() + dir.to_v2();
        if target_loc.has_mobs() {
            action::input(Melee(dir));
        } else {
            action::input(Step(dir));
        }
    }

    /// Process a player control keypress.
    pub fn process_key(&mut self, key: key::Key) -> bool {
        if action::control_state() != action::AwaitingInput {
            return false;
        }

        match key {
            key::KeyQ | key::KeyPad7 => { self.smart_move(NorthWest); }
            key::KeyW | key::KeyPad8 | key::KeyUp => { self.smart_move(North); }
            key::KeyE | key::KeyPad9 => { self.smart_move(NorthEast); }
            key::KeyA | key::KeyPad1 => { self.smart_move(SouthWest); }
            key::KeyS | key::KeyPad2 | key::KeyDown => { self.smart_move(South); }
            key::KeyD | key::KeyPad3 => { self.smart_move(SouthEast); }
            key::KeyF5 => { self.save_game(); }
            key::KeyF9 => { self.load_game(); }
            _ => { return false; }
        }
        return true;
    }

    pub fn process(&mut self, event: event::Event) -> bool {
        match event {
            event::Render(ctx) => {
                self.update(ctx);
            }
            event::KeyPressed(key::KeyEscape) => {
                return false;
            }
            event::KeyPressed(k) => {
                self.process_key(k);
            }
            _ => ()
        }
        true
    }
}
<commit_msg>Don't draw out-of-FOV sprites<commit_after>use std::io::File;
use std::io::fs::PathExtensions;

use calx::color;
use calx::Context;
use calx::event;
use calx::key;
use calx::{Fonter, V2};
use world;
use world::action;
use world::action::{Step, Melee};
use world::dir6::*;
use worldview;
use sprite::{WorldSprites, GibSprite};

pub struct GameState {
    world_spr: WorldSprites,
}

impl GameState {
    pub fn new(seed: Option<u32>) -> GameState {
        world::init_world(seed);
        GameState {
            world_spr: WorldSprites::new(),
        }
    }

    /// Repaint view, update game world if needed.
    pub fn update(&mut self, ctx: &mut Context) {
        ctx.clear(&color::BLACK);
        let camera = world::camera();

        // Process events
        loop {
            match world::pop_msg() {
                Some(world::Gib(loc)) => {
                    self.world_spr.add(box GibSprite::new(loc));
                }
                Some(x) => {
                    println!("Unhandled Msg type {}", x);
                }
                None => break
            }
        }

        worldview::draw_world(&camera, ctx);

        // TODO use FOV for sprite draw.
        self.world_spr.draw(|x| (camera + x).fov_status() == Some(world::Seen), &camera, ctx);
        self.world_spr.update();

        let fps = 1.0 / ctx.render_duration;
        let _ = write!(&mut ctx.text_writer(V2(0, 8), 0.1, color::LIGHTGREEN)
                       .set_border(color::BLACK),
                       "FPS {:.0}", fps);

        if action::control_state() == action::ReadyToUpdate {
            action::update();
        }
    }

    pub fn save_game(&self) {
        let save_data = world::save();
        let mut file = File::create(&Path::new("/tmp/magog_save.json"));
        file.write_str(save_data.as_slice()).unwrap();
    }

    pub fn load_game(&mut self) {
        let path = Path::new("/tmp/magog_save.json");
        if !path.exists() { return; }
        let save_data = File::open(&path).read_to_string().unwrap();
        // TODO: Handle failed load nicely.
        world::load(save_data.as_slice()).unwrap();
    }

    fn smart_move(&mut self, dir: Dir6) {
        let player = action::player().unwrap();
        let target_loc = player.location().unwrap() + dir.to_v2();
        if target_loc.has_mobs() {
            action::input(Melee(dir));
        } else {
            action::input(Step(dir));
        }
    }

    /// Process a player control keypress.
    pub fn process_key(&mut self, key: key::Key) -> bool {
        if action::control_state() != action::AwaitingInput {
            return false;
        }

        match key {
            key::KeyQ | key::KeyPad7 => { self.smart_move(NorthWest); }
            key::KeyW | key::KeyPad8 | key::KeyUp => { self.smart_move(North); }
            key::KeyE | key::KeyPad9 => { self.smart_move(NorthEast); }
            key::KeyA | key::KeyPad1 => { self.smart_move(SouthWest); }
            key::KeyS | key::KeyPad2 | key::KeyDown => { self.smart_move(South); }
            key::KeyD | key::KeyPad3 => { self.smart_move(SouthEast); }
            key::KeyF5 => { self.save_game(); }
            key::KeyF9 => { self.load_game(); }
            _ => { return false; }
        }
        return true;
    }

    pub fn process(&mut self, event: event::Event) -> bool {
        match event {
            event::Render(ctx) => {
                self.update(ctx);
            }
            event::KeyPressed(key::KeyEscape) => {
                return false;
            }
            event::KeyPressed(k) => {
                self.process_key(k);
            }
            _ => ()
        }
        true
    }
}
<|endoftext|>


<commit_before>// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// aux-build:deprecation-lint.rs

#![deny(deprecated)]
#![allow(warnings)]

#[macro_use]
extern crate deprecation_lint;

mod cross_crate {
    use deprecation_lint::*;

    fn test() {
        type Foo = MethodTester;
        let foo = MethodTester;

        deprecated(); //~ ERROR use of deprecated item
        foo.method_deprecated(); //~ ERROR use of deprecated item
        Foo::method_deprecated(&foo); //~ ERROR use of deprecated item
        <Foo>::method_deprecated(&foo); //~ ERROR use of deprecated item
        foo.trait_deprecated(); //~ ERROR use of deprecated item
        Trait::trait_deprecated(&foo); //~ ERROR use of deprecated item
        <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated item
        <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated item

        deprecated_text(); //~ ERROR use of deprecated item: text
        foo.method_deprecated_text(); //~ ERROR use of deprecated item: text
        Foo::method_deprecated_text(&foo); //~ ERROR use of deprecated item: text
        <Foo>::method_deprecated_text(&foo); //~ ERROR use of deprecated item: text
        foo.trait_deprecated_text(); //~ ERROR use of deprecated item: text
        Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text
        <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text
        <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text

        let _ = DeprecatedStruct { //~ ERROR use of deprecated item
            i: 0 //~ ERROR use of deprecated item
        };

        let _ = DeprecatedUnitStruct; //~ ERROR use of deprecated item

        let _ = Enum::DeprecatedVariant; //~ ERROR use of deprecated item

        let _ = DeprecatedTupleStruct (1); //~ ERROR use of deprecated item

        // At the moment, the lint checker only checks stability in
        // in the arguments of macros.
        // Eventually, we will want to lint the contents of the
        // macro in the module *defining* it. Also, stability levels
        // on macros themselves are not yet linted.
        macro_test_arg!(deprecated_text()); //~ ERROR use of deprecated item: text
        macro_test_arg!(macro_test_arg!(deprecated_text())); //~ ERROR use of deprecated item: text
    }

    fn test_method_param<Foo: Trait>(foo: Foo) {
        foo.trait_deprecated(); //~ ERROR use of deprecated item
        Trait::trait_deprecated(&foo); //~ ERROR use of deprecated item
        <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated item
        <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated item
        foo.trait_deprecated_text(); //~ ERROR use of deprecated item: text
        Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text
        <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text
        <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text
    }

    fn test_method_object(foo: &Trait) {
        foo.trait_deprecated(); //~ ERROR use of deprecated item
        foo.trait_deprecated_text(); //~ ERROR use of deprecated item: text
    }

    struct S;

    impl DeprecatedTrait for S {} //~ ERROR use of deprecated item: text
    trait LocalTrait : DeprecatedTrait { } //~ ERROR use of deprecated item: text

    pub fn foo() {
        let x = Stable {
            override2: 3,
            //~^ ERROR use of deprecated item
        };

        let _ = x.override2;
        //~^ ERROR use of deprecated item

        let Stable {
            override2: _
            //~^ ERROR use of deprecated item
        } = x;
        // all fine
        let Stable { .. } = x;

        let x = Stable2(1, 2, 3);

        let _ = x.2;
        //~^ ERROR use of deprecated item

        let Stable2(_,
                   _,
                   _)
            //~^ ERROR use of deprecated item
            = x;
        // all fine
        let Stable2(..) = x;

        let x = Deprecated {
            //~^ ERROR use of deprecated item
            inherit: 1,
            //~^ ERROR use of deprecated item
        };

        let _ = x.inherit;
        //~^ ERROR use of deprecated item

        let Deprecated {
            //~^ ERROR use of deprecated item
            inherit: _,
            //~^ ERROR use of deprecated item
        } = x;

        let Deprecated
            //~^ ERROR use of deprecated item
            { .. } = x;

        let x = Deprecated2(1, 2, 3);
        //~^ ERROR use of deprecated item

        let _ = x.0;
        //~^ ERROR use of deprecated item
        let _ = x.1;
        //~^ ERROR use of deprecated item
        let _ = x.2;
        //~^ ERROR use of deprecated item

        let Deprecated2
        //~^ ERROR use of deprecated item
            (_,
             //~^ ERROR use of deprecated item
             _,
             //~^ ERROR use of deprecated item
             _)
             //~^ ERROR use of deprecated item
            = x;
        let Deprecated2
        //~^ ERROR use of deprecated item
            // the patterns are all fine:
            (..) = x;
    }
}

mod inheritance {
    use deprecation_lint::*;

    fn test_inheritance() {
        deprecated_mod::deprecated(); //~ ERROR use of deprecated item
    }
}

mod this_crate {
    #[deprecated(since = "1.0.0", note = "text")]
    pub fn deprecated() {}
    #[deprecated(since = "1.0.0", note = "text")]
    pub fn deprecated_text() {}

    pub struct MethodTester;

    impl MethodTester {
        #[deprecated(since = "1.0.0", note = "text")]
        pub fn method_deprecated(&self) {}
        #[deprecated(since = "1.0.0", note = "text")]
        pub fn method_deprecated_text(&self) {}
    }

    pub trait Trait {
        #[deprecated(since = "1.0.0", note = "text")]
        fn trait_deprecated(&self) {}
        #[deprecated(since = "1.0.0", note = "text")]
        fn trait_deprecated_text(&self) {}
    }

    impl Trait for MethodTester {}

    #[deprecated(since = "1.0.0", note = "text")]
    pub struct DeprecatedStruct {
        i: isize
    }
    pub struct UnstableStruct {
        i: isize
    }
    pub struct StableStruct {
        i: isize
    }

    #[deprecated(since = "1.0.0", note = "text")]
    pub struct DeprecatedUnitStruct;

    pub enum Enum {
        #[deprecated(since = "1.0.0", note = "text")]
        DeprecatedVariant,
    }

    #[deprecated(since = "1.0.0", note = "text")]
    pub struct DeprecatedTupleStruct(isize);

    fn test() {
        // Only the deprecated cases of the following should generate
        // errors, because other stability attributes now have meaning
        // only *across* crates, not within a single crate.

        type Foo = MethodTester;
        let foo = MethodTester;

        deprecated(); //~ ERROR use of deprecated item
        foo.method_deprecated(); //~ ERROR use of deprecated item
        Foo::method_deprecated(&foo); //~ ERROR use of deprecated item
        <Foo>::method_deprecated(&foo); //~ ERROR use of deprecated item
        foo.trait_deprecated(); //~ ERROR use of deprecated item
        Trait::trait_deprecated(&foo); //~ ERROR use of deprecated item
        <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated item
        <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated item

        deprecated_text(); //~ ERROR use of deprecated item: text
        foo.method_deprecated_text(); //~ ERROR use of deprecated item: text
        Foo::method_deprecated_text(&foo); //~ ERROR use of deprecated item: text
        <Foo>::method_deprecated_text(&foo); //~ ERROR use of deprecated item: text
        foo.trait_deprecated_text(); //~ ERROR use of deprecated item: text
        Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text
        <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text
        <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text

        let _ = DeprecatedStruct {
            //~^ ERROR use of deprecated item
            i: 0 //~ ERROR use of deprecated item
        };

        let _ = DeprecatedUnitStruct; //~ ERROR use of deprecated item

        let _ = Enum::DeprecatedVariant; //~ ERROR use of deprecated item

        let _ = DeprecatedTupleStruct (1); //~ ERROR use of deprecated item
    }

    fn test_method_param<Foo: Trait>(foo: Foo) {
        foo.trait_deprecated(); //~ ERROR use of deprecated item
        Trait::trait_deprecated(&foo); //~ ERROR use of deprecated item
        <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated item
        <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated item
        foo.trait_deprecated_text(); //~ ERROR use of deprecated item: text
        Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text
        <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text
        <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text
    }

    fn test_method_object(foo: &Trait) {
        foo.trait_deprecated(); //~ ERROR use of deprecated item
        foo.trait_deprecated_text(); //~ ERROR use of deprecated item: text
    }

    #[deprecated(since = "1.0.0", note = "text")]
    fn test_fn_body() {
        fn fn_in_body() {}
        fn_in_body(); //~ ERROR use of deprecated item: text
    }

    impl MethodTester {
        #[deprecated(since = "1.0.0", note = "text")]
        fn test_method_body(&self) {
            fn fn_in_body() {}
            fn_in_body(); //~ ERROR use of deprecated item: text
        }
    }

    #[deprecated(since = "1.0.0", note = "text")]
    pub trait DeprecatedTrait {
        fn dummy(&self) { }
    }

    struct S;

    impl DeprecatedTrait for S { } //~ ERROR use of deprecated item

    trait LocalTrait : DeprecatedTrait { } //~ ERROR use of deprecated item
}

mod this_crate2 {
    struct Stable {
        #[deprecated(since = "1.0.0", note = "text")]
        override2: u8,
    }

    struct Stable2(u8,
                   u8,
                   #[deprecated(since = "1.0.0", note = "text")] u8);

    #[deprecated(since = "1.0.0", note = "text")]
    struct Deprecated {
        inherit: u8,
    }

    #[deprecated(since = "1.0.0", note = "text")]
    struct Deprecated2(u8,
                       u8,
                       u8);

    pub fn foo() {
        let x = Stable {
            override2: 3,
            //~^ ERROR use of deprecated item
        };

        let _ = x.override2;
        //~^ ERROR use of deprecated item

        let Stable {
            override2: _
            //~^ ERROR use of deprecated item
        } = x;
        // all fine
        let Stable { .. } = x;

        let x = Stable2(1, 2, 3);

        let _ = x.2;
        //~^ ERROR use of deprecated item

        let Stable2(_,
                   _,
                   _)
            //~^ ERROR use of deprecated item
            = x;
        // all fine
        let Stable2(..) = x;

        let x = Deprecated {
            //~^ ERROR use of deprecated item
            inherit: 1,
            //~^ ERROR use of deprecated item
        };

        let _ = x.inherit;
        //~^ ERROR use of deprecated item

        let Deprecated {
            //~^ ERROR use of deprecated item
            inherit: _,
            //~^ ERROR use of deprecated item
        } = x;

        let Deprecated
            //~^ ERROR use of deprecated item
            // the patterns are all fine:
            { .. } = x;

        let x = Deprecated2(1, 2, 3);
        //~^ ERROR use of deprecated item

        let _ = x.0;
        //~^ ERROR use of deprecated item
        let _ = x.1;
        //~^ ERROR use of deprecated item
        let _ = x.2;
        //~^ ERROR use of deprecated item

        let Deprecated2
        //~^ ERROR use of deprecated item
            (_,
             //~^ ERROR use of deprecated item
             _,
             //~^ ERROR use of deprecated item
             _)
            //~^ ERROR use of deprecated item
            = x;
        let Deprecated2
        //~^ ERROR use of deprecated item
            // the patterns are all fine:
            (..) = x;
    }
}

fn main() {}
<commit_msg>fix existing tests<commit_after>// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// aux-build:deprecation-lint.rs

#![deny(deprecated)]
#![allow(warnings)]

#[macro_use]
extern crate deprecation_lint;

mod cross_crate {
    use deprecation_lint::*;

    fn test() {
        type Foo = MethodTester;
        let foo = MethodTester;

        deprecated(); //~ ERROR use of deprecated item
        foo.method_deprecated(); //~ ERROR use of deprecated item
        Foo::method_deprecated(&foo); //~ ERROR use of deprecated item
        <Foo>::method_deprecated(&foo); //~ ERROR use of deprecated item
        foo.trait_deprecated(); //~ ERROR use of deprecated item
        Trait::trait_deprecated(&foo); //~ ERROR use of deprecated item
        <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated item
        <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated item

        deprecated_text(); //~ ERROR use of deprecated item: text
        foo.method_deprecated_text(); //~ ERROR use of deprecated item: text
        Foo::method_deprecated_text(&foo); //~ ERROR use of deprecated item: text
        <Foo>::method_deprecated_text(&foo); //~ ERROR use of deprecated item: text
        foo.trait_deprecated_text(); //~ ERROR use of deprecated item: text
        Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text
        <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text
        <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text

        let _ = DeprecatedStruct { //~ ERROR use of deprecated item
            i: 0 //~ ERROR use of deprecated item
        };

        let _ = DeprecatedUnitStruct; //~ ERROR use of deprecated item

        let _ = Enum::DeprecatedVariant; //~ ERROR use of deprecated item

        let _ = DeprecatedTupleStruct (1); //~ ERROR use of deprecated item

        // At the moment, the lint checker only checks stability in
        // in the arguments of macros.
        // Eventually, we will want to lint the contents of the
        // macro in the module *defining* it. Also, stability levels
        // on macros themselves are not yet linted.
        macro_test_arg!(deprecated_text()); //~ ERROR use of deprecated item: text
        macro_test_arg!(macro_test_arg!(deprecated_text())); //~ ERROR use of deprecated item: text
    }

    fn test_method_param<Foo: Trait>(foo: Foo) {
        foo.trait_deprecated(); //~ ERROR use of deprecated item
        Trait::trait_deprecated(&foo); //~ ERROR use of deprecated item
        <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated item
        <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated item
        foo.trait_deprecated_text(); //~ ERROR use of deprecated item: text
        Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text
        <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text
        <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text
    }

    fn test_method_object(foo: &Trait) {
        foo.trait_deprecated(); //~ ERROR use of deprecated item
        foo.trait_deprecated_text(); //~ ERROR use of deprecated item: text
    }

    struct S;

    impl DeprecatedTrait for S {} //~ ERROR use of deprecated item: text
    trait LocalTrait : DeprecatedTrait { } //~ ERROR use of deprecated item: text

    pub fn foo() {
        let x = Stable {
            override2: 3,
            //~^ ERROR use of deprecated item
        };

        let _ = x.override2;
        //~^ ERROR use of deprecated item

        let Stable {
            override2: _
            //~^ ERROR use of deprecated item
        } = x;
        // all fine
        let Stable { .. } = x;

        let x = Stable2(1, 2, 3);

        let _ = x.2;
        //~^ ERROR use of deprecated item

        let Stable2(_,
                   _,
                   _)
            //~^ ERROR use of deprecated item
            = x;
        // all fine
        let Stable2(..) = x;

        let x = Deprecated {
            //~^ ERROR use of deprecated item
            inherit: 1,
            //~^ ERROR use of deprecated item
        };

        let _ = x.inherit;
        //~^ ERROR use of deprecated item

        let Deprecated {
            //~^ ERROR use of deprecated item
            inherit: _,
            //~^ ERROR use of deprecated item
        } = x;

        let Deprecated
            //~^ ERROR use of deprecated item
            { .. } = x;

        let x = Deprecated2(1, 2, 3);
        //~^ ERROR use of deprecated item

        let _ = x.0;
        //~^ ERROR use of deprecated item
        let _ = x.1;
        //~^ ERROR use of deprecated item
        let _ = x.2;
        //~^ ERROR use of deprecated item

        let Deprecated2
        //~^ ERROR use of deprecated item
            (_,
             //~^ ERROR use of deprecated item
             _,
             //~^ ERROR use of deprecated item
             _)
             //~^ ERROR use of deprecated item
            = x;
        let Deprecated2
        //~^ ERROR use of deprecated item
            // the patterns are all fine:
            (..) = x;
    }
}

mod inheritance {
    use deprecation_lint::*;

    fn test_inheritance() {
        deprecated_mod::deprecated(); //~ ERROR use of deprecated item
    }
}

mod this_crate {
    #[deprecated(since = "1.0.0", note = "text")]
    pub fn deprecated() {}
    #[deprecated(since = "1.0.0", note = "text")]
    pub fn deprecated_text() {}

    pub struct MethodTester;

    impl MethodTester {
        #[deprecated(since = "1.0.0", note = "text")]
        pub fn method_deprecated(&self) {}
        #[deprecated(since = "1.0.0", note = "text")]
        pub fn method_deprecated_text(&self) {}
    }

    pub trait Trait {
        #[deprecated(since = "1.0.0", note = "text")]
        fn trait_deprecated(&self) {}
        #[deprecated(since = "1.0.0", note = "text")]
        fn trait_deprecated_text(&self) {}
    }

    impl Trait for MethodTester {}

    #[deprecated(since = "1.0.0", note = "text")]
    pub struct DeprecatedStruct {
        i: isize
    }
    pub struct UnstableStruct {
        i: isize
    }
    pub struct StableStruct {
        i: isize
    }

    #[deprecated(since = "1.0.0", note = "text")]
    pub struct DeprecatedUnitStruct;

    pub enum Enum {
        #[deprecated(since = "1.0.0", note = "text")]
        DeprecatedVariant,
    }

    #[deprecated(since = "1.0.0", note = "text")]
    pub struct DeprecatedTupleStruct(isize);

    fn test() {
        // Only the deprecated cases of the following should generate
        // errors, because other stability attributes now have meaning
        // only *across* crates, not within a single crate.

        type Foo = MethodTester;
        let foo = MethodTester;

        deprecated(); //~ ERROR use of deprecated item
        foo.method_deprecated(); //~ ERROR use of deprecated item
        Foo::method_deprecated(&foo); //~ ERROR use of deprecated item
        <Foo>::method_deprecated(&foo); //~ ERROR use of deprecated item
        foo.trait_deprecated(); //~ ERROR use of deprecated item
        Trait::trait_deprecated(&foo); //~ ERROR use of deprecated item
        <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated item
        <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated item

        deprecated_text(); //~ ERROR use of deprecated item: text
        foo.method_deprecated_text(); //~ ERROR use of deprecated item: text
        Foo::method_deprecated_text(&foo); //~ ERROR use of deprecated item: text
        <Foo>::method_deprecated_text(&foo); //~ ERROR use of deprecated item: text
        foo.trait_deprecated_text(); //~ ERROR use of deprecated item: text
        Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text
        <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text
        <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text

        let _ = DeprecatedStruct {
            //~^ ERROR use of deprecated item
            i: 0 //~ ERROR use of deprecated item
        };

        let _ = DeprecatedUnitStruct; //~ ERROR use of deprecated item

        let _ = Enum::DeprecatedVariant; //~ ERROR use of deprecated item

        let _ = DeprecatedTupleStruct (1); //~ ERROR use of deprecated item
    }

    fn test_method_param<Foo: Trait>(foo: Foo) {
        foo.trait_deprecated(); //~ ERROR use of deprecated item
        Trait::trait_deprecated(&foo); //~ ERROR use of deprecated item
        <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated item
        <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated item
        foo.trait_deprecated_text(); //~ ERROR use of deprecated item: text
        Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text
        <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text
        <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text
    }

    fn test_method_object(foo: &Trait) {
        foo.trait_deprecated(); //~ ERROR use of deprecated item
        foo.trait_deprecated_text(); //~ ERROR use of deprecated item: text
    }

    #[deprecated(since = "1.0.0", note = "text")]
    fn test_fn_body() {
        fn fn_in_body() {}
        fn_in_body();
    }

    impl MethodTester {
        #[deprecated(since = "1.0.0", note = "text")]
        fn test_method_body(&self) {
            fn fn_in_body() {}
            fn_in_body();
        }
    }

    #[deprecated(since = "1.0.0", note = "text")]
    pub trait DeprecatedTrait {
        fn dummy(&self) { }
    }

    struct S;

    impl DeprecatedTrait for S { } //~ ERROR use of deprecated item

    trait LocalTrait : DeprecatedTrait { } //~ ERROR use of deprecated item
}

mod this_crate2 {
    struct Stable {
        #[deprecated(since = "1.0.0", note = "text")]
        override2: u8,
    }

    struct Stable2(u8,
                   u8,
                   #[deprecated(since = "1.0.0", note = "text")] u8);

    #[deprecated(since = "1.0.0", note = "text")]
    struct Deprecated {
        inherit: u8,
    }

    #[deprecated(since = "1.0.0", note = "text")]
    struct Deprecated2(u8,
                       u8,
                       u8);

    pub fn foo() {
        let x = Stable {
            override2: 3,
            //~^ ERROR use of deprecated item
        };

        let _ = x.override2;
        //~^ ERROR use of deprecated item

        let Stable {
            override2: _
            //~^ ERROR use of deprecated item
        } = x;
        // all fine
        let Stable { .. } = x;

        let x = Stable2(1, 2, 3);

        let _ = x.2;
        //~^ ERROR use of deprecated item

        let Stable2(_,
                   _,
                   _)
            //~^ ERROR use of deprecated item
            = x;
        // all fine
        let Stable2(..) = x;

        let x = Deprecated {
            //~^ ERROR use of deprecated item
            inherit: 1,
            //~^ ERROR use of deprecated item
        };

        let _ = x.inherit;
        //~^ ERROR use of deprecated item

        let Deprecated {
            //~^ ERROR use of deprecated item
            inherit: _,
            //~^ ERROR use of deprecated item
        } = x;

        let Deprecated
            //~^ ERROR use of deprecated item
            // the patterns are all fine:
            { .. } = x;

        let x = Deprecated2(1, 2, 3);
        //~^ ERROR use of deprecated item

        let _ = x.0;
        //~^ ERROR use of deprecated item
        let _ = x.1;
        //~^ ERROR use of deprecated item
        let _ = x.2;
        //~^ ERROR use of deprecated item

        let Deprecated2
        //~^ ERROR use of deprecated item
            (_,
             //~^ ERROR use of deprecated item
             _,
             //~^ ERROR use of deprecated item
             _)
            //~^ ERROR use of deprecated item
            = x;
        let Deprecated2
        //~^ ERROR use of deprecated item
            // the patterns are all fine:
            (..) = x;
    }
}

fn main() {}
<|endoftext|>


<commit_before>// xfail-boot
// xfail-stage0
use std;
import std._str;

fn test(str actual, str expected) {
  log actual;
  log expected;
  check (_str.eq(actual, expected));
}

fn main() {
  test(#fmt("hello %d friends and %s things", 10, "formatted"),
    "hello 10 friends and formatted things");

  // Simple tests for types
  test(#fmt("%d", 1), "1");
  test(#fmt("%i", 2), "2");
  test(#fmt("%i", -1), "-1");
  test(#fmt("%u", 10u), "10");
  test(#fmt("%s", "test"), "test");
  test(#fmt("%b", true), "true");
  test(#fmt("%b", false), "false");
  test(#fmt("%c", 'A'), "A");
  test(#fmt("%x", 0xff_u), "ff");
  test(#fmt("%X", 0x12ab_u), "12AB");
  test(#fmt("%t", 0b11010101_u), "11010101");
}
<commit_msg>More tests for #fmt<commit_after>// xfail-boot
// xfail-stage0
use std;
import std._str;

fn test(str actual, str expected) {
  log actual;
  log expected;
  check (_str.eq(actual, expected));
}

fn main() {
  test(#fmt("hello %d friends and %s things", 10, "formatted"),
    "hello 10 friends and formatted things");

  // Simple tests for types
  test(#fmt("%d", 1), "1");
  test(#fmt("%i", 2), "2");
  test(#fmt("%i", -1), "-1");
  test(#fmt("%u", 10u), "10");
  test(#fmt("%s", "test"), "test");
  test(#fmt("%b", true), "true");
  test(#fmt("%b", false), "false");
  test(#fmt("%c", 'A'), "A");
  test(#fmt("%x", 0xff_u), "ff");
  test(#fmt("%X", 0x12ab_u), "12AB");
  test(#fmt("%t", 0b11010101_u), "11010101");

  // 32-bit limits
  test(#fmt("%i", -2147483648), "-2147483648");
  test(#fmt("%i", 2147483647), "2147483647");
  test(#fmt("%u", 4294967295u), "4294967295");
  test(#fmt("%x", 0xffffffff_u), "ffffffff");
  test(#fmt("%t", 0xffffffff_u), "11111111111111111111111111111111");
}
<|endoftext|>


<commit_before>use std::path::PathBuf;

use std::fmt::{Display, Debug, Formatter};
use std::fmt::Error as FmtError;
use std::result::Result as RResult;
use std::path::Components;

use libimagerror::into::IntoError;

use error::StoreErrorKind as SEK;
use store::Result;
use store::Store;

/// The Index into the Store
#[derive(Debug, Clone, PartialEq, Hash, Eq, PartialOrd, Ord)]
pub struct StoreId {
    base: Option<PathBuf>,
    id:   PathBuf,
}

impl StoreId {

    pub fn new(base: Option<PathBuf>, id: PathBuf) -> Result<StoreId> {
        StoreId::new_baseless(id).map(|mut sid| { sid.base = base; sid })
    }

    pub fn new_baseless(id: PathBuf) -> Result<StoreId> {
        if id.is_absolute() {
            Err(SEK::StoreIdLocalPartAbsoluteError.into_error())
        } else {
            Ok(StoreId {
                base: None,
                id: id
            })
        }
    }

    pub fn without_base(mut self) -> StoreId {
        self.base = None;
        self
    }

    pub fn with_base(mut self, base: PathBuf) -> Self {
        self.base = Some(base);
        self
    }

    pub fn storified(self, store: &Store) -> StoreId {
        StoreId {
            base: Some(store.path().clone()),
            id: self.id
        }
    }

    pub fn exists(&self) -> bool {
        let pb : PathBuf = self.clone().into();
        pb.exists()
    }

    pub fn is_file(&self) -> bool {
        true
    }

    pub fn is_dir(&self) -> bool {
        false
    }

    pub fn to_str(&self) -> Result<String> {
        if self.base.is_some() {
            let mut base = self.base.as_ref().cloned().unwrap();
            base.push(self.id.clone());
            base
        } else {
            self.id.clone()
        }
        .to_str()
        .map(String::from)
        .ok_or(SEK::StoreIdHandlingError.into_error())
    }

    /// Returns the components of the `id` part of the StoreId object.
    ///
    /// Can be used to check whether a StoreId points to an entry in a specific collection of
    /// StoreIds.
    pub fn components(&self) -> Components {
        self.id.components()
    }

}

impl Into<PathBuf> for StoreId {

    fn into(self) -> PathBuf {
        let mut base = self.base.unwrap_or(PathBuf::from("/"));
        base.push(self.id);
        base
    }

}

impl Display for StoreId {

    fn fmt(&self, fmt: &mut Formatter) -> RResult<(), FmtError> {
        match self.id.to_str() {
            Some(s) => write!(fmt, "{}", s),
            None    => write!(fmt, "{}", self.id.to_string_lossy()),
        }
    }

}

/// This Trait allows you to convert various representations to a single one
/// suitable for usage in the Store
pub trait IntoStoreId {
    fn into_storeid(self) -> Result<StoreId>;
}

impl IntoStoreId for StoreId {
    fn into_storeid(self) -> Result<StoreId> {
        Ok(self)
    }
}

impl IntoStoreId for PathBuf {
    fn into_storeid(self) -> Result<StoreId> {
        StoreId::new_baseless(self)
    }
}

#[macro_export]
macro_rules! module_entry_path_mod {
    ($name:expr) => (
        #[deny(missing_docs,
                missing_copy_implementations,
                trivial_casts, trivial_numeric_casts,
                unsafe_code,
                unstable_features,
                unused_import_braces, unused_qualifications,
                unused_imports)]
        /// A helper module to create valid module entry paths
        pub mod module_path {
            use std::convert::AsRef;
            use std::path::Path;
            use std::path::PathBuf;

            use $crate::storeid::StoreId;
            use $crate::store::Result;

            /// A Struct giving you the ability to choose store entries assigned
            /// to it.
            ///
            /// It is created through a call to `new`.
            pub struct ModuleEntryPath(PathBuf);

            impl ModuleEntryPath {
                /// Path has to be a valid UTF-8 string or this will panic!
                pub fn new<P: AsRef<Path>>(pa: P) -> ModuleEntryPath {
                    let mut path = PathBuf::new();
                    path.push(format!("{}", $name));
                    path.push(pa.as_ref().clone());
                    let name = pa.as_ref().file_name().unwrap()
                        .to_str().unwrap();
                    path.set_file_name(name);
                    ModuleEntryPath(path)
                }
            }

            impl $crate::storeid::IntoStoreId for ModuleEntryPath {
                fn into_storeid(self) -> Result<$crate::storeid::StoreId> {
                    StoreId::new(None, self.0)
                }
            }
        }
    )
}

pub struct StoreIdIterator {
    iter: Box<Iterator<Item = StoreId>>,
}

impl Debug for StoreIdIterator {

    fn fmt(&self, fmt: &mut Formatter) -> RResult<(), FmtError> {
        write!(fmt, "StoreIdIterator")
    }

}

impl StoreIdIterator {

    pub fn new(iter: Box<Iterator<Item = StoreId>>) -> StoreIdIterator {
        StoreIdIterator {
            iter: iter,
        }
    }

}

impl Iterator for StoreIdIterator {
    type Item = StoreId;

    fn next(&mut self) -> Option<StoreId> {
        self.iter.next()
    }

}

#[cfg(test)]
mod test {

    use storeid::IntoStoreId;

    module_entry_path_mod!("test");

    #[test]
    fn correct_path() {
        let p = module_path::ModuleEntryPath::new("test");

        assert_eq!(p.into_storeid().unwrap().to_str().unwrap(), "test/test");
    }

}
<commit_msg>Add StoreId::is_in_collection()<commit_after>use std::path::PathBuf;

use std::fmt::{Display, Debug, Formatter};
use std::fmt::Error as FmtError;
use std::result::Result as RResult;
use std::path::Components;

use libimagerror::into::IntoError;

use error::StoreErrorKind as SEK;
use store::Result;
use store::Store;

/// The Index into the Store
#[derive(Debug, Clone, PartialEq, Hash, Eq, PartialOrd, Ord)]
pub struct StoreId {
    base: Option<PathBuf>,
    id:   PathBuf,
}

impl StoreId {

    pub fn new(base: Option<PathBuf>, id: PathBuf) -> Result<StoreId> {
        StoreId::new_baseless(id).map(|mut sid| { sid.base = base; sid })
    }

    pub fn new_baseless(id: PathBuf) -> Result<StoreId> {
        if id.is_absolute() {
            Err(SEK::StoreIdLocalPartAbsoluteError.into_error())
        } else {
            Ok(StoreId {
                base: None,
                id: id
            })
        }
    }

    pub fn without_base(mut self) -> StoreId {
        self.base = None;
        self
    }

    pub fn with_base(mut self, base: PathBuf) -> Self {
        self.base = Some(base);
        self
    }

    pub fn storified(self, store: &Store) -> StoreId {
        StoreId {
            base: Some(store.path().clone()),
            id: self.id
        }
    }

    pub fn exists(&self) -> bool {
        let pb : PathBuf = self.clone().into();
        pb.exists()
    }

    pub fn is_file(&self) -> bool {
        true
    }

    pub fn is_dir(&self) -> bool {
        false
    }

    pub fn to_str(&self) -> Result<String> {
        if self.base.is_some() {
            let mut base = self.base.as_ref().cloned().unwrap();
            base.push(self.id.clone());
            base
        } else {
            self.id.clone()
        }
        .to_str()
        .map(String::from)
        .ok_or(SEK::StoreIdHandlingError.into_error())
    }

    /// Returns the components of the `id` part of the StoreId object.
    ///
    /// Can be used to check whether a StoreId points to an entry in a specific collection of
    /// StoreIds.
    pub fn components(&self) -> Components {
        self.id.components()
    }

    /// Check whether a StoreId points to an entry in a specific collection.
    ///
    /// A "collection" here is simply a directory. So `foo/bar/baz` is an entry which is in
    /// collection ["foo", "bar"].
    ///
    /// # Warning
    ///
    /// The collection specification _has_ to start with the module name. Otherwise this function
    /// may return false negatives.
    ///
    pub fn is_in_collection(&self, colls: &[&str]) -> bool {
        use std::path::Component;

        self.id
            .components()
            .zip(colls)
            .map(|(component, pred_coll)| match component {
                Component::Normal(ref s) => s.to_str().map(|ref s| s == pred_coll).unwrap_or(false),
                _ => false
            })
            .all(|x| x) && colls.last().map(|last| !self.id.ends_with(last)).unwrap_or(false)
    }

}

impl Into<PathBuf> for StoreId {

    fn into(self) -> PathBuf {
        let mut base = self.base.unwrap_or(PathBuf::from("/"));
        base.push(self.id);
        base
    }

}

impl Display for StoreId {

    fn fmt(&self, fmt: &mut Formatter) -> RResult<(), FmtError> {
        match self.id.to_str() {
            Some(s) => write!(fmt, "{}", s),
            None    => write!(fmt, "{}", self.id.to_string_lossy()),
        }
    }

}

/// This Trait allows you to convert various representations to a single one
/// suitable for usage in the Store
pub trait IntoStoreId {
    fn into_storeid(self) -> Result<StoreId>;
}

impl IntoStoreId for StoreId {
    fn into_storeid(self) -> Result<StoreId> {
        Ok(self)
    }
}

impl IntoStoreId for PathBuf {
    fn into_storeid(self) -> Result<StoreId> {
        StoreId::new_baseless(self)
    }
}

#[macro_export]
macro_rules! module_entry_path_mod {
    ($name:expr) => (
        #[deny(missing_docs,
                missing_copy_implementations,
                trivial_casts, trivial_numeric_casts,
                unsafe_code,
                unstable_features,
                unused_import_braces, unused_qualifications,
                unused_imports)]
        /// A helper module to create valid module entry paths
        pub mod module_path {
            use std::convert::AsRef;
            use std::path::Path;
            use std::path::PathBuf;

            use $crate::storeid::StoreId;
            use $crate::store::Result;

            /// A Struct giving you the ability to choose store entries assigned
            /// to it.
            ///
            /// It is created through a call to `new`.
            pub struct ModuleEntryPath(PathBuf);

            impl ModuleEntryPath {
                /// Path has to be a valid UTF-8 string or this will panic!
                pub fn new<P: AsRef<Path>>(pa: P) -> ModuleEntryPath {
                    let mut path = PathBuf::new();
                    path.push(format!("{}", $name));
                    path.push(pa.as_ref().clone());
                    let name = pa.as_ref().file_name().unwrap()
                        .to_str().unwrap();
                    path.set_file_name(name);
                    ModuleEntryPath(path)
                }
            }

            impl $crate::storeid::IntoStoreId for ModuleEntryPath {
                fn into_storeid(self) -> Result<$crate::storeid::StoreId> {
                    StoreId::new(None, self.0)
                }
            }
        }
    )
}

pub struct StoreIdIterator {
    iter: Box<Iterator<Item = StoreId>>,
}

impl Debug for StoreIdIterator {

    fn fmt(&self, fmt: &mut Formatter) -> RResult<(), FmtError> {
        write!(fmt, "StoreIdIterator")
    }

}

impl StoreIdIterator {

    pub fn new(iter: Box<Iterator<Item = StoreId>>) -> StoreIdIterator {
        StoreIdIterator {
            iter: iter,
        }
    }

}

impl Iterator for StoreIdIterator {
    type Item = StoreId;

    fn next(&mut self) -> Option<StoreId> {
        self.iter.next()
    }

}

#[cfg(test)]
mod test {

    use storeid::IntoStoreId;

    module_entry_path_mod!("test");

    #[test]
    fn correct_path() {
        let p = module_path::ModuleEntryPath::new("test");

        assert_eq!(p.into_storeid().unwrap().to_str().unwrap(), "test/test");
    }

    #[test]
    fn storeid_in_collection() {
        let p = module_path::ModuleEntryPath::new("1/2/3/4/5/6/7/8/9/0").into_storeid().unwrap();

        assert!(p.is_in_collection(&["test", "1"]));
        assert!(p.is_in_collection(&["test", "1", "2"]));
        assert!(p.is_in_collection(&["test", "1", "2", "3"]));
        assert!(p.is_in_collection(&["test", "1", "2", "3", "4"]));
        assert!(p.is_in_collection(&["test", "1", "2", "3", "4", "5"]));
        assert!(p.is_in_collection(&["test", "1", "2", "3", "4", "5", "6"]));
        assert!(p.is_in_collection(&["test", "1", "2", "3", "4", "5", "6", "7"]));
        assert!(p.is_in_collection(&["test", "1", "2", "3", "4", "5", "6", "7", "8"]));
        assert!(p.is_in_collection(&["test", "1", "2", "3", "4", "5", "6", "7", "8", "9"]));

        // "0" is the filename, not a collection
        assert!(!p.is_in_collection(&["test", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0"]));

        assert!(!p.is_in_collection(&["test", "0", "2", "3", "4", "5", "6", "7", "8", "9", "0"]));
        assert!(!p.is_in_collection(&["test", "1", "2", "3", "4", "5", "6", "8"]));
        assert!(!p.is_in_collection(&["test", "1", "2", "3", "leet", "5", "6", "7"]));
    }

}
<|endoftext|>


<commit_before>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

use std::ops::Deref;
use std::path::Path;
use std::path::PathBuf;

use std::fmt::{Display, Debug, Formatter};
use std::fmt::Error as FmtError;
use std::result::Result as RResult;
use std::path::Components;

use libimagerror::into::IntoError;

use error::StoreErrorKind as SEK;
use error::MapErrInto;
use store::Result;

/// The Index into the Store
#[derive(Debug, Clone, Hash, Eq, PartialOrd, Ord)]
pub struct StoreId {
    base: Option<PathBuf>,
    id:   PathBuf,
}

impl PartialEq for StoreId {
    fn eq(&self, other: &StoreId) -> bool {
        self.id == other.id
    }
}

impl StoreId {

    pub fn new(base: Option<PathBuf>, id: PathBuf) -> Result<StoreId> {
        StoreId::new_baseless(id).map(|mut sid| { sid.base = base; sid })
    }

    /// Try to create a StoreId object from a filesystem-absolute path.
    ///
    /// Automatically creates a StoreId object which has a `base` set to `store_part` if stripping
    /// the `store_part` from the `full_path` succeeded.
    ///
    /// Returns a `StoreErrorKind::StoreIdBuildFromFullPathError` if stripping failes.
    pub fn from_full_path<D>(store_part: &PathBuf, full_path: D) -> Result<StoreId>
        where D: Deref<Target = Path>
    {
        let p = try!(
            full_path.strip_prefix(store_part).map_err_into(SEK::StoreIdBuildFromFullPathError)
        );
        StoreId::new(Some(store_part.clone()), PathBuf::from(p))
    }

    pub fn new_baseless(id: PathBuf) -> Result<StoreId> {
        if id.is_absolute() {
            Err(SEK::StoreIdLocalPartAbsoluteError.into_error())
        } else {
            Ok(StoreId {
                base: None,
                id: id
            })
        }
    }

    pub fn without_base(mut self) -> StoreId {
        self.base = None;
        self
    }

    pub fn with_base(mut self, base: PathBuf) -> Self {
        self.base = Some(base);
        self
    }

    /// Transform the StoreId object into a PathBuf, error if the base of the StoreId is not
    /// specified.
    pub fn into_pathbuf(self) -> Result<PathBuf> {
        let mut base = try!(self.base.ok_or(SEK::StoreIdHasNoBaseError.into_error()));
        base.push(self.id);
        Ok(base)
    }

    pub fn exists(&self) -> Result<bool> {
        self.clone().into_pathbuf().map(|pb| pb.exists())
    }

    pub fn to_str(&self) -> Result<String> {
        self.base
            .as_ref()
            .cloned()
            .map(|mut base| { base.push(self.id.clone()); base })
            .unwrap_or_else(|| self.id.clone())
            .to_str()
            .map(String::from)
            .ok_or(SEK::StoreIdHandlingError.into_error())
    }

    /// Returns the components of the `id` part of the StoreId object.
    ///
    /// Can be used to check whether a StoreId points to an entry in a specific collection of
    /// StoreIds.
    pub fn components(&self) -> Components {
        self.id.components()
    }

    /// Get the _local_ part of a StoreId object, as in "the part from the store root to the entry".
    pub fn local(&self) -> &PathBuf {
        &self.id
    }

}

impl Display for StoreId {

    fn fmt(&self, fmt: &mut Formatter) -> RResult<(), FmtError> {
        match self.id.to_str() {
            Some(s) => write!(fmt, "{}", s),
            None    => write!(fmt, "{}", self.id.to_string_lossy()),
        }
    }

}

/// This Trait allows you to convert various representations to a single one
/// suitable for usage in the Store
pub trait IntoStoreId {
    fn into_storeid(self) -> Result<StoreId>;
}

impl IntoStoreId for StoreId {
    fn into_storeid(self) -> Result<StoreId> {
        Ok(self)
    }
}

impl IntoStoreId for PathBuf {
    fn into_storeid(self) -> Result<StoreId> {
        StoreId::new_baseless(self)
    }
}

#[macro_export]
macro_rules! module_entry_path_mod {
    ($name:expr) => (
        #[deny(missing_docs,
                missing_copy_implementations,
                trivial_casts, trivial_numeric_casts,
                unsafe_code,
                unstable_features,
                unused_import_braces, unused_qualifications,
                unused_imports)]
        /// A helper module to create valid module entry paths
        pub mod module_path {
            use std::convert::AsRef;
            use std::path::Path;
            use std::path::PathBuf;

            use $crate::storeid::StoreId;
            use $crate::store::Result;

            /// A Struct giving you the ability to choose store entries assigned
            /// to it.
            ///
            /// It is created through a call to `new`.
            pub struct ModuleEntryPath(PathBuf);

            impl ModuleEntryPath {
                /// Path has to be a valid UTF-8 string or this will panic!
                pub fn new<P: AsRef<Path>>(pa: P) -> ModuleEntryPath {
                    let mut path = PathBuf::new();
                    path.push(format!("{}", $name));
                    path.push(pa.as_ref().clone());
                    let name = pa.as_ref().file_name().unwrap()
                        .to_str().unwrap();
                    path.set_file_name(name);
                    ModuleEntryPath(path)
                }
            }

            impl $crate::storeid::IntoStoreId for ModuleEntryPath {
                fn into_storeid(self) -> Result<$crate::storeid::StoreId> {
                    StoreId::new(None, self.0)
                }
            }
        }
    )
}

pub struct StoreIdIterator {
    iter: Box<Iterator<Item = StoreId>>,
}

impl Debug for StoreIdIterator {

    fn fmt(&self, fmt: &mut Formatter) -> RResult<(), FmtError> {
        write!(fmt, "StoreIdIterator")
    }

}

impl StoreIdIterator {

    pub fn new(iter: Box<Iterator<Item = StoreId>>) -> StoreIdIterator {
        StoreIdIterator {
            iter: iter,
        }
    }

}

impl Iterator for StoreIdIterator {
    type Item = StoreId;

    fn next(&mut self) -> Option<StoreId> {
        self.iter.next()
    }

}

#[cfg(test)]
mod test {

    use storeid::IntoStoreId;

    module_entry_path_mod!("test");

    #[test]
    fn correct_path() {
        let p = module_path::ModuleEntryPath::new("test");

        assert_eq!(p.into_storeid().unwrap().to_str().unwrap(), "test/test");
    }

}
<commit_msg>Rename test<commit_after>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

use std::ops::Deref;
use std::path::Path;
use std::path::PathBuf;

use std::fmt::{Display, Debug, Formatter};
use std::fmt::Error as FmtError;
use std::result::Result as RResult;
use std::path::Components;

use libimagerror::into::IntoError;

use error::StoreErrorKind as SEK;
use error::MapErrInto;
use store::Result;

/// The Index into the Store
#[derive(Debug, Clone, Hash, Eq, PartialOrd, Ord)]
pub struct StoreId {
    base: Option<PathBuf>,
    id:   PathBuf,
}

impl PartialEq for StoreId {
    fn eq(&self, other: &StoreId) -> bool {
        self.id == other.id
    }
}

impl StoreId {

    pub fn new(base: Option<PathBuf>, id: PathBuf) -> Result<StoreId> {
        StoreId::new_baseless(id).map(|mut sid| { sid.base = base; sid })
    }

    /// Try to create a StoreId object from a filesystem-absolute path.
    ///
    /// Automatically creates a StoreId object which has a `base` set to `store_part` if stripping
    /// the `store_part` from the `full_path` succeeded.
    ///
    /// Returns a `StoreErrorKind::StoreIdBuildFromFullPathError` if stripping failes.
    pub fn from_full_path<D>(store_part: &PathBuf, full_path: D) -> Result<StoreId>
        where D: Deref<Target = Path>
    {
        let p = try!(
            full_path.strip_prefix(store_part).map_err_into(SEK::StoreIdBuildFromFullPathError)
        );
        StoreId::new(Some(store_part.clone()), PathBuf::from(p))
    }

    pub fn new_baseless(id: PathBuf) -> Result<StoreId> {
        if id.is_absolute() {
            Err(SEK::StoreIdLocalPartAbsoluteError.into_error())
        } else {
            Ok(StoreId {
                base: None,
                id: id
            })
        }
    }

    pub fn without_base(mut self) -> StoreId {
        self.base = None;
        self
    }

    pub fn with_base(mut self, base: PathBuf) -> Self {
        self.base = Some(base);
        self
    }

    /// Transform the StoreId object into a PathBuf, error if the base of the StoreId is not
    /// specified.
    pub fn into_pathbuf(self) -> Result<PathBuf> {
        let mut base = try!(self.base.ok_or(SEK::StoreIdHasNoBaseError.into_error()));
        base.push(self.id);
        Ok(base)
    }

    pub fn exists(&self) -> Result<bool> {
        self.clone().into_pathbuf().map(|pb| pb.exists())
    }

    pub fn to_str(&self) -> Result<String> {
        self.base
            .as_ref()
            .cloned()
            .map(|mut base| { base.push(self.id.clone()); base })
            .unwrap_or_else(|| self.id.clone())
            .to_str()
            .map(String::from)
            .ok_or(SEK::StoreIdHandlingError.into_error())
    }

    /// Returns the components of the `id` part of the StoreId object.
    ///
    /// Can be used to check whether a StoreId points to an entry in a specific collection of
    /// StoreIds.
    pub fn components(&self) -> Components {
        self.id.components()
    }

    /// Get the _local_ part of a StoreId object, as in "the part from the store root to the entry".
    pub fn local(&self) -> &PathBuf {
        &self.id
    }

}

impl Display for StoreId {

    fn fmt(&self, fmt: &mut Formatter) -> RResult<(), FmtError> {
        match self.id.to_str() {
            Some(s) => write!(fmt, "{}", s),
            None    => write!(fmt, "{}", self.id.to_string_lossy()),
        }
    }

}

/// This Trait allows you to convert various representations to a single one
/// suitable for usage in the Store
pub trait IntoStoreId {
    fn into_storeid(self) -> Result<StoreId>;
}

impl IntoStoreId for StoreId {
    fn into_storeid(self) -> Result<StoreId> {
        Ok(self)
    }
}

impl IntoStoreId for PathBuf {
    fn into_storeid(self) -> Result<StoreId> {
        StoreId::new_baseless(self)
    }
}

#[macro_export]
macro_rules! module_entry_path_mod {
    ($name:expr) => (
        #[deny(missing_docs,
                missing_copy_implementations,
                trivial_casts, trivial_numeric_casts,
                unsafe_code,
                unstable_features,
                unused_import_braces, unused_qualifications,
                unused_imports)]
        /// A helper module to create valid module entry paths
        pub mod module_path {
            use std::convert::AsRef;
            use std::path::Path;
            use std::path::PathBuf;

            use $crate::storeid::StoreId;
            use $crate::store::Result;

            /// A Struct giving you the ability to choose store entries assigned
            /// to it.
            ///
            /// It is created through a call to `new`.
            pub struct ModuleEntryPath(PathBuf);

            impl ModuleEntryPath {
                /// Path has to be a valid UTF-8 string or this will panic!
                pub fn new<P: AsRef<Path>>(pa: P) -> ModuleEntryPath {
                    let mut path = PathBuf::new();
                    path.push(format!("{}", $name));
                    path.push(pa.as_ref().clone());
                    let name = pa.as_ref().file_name().unwrap()
                        .to_str().unwrap();
                    path.set_file_name(name);
                    ModuleEntryPath(path)
                }
            }

            impl $crate::storeid::IntoStoreId for ModuleEntryPath {
                fn into_storeid(self) -> Result<$crate::storeid::StoreId> {
                    StoreId::new(None, self.0)
                }
            }
        }
    )
}

pub struct StoreIdIterator {
    iter: Box<Iterator<Item = StoreId>>,
}

impl Debug for StoreIdIterator {

    fn fmt(&self, fmt: &mut Formatter) -> RResult<(), FmtError> {
        write!(fmt, "StoreIdIterator")
    }

}

impl StoreIdIterator {

    pub fn new(iter: Box<Iterator<Item = StoreId>>) -> StoreIdIterator {
        StoreIdIterator {
            iter: iter,
        }
    }

}

impl Iterator for StoreIdIterator {
    type Item = StoreId;

    fn next(&mut self) -> Option<StoreId> {
        self.iter.next()
    }

}

#[cfg(test)]
mod test {

    use storeid::IntoStoreId;

    module_entry_path_mod!("test");

    #[test]
    fn test_correct_path() {
        let p = module_path::ModuleEntryPath::new("test");

        assert_eq!(p.into_storeid().unwrap().to_str().unwrap(), "test/test");
    }

}
<|endoftext|>