<commit_before>// Zinc, the bare metal stack for rust.
// Copyright 2014 Ben Gamari <bgamari@gmail.com>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/*!
## I/O register interface

On most embedded platforms interaction with hardware peripherals
occurs through memory-mapped registers. This crate provides a syntax
extension for `rustc` to generate convenient, type-safe register
interfaces from a minimal definition.

### Concepts

A *register* is group of bits (typically a word, although on some
platforms smaller). By manipulating the bits of a register one can
affect the state of the associated peripheral.

### Example register definition

Let's consider a register block for a simple UART-like peripheral. The
documentation for the peripheral will likely have a table defining the
interface resembling the following,

```notrust
offset       name         description
───────      ────────     ──────────────────────────
0x0          CR           Configuration register
  bit 0      RXE          Receive enable
  bit 1      TXE          Transmit enable
  bit 2      RXIE         Recieve interrupt enable
  bit 3      TXIE         Transmit interrupt enable
  bit 12:4   BR           Baudrate
  bit 16:14  PARITY       Parity
                            0x0     No parity
                            0x1     Reserved
                            0x2     Even parity
                            0x3     Odd parity

0x4          SR           Status register
  bit 0      RXNE         Receive data register not empty flag (read-only)
  bit 1      TXE          Transmit data register not empty flag (read-only)
  bit 2      FE           Framing error flag (set to clear)

0x8          DR           Data register
  bits 7:0   D            Read returns received data
                          Write transmits data
```

The syntax extension is invoked through through the `ioregs!` macro. A
register definition for the above peripheral might look like this,

```
ioregs!(UART = {
    0x0    => reg32 cr {
        0      => rxe,
        1      => txe,
        2      => rxie,
        3      => txie,
        4..12  => br,
        14..16 => parity {
          0x0  => NoParity,
          0x2  => EvenParity,
          0x3  => OddParity,
        }
    }

    0x4    => reg32 sr {
        0      => rxne: ro,
        1      => txe: ro,
        2      => fe: set_to_clear,
    }

    0x8    => reg32 dr {
        0..7   => d
    }
})
```

Here we've defined a register block called `UART` consisting of a
three registers: `cr`, `sr`, and `dr`. Each register definition
consists of an offset from the beginning of the register block width,
a register type giving the width of the register (`reg32` in this
case), a name, and a list of fields.

The `cr` register has four boolean flags, an integer
field `br`, and a field `parity` with four possible values
(`NoParity`, `EvenParity`, and `OddParity`). Each field is defined by
a bit or bit range, a name, some optional modifiers (e.g. `ro` in the
case of `rxne`), and an optional list of values.

This register definition will produce a variety of types, along with
associated accessor methods for convenient, safe manipulation of the
described registers. In the process of generating these, `ioregs!`
will perform a variety of sanity checks (e.g. ensuring that registers
and bitfields are free of overlap).

#### Documenting register definitions

It is highly recommended that register definitions include
docstrings. Registers, fields, and `enum` values can all be annotated
with docstrings with the typical Rust doc comment syntax. Both outer
(`/// comment`) and inner (`//! comment`) comments are accepted. Inner
comments apply to the item to which the current block belongs whereas
outer comments apply to the item that follows. In addition,
trailing comments are supported with the `//=` syntax. These apply
to the preceding item, allowing definitions and associated comments
to inhabit the same line. Multiple successive comments of the same
type will be concatenated together into a single doc comment.

For instance, we might document the above example as follows,

```
ioregs!(UART = {
    /// Control register
    /// Here is some discussion of the function of the `cr` register.
    0x0    => reg32 cr {
        0      => rxe,         //= Receive enable
        1      => txe,         //= Transmit enable
        2      => rxie,        //= Receive interrupt enable
        3      => txie,        //= Transmit interrupt enable
        4..12  => br,          //= Baud rate
        14..16 => parity {     //! Parity selection
          0x0  => NoParity,    //= No parity
          0x2  => EvenParity,  //= Even parity
          0x3  => OddParity,   //= Odd parity
        }
    }

    ...
})
```

#### Nesting register blocks

In addition to primitive register types (e.g. `reg32`), one can also
nest groups of logically related registers. For instance, in the case
of a DMA peripheral it is common that the same block of registers will
be replicated, one for each DMA channel. This can be accomplished with
`ioregs!` as follows,

```
ioregs!(DMA = {
    0x0    => reg32 cr { ... }
    0x10   => group channel[4] {
        0x0    => reg32 cr { ... }
        0x4    => reg32 sr { ... }
    }
    0x30   => reg32 sr { ... }
})
```

This will produce the following layout in memory,

```notrust
address        register
────────       ──────────────
0x0            cr
0x10           channel[0].cr
0x14           channel[0].sr
0x18           channel[1].cr
0x1c           channel[1].sr
0x20           channel[2].cr
0x24           channel[2].sr
0x28           channel[3].cr
0x2c           channel[3].sr
0x30           sr
```

### What is produced

The `ioregs!` extension produces a variety of types and methods for
each register and field. Let's start by examining the top-level types
representing the structure of the interface.

```
pub enum UART_cr_parity {
    NoParity = 0, EvenParity = 2, OddParity = 3,
}

pub struct UART_cr { ... }
pub struct UART_sr { ... }
pub struct UART_dr { ... }

pub struct UART {
    pub cr: UART_cr,
    pub sr: UART_sr,
    pub dr: UART_dr,
}
```

The `UART` struct is the the "entry-point" into the interface and is
ultimately what will be instantiated to represent the peripheral's
register window, typically as a `static extern` item,

```
extern { pub static UART: UART; }
```

The register structs (`UART_cr`, `UART_sr`, and `UART_dr`)
have no user visible members but expose a variety of methods. Let's
look at `cr` in particular,

```
impl UART_cr {
    pub fn get(&self) -> UART_cr_Get { ... }

    pub fn set_rxe(&self, new_value: bool) -> UART_cr_Update { ... }
    pub fn rxe(&self) -> bool { ... }

    // similar methods for `txe`, `rxie`, `txie`

    pub fn set_br(&self, new_value: u32) -> UART_cr_Update { ... }
    pub fn br(&self) -> u32 { ... }

    pub fn set_parity(&self, new_value: UART_cr_parity) -> UART_cr_Update { ... }
    pub fn parity(&self) -> UART_cr_parity { ... }
}
```

Here we see each field has a corresponding "get" function (e.g. `rxe`,
`br`, and `parity`) as well as a "set" function. Note that the set
function returns a `UART_cr_Update` object. This object mirrors the
setter methods of `UART_cr`, collecting multiple field updates within
a register, performing them on destruction with the `Drop` trait,

```
pub struct UART_cr_Update { ... }
impl Drop for UART_cr_Update { ... }

impl UART_cr_Update {
    pub fn set_rxe<'a>(&'a mut self, new_value: bool) -> &'a mut UART_cr_Update { ... }
    pub fn set_txe<'a>(&'a mut self, new_value: bool) -> &'a mut UART_cr_Update { ... }
    ...
}
```

As the set methods return references to `self` they can be easily
chained together. For instance, we can update the `rxe` and `txe`
fields of the `cr` register atomically,

```
UART.cr.set_rxe(true).set_txe(false);
```

In addition to get and set methods, `UART_cr` also implements a `get`
method which returns a `UART_cr_Get` object mirroring the get methods
of `UART_cr`. This object captures the state of the register allowing
field values to be later atomically queried,

```
let cr: UART_cr_Get = UART.cr.get();
format!("txe={}, rxe={}, br={}", cr.txe(), cr.rxe(), cr.br())
```

In the case of read-only (resp. write-only) fields the set (resp. get)
method is omitted. In the case of `set_to_clear` fields a `clear`
method is instead produced in place of `set`. For instance, in the
case of the `sr` register's `fe` flag,

```
pub fn fe(self: &UART_sr_Getter) -> bool { ... }
pub fn clear_fe(self: &UART_sr_Update) -> UART_sr_Update { ... }
```

### Informal grammar

In the below discussion `THING, ...` will denote a list of one or more
`THING`s. The `THING`s must be comma separated except when ending
with a brace-enclosed block. Optional elements are enclosed in `⟦...⟧`
brackets.

The `ioregs!` macro expects a definition of the form,

```
ioregs!(IDENT = { REG, ... })
```

Where a `REG` is either a register group,

```notrust
OFFSET => group IDENT⟦[COUNT]⟧ { REG, ... }
```

or a primitive register,

```notrust
OFFSET => TYPE IDENT⟦[COUNT]⟧ { FIELD, ... }
```

`COUNT` is an integer count and a register `TYPE` is one of `reg8` (a
one byte wide register), `reg16` (two bytes wide), or `reg32` (four
bytes wide).

A field is given by

```notrust
BITS => IDENT⟦[COUNT]⟧ ⟦: MODIFIER⟧ ⟦{ VALUE, ... }⟧
```

where `BITS` is either an inclusive range of integers (`N..M`) or a
single integer (shorthand for `N..N`). If a list of values is given
the field is of an enumerated type. Otherwise single bit fields are
of type `bool` and wider fields unsigned integers (in particular, of
the same width as the containing register).

A `MODIFIER` is one of `rw` (read/write), `ro` (read-only), `wo`
(write-only), or `set_to_clear` (a flag which can be cleared by
setting to one).

A `VALUE` is given by,

```notrust
N => NAME
```

*/

#![feature(quote, plugin_registrar)]
#![crate_name="ioreg"]
#![crate_type="dylib"]

extern crate rustc;
extern crate syntax;
extern crate serialize;

use rustc::plugin::Registry;
use syntax::ast;
use syntax::ptr::P;
use syntax::codemap::Span;
use syntax::ext::base::{ExtCtxt, MacResult};
use syntax::util::small_vector::SmallVector;

pub mod node;
pub mod parser;
pub mod builder;

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
  reg.register_macro("ioregs", macro_ioregs);
}

pub fn macro_ioregs(cx: &mut ExtCtxt, _: Span, tts: &[ast::TokenTree])
                    -> Box<MacResult+'static> {
  match parser::Parser::new(cx, tts).parse_ioregs() {
    Some(group) => {
      let mut builder = builder::Builder::new();
      let items = builder.emit_items(cx, group);
      MacItems::new(items)
    },
    None => {
      panic!();
    }
  }
}

pub struct MacItems {
  items: Vec<P<ast::Item>>
}

impl MacItems {
  pub fn new(items: Vec<P<ast::Item>>) -> Box<MacResult+'static> {
    Box::new(MacItems { items: items })
  }
}

impl MacResult for MacItems {
  fn make_items(self: Box<MacItems>) -> Option<SmallVector<P<ast::Item>>> {
    Some(SmallVector::many(self.items.clone()))
  }
}
<commit_msg>ioreg: Allow(unstable)<commit_after>// Zinc, the bare metal stack for rust.
// Copyright 2014 Ben Gamari <bgamari@gmail.com>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/*!
## I/O register interface

On most embedded platforms interaction with hardware peripherals
occurs through memory-mapped registers. This crate provides a syntax
extension for `rustc` to generate convenient, type-safe register
interfaces from a minimal definition.

### Concepts

A *register* is group of bits (typically a word, although on some
platforms smaller). By manipulating the bits of a register one can
affect the state of the associated peripheral.

### Example register definition

Let's consider a register block for a simple UART-like peripheral. The
documentation for the peripheral will likely have a table defining the
interface resembling the following,

```notrust
offset       name         description
───────      ────────     ──────────────────────────
0x0          CR           Configuration register
  bit 0      RXE          Receive enable
  bit 1      TXE          Transmit enable
  bit 2      RXIE         Recieve interrupt enable
  bit 3      TXIE         Transmit interrupt enable
  bit 12:4   BR           Baudrate
  bit 16:14  PARITY       Parity
                            0x0     No parity
                            0x1     Reserved
                            0x2     Even parity
                            0x3     Odd parity

0x4          SR           Status register
  bit 0      RXNE         Receive data register not empty flag (read-only)
  bit 1      TXE          Transmit data register not empty flag (read-only)
  bit 2      FE           Framing error flag (set to clear)

0x8          DR           Data register
  bits 7:0   D            Read returns received data
                          Write transmits data
```

The syntax extension is invoked through through the `ioregs!` macro. A
register definition for the above peripheral might look like this,

```
ioregs!(UART = {
    0x0    => reg32 cr {
        0      => rxe,
        1      => txe,
        2      => rxie,
        3      => txie,
        4..12  => br,
        14..16 => parity {
          0x0  => NoParity,
          0x2  => EvenParity,
          0x3  => OddParity,
        }
    }

    0x4    => reg32 sr {
        0      => rxne: ro,
        1      => txe: ro,
        2      => fe: set_to_clear,
    }

    0x8    => reg32 dr {
        0..7   => d
    }
})
```

Here we've defined a register block called `UART` consisting of a
three registers: `cr`, `sr`, and `dr`. Each register definition
consists of an offset from the beginning of the register block width,
a register type giving the width of the register (`reg32` in this
case), a name, and a list of fields.

The `cr` register has four boolean flags, an integer
field `br`, and a field `parity` with four possible values
(`NoParity`, `EvenParity`, and `OddParity`). Each field is defined by
a bit or bit range, a name, some optional modifiers (e.g. `ro` in the
case of `rxne`), and an optional list of values.

This register definition will produce a variety of types, along with
associated accessor methods for convenient, safe manipulation of the
described registers. In the process of generating these, `ioregs!`
will perform a variety of sanity checks (e.g. ensuring that registers
and bitfields are free of overlap).

#### Documenting register definitions

It is highly recommended that register definitions include
docstrings. Registers, fields, and `enum` values can all be annotated
with docstrings with the typical Rust doc comment syntax. Both outer
(`/// comment`) and inner (`//! comment`) comments are accepted. Inner
comments apply to the item to which the current block belongs whereas
outer comments apply to the item that follows. In addition,
trailing comments are supported with the `//=` syntax. These apply
to the preceding item, allowing definitions and associated comments
to inhabit the same line. Multiple successive comments of the same
type will be concatenated together into a single doc comment.

For instance, we might document the above example as follows,

```
ioregs!(UART = {
    /// Control register
    /// Here is some discussion of the function of the `cr` register.
    0x0    => reg32 cr {
        0      => rxe,         //= Receive enable
        1      => txe,         //= Transmit enable
        2      => rxie,        //= Receive interrupt enable
        3      => txie,        //= Transmit interrupt enable
        4..12  => br,          //= Baud rate
        14..16 => parity {     //! Parity selection
          0x0  => NoParity,    //= No parity
          0x2  => EvenParity,  //= Even parity
          0x3  => OddParity,   //= Odd parity
        }
    }

    ...
})
```

#### Nesting register blocks

In addition to primitive register types (e.g. `reg32`), one can also
nest groups of logically related registers. For instance, in the case
of a DMA peripheral it is common that the same block of registers will
be replicated, one for each DMA channel. This can be accomplished with
`ioregs!` as follows,

```
ioregs!(DMA = {
    0x0    => reg32 cr { ... }
    0x10   => group channel[4] {
        0x0    => reg32 cr { ... }
        0x4    => reg32 sr { ... }
    }
    0x30   => reg32 sr { ... }
})
```

This will produce the following layout in memory,

```notrust
address        register
────────       ──────────────
0x0            cr
0x10           channel[0].cr
0x14           channel[0].sr
0x18           channel[1].cr
0x1c           channel[1].sr
0x20           channel[2].cr
0x24           channel[2].sr
0x28           channel[3].cr
0x2c           channel[3].sr
0x30           sr
```

### What is produced

The `ioregs!` extension produces a variety of types and methods for
each register and field. Let's start by examining the top-level types
representing the structure of the interface.

```
pub enum UART_cr_parity {
    NoParity = 0, EvenParity = 2, OddParity = 3,
}

pub struct UART_cr { ... }
pub struct UART_sr { ... }
pub struct UART_dr { ... }

pub struct UART {
    pub cr: UART_cr,
    pub sr: UART_sr,
    pub dr: UART_dr,
}
```

The `UART` struct is the the "entry-point" into the interface and is
ultimately what will be instantiated to represent the peripheral's
register window, typically as a `static extern` item,

```
extern { pub static UART: UART; }
```

The register structs (`UART_cr`, `UART_sr`, and `UART_dr`)
have no user visible members but expose a variety of methods. Let's
look at `cr` in particular,

```
impl UART_cr {
    pub fn get(&self) -> UART_cr_Get { ... }

    pub fn set_rxe(&self, new_value: bool) -> UART_cr_Update { ... }
    pub fn rxe(&self) -> bool { ... }

    // similar methods for `txe`, `rxie`, `txie`

    pub fn set_br(&self, new_value: u32) -> UART_cr_Update { ... }
    pub fn br(&self) -> u32 { ... }

    pub fn set_parity(&self, new_value: UART_cr_parity) -> UART_cr_Update { ... }
    pub fn parity(&self) -> UART_cr_parity { ... }
}
```

Here we see each field has a corresponding "get" function (e.g. `rxe`,
`br`, and `parity`) as well as a "set" function. Note that the set
function returns a `UART_cr_Update` object. This object mirrors the
setter methods of `UART_cr`, collecting multiple field updates within
a register, performing them on destruction with the `Drop` trait,

```
pub struct UART_cr_Update { ... }
impl Drop for UART_cr_Update { ... }

impl UART_cr_Update {
    pub fn set_rxe<'a>(&'a mut self, new_value: bool) -> &'a mut UART_cr_Update { ... }
    pub fn set_txe<'a>(&'a mut self, new_value: bool) -> &'a mut UART_cr_Update { ... }
    ...
}
```

As the set methods return references to `self` they can be easily
chained together. For instance, we can update the `rxe` and `txe`
fields of the `cr` register atomically,

```
UART.cr.set_rxe(true).set_txe(false);
```

In addition to get and set methods, `UART_cr` also implements a `get`
method which returns a `UART_cr_Get` object mirroring the get methods
of `UART_cr`. This object captures the state of the register allowing
field values to be later atomically queried,

```
let cr: UART_cr_Get = UART.cr.get();
format!("txe={}, rxe={}, br={}", cr.txe(), cr.rxe(), cr.br())
```

In the case of read-only (resp. write-only) fields the set (resp. get)
method is omitted. In the case of `set_to_clear` fields a `clear`
method is instead produced in place of `set`. For instance, in the
case of the `sr` register's `fe` flag,

```
pub fn fe(self: &UART_sr_Getter) -> bool { ... }
pub fn clear_fe(self: &UART_sr_Update) -> UART_sr_Update { ... }
```

### Informal grammar

In the below discussion `THING, ...` will denote a list of one or more
`THING`s. The `THING`s must be comma separated except when ending
with a brace-enclosed block. Optional elements are enclosed in `⟦...⟧`
brackets.

The `ioregs!` macro expects a definition of the form,

```
ioregs!(IDENT = { REG, ... })
```

Where a `REG` is either a register group,

```notrust
OFFSET => group IDENT⟦[COUNT]⟧ { REG, ... }
```

or a primitive register,

```notrust
OFFSET => TYPE IDENT⟦[COUNT]⟧ { FIELD, ... }
```

`COUNT` is an integer count and a register `TYPE` is one of `reg8` (a
one byte wide register), `reg16` (two bytes wide), or `reg32` (four
bytes wide).

A field is given by

```notrust
BITS => IDENT⟦[COUNT]⟧ ⟦: MODIFIER⟧ ⟦{ VALUE, ... }⟧
```

where `BITS` is either an inclusive range of integers (`N..M`) or a
single integer (shorthand for `N..N`). If a list of values is given
the field is of an enumerated type. Otherwise single bit fields are
of type `bool` and wider fields unsigned integers (in particular, of
the same width as the containing register).

A `MODIFIER` is one of `rw` (read/write), `ro` (read-only), `wo`
(write-only), or `set_to_clear` (a flag which can be cleared by
setting to one).

A `VALUE` is given by,

```notrust
N => NAME
```

*/

#![feature(quote, plugin_registrar)]
#![crate_name="ioreg"]
#![crate_type="dylib"]
#![allow(unstable)]

extern crate rustc;
extern crate syntax;
extern crate serialize;

use rustc::plugin::Registry;
use syntax::ast;
use syntax::ptr::P;
use syntax::codemap::Span;
use syntax::ext::base::{ExtCtxt, MacResult};
use syntax::util::small_vector::SmallVector;

pub mod node;
pub mod parser;
pub mod builder;

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
  reg.register_macro("ioregs", macro_ioregs);
}

pub fn macro_ioregs(cx: &mut ExtCtxt, _: Span, tts: &[ast::TokenTree])
                    -> Box<MacResult+'static> {
  match parser::Parser::new(cx, tts).parse_ioregs() {
    Some(group) => {
      let mut builder = builder::Builder::new();
      let items = builder.emit_items(cx, group);
      MacItems::new(items)
    },
    None => {
      panic!();
    }
  }
}

pub struct MacItems {
  items: Vec<P<ast::Item>>
}

impl MacItems {
  pub fn new(items: Vec<P<ast::Item>>) -> Box<MacResult+'static> {
    Box::new(MacItems { items: items })
  }
}

impl MacResult for MacItems {
  fn make_items(self: Box<MacItems>) -> Option<SmallVector<P<ast::Item>>> {
    Some(SmallVector::many(self.items.clone()))
  }
}
<|endoftext|>


<commit_before>// compile-flags: -Zmiri-tag-raw-pointers
// Gather all references from a mutable iterator and make sure Miri notices if
// using them is dangerous.
fn test_all_refs<'a, T: 'a>(dummy: &mut T, iter: impl Iterator<Item = &'a mut T>) {
    // Gather all those references.
    let mut refs: Vec<&mut T> = iter.collect();
    // Use them all. Twice, to be sure we got all interleavings.
    for r in refs.iter_mut() {
        std::mem::swap(dummy, r);
    }
    for r in refs {
        std::mem::swap(dummy, r);
    }
}

fn make_vec() -> Vec<u8> {
    let mut v = Vec::with_capacity(4);
    v.push(1);
    v.push(2);
    v
}

fn make_vec_macro() -> Vec<u8> {
    vec![1, 2]
}

fn make_vec_macro_repeat() -> Vec<u8> {
    vec![42; 5]
}

fn make_vec_macro_repeat_zeroed() -> Vec<u8> {
    vec![0; 7]
}

fn vec_into_iter() -> u8 {
    vec![1, 2, 3, 4]
        .into_iter()
        .map(|x| x * x)
        .fold(0, |x, y| x + y)
}

fn vec_into_iter_rev() -> u8 {
    vec![1, 2, 3, 4]
        .into_iter()
        .map(|x| x * x)
        .fold(0, |x, y| x + y)
}

fn vec_into_iter_zst() -> usize {
    vec![[0u64; 0], [0u64; 0]]
        .into_iter()
        .rev()
        .map(|x| x.len())
        .sum()
}

fn vec_into_iter_rev_zst() -> usize {
    vec![[0u64; 0], [0u64; 0]]
        .into_iter()
        .rev()
        .map(|x| x.len())
        .sum()
}

fn vec_iter_and_mut() {
    let mut v = vec![1,2,3,4];
    for i in v.iter_mut() {
        *i += 1;
    }
    assert_eq!(v.iter().sum::<i32>(), 2+3+4+5);

    test_all_refs(&mut 13, v.iter_mut());
}

fn vec_iter_and_mut_rev() {
    let mut v = vec![1,2,3,4];
    for i in v.iter_mut().rev() {
        *i += 1;
    }
    assert_eq!(v.iter().sum::<i32>(), 2+3+4+5);
}

fn vec_reallocate() -> Vec<u8> {
    let mut v = vec![1, 2];
    v.push(3);
    v.push(4);
    v.push(5);
    v
}

fn vec_push_ptr_stable() {
    let mut v = Vec::with_capacity(10);
    v.push(0);
    let v0 = unsafe { &mut *(&mut v[0] as *mut _) }; // laundering the lifetime -- we take care that `v` does not reallocate, so that's okay.
    v.push(1);
    let _val = *v0;
}

fn vec_extend_ptr_stable() {
    let mut v = Vec::with_capacity(10);
    v.push(0);
    let v0 = unsafe { &mut *(&mut v[0] as *mut _) }; // laundering the lifetime -- we take care that `v` does not reallocate, so that's okay.
    // `slice::Iter` (with `T: Copy`) specialization
    v.extend(&[1]);
    let _val = *v0;
    // `vec::IntoIter` specialization
    v.extend(vec![2]);
    let _val = *v0;
    // `TrustedLen` specialization
    v.extend(std::iter::once(3));
    let _val = *v0;
    // base case
    v.extend(std::iter::once(3).filter(|_| true));
    let _val = *v0;
}

fn vec_truncate_ptr_stable() {
    let mut v = vec![0; 10];
    let v0 = unsafe { &mut *(&mut v[0] as *mut _) }; // laundering the lifetime -- we take care that `v` does not reallocate, so that's okay.
    v.truncate(5);
    let _val = *v0;
}

fn push_str_ptr_stable() {
    let mut buf = String::with_capacity(11);
    buf.push_str("hello");
    let hello: &str = unsafe { &*(buf.as_str() as *const _) }; // laundering the lifetime -- we take care that `buf` does not reallocate, so that's okay.
    buf.push_str(" world");
    assert_eq!(format!("{}", hello), "hello");
}

fn sort() {
    let mut v = vec![1; 20];
    v.push(0);
    v.sort();
}

fn swap() {
    let mut v = vec![1, 2, 3, 4];
    v.swap(2, 2);
}

fn swap_remove() {
    let mut a = 0;
    let mut b = 1;
    let mut vec = vec![&mut a, &mut b];

    vec.swap_remove(1);
}

fn main() {
    assert_eq!(vec_reallocate().len(), 5);

    assert_eq!(vec_into_iter(), 30);
    assert_eq!(vec_into_iter_rev(), 30);
    vec_iter_and_mut();
    assert_eq!(vec_into_iter_zst(), 0);
    assert_eq!(vec_into_iter_rev_zst(), 0);
    vec_iter_and_mut_rev();

    assert_eq!(make_vec().capacity(), 4);
    assert_eq!(make_vec_macro(), [1, 2]);
    assert_eq!(make_vec_macro_repeat(), [42; 5]);
    assert_eq!(make_vec_macro_repeat_zeroed(), [0; 7]);

    // Test interesting empty slice comparison
    // (one is a real pointer, one an integer pointer).
    assert_eq!((200..-5).step_by(1).collect::<Vec<isize>>(), []);

    // liballoc has a more extensive test of this, but let's at least do a smoke test here.
    vec_push_ptr_stable();
    vec_extend_ptr_stable();
    vec_truncate_ptr_stable();
    push_str_ptr_stable();

    sort();
    swap();
    swap_remove();
}
<commit_msg>vec test: check number validity<commit_after>// compile-flags: -Zmiri-tag-raw-pointers -Zmiri-check-number-validity
// Gather all references from a mutable iterator and make sure Miri notices if
// using them is dangerous.
fn test_all_refs<'a, T: 'a>(dummy: &mut T, iter: impl Iterator<Item = &'a mut T>) {
    // Gather all those references.
    let mut refs: Vec<&mut T> = iter.collect();
    // Use them all. Twice, to be sure we got all interleavings.
    for r in refs.iter_mut() {
        std::mem::swap(dummy, r);
    }
    for r in refs {
        std::mem::swap(dummy, r);
    }
}

fn make_vec() -> Vec<u8> {
    let mut v = Vec::with_capacity(4);
    v.push(1);
    v.push(2);
    v
}

fn make_vec_macro() -> Vec<u8> {
    vec![1, 2]
}

fn make_vec_macro_repeat() -> Vec<u8> {
    vec![42; 5]
}

fn make_vec_macro_repeat_zeroed() -> Vec<u8> {
    vec![0; 7]
}

fn vec_into_iter() -> u8 {
    vec![1, 2, 3, 4]
        .into_iter()
        .map(|x| x * x)
        .fold(0, |x, y| x + y)
}

fn vec_into_iter_rev() -> u8 {
    vec![1, 2, 3, 4]
        .into_iter()
        .map(|x| x * x)
        .fold(0, |x, y| x + y)
}

fn vec_into_iter_zst() -> usize {
    vec![[0u64; 0], [0u64; 0]]
        .into_iter()
        .rev()
        .map(|x| x.len())
        .sum()
}

fn vec_into_iter_rev_zst() -> usize {
    vec![[0u64; 0], [0u64; 0]]
        .into_iter()
        .rev()
        .map(|x| x.len())
        .sum()
}

fn vec_iter_and_mut() {
    let mut v = vec![1,2,3,4];
    for i in v.iter_mut() {
        *i += 1;
    }
    assert_eq!(v.iter().sum::<i32>(), 2+3+4+5);

    test_all_refs(&mut 13, v.iter_mut());
}

fn vec_iter_and_mut_rev() {
    let mut v = vec![1,2,3,4];
    for i in v.iter_mut().rev() {
        *i += 1;
    }
    assert_eq!(v.iter().sum::<i32>(), 2+3+4+5);
}

fn vec_reallocate() -> Vec<u8> {
    let mut v = vec![1, 2];
    v.push(3);
    v.push(4);
    v.push(5);
    v
}

fn vec_push_ptr_stable() {
    let mut v = Vec::with_capacity(10);
    v.push(0);
    let v0 = unsafe { &mut *(&mut v[0] as *mut _) }; // laundering the lifetime -- we take care that `v` does not reallocate, so that's okay.
    v.push(1);
    let _val = *v0;
}

fn vec_extend_ptr_stable() {
    let mut v = Vec::with_capacity(10);
    v.push(0);
    let v0 = unsafe { &mut *(&mut v[0] as *mut _) }; // laundering the lifetime -- we take care that `v` does not reallocate, so that's okay.
    // `slice::Iter` (with `T: Copy`) specialization
    v.extend(&[1]);
    let _val = *v0;
    // `vec::IntoIter` specialization
    v.extend(vec![2]);
    let _val = *v0;
    // `TrustedLen` specialization
    v.extend(std::iter::once(3));
    let _val = *v0;
    // base case
    v.extend(std::iter::once(3).filter(|_| true));
    let _val = *v0;
}

fn vec_truncate_ptr_stable() {
    let mut v = vec![0; 10];
    let v0 = unsafe { &mut *(&mut v[0] as *mut _) }; // laundering the lifetime -- we take care that `v` does not reallocate, so that's okay.
    v.truncate(5);
    let _val = *v0;
}

fn push_str_ptr_stable() {
    let mut buf = String::with_capacity(11);
    buf.push_str("hello");
    let hello: &str = unsafe { &*(buf.as_str() as *const _) }; // laundering the lifetime -- we take care that `buf` does not reallocate, so that's okay.
    buf.push_str(" world");
    assert_eq!(format!("{}", hello), "hello");
}

fn sort() {
    let mut v = vec![1; 20];
    v.push(0);
    v.sort();
}

fn swap() {
    let mut v = vec![1, 2, 3, 4];
    v.swap(2, 2);
}

fn swap_remove() {
    let mut a = 0;
    let mut b = 1;
    let mut vec = vec![&mut a, &mut b];

    vec.swap_remove(1);
}

fn main() {
    assert_eq!(vec_reallocate().len(), 5);

    assert_eq!(vec_into_iter(), 30);
    assert_eq!(vec_into_iter_rev(), 30);
    vec_iter_and_mut();
    assert_eq!(vec_into_iter_zst(), 0);
    assert_eq!(vec_into_iter_rev_zst(), 0);
    vec_iter_and_mut_rev();

    assert_eq!(make_vec().capacity(), 4);
    assert_eq!(make_vec_macro(), [1, 2]);
    assert_eq!(make_vec_macro_repeat(), [42; 5]);
    assert_eq!(make_vec_macro_repeat_zeroed(), [0; 7]);

    // Test interesting empty slice comparison
    // (one is a real pointer, one an integer pointer).
    assert_eq!((200..-5).step_by(1).collect::<Vec<isize>>(), []);

    // liballoc has a more extensive test of this, but let's at least do a smoke test here.
    vec_push_ptr_stable();
    vec_extend_ptr_stable();
    vec_truncate_ptr_stable();
    push_str_ptr_stable();

    sort();
    swap();
    swap_remove();
}
<|endoftext|>


<commit_before>#![cfg(feature = "stable_graph")]

extern crate petgraph;
extern crate itertools;
#[macro_use] extern crate defmac;

use petgraph::prelude::*;
use petgraph::stable_graph::node_index as n;
use petgraph::EdgeType;
use petgraph::algo::{kosaraju_scc, tarjan_scc};
use petgraph::visit::{
    NodeIndexable,
    IntoEdgeReferences,
};

use itertools::assert_equal;

#[test]
fn node_indices() {
    let mut g = StableGraph::<_, ()>::new();
    let a = g.add_node(0);
    let b = g.add_node(1);
    let c = g.add_node(2);
    g.remove_node(b);
    let mut iter = g.node_indices();
    assert_eq!(iter.next(), Some(a));
    assert_eq!(iter.next(), Some(c));
    assert_eq!(iter.next(), None);
}

fn assert_sccs_eq(mut res: Vec<Vec<NodeIndex>>, normalized: Vec<Vec<NodeIndex>>) {
    // normalize the result and compare with the answer.
    for scc in &mut res {
        scc.sort();
    }
    // sort by minimum element
    res.sort_by(|v, w| v[0].cmp(&w[0]));
    assert_eq!(res, normalized);
}

#[test]
fn test_scc() {
    let mut gr: StableGraph<(), ()> = StableGraph::from_edges(&[
        (6, 0),
        (0, 3),
        (3, 6),
        (8, 6), (8, 2),
        (2, 5), (5, 8), (7, 5),
        (1, 7),
        (7, 4),
        (4, 1)]);
    // make an identical replacement of n(4) and leave a hole
    let x = gr.add_node(());
    gr.add_edge(n(7), x, ());
    gr.add_edge(x, n(1), ());
    gr.remove_node(n(4));
    println!("{:?}", gr);

    assert_sccs_eq(kosaraju_scc(&gr), vec![
        vec![n(0), n(3), n(6)],
        vec![n(1), n(7),   x ],
        vec![n(2), n(5), n(8)],
    ]);
}

#[test]
fn test_tarjan_scc() {
    let mut gr: StableGraph<(), ()> = StableGraph::from_edges(&[
        (6, 0),
        (0, 3),
        (3, 6),
        (8, 6), (8, 2),
        (2, 5), (5, 8), (7, 5),
        (1, 7),
        (7, 4),
        (4, 1)]);
    // make an identical replacement of n(4) and leave a hole
    let x = gr.add_node(());
    gr.add_edge(n(7), x, ());
    gr.add_edge(x, n(1), ());
    gr.remove_node(n(4));

    assert_sccs_eq(tarjan_scc(&gr), vec![
        vec![n(0), n(3), n(6)],
        vec![n(1), n(7),   x ],
        vec![n(2), n(5), n(8)],
    ]);
}

fn make_graph<Ty>() -> StableGraph<(), i32, Ty>
    where Ty: EdgeType,
{
    let mut gr = StableGraph::default();
    let mut c = 0..;
    let mut e = || -> i32 { c.next().unwrap() };
    gr.extend_with_edges(&[
        (6, 0, e()),
        (0, 3, e()),
        (3, 6, e()),
        (8, 6, e()),
        (8, 2, e()),
        (2, 5, e()),
        (5, 8, e()),
        (7, 5, e()),
        (1, 7, e()),
        (7, 4, e()),
        (8, 6, e()), // parallel edge
        (4, 1, e())]);
    // make an identical replacement of n(4) and leave a hole
    let x = gr.add_node(());
    gr.add_edge(n(7), x, e());
    gr.add_edge(x, n(1), e());
    gr.add_edge(x, x, e()); // make two self loops
    let rm_self_loop = gr.add_edge(x, x, e());
    gr.add_edge(x, x, e());
    gr.remove_node(n(4));
    gr.remove_node(n(6));
    gr.remove_edge(rm_self_loop);
    gr
}

defmac!(edges ref gr, x => gr.edges(x).map(|r| (r.target(), *r.weight())));

#[test]
fn test_edges_directed() {
    let gr = make_graph::<Directed>();
    let x = n(9);
    assert_equal(edges!(gr, x), vec![(x, 16), (x, 14), (n(1), 13)]);
    assert_equal(edges!(gr, n(0)), vec![(n(3), 1)]);
    assert_equal(edges!(gr, n(4)), vec![]);
}

#[test]
fn test_edge_references() {
    let gr = make_graph::<Directed>();
    assert_eq!(gr.edge_count(), gr.edge_references().count());
}

#[test]
fn test_edges_undirected() {
    let gr = make_graph::<Undirected>();
    let x = n(9);
    assert_equal(edges!(gr, x), vec![(x, 16), (x, 14), (n(1), 13), (n(7), 12)]);
    assert_equal(edges!(gr, n(0)), vec![(n(3), 1)]);
    assert_equal(edges!(gr, n(4)), vec![]);
}

#[test]
fn test_edge_iterators_directed() {
    let gr = make_graph::<Directed>();
    for i in gr.node_indices() {
        itertools::assert_equal(
            gr.edges_directed(i, Outgoing),
            gr.edges(i));
    }
    let mut incoming = vec![Vec::new(); gr.node_bound()];

    for i in gr.node_indices() {
        for j in gr.neighbors(i) {
            incoming[j.index()].push(i);
        }
    }

    println!("{:#?}", gr);
    for i in gr.node_indices() {
        itertools::assert_equal(
            gr.edges_directed(i, Incoming).map(|e| e.source()),
            incoming[i.index()].iter().rev().cloned());
    }
}

#[test]
fn test_edge_iterators_undir() {
    let gr = make_graph::<Undirected>();
    for i in gr.node_indices() {
        itertools::assert_equal(
            gr.edges_directed(i, Outgoing),
            gr.edges(i));
    }
    for i in gr.node_indices() {
        itertools::assert_equal(
            gr.edges_directed(i, Incoming),
            gr.edges(i));
    }
}
<commit_msg>BUG: Test for StableGraph::node_bound()<commit_after>#![cfg(feature = "stable_graph")]

extern crate petgraph;
extern crate itertools;
#[macro_use] extern crate defmac;

use petgraph::prelude::*;
use petgraph::stable_graph::node_index as n;
use petgraph::EdgeType;
use petgraph::algo::{kosaraju_scc, tarjan_scc};
use petgraph::visit::{
    NodeIndexable,
    IntoEdgeReferences,
};

use itertools::assert_equal;

#[test]
fn node_indices() {
    let mut g = StableGraph::<_, ()>::new();
    let a = g.add_node(0);
    let b = g.add_node(1);
    let c = g.add_node(2);
    g.remove_node(b);
    let mut iter = g.node_indices();
    assert_eq!(iter.next(), Some(a));
    assert_eq!(iter.next(), Some(c));
    assert_eq!(iter.next(), None);
}

#[test]
fn node_bound() {
    let mut g = StableGraph::<_, ()>::new();
    assert_eq!(g.node_bound(), g.node_count());
    for i in 0..10 {
        g.add_node(i);
        assert_eq!(g.node_bound(), g.node_count());
    }
    let full_count = g.node_count();
    g.remove_node(n(0));
    g.remove_node(n(2));
    assert_eq!(g.node_bound(), full_count);
    g.clear();
    assert_eq!(g.node_bound(), 0);
}

fn assert_sccs_eq(mut res: Vec<Vec<NodeIndex>>, normalized: Vec<Vec<NodeIndex>>) {
    // normalize the result and compare with the answer.
    for scc in &mut res {
        scc.sort();
    }
    // sort by minimum element
    res.sort_by(|v, w| v[0].cmp(&w[0]));
    assert_eq!(res, normalized);
}

#[test]
fn test_scc() {
    let mut gr: StableGraph<(), ()> = StableGraph::from_edges(&[
        (6, 0),
        (0, 3),
        (3, 6),
        (8, 6), (8, 2),
        (2, 5), (5, 8), (7, 5),
        (1, 7),
        (7, 4),
        (4, 1)]);
    // make an identical replacement of n(4) and leave a hole
    let x = gr.add_node(());
    gr.add_edge(n(7), x, ());
    gr.add_edge(x, n(1), ());
    gr.remove_node(n(4));
    println!("{:?}", gr);

    assert_sccs_eq(kosaraju_scc(&gr), vec![
        vec![n(0), n(3), n(6)],
        vec![n(1), n(7),   x ],
        vec![n(2), n(5), n(8)],
    ]);
}

#[test]
fn test_tarjan_scc() {
    let mut gr: StableGraph<(), ()> = StableGraph::from_edges(&[
        (6, 0),
        (0, 3),
        (3, 6),
        (8, 6), (8, 2),
        (2, 5), (5, 8), (7, 5),
        (1, 7),
        (7, 4),
        (4, 1)]);
    // make an identical replacement of n(4) and leave a hole
    let x = gr.add_node(());
    gr.add_edge(n(7), x, ());
    gr.add_edge(x, n(1), ());
    gr.remove_node(n(4));

    assert_sccs_eq(tarjan_scc(&gr), vec![
        vec![n(0), n(3), n(6)],
        vec![n(1), n(7),   x ],
        vec![n(2), n(5), n(8)],
    ]);
}

fn make_graph<Ty>() -> StableGraph<(), i32, Ty>
    where Ty: EdgeType,
{
    let mut gr = StableGraph::default();
    let mut c = 0..;
    let mut e = || -> i32 { c.next().unwrap() };
    gr.extend_with_edges(&[
        (6, 0, e()),
        (0, 3, e()),
        (3, 6, e()),
        (8, 6, e()),
        (8, 2, e()),
        (2, 5, e()),
        (5, 8, e()),
        (7, 5, e()),
        (1, 7, e()),
        (7, 4, e()),
        (8, 6, e()), // parallel edge
        (4, 1, e())]);
    // make an identical replacement of n(4) and leave a hole
    let x = gr.add_node(());
    gr.add_edge(n(7), x, e());
    gr.add_edge(x, n(1), e());
    gr.add_edge(x, x, e()); // make two self loops
    let rm_self_loop = gr.add_edge(x, x, e());
    gr.add_edge(x, x, e());
    gr.remove_node(n(4));
    gr.remove_node(n(6));
    gr.remove_edge(rm_self_loop);
    gr
}

defmac!(edges ref gr, x => gr.edges(x).map(|r| (r.target(), *r.weight())));

#[test]
fn test_edges_directed() {
    let gr = make_graph::<Directed>();
    let x = n(9);
    assert_equal(edges!(gr, x), vec![(x, 16), (x, 14), (n(1), 13)]);
    assert_equal(edges!(gr, n(0)), vec![(n(3), 1)]);
    assert_equal(edges!(gr, n(4)), vec![]);
}

#[test]
fn test_edge_references() {
    let gr = make_graph::<Directed>();
    assert_eq!(gr.edge_count(), gr.edge_references().count());
}

#[test]
fn test_edges_undirected() {
    let gr = make_graph::<Undirected>();
    let x = n(9);
    assert_equal(edges!(gr, x), vec![(x, 16), (x, 14), (n(1), 13), (n(7), 12)]);
    assert_equal(edges!(gr, n(0)), vec![(n(3), 1)]);
    assert_equal(edges!(gr, n(4)), vec![]);
}

#[test]
fn test_edge_iterators_directed() {
    let gr = make_graph::<Directed>();
    for i in gr.node_indices() {
        itertools::assert_equal(
            gr.edges_directed(i, Outgoing),
            gr.edges(i));
    }
    let mut incoming = vec![Vec::new(); gr.node_bound()];

    for i in gr.node_indices() {
        for j in gr.neighbors(i) {
            incoming[j.index()].push(i);
        }
    }

    println!("{:#?}", gr);
    for i in gr.node_indices() {
        itertools::assert_equal(
            gr.edges_directed(i, Incoming).map(|e| e.source()),
            incoming[i.index()].iter().rev().cloned());
    }
}

#[test]
fn test_edge_iterators_undir() {
    let gr = make_graph::<Undirected>();
    for i in gr.node_indices() {
        itertools::assert_equal(
            gr.edges_directed(i, Outgoing),
            gr.edges(i));
    }
    for i in gr.node_indices() {
        itertools::assert_equal(
            gr.edges_directed(i, Incoming),
            gr.edges(i));
    }
}
<|endoftext|>


<commit_before>/*!
A macro for declaring lazily evaluated statics.

Using this macro, it is possible to have `static`s that require code to be
executed at runtime in order to be initialized.
This includes anything requiring heap allocations, like vectors or hash maps,
as well as anything that requires function calls to be computed.

# Syntax

```ignore
lazy_static! {
    [pub] static ref NAME_1: TYPE_1 = EXPR_1;
    [pub] static ref NAME_2: TYPE_2 = EXPR_2;
    ...
    [pub] static ref NAME_N: TYPE_N = EXPR_N;
}
```

# Semantic

For a given `static ref NAME: TYPE = EXPR;`, the macro generates a
unique type that implements `Deref<TYPE>` and stores it in a static with name `NAME`.

On first deref, `EXPR` gets evaluated and stored internally, such that all further derefs
can return a reference to the same object.

Like regular `static mut`s, this macro only works for types that fulfill the `Sync`
trait.

# Example

Using the macro:

```rust
#![feature(phase)]

#[phase(plugin)]
extern crate lazy_static;

use std::collections::HashMap;

lazy_static! {
    static ref HASHMAP: HashMap<uint, &'static str> = {
        let mut m = HashMap::new();
        m.insert(0u, "foo");
        m.insert(1u, "bar");
        m.insert(2u, "baz");
        m
    };
    static ref COUNT: uint = HASHMAP.len();
    static ref NUMBER: uint = times_two(21);
}

fn times_two(n: uint) -> uint { n * 2 }

fn main() {
    println!("The map has {} entries.", *COUNT);
    println!("The entry for `0` is \"{}\".", HASHMAP.get(&0).unwrap());
    println!("A expensive calculation on a static results in: {}.", *NUMBER);
}
```

# Implementation details

The `Deref` implementation uses a hidden `static mut` that is guarded by a atomic check
using the `sync::Once` abstraction. All lazily evaluated values are currently
put in a heap allocated box, due to the Rust language currently not providing any way to
define uninitialized `static mut` values.

*/

#![crate_type = "dylib"]
#![license = "MIT"]

#![feature(macro_rules)]

#[macro_export]
macro_rules! lazy_static {
    (static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
        lazy_static!(PRIV static ref $N : $T = $e; $($t)*)
    };
    (pub static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
        lazy_static!(PUB static ref $N : $T = $e; $($t)*)
    };
    ($VIS:ident static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
        lazy_static!(MAKE TY $VIS $N)
        impl Deref<$T> for $N {
            fn deref<'a>(&'a self) -> &'a $T {
                use std::sync::{Once, ONCE_INIT};
                use std::mem::transmute;

                #[inline(always)]
                fn require_sync<T: Sync>(_: &T) { }

                unsafe {
                    static mut s: *const $T = 0 as *const $T;
                    static mut ONCE: Once = ONCE_INIT;
                    ONCE.doit(|| {
                        s = transmute::<Box<$T>, *const $T>(box() ($e));
                    });
                    let static_ref = &*s;
                    require_sync(static_ref);
                    static_ref
                }
            }
        }
        lazy_static!($($t)*)
    };
    (MAKE TY PUB $N:ident) => {
        #[allow(non_camel_case_types)]
        #[allow(dead_code)]
        pub struct $N {__private_field: ()}
        pub static $N: $N = $N {__private_field: ()};
    };
    (MAKE TY PRIV $N:ident) => {
        #[allow(non_camel_case_types)]
        #[allow(dead_code)]
        struct $N {__private_field: ()}
        static $N: $N = $N {__private_field: ()};
    };
    () => ()
}
<commit_msg>Add missing semicolons for macro expansions.<commit_after>/*!
A macro for declaring lazily evaluated statics.

Using this macro, it is possible to have `static`s that require code to be
executed at runtime in order to be initialized.
This includes anything requiring heap allocations, like vectors or hash maps,
as well as anything that requires function calls to be computed.

# Syntax

```ignore
lazy_static! {
    [pub] static ref NAME_1: TYPE_1 = EXPR_1;
    [pub] static ref NAME_2: TYPE_2 = EXPR_2;
    ...
    [pub] static ref NAME_N: TYPE_N = EXPR_N;
}
```

# Semantic

For a given `static ref NAME: TYPE = EXPR;`, the macro generates a
unique type that implements `Deref<TYPE>` and stores it in a static with name `NAME`.

On first deref, `EXPR` gets evaluated and stored internally, such that all further derefs
can return a reference to the same object.

Like regular `static mut`s, this macro only works for types that fulfill the `Sync`
trait.

# Example

Using the macro:

```rust
#![feature(phase)]

#[phase(plugin)]
extern crate lazy_static;

use std::collections::HashMap;

lazy_static! {
    static ref HASHMAP: HashMap<uint, &'static str> = {
        let mut m = HashMap::new();
        m.insert(0u, "foo");
        m.insert(1u, "bar");
        m.insert(2u, "baz");
        m
    };
    static ref COUNT: uint = HASHMAP.len();
    static ref NUMBER: uint = times_two(21);
}

fn times_two(n: uint) -> uint { n * 2 }

fn main() {
    println!("The map has {} entries.", *COUNT);
    println!("The entry for `0` is \"{}\".", HASHMAP.get(&0).unwrap());
    println!("A expensive calculation on a static results in: {}.", *NUMBER);
}
```

# Implementation details

The `Deref` implementation uses a hidden `static mut` that is guarded by a atomic check
using the `sync::Once` abstraction. All lazily evaluated values are currently
put in a heap allocated box, due to the Rust language currently not providing any way to
define uninitialized `static mut` values.

*/

#![crate_type = "dylib"]
#![license = "MIT"]

#![feature(macro_rules)]

#[macro_export]
macro_rules! lazy_static {
    (static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
        lazy_static!(PRIV static ref $N : $T = $e; $($t)*);
    };
    (pub static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
        lazy_static!(PUB static ref $N : $T = $e; $($t)*);
    };
    ($VIS:ident static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
        lazy_static!(MAKE TY $VIS $N);
        impl Deref<$T> for $N {
            fn deref<'a>(&'a self) -> &'a $T {
                use std::sync::{Once, ONCE_INIT};
                use std::mem::transmute;

                #[inline(always)]
                fn require_sync<T: Sync>(_: &T) { }

                unsafe {
                    static mut s: *const $T = 0 as *const $T;
                    static mut ONCE: Once = ONCE_INIT;
                    ONCE.doit(|| {
                        s = transmute::<Box<$T>, *const $T>(box() ($e));
                    });
                    let static_ref = &*s;
                    require_sync(static_ref);
                    static_ref
                }
            }
        }
        lazy_static!($($t)*);
    };
    (MAKE TY PUB $N:ident) => {
        #[allow(non_camel_case_types)]
        #[allow(dead_code)]
        pub struct $N {__private_field: ()}
        pub static $N: $N = $N {__private_field: ()};
    };
    (MAKE TY PRIV $N:ident) => {
        #[allow(non_camel_case_types)]
        #[allow(dead_code)]
        struct $N {__private_field: ()}
        static $N: $N = $N {__private_field: ()};
    };
    () => ()
}
<|endoftext|>


<commit_before>extern crate chrono;

use self::chrono::*;
use constant::*;
use std::collections::BTreeSet;
use std::fs;
use std::fs::File;
use std::io::{Read, Write};
use std::path::{Path, PathBuf};
use lib::cmd_helper::*;
use lib::fs_helper::*;

pub fn initialize() {
    println!("Initialize ...");

    let dir_name    = WORKING_DIR_NAME;
    let path_to_dir = Path::new(dir_name);
    if working_dir_exists() {
        println!("  OK: \"{}\" directory has already exist.", dir_name);
    } else {
        match fs::create_dir(path_to_dir) {
            Ok(_)    => println!("  OK: Created \"{}\" directory.", dir_name),
            Err(why) => panic!("{:?}", why),
        }
    }

    let path_to_config = path_to_dir.clone().join(CONFIG_FILE_NAME);
    create_setting_file(path_to_config, DEFAULT_CONFIG);

    let path_to_ignore = path_to_dir.clone().join(IGNORE_FILE_NAME);
    let ignore_contents = walk_dir(".").iter()
        .fold(String::new(), |c, f| c + &f + "\n");
    create_setting_file(path_to_ignore, ignore_contents);
}

fn create_setting_file<S: AsRef<str>>(path_to_file: PathBuf, contents: S) {
    let file_name = path_to_file.file_name().and_then(|f| f.to_str()).unwrap();
    if path_to_file.exists() && path_to_file.is_file() {
        println!("  OK: \"{}\" file has already exist.", file_name);
    } else {
        match File::create(&path_to_file) {
            Ok(mut f) => {
                println!("  OK: Created \"{}\" file.", file_name);
                match f.write(contents.as_ref().as_bytes()) {
                    Ok(_)    => {},
                    Err(why) => panic!("{:?}", why),
                }
            },
            Err(why) => panic!("{:?}", why),
        }
    }
}

pub fn set_params() {
    println!("set parameters");
}

pub fn sweep() {
    if !working_dir_exists() {
        print_warning_for_working_dir();
        return
    }

    if !config_file_exists() {
        print_warning_for_config_file();
        return
    }

    if !ignore_file_exists() {
        print_warning_for_ignore_file();
        return
    }

    let now           = Local::now();
    let trash_name    = format!("trash_{}", now.format("%Y-%m-%d"));
    let path_to_trash = Path::new(WORKING_DIR_NAME).join(trash_name);
    if !(path_to_trash.exists() && path_to_trash.is_dir()) {
        match fs::create_dir(path_to_trash) {
            Ok(_)    => {},
            Err(why) => panic!("{:?}", why),
        }
    }

    println!("Sweep ...");

    let ignore = read_ignore_file();

    let target_files = walk_dir(".")
        .difference(&ignore)
        .cloned()
        .collect::<Vec<String>>();

    println!("{:?}", target_files);
}

fn read_ignore_file() -> BTreeSet<String> {
    let ignore_file = Path::new(WORKING_DIR_NAME).join(IGNORE_FILE_NAME);
    let mut f       = match File::open(ignore_file) {
        Ok(f)    => f,
        Err(why) => panic!("{:?}", why),
    };
    let mut contents = String::new();
    match f.read_to_string(&mut contents) {
        Ok(_)    => {},
        Err(why) => panic!("{:?}", why),
    }
    contents
        .lines()
        .map(|l| l.trim().to_string())
        .collect::<BTreeSet<String>>()
}

pub fn burn() {
    println!("burn");
}

pub fn register_with_cron() {
    println!("register");
}

pub fn unregister_cron() {
    println!("unregister");
}

pub fn destroy() {
    println!("Destroy ...");

    if !working_dir_exists() {
        print_warning_for_working_dir();
        return
    }

    match fs::remove_dir_all(WORKING_DIR_NAME) {
        Ok(_)    => println!("  OK: Removed \"{}\" directory.", WORKING_DIR_NAME),
        Err(why) => panic!("{:?}", why),
    }
}
<commit_msg>Change absolute path to relative path because of clarifing hierarchy<commit_after>extern crate chrono;

use self::chrono::*;
use constant::*;
use std::collections::BTreeSet;
use std::fs;
use std::fs::File;
use std::io::{Read, Write};
use std::path::{Path, PathBuf};
use super::cmd_helper::*;
use super::fs_helper::*;

pub fn initialize() {
    println!("Initialize ...");

    let dir_name    = WORKING_DIR_NAME;
    let path_to_dir = Path::new(dir_name);
    if working_dir_exists() {
        println!("  OK: \"{}\" directory has already exist.", dir_name);
    } else {
        match fs::create_dir(path_to_dir) {
            Ok(_)    => println!("  OK: Created \"{}\" directory.", dir_name),
            Err(why) => panic!("{:?}", why),
        }
    }

    let path_to_config = path_to_dir.clone().join(CONFIG_FILE_NAME);
    create_setting_file(path_to_config, DEFAULT_CONFIG);

    let path_to_ignore = path_to_dir.clone().join(IGNORE_FILE_NAME);
    let ignore_contents = walk_dir(".").iter()
        .fold(String::new(), |c, f| c + &f + "\n");
    create_setting_file(path_to_ignore, ignore_contents);
}

fn create_setting_file<S: AsRef<str>>(path_to_file: PathBuf, contents: S) {
    let file_name = path_to_file.file_name().and_then(|f| f.to_str()).unwrap();
    if path_to_file.exists() && path_to_file.is_file() {
        println!("  OK: \"{}\" file has already exist.", file_name);
    } else {
        match File::create(&path_to_file) {
            Ok(mut f) => {
                println!("  OK: Created \"{}\" file.", file_name);
                match f.write(contents.as_ref().as_bytes()) {
                    Ok(_)    => {},
                    Err(why) => panic!("{:?}", why),
                }
            },
            Err(why) => panic!("{:?}", why),
        }
    }
}

pub fn set_params() {
    println!("set parameters");
}

pub fn sweep() {
    if !working_dir_exists() {
        print_warning_for_working_dir();
        return
    }

    if !config_file_exists() {
        print_warning_for_config_file();
        return
    }

    if !ignore_file_exists() {
        print_warning_for_ignore_file();
        return
    }

    let now           = Local::now();
    let trash_name    = format!("trash_{}", now.format("%Y-%m-%d"));
    let path_to_trash = Path::new(WORKING_DIR_NAME).join(trash_name);
    if !(path_to_trash.exists() && path_to_trash.is_dir()) {
        match fs::create_dir(path_to_trash) {
            Ok(_)    => {},
            Err(why) => panic!("{:?}", why),
        }
    }

    println!("Sweep ...");

    let ignore = read_ignore_file();

    let target_files = walk_dir(".")
        .difference(&ignore)
        .cloned()
        .collect::<Vec<String>>();

    println!("{:?}", target_files);
}

fn read_ignore_file() -> BTreeSet<String> {
    let ignore_file = Path::new(WORKING_DIR_NAME).join(IGNORE_FILE_NAME);
    let mut f       = match File::open(ignore_file) {
        Ok(f)    => f,
        Err(why) => panic!("{:?}", why),
    };
    let mut contents = String::new();
    match f.read_to_string(&mut contents) {
        Ok(_)    => {},
        Err(why) => panic!("{:?}", why),
    }
    contents
        .lines()
        .map(|l| l.trim().to_string())
        .collect::<BTreeSet<String>>()
}

pub fn burn() {
    println!("burn");
}

pub fn register_with_cron() {
    println!("register");
}

pub fn unregister_cron() {
    println!("unregister");
}

pub fn destroy() {
    println!("Destroy ...");

    if !working_dir_exists() {
        print_warning_for_working_dir();
        return
    }

    match fs::remove_dir_all(WORKING_DIR_NAME) {
        Ok(_)    => println!("  OK: Removed \"{}\" directory.", WORKING_DIR_NAME),
        Err(why) => panic!("{:?}", why),
    }
}
<|endoftext|>


<commit_before>use std::fs::{self, OpenOptions, File};
use std::io::{Error, ErrorKind};
use std::io::prelude::Write;
use std::ops::Deref;
use std::path::Path;
use std::sync::{Arc, Mutex};

use log::{self, LogRecord, LogLevel, LogMetadata, LogLevelFilter,
          SetLoggerError};
use time;

struct StdoutLogger {
    level: LogLevel,
}

impl log::Log for StdoutLogger {
    fn enabled(&self, metadata: &LogMetadata) -> bool {
        metadata.level() <= self.level
    }

    fn log(&self, record: &LogRecord) {
        if self.enabled(record.metadata()) {
            println!("{} {} {}:{}] {}",
                     record.level(),
                     time::now().to_timespec().sec,
                     record.location().file().split("/").last().unwrap(),
                     record.location().line(),
                     record.args());
        }
    }
}

struct FileLogger {
    file: Arc<Mutex<File>>,
    level: LogLevel,
}

impl FileLogger {
    pub fn new(path: &str, level: LogLevel) -> Result<FileLogger, Error> {
        let ospath = Path::new(path).parent();
        if ospath.is_none() {
            return Err(Error::new(
                ErrorKind::Other,
                format!("Failed to use log directory: {}", path)
            ));
        }

        match fs::create_dir_all(&ospath.unwrap()) {
            Err(e) => return Err(Error::new(
                ErrorKind::Other,
                format!("Failed to create log directory: {}", e)
            )),
            Ok(_) => (),
        }

        OpenOptions::new()
            .create(true).write(true).append(true).open(path).map( |file| {
                FileLogger{
                    file: Arc::new(Mutex::new(file)),
                    level: level,
                }
            })
    }
}

impl log::Log for FileLogger {
    fn enabled(&self, metadata: &LogMetadata) -> bool {
        metadata.level() <= self.level
    }

    fn log(&self, record: &LogRecord) {
        if self.enabled(record.metadata()) {
            let mut logfile = self.file.clone();
            logfile.lock()
                .unwrap()
                .write_all(format!("{} {} {}:{}] {}\n",
                                   record.level(),
                                   time::now().to_timespec().sec,
                                   record.location()
                                    .file().split("/").last().unwrap(),
                                   record.location().line(),
                                   record.args()).as_bytes());
        }
    }
}

pub fn init_logger(path: Option<String>, level: LogLevel) -> Result<(), SetLoggerError> {
    let logger: Box<log::Log> = match path {
        Some(p) => Box::new(FileLogger::new(p.trim_left(), level).unwrap()),
        None => Box::new(StdoutLogger{ level: level })
    };

    log::set_logger(|max_log_level| {
        max_log_level.set(LogLevelFilter::Debug);
        logger
    })
}
<commit_msg>formatting<commit_after>use std::fs::{self, OpenOptions, File};
use std::io::{Error, ErrorKind};
use std::io::prelude::Write;
use std::ops::Deref;
use std::path::Path;
use std::sync::{Arc, Mutex};

use log::{self, LogRecord, LogLevel, LogMetadata, LogLevelFilter,
          SetLoggerError};
use time;

struct StdoutLogger {
    level: LogLevel,
}

impl log::Log for StdoutLogger {
    fn enabled(&self, metadata: &LogMetadata) -> bool {
        metadata.level() <= self.level
    }

    fn log(&self, record: &LogRecord) {
        if self.enabled(record.metadata()) {
            println!("{} {} {}:{}] {}",
                     record.level(),
                     time::now().to_timespec().sec,
                     record.location().file().split("/").last().unwrap(),
                     record.location().line(),
                     record.args());
        }
    }
}

struct FileLogger {
    file: Arc<Mutex<File>>,
    level: LogLevel,
}

impl FileLogger {
    pub fn new(path: &str, level: LogLevel) -> Result<FileLogger, Error> {
        let ospath = Path::new(path).parent();
        if ospath.is_none() {
            return Err(Error::new(
                ErrorKind::Other,
                format!("Failed to use log directory: {}", path)
            ));
        }

        match fs::create_dir_all(&ospath.unwrap()) {
            Err(e) => return Err(Error::new(
                ErrorKind::Other,
                format!("Failed to create log directory: {}", e)
            )),
            Ok(_) => (),
        }

        OpenOptions::new()
            .create(true).write(true).append(true).open(path).map( |file| {
                FileLogger{
                    file: Arc::new(Mutex::new(file)),
                    level: level,
                }
            })
    }
}

impl log::Log for FileLogger {
    fn enabled(&self, metadata: &LogMetadata) -> bool {
        metadata.level() <= self.level
    }

    fn log(&self, record: &LogRecord) {
        if self.enabled(record.metadata()) {
            let mut logfile = self.file.clone();
            logfile.lock()
                .unwrap()
                .write_all(format!("{} {} {}:{}] {}\n",
                                   record.level(),
                                   time::now().to_timespec().sec,
                                   record.location()
                                         .file().split("/").last().unwrap(),
                                   record.location().line(),
                                   record.args()).as_bytes());
        }
    }
}

pub fn init_logger(path: Option<String>, level: LogLevel) -> Result<(), SetLoggerError> {
    let logger: Box<log::Log> = match path {
        Some(p) => Box::new(FileLogger::new(p.trim_left(), level).unwrap()),
        None => Box::new(StdoutLogger{ level: level })
    };

    log::set_logger(|max_log_level| {
        max_log_level.set(LogLevelFilter::Debug);
        logger
    })
}
<|endoftext|>


<commit_before>enum Direction {
    North,
    East,
    South,
    West,
    Empty,
}

struct Table {
    w: i32,
    h: i32,
}

struct Robot {
    x: i32,
    y: i32,
    d: Direction,
    t: Table,
}

impl Default for Robot {
    fn default() -> Robot {
        let table = Table{w: 5, h: 5};

        Robot{x: 0, y: 0, d: Direction::Empty, t: table}
    }
}

impl Table {
    fn valid_pos(&self, x: i32, y: i32) -> bool {
        x >= 0 && x < self.w && y >= 0 && y < self.h
    }
}

impl Robot {
    fn place(&mut self, x: i32, y: i32, d: Direction) {
        if self.t.valid_pos(x, y) {
            self.x = x;
            self.y = y;
            self.d = d;
        }
    }

    fn left(&mut self) {
    }

    fn right(&mut self) {
    }

    fn report(&self) {
    }
}

fn main() {
    let mut robot: Robot = Default::default();

    robot.place(1, 2, Direction::North);
}
<commit_msg>Added equality check for Direction<commit_after>#[derive(Eq, PartialEq)]
enum Direction {
    North,
    East,
    South,
    West,
    Empty,
}

struct Table {
    w: i32,
    h: i32,
}

struct Robot {
    x: i32,
    y: i32,
    d: Direction,
    t: Table,
}

impl Default for Robot {
    fn default() -> Robot {
        let table = Table{w: 5, h: 5};

        Robot{x: 0, y: 0, d: Direction::Empty, t: table}
    }
}

impl Table {
    fn valid_pos(&self, x: i32, y: i32) -> bool {
        x >= 0 && x < self.w && y >= 0 && y < self.h
    }
}

impl Robot {
    fn is_placed(&self) -> bool {
        self.d == Direction::Empty
    }

    fn place(&mut self, x: i32, y: i32, d: Direction) {
        if self.t.valid_pos(x, y) {
            self.x = x;
            self.y = y;
            self.d = d;
        }
    }

    fn left(&mut self) {
    }

    fn right(&mut self) {
    }

    fn step(&mut self) {
    }

    fn report(&self) {
    }
}

fn main() {
    let mut robot: Robot = Default::default();

    robot.place(1, 2, Direction::North);
}
<|endoftext|>


<commit_before>use std::path::Path;
use std::io::prelude::*;
use std::fs::File;
use yaml_rust::{YamlLoader, YamlEmitter, Yaml};
use project::parser::Command;
#[cfg(not(test))] use std::env::home_dir;

mod parser;
pub mod processor;

static MUXED_FOLDER: &'static str = "muxed";

pub fn open(project_name: String) -> Vec<Command> {
    let yaml = YamlLoader::load_from_str(&read(path_string(project_name))).unwrap();
    parser::main(&yaml)
}

pub fn path_string(project_name: String) -> String {
    format!("{}/.{}/{}.yml", homedir_string(), &MUXED_FOLDER.to_string(), project_name)
}

fn read(config_str: String) -> String {
    let path = Path::new(&config_str);
    let mut s = String::new();
    File::open(path).expect("Config Read error").read_to_string(&mut s);

    return s
}

#[cfg(not(test))] fn homedir_string() -> String {
    match home_dir() {
        Some(dir) => format!("{}", dir.display()),
        None      => panic!("Impossible to get your home dir!")
    }
}

#[cfg(test)] fn homedir_string() -> String {
  String::from("/tmp")
}

#[test]
pub fn path_string_returns_muxed_inside_homedir() {
    let path = format!("{}", path_string("".to_string()));
    let new  = format!("{}", Path::new("/tmp/.muxed/").display());
    assert_eq!(path, new)
}
<commit_msg>Request a specific project file so we can verify the extension in the name as well.<commit_after>use std::path::Path;
use std::io::prelude::*;
use std::fs::File;
use yaml_rust::{YamlLoader, YamlEmitter, Yaml};
use project::parser::Command;
#[cfg(not(test))] use std::env::home_dir;

mod parser;
pub mod processor;

static MUXED_FOLDER: &'static str = "muxed";

pub fn open(project_name: String) -> Vec<Command> {
    let yaml = YamlLoader::load_from_str(&read(path_string(project_name))).unwrap();
    parser::main(&yaml)
}

pub fn path_string(project_name: String) -> String {
    format!("{}/.{}/{}.yml", homedir_string(), &MUXED_FOLDER.to_string(), project_name)
}

fn read(config_str: String) -> String {
    let path = Path::new(&config_str);
    let mut s = String::new();
    File::open(path).expect("Config Read error").read_to_string(&mut s);

    return s
}

#[cfg(not(test))] fn homedir_string() -> String {
    match home_dir() {
        Some(dir) => format!("{}", dir.display()),
        None      => panic!("Impossible to get your home dir!")
    }
}

#[cfg(test)] fn homedir_string() -> String {
  String::from("/tmp")
}

#[test]
pub fn path_string_returns_muxed_inside_homedir() {
    let path = format!("{}", path_string("test".to_string()));
    let new  = format!("{}", Path::new("/tmp/.muxed/test.yml").display());
    assert_eq!(path, new)
}
<|endoftext|>


<commit_before>//! Iron's HTTP Request representation and associated methods.

use std::io::net::ip::SocketAddr;
use std::fmt::{Show, Formatter, FormatError};

use http::server::request::{AbsoluteUri, AbsolutePath};
use http::headers::request::HeaderCollection;
use http::method::Method;

use typemap::TypeMap;
use plugin::Extensible;

pub use http::server::request::Request as HttpRequest;

pub use self::url::Url;

mod url;

/// The `Request` given to all `Middleware`.
///
/// Stores all the properties of the client's request plus
/// an `TypeMap` for data communication between middleware.
pub struct Request {
    /// The requested URL.
    pub url: Url,

    /// The originating address of the request.
    pub remote_addr: Option<SocketAddr>,

    /// The request headers.
    pub headers: Box<HeaderCollection>,

    /// The request body.
    pub body: String,

    /// The request method.
    pub method: Method,

    /// Extensible storage for data passed between middleware.
    pub extensions: TypeMap
}

impl Show for Request {
    fn fmt(&self, f: &mut Formatter) -> Result<(), FormatError> {
        try!(writeln!(f, "Request {{"));

        try!(writeln!(f, "    url: {}", self.url));
        try!(writeln!(f, "    method: {}", self.method));
        try!(writeln!(f, "    remote_addr: {}", self.remote_addr));
        try!(writeln!(f, "    body: {}", self.body));

        try!(writeln!(f, "}}"));
        Ok(())
    }
}

impl Request {
    /// Create a request from an HttpRequest.
    ///
    /// This constructor consumes the HttpRequest.
    pub fn from_http(req: HttpRequest) -> Result<Request, String> {
        match req.request_uri {
            AbsoluteUri(url) => {
                let url = match Url::from_generic_url(url) {
                    Ok(url) => url,
                    Err(e) => return Err(e)
                };

                Ok(Request {
                    url: url,
                    remote_addr: req.remote_addr,
                    headers: req.headers,
                    body: req.body,
                    method: req.method,
                    extensions: TypeMap::new()
                })
            },
            AbsolutePath(path) => {
                // Attempt to prepend the Host header (mandatory in HTTP/1.1)
                // XXX: HTTPS incompatible, update when switching to Teepee.
                let url_string = match req.headers.host {
                    Some(ref host) => format!("http://{}{}", host, path),
                    None => return Err("No host specified in request".to_string())
                };

                let url = match Url::parse(url_string.as_slice()) {
                    Ok(url) => url,
                    Err(e) => return Err(format!("Couldn't parse requested URL: {}", e))
                };

                Ok(Request {
                    url: url,
                    remote_addr: req.remote_addr,
                    headers: req.headers,
                    body: req.body,
                    method: req.method,
                    extensions: TypeMap::new()
                })
            },
            _ => Err("Unsupported request URI".to_string())
        }
    }
}

// Allow plugins to attach to requests.
impl Extensible for Request {
    fn extensions(&self) -> &TypeMap {
        &self.extensions
    }

    fn extensions_mut(&mut self) -> &mut TypeMap {
        &mut self.extensions
    }
}

<commit_msg>(cleanup) Removed excess newline in request::fmt.<commit_after>//! Iron's HTTP Request representation and associated methods.

use std::io::net::ip::SocketAddr;
use std::fmt::{Show, Formatter, FormatError};

use http::server::request::{AbsoluteUri, AbsolutePath};
use http::headers::request::HeaderCollection;
use http::method::Method;

use typemap::TypeMap;
use plugin::Extensible;

pub use http::server::request::Request as HttpRequest;

pub use self::url::Url;

mod url;

/// The `Request` given to all `Middleware`.
///
/// Stores all the properties of the client's request plus
/// an `TypeMap` for data communication between middleware.
pub struct Request {
    /// The requested URL.
    pub url: Url,

    /// The originating address of the request.
    pub remote_addr: Option<SocketAddr>,

    /// The request headers.
    pub headers: Box<HeaderCollection>,

    /// The request body.
    pub body: String,

    /// The request method.
    pub method: Method,

    /// Extensible storage for data passed between middleware.
    pub extensions: TypeMap
}

impl Show for Request {
    fn fmt(&self, f: &mut Formatter) -> Result<(), FormatError> {
        try!(writeln!(f, "Request {{"));

        try!(writeln!(f, "    url: {}", self.url));
        try!(writeln!(f, "    method: {}", self.method));
        try!(writeln!(f, "    remote_addr: {}", self.remote_addr));
        try!(writeln!(f, "    body: {}", self.body));

        try!(write!(f, "}}"));
        Ok(())
    }
}

impl Request {
    /// Create a request from an HttpRequest.
    ///
    /// This constructor consumes the HttpRequest.
    pub fn from_http(req: HttpRequest) -> Result<Request, String> {
        match req.request_uri {
            AbsoluteUri(url) => {
                let url = match Url::from_generic_url(url) {
                    Ok(url) => url,
                    Err(e) => return Err(e)
                };

                Ok(Request {
                    url: url,
                    remote_addr: req.remote_addr,
                    headers: req.headers,
                    body: req.body,
                    method: req.method,
                    extensions: TypeMap::new()
                })
            },
            AbsolutePath(path) => {
                // Attempt to prepend the Host header (mandatory in HTTP/1.1)
                // XXX: HTTPS incompatible, update when switching to Teepee.
                let url_string = match req.headers.host {
                    Some(ref host) => format!("http://{}{}", host, path),
                    None => return Err("No host specified in request".to_string())
                };

                let url = match Url::parse(url_string.as_slice()) {
                    Ok(url) => url,
                    Err(e) => return Err(format!("Couldn't parse requested URL: {}", e))
                };

                Ok(Request {
                    url: url,
                    remote_addr: req.remote_addr,
                    headers: req.headers,
                    body: req.body,
                    method: req.method,
                    extensions: TypeMap::new()
                })
            },
            _ => Err("Unsupported request URI".to_string())
        }
    }
}

// Allow plugins to attach to requests.
impl Extensible for Request {
    fn extensions(&self) -> &TypeMap {
        &self.extensions
    }

    fn extensions_mut(&mut self) -> &mut TypeMap {
        &mut self.extensions
    }
}

<|endoftext|>


<commit_before>use color::Color;
use geom::{Point};

pub struct LightSource {
    source: Box<LightSourceImpl>
}

impl LightSource {
    pub fn position(&self) -> Point {
        self.source.position()
    }

    pub fn illuminate(&self, p: Point) -> Color {
        let distance = (p - self.position()).length();
        return self.source.outgoing_light(p) / distance.sqrt()
    }
}

#[derive(Debug, RustcDecodable)]
pub struct LightConfig {
    color: Color,
    intensity: f64,
    position: Point
}

impl From<LightConfig> for LightSource {
    fn from(config: LightConfig) -> LightSource {
        LightSource {
            source: Box::new(PointLight {
                color: config.color,
                intensity: config.intensity,
                position: config.position })
        }
    }
}

trait LightSourceImpl {
    fn position(&self) -> Point;
    fn outgoing_light(&self, p: Point) -> Color;
}

#[derive(Debug, RustcDecodable)]
struct PointLight {
    color: Color,
    intensity: f64,
    position: Point
}

impl LightSourceImpl for PointLight {
    fn position(&self) -> Point {
        self.position
    }

    fn outgoing_light(&self, _p: Point) -> Color {
        self.color * self.intensity
    }
}
<commit_msg>refactor lights<commit_after>use color::Color;
use geom::{Point};

pub struct LightSource {
    color: Color,
    intensity: f64,
    position: Point,
    source: Box<LightSourceImpl>,
}

impl LightSource {
    pub fn position(&self) -> Point {
        self.position
    }

    pub fn illuminate(&self, p: Point) -> Color {
        let distance = (p - self.position()).length();
        let coef = self.intensity * self.source.intensity_at(p) / distance.sqrt();
        return self.color * coef
    }
}

#[derive(Debug, RustcDecodable)]
pub struct LightConfig {
    color: Color,
    intensity: f64,
    position: Point,
}

impl From<LightConfig> for LightSource {
    fn from(config: LightConfig) -> LightSource {
        LightSource {
            color: config.color,
            intensity: config.intensity,
            position: config.position,
            source: Box::new(PointLight),
        }
    }
}

trait LightSourceImpl {
    fn intensity_at(&self, p: Point) -> f64;
}

struct PointLight;

impl LightSourceImpl for PointLight {
    fn intensity_at(&self, _p: Point) -> f64 {
        1.0
    }
}
<|endoftext|>


<commit_before>pub enum UnitStates {
    Inactive,
    Loaded,
    Launched,
}

impl UnitStates {
    pub fn from_str(s: &str) -> UnitStates {
        match s {
            "inactive" => UnitStates::Inactive,
            "loaded" => UnitStates::Loaded,
            "launched" => UnitStates::Launched,
            variant => panic!("not a valid UnitStates variant: {}", variant),
        }
    }
}

impl UnitStates {
    pub fn to_json(&self) -> &'static str {
        match *self {
            UnitStates::Inactive => "inactive",
            UnitStates::Loaded => "loaded",
            UnitStates::Launched => "launched",
        }
    }
}

#[derive(RustcEncodable)]
pub struct UnitOption {
    pub name: String,
    pub section: String,
    pub value: String,
}

pub struct Unit {
    pub current_state: UnitStates,
    pub desired_state: UnitStates,
    pub machine_id: String,
    pub name: String,
    pub options: Vec<UnitOption>,
}

pub struct UnitPage {
    units: Vec<Unit>,
    next_page_token: Option<String>,
}

pub struct UnitState {
    pub name: String,
    pub hash: String,
    pub machine_id: String,
    pub systemd_load_state: String,
    pub systemd_active_state: String,
    pub systemd_sub_state: String,
}

pub struct UnitStatePage {
    states: Vec<UnitState>,
    next_page_token: Option<String>,
}

#[cfg(test)]
mod unit_tests {
    use super::{Unit, UnitStates, UnitOption};

    #[test]
    fn it_can_be_constructed() {
        let unit_option = UnitOption {
            name: "Description".to_string(),
            section: "Unit".to_string(),
            value: "Example unit".to_string(),
        };

        Unit {
            current_state: UnitStates::Inactive,
            desired_state: UnitStates::Launched,
            machine_id: "abc123".to_string(),
            name: "example.service".to_string(),
            options: vec![unit_option],
        };
    }
}

#[cfg(test)]
mod unit_page_tests {
    use super::{Unit, UnitPage, UnitStates};

    #[test]
    fn it_can_be_paginated() {
        let unit = Unit {
            current_state: UnitStates::Inactive,
            desired_state: UnitStates::Launched,
            machine_id: "abc123".to_string(),
            name: "example.service".to_string(),
            options: vec![],
        };

        UnitPage {
            units: vec![unit],
            next_page_token: Some("8fefec2c".to_string()),
        };
    }

    #[test]
    fn it_can_have_no_additional_pages() {
        let unit = Unit {
            current_state: UnitStates::Inactive,
            desired_state: UnitStates::Launched,
            machine_id: "abc123".to_string(),
            name: "example.service".to_string(),
            options: vec![],
        };

        UnitPage {
            units: vec![unit],
            next_page_token: None,
        };
    }
}

#[cfg(test)]
mod unit_state_tests {
    use super::UnitState;

    #[test]
    fn it_can_be_constructed() {
        UnitState {
            name: "example.service".to_string(),
            hash: "abc123".to_string(),
            machine_id: "123abc".to_string(),
            systemd_load_state: "loaded".to_string(),
            systemd_active_state: "active".to_string(),
            systemd_sub_state: "running".to_string(),
        };
    }
}

#[cfg(test)]
mod unit_state_page_tests {
    use super::{UnitState, UnitStatePage};

    fn it_can_be_paginated() {
        let unit_state = UnitState {
            name: "example.service".to_string(),
            hash: "abc123".to_string(),
            machine_id: "123abc".to_string(),
            systemd_load_state: "loaded".to_string(),
            systemd_active_state: "active".to_string(),
            systemd_sub_state: "running".to_string(),
        };

        UnitStatePage {
            states: vec![unit_state],
            next_page_token: Some("8fefec2c".to_string()),
        };
    }

    fn it_can_have_no_additional_pages() {
        let unit_state = UnitState {
            name: "example.service".to_string(),
            hash: "abc123".to_string(),
            machine_id: "123abc".to_string(),
            systemd_load_state: "loaded".to_string(),
            systemd_active_state: "active".to_string(),
            systemd_sub_state: "running".to_string(),
        };

        UnitStatePage {
            states: vec![unit_state],
            next_page_token: None,
        };
    }
}
<commit_msg>Remove double impl blocks for UnitStates.<commit_after>pub enum UnitStates {
    Inactive,
    Loaded,
    Launched,
}

impl UnitStates {
    pub fn from_str(s: &str) -> UnitStates {
        match s {
            "inactive" => UnitStates::Inactive,
            "loaded" => UnitStates::Loaded,
            "launched" => UnitStates::Launched,
            variant => panic!("not a valid UnitStates variant: {}", variant),
        }
    }

    pub fn to_json(&self) -> &'static str {
        match *self {
            UnitStates::Inactive => "inactive",
            UnitStates::Loaded => "loaded",
            UnitStates::Launched => "launched",
        }
    }
}

#[derive(RustcEncodable)]
pub struct UnitOption {
    pub name: String,
    pub section: String,
    pub value: String,
}

pub struct Unit {
    pub current_state: UnitStates,
    pub desired_state: UnitStates,
    pub machine_id: String,
    pub name: String,
    pub options: Vec<UnitOption>,
}

pub struct UnitPage {
    units: Vec<Unit>,
    next_page_token: Option<String>,
}

pub struct UnitState {
    pub name: String,
    pub hash: String,
    pub machine_id: String,
    pub systemd_load_state: String,
    pub systemd_active_state: String,
    pub systemd_sub_state: String,
}

pub struct UnitStatePage {
    states: Vec<UnitState>,
    next_page_token: Option<String>,
}

#[cfg(test)]
mod unit_tests {
    use super::{Unit, UnitStates, UnitOption};

    #[test]
    fn it_can_be_constructed() {
        let unit_option = UnitOption {
            name: "Description".to_string(),
            section: "Unit".to_string(),
            value: "Example unit".to_string(),
        };

        Unit {
            current_state: UnitStates::Inactive,
            desired_state: UnitStates::Launched,
            machine_id: "abc123".to_string(),
            name: "example.service".to_string(),
            options: vec![unit_option],
        };
    }
}

#[cfg(test)]
mod unit_page_tests {
    use super::{Unit, UnitPage, UnitStates};

    #[test]
    fn it_can_be_paginated() {
        let unit = Unit {
            current_state: UnitStates::Inactive,
            desired_state: UnitStates::Launched,
            machine_id: "abc123".to_string(),
            name: "example.service".to_string(),
            options: vec![],
        };

        UnitPage {
            units: vec![unit],
            next_page_token: Some("8fefec2c".to_string()),
        };
    }

    #[test]
    fn it_can_have_no_additional_pages() {
        let unit = Unit {
            current_state: UnitStates::Inactive,
            desired_state: UnitStates::Launched,
            machine_id: "abc123".to_string(),
            name: "example.service".to_string(),
            options: vec![],
        };

        UnitPage {
            units: vec![unit],
            next_page_token: None,
        };
    }
}

#[cfg(test)]
mod unit_state_tests {
    use super::UnitState;

    #[test]
    fn it_can_be_constructed() {
        UnitState {
            name: "example.service".to_string(),
            hash: "abc123".to_string(),
            machine_id: "123abc".to_string(),
            systemd_load_state: "loaded".to_string(),
            systemd_active_state: "active".to_string(),
            systemd_sub_state: "running".to_string(),
        };
    }
}

#[cfg(test)]
mod unit_state_page_tests {
    use super::{UnitState, UnitStatePage};

    fn it_can_be_paginated() {
        let unit_state = UnitState {
            name: "example.service".to_string(),
            hash: "abc123".to_string(),
            machine_id: "123abc".to_string(),
            systemd_load_state: "loaded".to_string(),
            systemd_active_state: "active".to_string(),
            systemd_sub_state: "running".to_string(),
        };

        UnitStatePage {
            states: vec![unit_state],
            next_page_token: Some("8fefec2c".to_string()),
        };
    }

    fn it_can_have_no_additional_pages() {
        let unit_state = UnitState {
            name: "example.service".to_string(),
            hash: "abc123".to_string(),
            machine_id: "123abc".to_string(),
            systemd_load_state: "loaded".to_string(),
            systemd_active_state: "active".to_string(),
            systemd_sub_state: "running".to_string(),
        };

        UnitStatePage {
            states: vec![unit_state],
            next_page_token: None,
        };
    }
}
<|endoftext|>


<commit_before>///
/// Represents the possible values of an attribute on a tree node
///
pub enum TreeValue {
    Nothing,
    Int(i32),
    Real(f64),
    String(String),
    Data(Vec<u8>)
}

///
/// Traits implemented by types that can be treated as tree values
///
pub trait ToTreeValue {
    fn to_tree_value(&self) -> TreeValue;
}

impl ToTreeValue for TreeValue {
    fn to_tree_value(&self) -> TreeValue {
        match *self {
            TreeValue::Nothing          => TreeValue::Nothing,
            TreeValue::Int(v)           => TreeValue::Int(v),
            TreeValue::Real(f)          => TreeValue::Real(f),
            TreeValue::String(ref s)    => TreeValue::String(s.to_string()),
            TreeValue::Data(ref d)      => TreeValue::Data(d.to_vec())
        }
    }
}

impl ToTreeValue for () {
    fn to_tree_value(&self) -> TreeValue { TreeValue::Nothing }
}

impl ToTreeValue for i32 {
    fn to_tree_value(&self) -> TreeValue { TreeValue::Int(*self) }
}

impl ToTreeValue for f64 {
    fn to_tree_value(&self) -> TreeValue { TreeValue::Real(*self) }
}

impl ToTreeValue for str {
    fn to_tree_value(&self) -> TreeValue { TreeValue::String(self.to_string()) }
}

impl ToTreeValue for String {
    fn to_tree_value(&self) -> TreeValue { TreeValue::String(self.to_string()) }
}

impl ToTreeValue for Vec<u8> {
    fn to_tree_value(&self) -> TreeValue { TreeValue::Data(self.to_vec()) }
}
<commit_msg>Using to_owned might make more sense here in terms of what we're doing<commit_after>///
/// Represents the possible values of an attribute on a tree node
///
pub enum TreeValue {
    Nothing,
    Int(i32),
    Real(f64),
    String(String),
    Data(Vec<u8>)
}

///
/// Traits implemented by types that can be treated as tree values
///
pub trait ToTreeValue {
    fn to_tree_value(&self) -> TreeValue;
}

impl ToTreeValue for TreeValue {
    fn to_tree_value(&self) -> TreeValue {
        match *self {
            TreeValue::Nothing          => TreeValue::Nothing,
            TreeValue::Int(v)           => TreeValue::Int(v),
            TreeValue::Real(f)          => TreeValue::Real(f),
            TreeValue::String(ref s)    => TreeValue::String(s.to_string()),
            TreeValue::Data(ref d)      => TreeValue::Data(d.to_vec())
        }
    }
}

impl ToTreeValue for () {
    fn to_tree_value(&self) -> TreeValue { TreeValue::Nothing }
}

impl ToTreeValue for i32 {
    fn to_tree_value(&self) -> TreeValue { TreeValue::Int(*self) }
}

impl ToTreeValue for f64 {
    fn to_tree_value(&self) -> TreeValue { TreeValue::Real(*self) }
}

impl ToTreeValue for str {
    fn to_tree_value(&self) -> TreeValue { TreeValue::String(self.to_owned()) }
}

impl ToTreeValue for String {
    fn to_tree_value(&self) -> TreeValue { TreeValue::String(self.to_owned()) }
}

impl ToTreeValue for Vec<u8> {
    fn to_tree_value(&self) -> TreeValue { TreeValue::Data(self.to_owned()) }
}
<|endoftext|>


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

/*===============================================================================================*/
//! The logging module.
//!
//! It provides basic logging functionality.
/*===============================================================================================*/

extern crate ansi_term;
extern crate log;

use self::ansi_term::Colour::{Blue, White, Yellow, Red};

use std::boxed::Box;
use std::fs::File;
use std::io::BufWriter;
use std::io::prelude::Write;

/*===============================================================================================*/
/*------LOGGER STRUCT----------------------------------------------------------------------------*/
/*===============================================================================================*/

/// The logger struct
///
/// It provides basic logging capabilities, and is designed for use within ion.
pub struct Logger {

    // Private
    log_file: BufWriter <File>,
    log_to_console: bool
}

/*===============================================================================================*/
/*------LOGGER PUBLIC STATIC METHODS-------------------------------------------------------------*/
/*===============================================================================================*/

impl Logger {

    /// Initializes the logger
    ///
    /// This is required before any logging functions are performed.
    /// Any logging done beforehand will be ignored.
    ///
    /// # Arguments
    /// * `log_file_path` - The path to where the log will be saved
    /// * `log_to_console` - Whether the log output should also be printed to the console
    ///
    /// # Return value
    /// A result, returning an error on failure.
    ///
    /// # Examples
    /// ```
    /// # use ion_core::util::Logger;
    /// #
    /// Logger::init ("LogFile.log", false);
    pub fn init (log_file_path: &str, log_to_console: bool) -> Result<(), log::SetLoggerError> {

        log::set_logger (|max_log_level| {

            if cfg! (debug_assertions) {
                max_log_level.set (log::LogLevelFilter::Debug);
            }

            else {
                max_log_level.set (log::LogLevelFilter::Info);
            }

            Box::new (Logger {log_file: BufWriter::new (File::create (&log_file_path).unwrap ()),
                              log_to_console: log_to_console})
        })
    }
}

/*===============================================================================================*/
/*------LOGGER PRIVATE METHODS-------------------------------------------------------------------*/
/*===============================================================================================*/

impl log::Log for Logger {

    fn enabled (&self, metadata: &log::LogMetadata) -> bool {

        if cfg! (debug_assertions) {
            return metadata.level () <= log::LogLevel::Debug;
        }

        metadata.level () <= log::LogLevel::Info
    }

/*-----------------------------------------------------------------------------------------------*/

    fn log (&self, record: &log::LogRecord) {

        let string_output = format! ("{} ({} : {}) - {}\n", record.level (),
                                                            record.location ().module_path (),
                                                            record.location ().line (),
                                                            record.args ());
        if self.log_to_console {

            match record.level () {

                log::LogLevel::Debug => print! ("{}", Blue.paint (string_output.as_str ())),
                log::LogLevel::Info  => print! ("{}", White.paint (string_output.as_str ())),
                log::LogLevel::Warn  => print! ("{}", Yellow.paint (string_output.as_str ())),
                log::LogLevel::Error => print! ("{}", Red.paint (string_output.as_str ())),
                _ => {}
            }
        }

        self.log_file.get_ref ().write (string_output.as_bytes ()).unwrap ();
    }
}
<commit_msg>Improved logger colour coding<commit_after>/*===============================================================================================*/
// Copyright 2016 Kyle Finlay
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*===============================================================================================*/

/*===============================================================================================*/
//! The logging module.
//!
//! It provides basic logging functionality.
/*===============================================================================================*/

extern crate ansi_term;
extern crate log;

use self::ansi_term::Colour::{Blue, Purple, Yellow, Red};

use std::boxed::Box;
use std::fs::File;
use std::io::BufWriter;
use std::io::prelude::Write;

/*===============================================================================================*/
/*------LOGGER STRUCT----------------------------------------------------------------------------*/
/*===============================================================================================*/

/// The logger struct
///
/// It provides basic logging capabilities, and is designed for use within ion.
pub struct Logger {

    // Private
    log_file: BufWriter <File>,
    log_to_console: bool
}

/*===============================================================================================*/
/*------LOGGER PUBLIC STATIC METHODS-------------------------------------------------------------*/
/*===============================================================================================*/

impl Logger {

    /// Initializes the logger
    ///
    /// This is required before any logging functions are performed.
    /// Any logging done beforehand will be ignored.
    ///
    /// # Arguments
    /// * `log_file_path` - The path to where the log will be saved
    /// * `log_to_console` - Whether the log output should also be printed to the console
    ///
    /// # Return value
    /// A result, returning an error on failure.
    ///
    /// # Examples
    /// ```
    /// # use ion_core::util::Logger;
    /// #
    /// Logger::init ("LogFile.log", false);
    pub fn init (log_file_path: &str, log_to_console: bool) -> Result<(), log::SetLoggerError> {

        log::set_logger (|max_log_level| {

            if cfg! (debug_assertions) {
                max_log_level.set (log::LogLevelFilter::Debug);
            }

            else {
                max_log_level.set (log::LogLevelFilter::Info);
            }

            Box::new (Logger {log_file: BufWriter::new (File::create (&log_file_path).unwrap ()),
                              log_to_console: log_to_console})
        })
    }
}

/*===============================================================================================*/
/*------LOGGER PRIVATE METHODS-------------------------------------------------------------------*/
/*===============================================================================================*/

impl log::Log for Logger {

    fn enabled (&self, metadata: &log::LogMetadata) -> bool {

        if cfg! (debug_assertions) {
            return metadata.level () <= log::LogLevel::Debug;
        }

        metadata.level () <= log::LogLevel::Info
    }

/*-----------------------------------------------------------------------------------------------*/

    fn log (&self, record: &log::LogRecord) {

        let output = match record.level () {

            log::LogLevel::Debug => format! ("{} ({} : {}) - {}\n", Purple.paint (record.level ().to_string ()),
                                                                    record.location ().module_path (),
                                                                    record.location ().line (),
                                                                    record.args ()),

            log::LogLevel::Info => format! ("{} ({} : {}) - {}\n", Blue.paint (record.level ().to_string ()),
                                                                   record.location ().module_path (),
                                                                   record.location ().line (),
                                                                   record.args ()),

            log::LogLevel::Warn => format! ("{} ({} : {}) - {}\n", Yellow.paint (record.level ().to_string ()),
                                                                   record.location ().module_path (),
                                                                   record.location ().line (),
                                                                   record.args ()),

            log::LogLevel::Error => format! ("{} ({} : {}) - {}\n", Red.paint (record.level ().to_string ()),
                                                                    record.location ().module_path (),
                                                                    record.location ().line (),
                                                                    record.args ()),
            _ => String::new ()
        };

        if self.log_to_console {
            print! ("{}", output);
        }

        self.log_file.get_ref ().write (format! ("{} ({} : {}) - {}\n", record.level (),
                                                                        record.location ().module_path (),
                                                                        record.location ().line (),
                                                                        record.args ()).as_bytes ()).unwrap ();
    }
}
<|endoftext|>