<commit_before>//! The enum `Either`.

use std::io::{self, Write, Read, BufRead};
use std::convert::{AsRef, AsMut};
use std::ops::Deref;
use std::ops::DerefMut;

pub use Either::{Left, Right};

/// `Either` represents an alternative holding one value out of
/// either of the two possible values.
///
/// `Either` is a general purpose sum type of two parts. For representing
/// success or error, use the regular `Result<T, E>` instead.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub enum Either<L, R> {
    /// A value of type `L`.
    Left(L),
    /// A value of type `R`.
    Right(R),
}

macro_rules! either {
    ($value:expr, $inner:ident => $result:expr) => (
        match $value {
            Either::Left(ref $inner) => $result,
            Either::Right(ref $inner) => $result,
        }
    )
}

macro_rules! either_mut {
    ($value:expr, $inner:ident => $result:expr) => (
        match $value {
            Either::Left(ref mut $inner) => $result,
            Either::Right(ref mut $inner) => $result,
        }
    )
}

/// Macro for unwrapping the left side of an `Either`, which fails early
/// with the opposite side. Can only be used in functions that return
/// `Either` because of the early return of `Right` that it provides.
///
/// See also `right!` for its dual, which applies the same just to the
/// right side.
///
/// # Example
///
/// ```
/// # #[macro_use] extern crate either; use either::*; fn main() {
/// fn twice(wrapper: Either<u32, &str>) -> Either<u32, &str> {
///     let value = left!(wrapper);
///     Left(value * 2)
/// }
///
/// assert_eq!(twice(Left(2)), Left(4));
/// assert_eq!(twice(Right("ups")), Right("ups"));
/// # }
/// ```
#[macro_export]
macro_rules! left {
    ($expr:expr) => (
        match $expr {
            $crate::Left(val) => val,
            $crate::Right(err) => return $crate::Right(::std::convert::From::from(err))
        }
    )
}

/// Dual to `left!`, see its documentation for more information.
#[macro_export]
macro_rules! right {
    ($expr:expr) => (
        match $expr {
            $crate::Left(err) => return $crate::Left(::std::convert::From::from(err)),
            $crate::Right(val) => val
        }
    )
}

impl<L, R> Either<L, R> {
    pub fn is_left(&self) -> bool {
        match *self {
            Left(_) => true,
            Right(_) => false,
        }
    }

    pub fn is_right(&self) -> bool {
        !self.is_left()
    }

    pub fn left(self) -> Option<L> {
        match self {
            Left(l) => Some(l),
            Right(_) => None,
        }
    }

    pub fn right(self) -> Option<R> {
        match self {
            Left(_) => None,
            Right(r) => Some(r),
        }
    }

    pub fn as_ref(&self) -> Either<&L, &R> {
        match *self {
            Left(ref inner) => Left(inner),
            Right(ref inner) => Right(inner),
        }
    }

    pub fn as_mut(&mut self) -> Either<&mut L, &mut R> {
        match *self {
            Left(ref mut inner) => Left(inner),
            Right(ref mut inner) => Right(inner),
        }
    }

    pub fn flip(self) -> Either<R, L> {
        match self {
            Left(l) => Right(l),
            Right(r) => Left(r),
        }
    }
}

/// Convert from `Result` to `Either` with `Ok => Right` and `Err => Left`.
impl<L, R> From<Result<R, L>> for Either<L, R> {
    fn from(r: Result<R, L>) -> Self {
        match r {
            Err(e) => Left(e),
            Ok(o) => Right(o),
        }
    }
}

/// Convert from `Either` to `Result` with `Right => Ok` and `Left => Err`.
impl<L, R> Into<Result<R, L>> for Either<L, R> {
    fn into(self) -> Result<R, L> {
        match self {
            Left(l) => Err(l),
            Right(r) => Ok(r),
        }
    }
}

/// `Either<L, R>` is an iterator if both `L` and `R` are iterators.
impl<L, R> Iterator for Either<L, R>
    where L: Iterator, R: Iterator<Item=L::Item>
{
    type Item = L::Item;

    fn next(&mut self) -> Option<L::Item> {
        either_mut!(*self, inner => inner.next())
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        either!(*self, inner => inner.size_hint())
    }
}

impl<L, R> DoubleEndedIterator for Either<L, R>
    where L: DoubleEndedIterator, R: DoubleEndedIterator<Item=L::Item>
{
    fn next_back(&mut self) -> Option<L::Item> {
        either_mut!(*self, inner => inner.next_back())
    }
}

impl<L, R> ExactSizeIterator for Either<L, R>
    where L: ExactSizeIterator, R: ExactSizeIterator<Item=L::Item>
{
}

/// `Either<L, R>` implements `Read` if both `L` and `R` do.
impl<L, R> Read for Either<L, R>
    where L: Read, R: Read
{
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        either_mut!(*self, inner => inner.read(buf))
    }

    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
        either_mut!(*self, inner => inner.read_to_end(buf))
    }
}

impl<L, R> BufRead for Either<L, R>
    where L: BufRead, R: BufRead
{
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        either_mut!(*self, inner => inner.fill_buf())
    }

    fn consume(&mut self, amt: usize) {
        either_mut!(*self, inner => inner.consume(amt))
    }
}

/// `Either<L, R>` implements `Write` if both `L` and `R` do.
impl<L, R> Write for Either<L, R>
    where L: Write, R: Write
{
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        either_mut!(*self, inner => inner.write(buf))
    }

    fn flush(&mut self) -> io::Result<()> {
        either_mut!(*self, inner => inner.flush())
    }
}

impl<L, R, Target> AsRef<Target> for Either<L, R>
    where L: AsRef<Target>, R: AsRef<Target>
{
    fn as_ref(&self) -> &Target {
        either!(*self, inner => inner.as_ref())
    }
}

impl<L, R, Target> AsMut<Target> for Either<L, R>
    where L: AsMut<Target>, R: AsMut<Target>
{
    fn as_mut(&mut self) -> &mut Target {
        either_mut!(*self, inner => inner.as_mut())
    }
}

impl<L, R> Deref for Either<L, R>
    where L: Deref, R: Deref<Target=L::Target>
{
    type Target = L::Target;

    fn deref(&self) -> &Self::Target {
        either!(*self, inner => &*inner)
    }
}

impl<L, R> DerefMut for Either<L, R>
    where L: DerefMut, R: DerefMut<Target=L::Target>
{
    fn deref_mut(&mut self) -> &mut Self::Target {
        either_mut!(*self, inner => &mut *inner)
    }
}

#[test]
fn basic() {
    let mut e = Left(2);
    let r = Right(2);
    assert_eq!(e, Left(2));
    e = r;
    assert_eq!(e, Right(2));
    assert_eq!(e.left(), None);
    assert_eq!(e.right(), Some(2));
    assert_eq!(e.as_ref().right(), Some(&2));
    assert_eq!(e.as_mut().right(), Some(&mut 2));
}

#[test]
fn macros() {
    fn a() -> Either<u32, u32> {
        let x: u32 = left!(Right(1337));
        Left(x * 2)
    }
    assert_eq!(a(), Right(1337));

    fn b() -> Either<String, &'static str> {
        Right(right!(Left("foo bar")))
    }
    assert_eq!(b(), Left(String::from("foo bar")));
}

#[test]
fn deref() {
    fn is_str(_: &str) {}
    let value: Either<String, &str> = Left(String::from("test"));
    is_str(&*value);
}

#[test]
fn iter() {
    let x = 3;
    let mut iter = match x {
        1...3 => Left(0..10),
        _ => Right(17..),
    };

    assert_eq!(iter.next(), Some(0));
    assert_eq!(iter.count(), 9);
}

#[test]
fn read_write() {
    use std::io;

    let use_stdio = false;
    let mockdata = [0xff; 256];

    let mut reader = if use_stdio {
        Left(io::stdin())
    } else {
        Right(&mockdata[..])
    };

    let mut buf = [0u8; 16];
    assert_eq!(reader.read(&mut buf).unwrap(), buf.len());
    assert_eq!(&buf, &mockdata[..buf.len()]);

    let mut mockbuf = [0u8; 256];
    let mut writer = if use_stdio {
        Left(io::stdout())
    } else {
        Right(&mut mockbuf[..])
    };

    let buf = [1u8; 16];
    assert_eq!(writer.write(&buf).unwrap(), buf.len());
}
<commit_msg>Rename macros to establish connection to `try!`<commit_after>//! The enum `Either`.

use std::io::{self, Write, Read, BufRead};
use std::convert::{AsRef, AsMut};
use std::ops::Deref;
use std::ops::DerefMut;

pub use Either::{Left, Right};

/// `Either` represents an alternative holding one value out of
/// either of the two possible values.
///
/// `Either` is a general purpose sum type of two parts. For representing
/// success or error, use the regular `Result<T, E>` instead.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub enum Either<L, R> {
    /// A value of type `L`.
    Left(L),
    /// A value of type `R`.
    Right(R),
}

macro_rules! either {
    ($value:expr, $inner:ident => $result:expr) => (
        match $value {
            Either::Left(ref $inner) => $result,
            Either::Right(ref $inner) => $result,
        }
    )
}

macro_rules! either_mut {
    ($value:expr, $inner:ident => $result:expr) => (
        match $value {
            Either::Left(ref mut $inner) => $result,
            Either::Right(ref mut $inner) => $result,
        }
    )
}

/// Macro for unwrapping the left side of an `Either`, which fails early
/// with the opposite side. Can only be used in functions that return
/// `Either` because of the early return of `Right` that it provides.
///
/// See also `try_right!` for its dual, which applies the same just to the
/// right side.
///
/// # Example
///
/// ```
/// # #[macro_use] extern crate either; use either::*; fn main() {
/// fn twice(wrapper: Either<u32, &str>) -> Either<u32, &str> {
///     let value = try_left!(wrapper);
///     Left(value * 2)
/// }
///
/// assert_eq!(twice(Left(2)), Left(4));
/// assert_eq!(twice(Right("ups")), Right("ups"));
/// # }
/// ```
#[macro_export]
macro_rules! try_left {
    ($expr:expr) => (
        match $expr {
            $crate::Left(val) => val,
            $crate::Right(err) => return $crate::Right(::std::convert::From::from(err))
        }
    )
}

/// Dual to `try_left!`, see its documentation for more information.
#[macro_export]
macro_rules! try_right {
    ($expr:expr) => (
        match $expr {
            $crate::Left(err) => return $crate::Left(::std::convert::From::from(err)),
            $crate::Right(val) => val
        }
    )
}

impl<L, R> Either<L, R> {
    pub fn is_left(&self) -> bool {
        match *self {
            Left(_) => true,
            Right(_) => false,
        }
    }

    pub fn is_right(&self) -> bool {
        !self.is_left()
    }

    pub fn left(self) -> Option<L> {
        match self {
            Left(l) => Some(l),
            Right(_) => None,
        }
    }

    pub fn right(self) -> Option<R> {
        match self {
            Left(_) => None,
            Right(r) => Some(r),
        }
    }

    pub fn as_ref(&self) -> Either<&L, &R> {
        match *self {
            Left(ref inner) => Left(inner),
            Right(ref inner) => Right(inner),
        }
    }

    pub fn as_mut(&mut self) -> Either<&mut L, &mut R> {
        match *self {
            Left(ref mut inner) => Left(inner),
            Right(ref mut inner) => Right(inner),
        }
    }

    pub fn flip(self) -> Either<R, L> {
        match self {
            Left(l) => Right(l),
            Right(r) => Left(r),
        }
    }
}

/// Convert from `Result` to `Either` with `Ok => Right` and `Err => Left`.
impl<L, R> From<Result<R, L>> for Either<L, R> {
    fn from(r: Result<R, L>) -> Self {
        match r {
            Err(e) => Left(e),
            Ok(o) => Right(o),
        }
    }
}

/// Convert from `Either` to `Result` with `Right => Ok` and `Left => Err`.
impl<L, R> Into<Result<R, L>> for Either<L, R> {
    fn into(self) -> Result<R, L> {
        match self {
            Left(l) => Err(l),
            Right(r) => Ok(r),
        }
    }
}

/// `Either<L, R>` is an iterator if both `L` and `R` are iterators.
impl<L, R> Iterator for Either<L, R>
    where L: Iterator, R: Iterator<Item=L::Item>
{
    type Item = L::Item;

    fn next(&mut self) -> Option<L::Item> {
        either_mut!(*self, inner => inner.next())
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        either!(*self, inner => inner.size_hint())
    }
}

impl<L, R> DoubleEndedIterator for Either<L, R>
    where L: DoubleEndedIterator, R: DoubleEndedIterator<Item=L::Item>
{
    fn next_back(&mut self) -> Option<L::Item> {
        either_mut!(*self, inner => inner.next_back())
    }
}

impl<L, R> ExactSizeIterator for Either<L, R>
    where L: ExactSizeIterator, R: ExactSizeIterator<Item=L::Item>
{
}

/// `Either<L, R>` implements `Read` if both `L` and `R` do.
impl<L, R> Read for Either<L, R>
    where L: Read, R: Read
{
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        either_mut!(*self, inner => inner.read(buf))
    }

    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
        either_mut!(*self, inner => inner.read_to_end(buf))
    }
}

impl<L, R> BufRead for Either<L, R>
    where L: BufRead, R: BufRead
{
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        either_mut!(*self, inner => inner.fill_buf())
    }

    fn consume(&mut self, amt: usize) {
        either_mut!(*self, inner => inner.consume(amt))
    }
}

/// `Either<L, R>` implements `Write` if both `L` and `R` do.
impl<L, R> Write for Either<L, R>
    where L: Write, R: Write
{
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        either_mut!(*self, inner => inner.write(buf))
    }

    fn flush(&mut self) -> io::Result<()> {
        either_mut!(*self, inner => inner.flush())
    }
}

impl<L, R, Target> AsRef<Target> for Either<L, R>
    where L: AsRef<Target>, R: AsRef<Target>
{
    fn as_ref(&self) -> &Target {
        either!(*self, inner => inner.as_ref())
    }
}

impl<L, R, Target> AsMut<Target> for Either<L, R>
    where L: AsMut<Target>, R: AsMut<Target>
{
    fn as_mut(&mut self) -> &mut Target {
        either_mut!(*self, inner => inner.as_mut())
    }
}

impl<L, R> Deref for Either<L, R>
    where L: Deref, R: Deref<Target=L::Target>
{
    type Target = L::Target;

    fn deref(&self) -> &Self::Target {
        either!(*self, inner => &*inner)
    }
}

impl<L, R> DerefMut for Either<L, R>
    where L: DerefMut, R: DerefMut<Target=L::Target>
{
    fn deref_mut(&mut self) -> &mut Self::Target {
        either_mut!(*self, inner => &mut *inner)
    }
}

#[test]
fn basic() {
    let mut e = Left(2);
    let r = Right(2);
    assert_eq!(e, Left(2));
    e = r;
    assert_eq!(e, Right(2));
    assert_eq!(e.left(), None);
    assert_eq!(e.right(), Some(2));
    assert_eq!(e.as_ref().right(), Some(&2));
    assert_eq!(e.as_mut().right(), Some(&mut 2));
}

#[test]
fn macros() {
    fn a() -> Either<u32, u32> {
        let x: u32 = try_left!(Right(1337));
        Left(x * 2)
    }
    assert_eq!(a(), Right(1337));

    fn b() -> Either<String, &'static str> {
        Right(try_right!(Left("foo bar")))
    }
    assert_eq!(b(), Left(String::from("foo bar")));
}

#[test]
fn deref() {
    fn is_str(_: &str) {}
    let value: Either<String, &str> = Left(String::from("test"));
    is_str(&*value);
}

#[test]
fn iter() {
    let x = 3;
    let mut iter = match x {
        1...3 => Left(0..10),
        _ => Right(17..),
    };

    assert_eq!(iter.next(), Some(0));
    assert_eq!(iter.count(), 9);
}

#[test]
fn read_write() {
    use std::io;

    let use_stdio = false;
    let mockdata = [0xff; 256];

    let mut reader = if use_stdio {
        Left(io::stdin())
    } else {
        Right(&mockdata[..])
    };

    let mut buf = [0u8; 16];
    assert_eq!(reader.read(&mut buf).unwrap(), buf.len());
    assert_eq!(&buf, &mockdata[..buf.len()]);

    let mut mockbuf = [0u8; 256];
    let mut writer = if use_stdio {
        Left(io::stdout())
    } else {
        Right(&mut mockbuf[..])
    };

    let buf = [1u8; 16];
    assert_eq!(writer.write(&buf).unwrap(), buf.len());
}
<|endoftext|>


<commit_before>#[cfg(feature = "chrono")]
extern crate chrono;
#[cfg(feature = "time")]
extern crate time;
#[cfg(feature = "approx")]
extern crate approx;

pub mod duration;
pub mod error;

pub use duration::*;
<commit_msg>Moved from glob `pub use` to specific items.<commit_after>#[cfg(feature = "chrono")]
extern crate chrono;
#[cfg(feature = "time")]
extern crate time;
#[cfg(feature = "approx")]
extern crate approx;

pub mod duration;
pub mod error;

pub use duration::{FloatDuration, TimePoint};
pub use duration::{NANOS_PER_SEC, MICROS_PER_SEC, MILLIS_PER_SEC, SECS_PER_MINUTE, SECS_PER_DAY,
                   SECS_PER_YEAR};
<|endoftext|>


<commit_before>use std::io::{self, Write};

pub use position::Position;
use bounds::Bounds;

pub mod position;
mod bounds;

pub trait Shape {
    fn bounds(&self) -> Bounds;
    fn write_eps(&self, wr: &mut Write) -> io::Result<()>;
}

pub struct Point(pub Position, pub f32);
pub struct Points(pub Vec<Position>, pub f32);
pub struct Line(pub Position, pub Position);

impl Shape for Point {
    fn bounds(&self) -> Bounds {
        let mut b = Bounds::new();
        b.add_position(self.0);
        b
    }

    fn write_eps(&self, wr: &mut Write) -> io::Result<()> {
        writeln!(wr,
                 "newpath {} {} {} 0 360 arc fill",
                 self.0.x,
                 self.0.y,
                 self.1)
    }
}

impl Shape for Points {
    fn bounds(&self) -> Bounds {
        let mut b = Bounds::new();
        for &pos in &self.0 {
            b.add_position(pos);
        }
        b
    }

    fn write_eps(&self, wr: &mut Write) -> io::Result<()> {
        try!(writeln!(wr,
                      "/p {{
2 dict begin
/y exch def
/x exch def
gsave
newpath x y {} 0 360 \
                       arc fill
grestore
end
}} def",
                      self.1));
        for pos in &self.0 {
            try!(writeln!(wr, "{} {} p", pos.x, pos.y));
        }

        Ok(())
    }
}

impl Shape for Line {
    fn bounds(&self) -> Bounds {
        let mut b = Bounds::new();
        b.add_position(self.0);
        b.add_position(self.1);
        b
    }

    fn write_eps(&self, wr: &mut Write) -> io::Result<()> {
        writeln!(wr,
                 "newpath {} {} moveto {} {} lineto stroke",
                 self.0.x,
                 self.0.y,
                 self.1.x,
                 self.1.y)
    }
}

pub struct EpsDocument {
    shapes: Vec<Box<Shape>>,
}

impl EpsDocument {
    pub fn new() -> EpsDocument {
        EpsDocument { shapes: Vec::new() }
    }

    pub fn add_shape(&mut self, shape: Box<Shape>) {
        self.shapes.push(shape);
    }

    /// Write as Embedded Postscript (EPS)
    pub fn write_eps(&self, wr: &mut Write, min_width: f32, min_height: f32) -> io::Result<()> {
        // Determine extend of canvas
        let mut bounds = Bounds::new();

        for shape in &self.shapes {
            bounds.extend(shape.bounds());
        }

        let width = bounds.width().max(min_width);
        let height = bounds.height().max(min_height);
        let border_percent = 0.1;

        let scale = 1.0 + 2.0 * border_percent;

        try!(writeln!(wr,
                      r#"%%!PS-Adobe-3.0 EPSF-3.0
%%Creator: https://github.com/mneumann/eps-writer-rs
%%DocumentData: Clean7Bit
%%Origin: 0 0
%%BoundingBox: {} {} {} {}
%%LanguageLevel: 2
%%Pages: 1
%%Page: 1 1
"#,
                      bounds.min_x() - border_percent * width,
                      bounds.min_y() - border_percent * height,
                      bounds.max_x() + border_percent * width,
                      bounds.max_y() + border_percent * height));

        // use a stroke width of 0.1% of the width or height of the canvas
        let stroke_width = scale * width.max(height) / 1000.0;
        try!(writeln!(wr, r#"{} setlinewidth"#, stroke_width));

        for shape in &self.shapes {
            try!(shape.write_eps(wr));
        }

        writeln!(wr, "%%EOF")
    }
}
<commit_msg>Limit precision to 4<commit_after>use std::io::{self, Write};

pub use position::Position;
use bounds::Bounds;

pub mod position;
mod bounds;

pub trait Shape {
    fn bounds(&self) -> Bounds;
    fn write_eps(&self, wr: &mut Write) -> io::Result<()>;
}

pub struct Point(pub Position, pub f32);
pub struct Points(pub Vec<Position>, pub f32);
pub struct Line(pub Position, pub Position);

impl Shape for Point {
    fn bounds(&self) -> Bounds {
        let mut b = Bounds::new();
        b.add_position(self.0);
        b
    }

    fn write_eps(&self, wr: &mut Write) -> io::Result<()> {
        writeln!(wr,
                 "newpath {} {} {} 0 360 arc fill",
                 self.0.x,
                 self.0.y,
                 self.1)
    }
}

impl Shape for Points {
    fn bounds(&self) -> Bounds {
        let mut b = Bounds::new();
        for &pos in &self.0 {
            b.add_position(pos);
        }
        b
    }

    fn write_eps(&self, wr: &mut Write) -> io::Result<()> {
        try!(writeln!(wr,
                      "/p {{
2 dict begin
/y exch def
/x exch def
gsave
newpath x y {} 0 360 \
                       arc fill
grestore
end
}} def",
                      self.1));
        for pos in &self.0 {
            try!(writeln!(wr, "{:.4} {:.4} p", pos.x, pos.y));
        }

        Ok(())
    }
}

impl Shape for Line {
    fn bounds(&self) -> Bounds {
        let mut b = Bounds::new();
        b.add_position(self.0);
        b.add_position(self.1);
        b
    }

    fn write_eps(&self, wr: &mut Write) -> io::Result<()> {
        writeln!(wr,
                 "newpath {} {} moveto {} {} lineto stroke",
                 self.0.x,
                 self.0.y,
                 self.1.x,
                 self.1.y)
    }
}

pub struct EpsDocument {
    shapes: Vec<Box<Shape>>,
}

impl EpsDocument {
    pub fn new() -> EpsDocument {
        EpsDocument { shapes: Vec::new() }
    }

    pub fn add_shape(&mut self, shape: Box<Shape>) {
        self.shapes.push(shape);
    }

    /// Write as Embedded Postscript (EPS)
    pub fn write_eps(&self, wr: &mut Write, min_width: f32, min_height: f32) -> io::Result<()> {
        // Determine extend of canvas
        let mut bounds = Bounds::new();

        for shape in &self.shapes {
            bounds.extend(shape.bounds());
        }

        let width = bounds.width().max(min_width);
        let height = bounds.height().max(min_height);
        let border_percent = 0.1;

        let scale = 1.0 + 2.0 * border_percent;

        try!(writeln!(wr,
                      r#"%%!PS-Adobe-3.0 EPSF-3.0
%%Creator: https://github.com/mneumann/eps-writer-rs
%%DocumentData: Clean7Bit
%%Origin: 0 0
%%BoundingBox: {} {} {} {}
%%LanguageLevel: 2
%%Pages: 1
%%Page: 1 1
"#,
                      bounds.min_x() - border_percent * width,
                      bounds.min_y() - border_percent * height,
                      bounds.max_x() + border_percent * width,
                      bounds.max_y() + border_percent * height));

        // use a stroke width of 0.1% of the width or height of the canvas
        let stroke_width = scale * width.max(height) / 1000.0;
        try!(writeln!(wr, r#"{} setlinewidth"#, stroke_width));

        for shape in &self.shapes {
            try!(shape.write_eps(wr));
        }

        writeln!(wr, "%%EOF")
    }
}
<|endoftext|>


<commit_before>#![feature(plugin)]
#![plugin(interpolate_idents)]

#[macro_use]
extern crate apache2;

#[macro_use]
mod code;

use apache2::{Request, Status, HookOrder};

use code::{STYLESHEET, SCRIPT};

apache2_module!(parallax, b"mod_parallax\0", handlers {
   (parallax_handler, handler, HookOrder::MIDDLE),
   (js_handler, handler, HookOrder::MIDDLE)
});

fn parallax_handler(r: &mut Request) -> Result<Status, ()> {
   if try!(r.handler()) != "parallax" {
      return Ok(Status::DECLINED)
   }

   r.set_content_type("text/html");

   try!(r.write(format!(
      html_template!(),
      STYLESHEET,
      SCRIPT
   )));

   Ok(Status::OK)
}

fn js_handler(r: &mut Request) -> Result<Status, ()> {
   if try!(r.handler()) != "js" {
      return Ok(Status::DECLINED)
   }

   r.set_content_type("text/plain");

   try!(r.write("JS"));

   Ok(Status::OK)
}
<commit_msg>Tracking apache2-rs return value changes.<commit_after>#![feature(plugin)]
#![plugin(interpolate_idents)]

#[macro_use]
extern crate apache2;

#[macro_use]
mod code;

use apache2::{Request, Status, HookOrder};

use code::{STYLESHEET, SCRIPT};

apache2_module!(parallax, b"mod_parallax\0", handlers {
   (parallax_handler, handler, HookOrder::MIDDLE),
   (js_handler, handler, HookOrder::MIDDLE)
});

fn parallax_handler(r: &mut Request) -> Result<Status, ()> {
   if get!(r.handler()) != "parallax" {
      return Ok(Status::DECLINED)
   }

   r.set_content_type("text/html");

   try!(r.write(format!(
      html_template!(),
      STYLESHEET,
      SCRIPT
   )));

   Ok(Status::OK)
}

fn js_handler(r: &mut Request) -> Result<Status, ()> {
   if get!(r.handler()) != "js" {
      return Ok(Status::DECLINED)
   }

   r.set_content_type("text/plain");

   try!(r.write("JS"));

   Ok(Status::OK)
}
<|endoftext|>


<commit_before>#![deny(missing_docs)]

//! A Gfx texture representation that works nicely with Piston libraries.

extern crate gfx;
extern crate gfx_core;
extern crate texture;
extern crate image;

pub use texture::*;

use std::path::Path;
use image::{
    DynamicImage,
    RgbaImage,
};
use gfx::format::{Srgba8, R8_G8_B8_A8};

/// Context required to create and update textures.
pub struct TextureContext<F, R, C>
    where F: gfx::Factory<R>,
          R: gfx::Resources,
          C: gfx::CommandBuffer<R>,
{
    /// A factory to create textures.
    pub factory: F,
    /// An encoder to update textures.
    pub encoder: gfx::Encoder<R, C>,
}

/// Create creation or update error.
#[derive(Debug, Clone, PartialEq)]
pub enum Error {
    /// An error when creating texture.
    Create(gfx::CombinedError),
    /// An error when updating texture.
    Update(gfx::UpdateError<[u16; 3]>),
}

impl From<gfx::UpdateError<[u16; 3]>> for Error {
    fn from(val: gfx::UpdateError<[u16; 3]>) -> Error {
        Error::Update(val)
    }
}

impl From<gfx::texture::CreationError> for Error {
    fn from(val: gfx::texture::CreationError) -> Error {
        Error::Create(val.into())
    }
}

impl From<gfx::ResourceViewError> for Error {
    fn from(val: gfx::ResourceViewError) -> Error {
        Error::Create(val.into())
    }
}

impl std::fmt::Display for Error {
    fn fmt(&self, w: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
        use std::fmt::{Display, Debug};

        match *self {
            Error::Create(ref err) => Display::fmt(err, w),
            Error::Update(ref err) => Debug::fmt(err, w),
        }
    }
}

impl std::error::Error for Error {}

/// Flip settings.
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub enum Flip {
    /// Does not flip.
    None,
    /// Flips image vertically.
    Vertical,
    /// Flips image horizontally.
    Horizontal,
    /// Flips image both vertically and horizontally.
    Both,
}

/// Represents a texture.
#[derive(Clone, Debug, PartialEq)]
pub struct Texture<R> where R: gfx::Resources {
    /// Pixel storage for texture.
    pub surface: gfx::handle::Texture<R, R8_G8_B8_A8>,
    /// Sampler for texture.
    pub sampler: gfx::handle::Sampler<R>,
    /// View used by shader.
    pub view: gfx::handle::ShaderResourceView<R, [f32; 4]>
}

impl<R: gfx::Resources> Texture<R> {
    /// Returns empty texture.
    pub fn empty<F, C>(context: &mut TextureContext<F, R, C>) -> Result<Self, Error>
        where F: gfx::Factory<R>,
              C: gfx::CommandBuffer<R>,
    {
        CreateTexture::create(context, Format::Rgba8, &[0u8; 4], [1, 1],
                              &TextureSettings::new())
    }

    /// Creates a texture from path.
    pub fn from_path<F, C, P>(
        context: &mut TextureContext<F, R, C>,
        path: P,
        flip: Flip,
        settings: &TextureSettings,
    ) -> Result<Self, Error>
        where F: gfx::Factory<R>,
              C: gfx::CommandBuffer<R>,
              P: AsRef<Path>
    {
        let img = image::open(path).map_err(|e| e.to_string())?;

        let img = match img {
            DynamicImage::ImageRgba8(img) => img,
            img => img.to_rgba8()
        };

        let img = match flip {
            Flip::Vertical => image::imageops::flip_vertical(&img),
            Flip::Horizontal => image::imageops::flip_horizontal(&img),
            Flip::Both => {
                let img = image::imageops::flip_vertical(&img);
                image::imageops::flip_horizontal(&img)
            }
            Flip::None => img,
        };

        Texture::from_image(context, &img, settings)
    }

    /// Creates a texture from image.
    pub fn from_image<F, C>(
        context: &mut TextureContext<F, R, C>,
        img: &RgbaImage,
        settings: &TextureSettings
    ) -> Result<Self, Error>
        where F: gfx::Factory<R>,
              C: gfx::CommandBuffer<R>,
    {
        let (width, height) = img.dimensions();
        CreateTexture::create(context, Format::Rgba8,
                              img, [width, height], settings)
    }

    /// Creates texture from memory alpha.
    pub fn from_memory_alpha<F, C>(
        context: &mut TextureContext<F, R, C>,
        buffer: &[u8],
        width: u32,
        height: u32,
        settings: &TextureSettings
    ) -> Result<Self, Error>
        where F: gfx::Factory<R>,
              C: gfx::CommandBuffer<R>,
    {
        if width == 0 || height == 0 {
            return Texture::empty(context);
        }

        let size = [width, height];
        let buffer = texture::ops::alpha_to_rgba8(buffer, size);
        CreateTexture::create(context, Format::Rgba8, &buffer, size, settings)
    }

    /// Updates the texture with an image.
    pub fn update<F, C>(
        &mut self,
        context: &mut TextureContext<F, R, C>,
        img: &RgbaImage
    ) -> Result<(), Error>
        where F: gfx::Factory<R>,
              C: gfx::CommandBuffer<R>
    {
        let (width, height) = img.dimensions();
        let offset = [0, 0];
        let size = [width, height];
        UpdateTexture::update(self, context, Format::Rgba8, img, offset, size)
    }
}

impl<F, R> TextureOp<F> for Texture<R> where R: gfx::Resources {
    type Error = Error;
}

impl<F, R, C> CreateTexture<TextureContext<F, R, C>> for Texture<R>
    where F: gfx::Factory<R>,
          R: gfx::Resources,
          C: gfx::CommandBuffer<R>,
{
    fn create<S: Into<[u32; 2]>>(
        context: &mut TextureContext<F, R, C>,
        _format: Format,
        memory: &[u8],
        size: S,
        settings: &TextureSettings
    ) -> Result<Self, Self::Error> {
        let factory = &mut context.factory;
        // Modified `Factory::create_texture_immutable_u8` for dynamic texture.
        fn create_texture<T, F, R>(
            factory: &mut F,
            kind: gfx::texture::Kind,
            data: &[&[u8]]
        ) -> Result<(
            gfx::handle::Texture<R, T::Surface>,
            gfx::handle::ShaderResourceView<R, T::View>
        ), Error>
            where F: gfx::Factory<R>,
                  R: gfx::Resources,
                  T: gfx::format::TextureFormat
        {
            use gfx::{format, texture};
            use gfx::memory::{Usage, Bind};
            use gfx_core::memory::Typed;
            use gfx_core::texture::Mipmap;

            let surface = <T::Surface as format::SurfaceTyped>::get_surface_type();
            let num_slices = kind.get_num_slices().unwrap_or(1) as usize;
            let num_faces = if kind.is_cube() {6} else {1};
            let desc = texture::Info {
                kind: kind,
                levels: (data.len() / (num_slices * num_faces)) as texture::Level,
                format: surface,
                bind: Bind::SHADER_RESOURCE,
                usage: Usage::Dynamic,
            };
            let cty = <T::Channel as format::ChannelTyped>::get_channel_type();
            let raw = factory.create_texture_raw(desc, Some(cty), Some((data, Mipmap::Provided)))?;
            let levels = (0, raw.get_info().levels - 1);
            let tex = Typed::new(raw);
            let view = factory.view_texture_as_shader_resource::<T>(
                &tex, levels, format::Swizzle::new())?;
            Ok((tex, view))
        }

        let size = size.into();
        let (width, height) = (size[0] as u16, size[1] as u16);
        let tex_kind = gfx::texture::Kind::D2(width, height,
            gfx::texture::AaMode::Single);

        // FIXME Use get_min too. gfx has only one filter setting for both.
        let filter_method = match settings.get_mag() {
            texture::Filter::Nearest => gfx::texture::FilterMethod::Scale,
            texture::Filter::Linear => gfx::texture::FilterMethod::Bilinear,
        };

        let wrap_mode_u = match settings.get_wrap_u() {
            Wrap::ClampToEdge => gfx::texture::WrapMode::Clamp,
            Wrap::ClampToBorder => gfx::texture::WrapMode::Border,
            Wrap::Repeat => gfx::texture::WrapMode::Tile,
            Wrap::MirroredRepeat => gfx::texture::WrapMode::Mirror,
        };

        let wrap_mode_v = match settings.get_wrap_v() {
            Wrap::ClampToEdge => gfx::texture::WrapMode::Clamp,
            Wrap::ClampToBorder => gfx::texture::WrapMode::Border,
            Wrap::Repeat => gfx::texture::WrapMode::Tile,
            Wrap::MirroredRepeat => gfx::texture::WrapMode::Mirror,
        };

        let mut sampler_info = gfx::texture::SamplerInfo::new(
            filter_method,
            wrap_mode_u
        );
        sampler_info.wrap_mode.1 = wrap_mode_v;
        sampler_info.border = settings.get_border_color().into();

        let (surface, view) = create_texture::<Srgba8, F, R>(
            factory, tex_kind, &[memory])?;
        let sampler = factory.create_sampler(sampler_info);
        Ok(Texture { surface: surface, sampler: sampler, view: view })
    }
}

impl<F, R, C> UpdateTexture<TextureContext<F, R, C>> for Texture<R>
    where F: gfx::Factory<R>,
          R: gfx::Resources,
          C: gfx::CommandBuffer<R>
{
    fn update<O, S>(
        &mut self,
        context: &mut TextureContext<F, R, C>,
        format: Format,
        memory: &[u8],
        offset: O,
        size: S,
    ) -> Result<(), Self::Error>
        where O: Into<[u32; 2]>,
              S: Into<[u32; 2]>,
    {
        let encoder = &mut context.encoder;
        let offset = offset.into();
        let size = size.into();
        let tex = &self.surface;
        let face = None;
        let img_info = gfx::texture::ImageInfoCommon {
            xoffset: offset[0] as u16,
            yoffset: offset[1] as u16,
            zoffset: 0,
            width: size[0] as u16,
            height: size[1] as u16,
            depth: 0,
            format: (),
            mipmap: 0,
        };
        let data = gfx::memory::cast_slice(memory);

        match format {
            Format::Rgba8 => {
                use gfx::format::Rgba8;
                encoder.update_texture::<_, Rgba8>(tex, face, img_info, data).map_err(Into::into)
            },
        }
    }
}

impl<R> ImageSize for Texture<R> where R: gfx::Resources {
    #[inline(always)]
    fn get_size(&self) -> (u32, u32) {
        let (w, h, _, _) = self.surface.get_info().kind.get_dimensions();
        (w as u32, h as u32)
    }
}
<commit_msg>Fixed build error<commit_after>#![deny(missing_docs)]

//! A Gfx texture representation that works nicely with Piston libraries.

extern crate gfx;
extern crate gfx_core;
extern crate texture;
extern crate image;

pub use texture::*;

use std::path::Path;
use image::{
    DynamicImage,
    ImageError,
    RgbaImage,
};
use gfx::format::{Srgba8, R8_G8_B8_A8};

/// Context required to create and update textures.
pub struct TextureContext<F, R, C>
    where F: gfx::Factory<R>,
          R: gfx::Resources,
          C: gfx::CommandBuffer<R>,
{
    /// A factory to create textures.
    pub factory: F,
    /// An encoder to update textures.
    pub encoder: gfx::Encoder<R, C>,
}

/// Create creation or update error.
#[derive(Debug, Clone, PartialEq)]
pub enum Error {
    /// An error when creating texture.
    Create(gfx::CombinedError),
    /// An error when updating texture.
    Update(gfx::UpdateError<[u16; 3]>),
    /// An error when performing an image operation.
    Image(String),
}

impl From<gfx::UpdateError<[u16; 3]>> for Error {
    fn from(val: gfx::UpdateError<[u16; 3]>) -> Error {
        Error::Update(val)
    }
}

impl From<gfx::texture::CreationError> for Error {
    fn from(val: gfx::texture::CreationError) -> Error {
        Error::Create(val.into())
    }
}

impl From<ImageError> for Error {
    fn from(val: ImageError) -> Error {
        Error::Image(val.to_string())
    }
}

impl From<gfx::ResourceViewError> for Error {
    fn from(val: gfx::ResourceViewError) -> Error {
        Error::Create(val.into())
    }
}

impl std::fmt::Display for Error {
    fn fmt(&self, w: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
        use std::fmt::{Display, Debug};

        match *self {
            Error::Create(ref err) => Display::fmt(err, w),
            Error::Update(ref err) => Debug::fmt(err, w),
            Error::Image(ref err) => Display::fmt(err, w),
        }
    }
}

impl std::error::Error for Error {}

/// Flip settings.
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub enum Flip {
    /// Does not flip.
    None,
    /// Flips image vertically.
    Vertical,
    /// Flips image horizontally.
    Horizontal,
    /// Flips image both vertically and horizontally.
    Both,
}

/// Represents a texture.
#[derive(Clone, Debug, PartialEq)]
pub struct Texture<R> where R: gfx::Resources {
    /// Pixel storage for texture.
    pub surface: gfx::handle::Texture<R, R8_G8_B8_A8>,
    /// Sampler for texture.
    pub sampler: gfx::handle::Sampler<R>,
    /// View used by shader.
    pub view: gfx::handle::ShaderResourceView<R, [f32; 4]>
}

impl<R: gfx::Resources> Texture<R> {
    /// Returns empty texture.
    pub fn empty<F, C>(context: &mut TextureContext<F, R, C>) -> Result<Self, Error>
        where F: gfx::Factory<R>,
              C: gfx::CommandBuffer<R>,
    {
        CreateTexture::create(context, Format::Rgba8, &[0u8; 4], [1, 1],
                              &TextureSettings::new())
    }

    /// Creates a texture from path.
    pub fn from_path<F, C, P>(
        context: &mut TextureContext<F, R, C>,
        path: P,
        flip: Flip,
        settings: &TextureSettings,
    ) -> Result<Self, Error>
        where F: gfx::Factory<R>,
              C: gfx::CommandBuffer<R>,
              P: AsRef<Path>
    {
        let img = image::open(path)?;

        let img = match img {
            DynamicImage::ImageRgba8(img) => img,
            img => img.to_rgba8()
        };

        let img = match flip {
            Flip::Vertical => image::imageops::flip_vertical(&img),
            Flip::Horizontal => image::imageops::flip_horizontal(&img),
            Flip::Both => {
                let img = image::imageops::flip_vertical(&img);
                image::imageops::flip_horizontal(&img)
            }
            Flip::None => img,
        };

        Texture::from_image(context, &img, settings)
    }

    /// Creates a texture from image.
    pub fn from_image<F, C>(
        context: &mut TextureContext<F, R, C>,
        img: &RgbaImage,
        settings: &TextureSettings
    ) -> Result<Self, Error>
        where F: gfx::Factory<R>,
              C: gfx::CommandBuffer<R>,
    {
        let (width, height) = img.dimensions();
        CreateTexture::create(context, Format::Rgba8,
                              img, [width, height], settings)
    }

    /// Creates texture from memory alpha.
    pub fn from_memory_alpha<F, C>(
        context: &mut TextureContext<F, R, C>,
        buffer: &[u8],
        width: u32,
        height: u32,
        settings: &TextureSettings
    ) -> Result<Self, Error>
        where F: gfx::Factory<R>,
              C: gfx::CommandBuffer<R>,
    {
        if width == 0 || height == 0 {
            return Texture::empty(context);
        }

        let size = [width, height];
        let buffer = texture::ops::alpha_to_rgba8(buffer, size);
        CreateTexture::create(context, Format::Rgba8, &buffer, size, settings)
    }

    /// Updates the texture with an image.
    pub fn update<F, C>(
        &mut self,
        context: &mut TextureContext<F, R, C>,
        img: &RgbaImage
    ) -> Result<(), Error>
        where F: gfx::Factory<R>,
              C: gfx::CommandBuffer<R>
    {
        let (width, height) = img.dimensions();
        let offset = [0, 0];
        let size = [width, height];
        UpdateTexture::update(self, context, Format::Rgba8, img, offset, size)
    }
}

impl<F, R> TextureOp<F> for Texture<R> where R: gfx::Resources {
    type Error = Error;
}

impl<F, R, C> CreateTexture<TextureContext<F, R, C>> for Texture<R>
    where F: gfx::Factory<R>,
          R: gfx::Resources,
          C: gfx::CommandBuffer<R>,
{
    fn create<S: Into<[u32; 2]>>(
        context: &mut TextureContext<F, R, C>,
        _format: Format,
        memory: &[u8],
        size: S,
        settings: &TextureSettings
    ) -> Result<Self, Self::Error> {
        let factory = &mut context.factory;
        // Modified `Factory::create_texture_immutable_u8` for dynamic texture.
        fn create_texture<T, F, R>(
            factory: &mut F,
            kind: gfx::texture::Kind,
            data: &[&[u8]]
        ) -> Result<(
            gfx::handle::Texture<R, T::Surface>,
            gfx::handle::ShaderResourceView<R, T::View>
        ), Error>
            where F: gfx::Factory<R>,
                  R: gfx::Resources,
                  T: gfx::format::TextureFormat
        {
            use gfx::{format, texture};
            use gfx::memory::{Usage, Bind};
            use gfx_core::memory::Typed;
            use gfx_core::texture::Mipmap;

            let surface = <T::Surface as format::SurfaceTyped>::get_surface_type();
            let num_slices = kind.get_num_slices().unwrap_or(1) as usize;
            let num_faces = if kind.is_cube() {6} else {1};
            let desc = texture::Info {
                kind: kind,
                levels: (data.len() / (num_slices * num_faces)) as texture::Level,
                format: surface,
                bind: Bind::SHADER_RESOURCE,
                usage: Usage::Dynamic,
            };
            let cty = <T::Channel as format::ChannelTyped>::get_channel_type();
            let raw = factory.create_texture_raw(desc, Some(cty), Some((data, Mipmap::Provided)))?;
            let levels = (0, raw.get_info().levels - 1);
            let tex = Typed::new(raw);
            let view = factory.view_texture_as_shader_resource::<T>(
                &tex, levels, format::Swizzle::new())?;
            Ok((tex, view))
        }

        let size = size.into();
        let (width, height) = (size[0] as u16, size[1] as u16);
        let tex_kind = gfx::texture::Kind::D2(width, height,
            gfx::texture::AaMode::Single);

        // FIXME Use get_min too. gfx has only one filter setting for both.
        let filter_method = match settings.get_mag() {
            texture::Filter::Nearest => gfx::texture::FilterMethod::Scale,
            texture::Filter::Linear => gfx::texture::FilterMethod::Bilinear,
        };

        let wrap_mode_u = match settings.get_wrap_u() {
            Wrap::ClampToEdge => gfx::texture::WrapMode::Clamp,
            Wrap::ClampToBorder => gfx::texture::WrapMode::Border,
            Wrap::Repeat => gfx::texture::WrapMode::Tile,
            Wrap::MirroredRepeat => gfx::texture::WrapMode::Mirror,
        };

        let wrap_mode_v = match settings.get_wrap_v() {
            Wrap::ClampToEdge => gfx::texture::WrapMode::Clamp,
            Wrap::ClampToBorder => gfx::texture::WrapMode::Border,
            Wrap::Repeat => gfx::texture::WrapMode::Tile,
            Wrap::MirroredRepeat => gfx::texture::WrapMode::Mirror,
        };

        let mut sampler_info = gfx::texture::SamplerInfo::new(
            filter_method,
            wrap_mode_u
        );
        sampler_info.wrap_mode.1 = wrap_mode_v;
        sampler_info.border = settings.get_border_color().into();

        let (surface, view) = create_texture::<Srgba8, F, R>(
            factory, tex_kind, &[memory])?;
        let sampler = factory.create_sampler(sampler_info);
        Ok(Texture { surface: surface, sampler: sampler, view: view })
    }
}

impl<F, R, C> UpdateTexture<TextureContext<F, R, C>> for Texture<R>
    where F: gfx::Factory<R>,
          R: gfx::Resources,
          C: gfx::CommandBuffer<R>
{
    fn update<O, S>(
        &mut self,
        context: &mut TextureContext<F, R, C>,
        format: Format,
        memory: &[u8],
        offset: O,
        size: S,
    ) -> Result<(), Self::Error>
        where O: Into<[u32; 2]>,
              S: Into<[u32; 2]>,
    {
        let encoder = &mut context.encoder;
        let offset = offset.into();
        let size = size.into();
        let tex = &self.surface;
        let face = None;
        let img_info = gfx::texture::ImageInfoCommon {
            xoffset: offset[0] as u16,
            yoffset: offset[1] as u16,
            zoffset: 0,
            width: size[0] as u16,
            height: size[1] as u16,
            depth: 0,
            format: (),
            mipmap: 0,
        };
        let data = gfx::memory::cast_slice(memory);

        match format {
            Format::Rgba8 => {
                use gfx::format::Rgba8;
                encoder.update_texture::<_, Rgba8>(tex, face, img_info, data).map_err(Into::into)
            },
        }
    }
}

impl<R> ImageSize for Texture<R> where R: gfx::Resources {
    #[inline(always)]
    fn get_size(&self) -> (u32, u32) {
        let (w, h, _, _) = self.surface.get_info().kind.get_dimensions();
        (w as u32, h as u32)
    }
}
<|endoftext|>


<commit_before>extern crate git2;
// TODO: Investigate ansi_term crate.  https://crates.io/crates/ansi_term

use std::path::Path;
// use std::path::PathBuf;
use std::fmt::Write;

pub struct GitPromptRepo {
    lg2_repo: Option<git2::Repository>,
    // origin_path: PathBuf,
    // root_path: PathBuf,
    repo_state: git2::RepositoryState,
    is_unborn: bool,
    has_head: bool,
    has_checkout: bool,
}

impl GitPromptRepo {
    pub fn new(path_spec: &Path) -> GitPromptRepo {
        let lg2_repo = git2::Repository::discover(path_spec).ok();
        // let mut root_path = PathBuf::new();
        let mut repo_state = git2::RepositoryState::Clean;
        let mut is_unborn = false;
        let mut has_head = false;
        let mut has_checkout = false;

        if let Some(ref repo) = lg2_repo {
            // root_path = repo.path().to_path_buf();
            repo_state = repo.state();
            if let Err(e) = repo.head() {
                is_unborn = e.code() == git2::ErrorCode::UnbornBranch;
            } else {
                has_head = true;
            }
            has_checkout = !repo.is_bare();
        }

        GitPromptRepo {
            lg2_repo: lg2_repo,
            // origin_path: path_spec.to_path_buf(),
            // root_path: root_path,
            repo_state: repo_state,
            is_unborn: is_unborn,
            has_head: has_head,
            has_checkout: has_checkout,
        }
    }

    // Assumes has_head is true
    fn head_name(&self) -> String {
        self.lg2_repo
            .as_ref()
            .unwrap()
            .head()
            .unwrap()
            .name()
            .unwrap_or("")
            .trim_left_matches("refs/heads/")
            .to_string()
    }

    fn head_to_branch(&self) -> Option<git2::Branch> {
        if self.has_head {
            let head_name = self.head_name();
            return self.lg2_repo
                .as_ref()
                .unwrap()
                .find_branch(head_name.as_str(), git2::BranchType::Local)
                .ok();
        }
        None
    }

    fn head_branch_has_upstream(&self) -> bool {
        if let Some(branch) = self.head_to_branch() {
            return branch.upstream().is_ok();
        }
        false
    }

    // fn is_remote(&self) -> bool {
    //     match &self.ref_result {
    //         &Ok(ref r) => r.is_remote(),
    //         &Err(_) => false
    //     }
    // }

    fn build_ref_name_for_commit(&self, commit: &git2::Commit, ref_string: &mut String) {
        let oid = commit.id();
        let mut candidate_branch_names = Vec::new();
        let branches_it = self.lg2_repo
            .as_ref()
            .unwrap()
            .branches(Some(git2::BranchType::Remote))
            .unwrap()
            .filter_map(|branch_result| branch_result.ok());
        for branch in branches_it {
            let ref branch_ref = branch.0.get();
            let peeled_obj_res = branch_ref.peel(git2::ObjectType::Commit);
            if peeled_obj_res.is_ok() && peeled_obj_res.unwrap().id() == oid &&
                branch_ref.name().is_some()
            {
                candidate_branch_names.push(branch_ref.name().unwrap().to_string());
            }
        }
        ref_string.clear();
        if candidate_branch_names.is_empty() {
            let mut oid_string = "".to_string();
            write!(oid_string, "{}", oid).unwrap();
            oid_string.truncate(8);
            write!(ref_string, "{}", oid_string).unwrap();
        } else {
            write!(
                ref_string,
                "{}",
                find_best_branch_name(candidate_branch_names)
            ).unwrap();
        }
    }

    pub fn ref_name_head(&self) -> String {
        let mut ref_string = "".to_string();
        // TODO: should check more repo_state possibilities
        if self.is_unborn {
            ref_string = "[Unborn]".to_string();
        } else if self.repo_state == git2::RepositoryState::Rebase ||
                   self.repo_state == git2::RepositoryState::RebaseInteractive ||
                   self.repo_state == git2::RepositoryState::RebaseMerge
        {
            // TODO: Should look at .git/rebase-apply/head-name rather than
            // compute rebasing_name as we do here
            if let Ok(rebasing_ref) = self.lg2_repo.as_ref().unwrap().find_reference(
                "rebase-apply/orig-head",
            )
            {
                let onto_ref = self.lg2_repo
                    .as_ref()
                    .unwrap()
                    .find_reference("rebase-apply/onto")
                    .unwrap();
                let mut rebasing_name = String::new();
                let mut onto_name = String::new();
                self.build_ref_name_for_commit(
                    rebasing_ref
                        .peel(git2::ObjectType::Commit)
                        .unwrap()
                        .as_commit()
                        .unwrap(),
                    &mut rebasing_name,
                );
                self.build_ref_name_for_commit(
                    onto_ref
                        .peel(git2::ObjectType::Commit)
                        .unwrap()
                        .as_commit()
                        .unwrap(),
                    &mut onto_name,
                );
                write!(
                    ref_string,
                    "\x1b[1;35m...rebasing\x1b[0m {} \x1b[1;35monto\x1b[0m {}",
                    rebasing_name,
                    onto_name
                ).unwrap();
            } else {
                write!(ref_string, "unhandled rebase case").unwrap();
            }
        } else if self.has_head {
            ref_string = self.head_name();
        }
        if ref_string == "HEAD" {
            let head_object = self.lg2_repo
                .as_ref()
                .unwrap()
                .head()
                .unwrap()
                .resolve()
                .unwrap()
                .peel(git2::ObjectType::Commit)
                .unwrap();
            let head_commit = head_object.as_commit().unwrap();
            self.build_ref_name_for_commit(head_commit, &mut ref_string);
        }
        ref_string.to_string()
    }

    pub fn upstream_name(&self) -> String {
        if self.head_branch_has_upstream() {
            let branch = self.head_to_branch().unwrap();
            let upstream_branch = branch.upstream().unwrap();
            if let Ok(Some(name)) = upstream_branch.name() {
                return name.to_string();
            }
        }
        "".to_string()
    }

    pub fn ahead_behind(&self) -> String {
        let mut result = String::from("");
        if self.head_branch_has_upstream() {
            let head_branch = self.head_to_branch().unwrap();
            let upstream_branch = head_branch.upstream().unwrap();
            let head_branch_oid = head_branch.get().resolve().unwrap().target().unwrap();
            let upstream_branch_oid = upstream_branch.get().resolve().unwrap().target().unwrap();
            let repo = self.lg2_repo.as_ref().unwrap();
            let (ahead, behind) = repo.graph_ahead_behind(head_branch_oid, upstream_branch_oid)
                .unwrap();
            if behind > 0 {
                result += "↓·";
                result += &*behind.to_string();
            }
            if ahead > 0 {
                result += "↑·";
                result += &*ahead.to_string();
            }
        }
        result
    }

    pub fn status(&self) -> String {
        let mut result = String::from("");
        if self.has_checkout {
            let mut opts = git2::StatusOptions::new();
            if let Ok(statuses) = self.lg2_repo.as_ref().unwrap().statuses(Some(
                opts.update_index(true)
                    .include_untracked(true)
                    .recurse_untracked_dirs(true),
            ))
            {
                result += &status_bit_to_string(&statuses, git2::STATUS_INDEX_MODIFIED, "∂");
                result += &status_bit_to_string(&statuses, git2::STATUS_INDEX_NEW, "…");
                result += &status_bit_to_string(&statuses, git2::STATUS_INDEX_DELETED, "✖");
                result +=
                    &status_bit_to_string(&statuses, git2::STATUS_CONFLICTED, "\x1b[31;1m≠");
                result += &status_bit_to_string(&statuses, git2::STATUS_WT_MODIFIED, "\x1b[34m∂");
                result += &status_bit_to_string(&statuses, git2::STATUS_WT_NEW, "\x1b[34m…");
                result += &status_bit_to_string(&statuses, git2::STATUS_WT_DELETED, "\x1b[34m✖");
            }
            if result.is_empty() {
                result = String::from("\x1b[36m√\x1b[m");
            }
        }
        result
    }
}

fn status_bit_to_string(statuses: &git2::Statuses, flag: git2::Status, prefix: &str) -> String {
    let count = statuses
        .iter()
        .filter(|s| s.status().contains(flag))
        .count();
    let mut result = "".to_string();
    if count > 0 {
        write!(result, "{}{}\x1b[m", prefix, count).unwrap();
    }
    result
}

fn abbreviated_remote_branch_name(full_name: &String) -> Option<String> {
    let mut full_name_it = full_name.split('/').peekable();
    if full_name_it.next() == Some("refs") && full_name_it.next() == Some("remotes") &&
        full_name_it.peek().is_some()
    {
        let mut abbreviated_name = full_name_it.next().unwrap().to_string();
        if full_name_it.peek().unwrap_or(&"").to_string() == "HEAD".to_string() {
            return None;
        }
        for s in full_name_it {
            abbreviated_name.push('/');
            abbreviated_name.push_str(s);
        }
        if !abbreviated_name.is_empty() {
            return Some(abbreviated_name);
        }
    }
    None
}

fn find_best_branch_name(branch_names: Vec<String>) -> String {
    // Transmute branch names into canonical shortened forms.
    // Also, remove all variants terminating in HEAD
    let working_branch_names: Vec<String> = branch_names
        .iter()
        .filter_map(abbreviated_remote_branch_name)
        .filter(|b| b != "HEAD")
        .collect();

    // Determine the minimum namespace depth of the names and
    // filter the list to include only those at the minimum depth.
    // The theory here is that we want to produce the "simplest" name,
    // and minimizing the depth should be done before, e.g., minimizing
    // the charcount
    let slash_counts: Vec<usize> = working_branch_names
        .iter()
        .map(|s| s.chars().filter(|c| c == &'/').count())
        .collect();
    let min_slashes = slash_counts.iter().min().unwrap();
    let branch_and_count_iter = working_branch_names.into_iter().zip(slash_counts.iter());
    let sifted_branch_names: Vec<String> = branch_and_count_iter
        .filter_map(|t| if t.1 == min_slashes { Some(t.0) } else { None })
        .collect();
    sifted_branch_names[0].clone()
}
<commit_msg>Various code cleanups, kill most clippy warnings.<commit_after>extern crate git2;
// TODO: Investigate ansi_term crate.  https://crates.io/crates/ansi_term

use std::path::Path;
// use std::path::PathBuf;
use std::fmt::Write;

pub struct GitPromptRepo {
    lg2_repo: Option<git2::Repository>,
    // origin_path: PathBuf,
    // root_path: PathBuf,
    repo_state: git2::RepositoryState,
    is_unborn: bool,
    has_head: bool,
    has_checkout: bool,
}

impl GitPromptRepo {
    pub fn new(path_spec: &Path) -> GitPromptRepo {
        let lg2_repo = git2::Repository::discover(path_spec).ok();
        // let mut root_path = PathBuf::new();
        let mut repo_state = git2::RepositoryState::Clean;
        let mut is_unborn = false;
        let mut has_head = false;
        let mut has_checkout = false;

        if let Some(ref repo) = lg2_repo {
            // root_path = repo.path().to_path_buf();
            repo_state = repo.state();
            if let Err(e) = repo.head() {
                is_unborn = e.code() == git2::ErrorCode::UnbornBranch;
            } else {
                has_head = true;
            }
            has_checkout = !repo.is_bare();
        }

        GitPromptRepo {
            lg2_repo,
            // origin_path: path_spec.to_path_buf(),
            // root_path,
            repo_state,
            is_unborn,
            has_head,
            has_checkout,
        }
    }

    // Assumes has_head is true
    fn head_name(&self) -> String {
        self.lg2_repo
            .as_ref()
            .unwrap()
            .head()
            .unwrap()
            .name()
            .unwrap_or("")
            .trim_left_matches("refs/heads/")
            .to_string()
    }

    fn head_to_branch(&self) -> Option<git2::Branch> {
        if self.has_head {
            let head_name = self.head_name();
            return self.lg2_repo
                .as_ref()
                .unwrap()
                .find_branch(head_name.as_str(), git2::BranchType::Local)
                .ok();
        }
        None
    }

    fn head_branch_has_upstream(&self) -> bool {
        if let Some(branch) = self.head_to_branch() {
            return branch.upstream().is_ok();
        }
        false
    }

    // fn is_remote(&self) -> bool {
    //     match &self.ref_result {
    //         &Ok(ref r) => r.is_remote(),
    //         &Err(_) => false
    //     }
    // }

    fn build_ref_name_for_commit(&self, commit: &git2::Commit, ref_string: &mut String) {
        let oid = commit.id();
        let mut candidate_branch_names = Vec::new();
        let branches_it = self.lg2_repo
            .as_ref()
            .unwrap()
            .branches(Some(git2::BranchType::Remote))
            .unwrap()
            .filter_map(|branch_result| branch_result.ok());
        for branch in branches_it {
            let branch_ref = &branch.0.get();
            let peeled_obj_res = branch_ref.peel(git2::ObjectType::Commit);
            if peeled_obj_res.is_ok() && peeled_obj_res.unwrap().id() == oid
                && branch_ref.name().is_some()
            {
                candidate_branch_names.push(branch_ref.name().unwrap().to_string());
            }
        }
        ref_string.clear();
        if candidate_branch_names.is_empty() {
            let mut oid_string = String::new();
            write!(oid_string, "{}", oid).unwrap();
            oid_string.truncate(8);
            write!(ref_string, "{}", oid_string).unwrap();
        } else {
            write!(
                ref_string,
                "{}",
                find_best_branch_name(&candidate_branch_names)
            ).unwrap();
        }
    }

    pub fn ref_name_head(&self) -> String {
        let mut ref_string = String::new();
        // TODO: should check more repo_state possibilities
        if self.is_unborn {
            ref_string = "[Unborn]".to_string();
        } else if self.repo_state == git2::RepositoryState::Rebase
            || self.repo_state == git2::RepositoryState::RebaseInteractive
            || self.repo_state == git2::RepositoryState::RebaseMerge
        {
            // TODO: Should look at .git/rebase-apply/head-name rather than
            // compute rebasing_name as we do here
            if let Ok(rebasing_ref) = self.lg2_repo
                .as_ref()
                .unwrap()
                .find_reference("rebase-apply/orig-head")
            {
                let onto_ref = self.lg2_repo
                    .as_ref()
                    .unwrap()
                    .find_reference("rebase-apply/onto")
                    .unwrap();
                let mut rebasing_name = String::new();
                let mut onto_name = String::new();
                self.build_ref_name_for_commit(
                    rebasing_ref
                        .peel(git2::ObjectType::Commit)
                        .unwrap()
                        .as_commit()
                        .unwrap(),
                    &mut rebasing_name,
                );
                self.build_ref_name_for_commit(
                    onto_ref
                        .peel(git2::ObjectType::Commit)
                        .unwrap()
                        .as_commit()
                        .unwrap(),
                    &mut onto_name,
                );
                write!(
                    ref_string,
                    "\x1b[1;35m...rebasing\x1b[0m {} \x1b[1;35monto\x1b[0m {}",
                    rebasing_name,
                    onto_name
                ).unwrap();
            } else {
                write!(ref_string, "unhandled rebase case").unwrap();
            }
        } else if self.has_head {
            ref_string = self.head_name();
        }
        if ref_string == "HEAD" {
            let head_object = self.lg2_repo
                .as_ref()
                .unwrap()
                .head()
                .unwrap()
                .resolve()
                .unwrap()
                .peel(git2::ObjectType::Commit)
                .unwrap();
            let head_commit = head_object.as_commit().unwrap();
            self.build_ref_name_for_commit(head_commit, &mut ref_string);
        }
        ref_string.to_string()
    }

    pub fn upstream_name(&self) -> String {
        if self.head_branch_has_upstream() {
            let branch = self.head_to_branch().unwrap();
            let upstream_branch = branch.upstream().unwrap();
            if let Ok(Some(name)) = upstream_branch.name() {
                return name.to_string();
            }
        }
        String::new()
    }

    pub fn ahead_behind(&self) -> String {
        let mut result = String::new();
        if self.head_branch_has_upstream() {
            let head_branch = self.head_to_branch().unwrap();
            let upstream_branch = head_branch.upstream().unwrap();
            let head_branch_oid = head_branch.get().resolve().unwrap().target().unwrap();
            let upstream_branch_oid = upstream_branch.get().resolve().unwrap().target().unwrap();
            let repo = self.lg2_repo.as_ref().unwrap();
            let (ahead, behind) = repo.graph_ahead_behind(head_branch_oid, upstream_branch_oid)
                .unwrap();
            if behind > 0 {
                result += "↓·";
                result += &*behind.to_string();
            }
            if ahead > 0 {
                result += "↑·";
                result += &*ahead.to_string();
            }
        }
        result
    }

    pub fn status(&self) -> String {
        let mut result = String::new();
        if self.has_checkout {
            let mut opts = git2::StatusOptions::new();
            if let Ok(statuses) = self.lg2_repo.as_ref().unwrap().statuses(Some(
                opts.update_index(true)
                    .include_untracked(true)
                    .recurse_untracked_dirs(true),
            )) {
                result += &status_bit_to_string(&statuses, git2::STATUS_INDEX_MODIFIED, "∂");
                result += &status_bit_to_string(&statuses, git2::STATUS_INDEX_NEW, "…");
                result += &status_bit_to_string(&statuses, git2::STATUS_INDEX_DELETED, "✖");
                result +=
                    &status_bit_to_string(&statuses, git2::STATUS_CONFLICTED, "\x1b[31;1m≠");
                result += &status_bit_to_string(&statuses, git2::STATUS_WT_MODIFIED, "\x1b[34m∂");
                result += &status_bit_to_string(&statuses, git2::STATUS_WT_NEW, "\x1b[34m…");
                result += &status_bit_to_string(&statuses, git2::STATUS_WT_DELETED, "\x1b[34m✖");
            }
            if result.is_empty() {
                result = String::from("\x1b[36m√\x1b[m");
            }
        }
        result
    }
}

fn status_bit_to_string(statuses: &git2::Statuses, flag: git2::Status, prefix: &str) -> String {
    let count = statuses
        .iter()
        .filter(|s| s.status().contains(flag))
        .count();
    let mut result = String::new();
    if count > 0 {
        write!(result, "{}{}\x1b[m", prefix, count).unwrap();
    }
    result
}

fn abbreviated_remote_branch_name(full_name: &String) -> Option<String> {
    let mut full_name_it = full_name.split('/').peekable();
    if full_name_it.next() == Some("refs") && full_name_it.next() == Some("remotes")
        && full_name_it.peek().is_some()
    {
        let mut abbreviated_name = full_name_it.next().unwrap().to_string();
        if full_name_it.peek().unwrap_or(&"") == &"HEAD" {
            return None;
        }
        for s in full_name_it {
            abbreviated_name.push('/');
            abbreviated_name.push_str(s);
        }
        if !abbreviated_name.is_empty() {
            return Some(abbreviated_name);
        }
    }
    None
}

fn find_best_branch_name(branch_names: &[String]) -> String {
    // Transmute branch names into canonical shortened forms.
    // Also, remove all variants terminating in HEAD
    let working_branch_names: Vec<String> = branch_names
        .iter()
        .filter_map(abbreviated_remote_branch_name)
        .filter(|b| b != "HEAD")
        .collect();

    // Determine the minimum namespace depth of the names and
    // filter the list to include only those at the minimum depth.
    // The theory here is that we want to produce the "simplest" name,
    // and minimizing the depth should be done before, e.g., minimizing
    // the charcount
    let slash_counts: Vec<usize> = working_branch_names
        .iter()
        .map(|s| s.chars().filter(|c| c == &'/').count())
        .collect();
    let min_slashes = slash_counts.iter().min().unwrap();
    let branch_and_count_iter = working_branch_names.into_iter().zip(slash_counts.iter());
    let sifted_branch_names: Vec<String> = branch_and_count_iter
        .filter_map(|t| if t.1 == min_slashes { Some(t.0) } else { None })
        .collect();
    sifted_branch_names[0].clone()
}
<|endoftext|>


<commit_before>/// The focus on this file is to describe the data-structures
/// for IA-32e paging mode.
use core::fmt;
use core::mem::{size_of};

pub type PAddr = u64;
pub type VAddr = usize;

pub const BASE_PAGE_SIZE: u64 = 4096; // 4 KiB
pub const LARGE_PAGE_SIZE: u64 = 1024*1024*2; // 2 MiB
pub const HUGE_PAGE_SIZE: u64 = 1024*1024*1024; // 1 GiB

/// A PML4 table.
/// In practice this has only 4 entries but it still needs to be the size of a 4K page.
pub type PML4  = [PML4Entry; 512];

/// A page directory pointer table.
pub type PDPT  = [PDPTEntry; 512];

/// A page directory.
pub type PD    = [PDEntry; 512];

/// A page table.
pub type PT    = [PTEntry; 512];

bitflags! {
    flags PML4Entry: u64 {
        /// Read/write; if 0, writes may not be allowed to the 512-GByte region
        /// controlled by this entry (see Section 4.6)
        const PML4_RW      = 0b00000010,
        /// User/supervisor; if 0, user-mode accesses are not allowed
        /// to the 512-GByte region controlled by this entry.
        const PML4_US      = 0b00000100,
        /// Page-level write-through; indirectly determines the memory type used to
        /// access the page-directory-pointer table referenced by this entry.
        const PML4_PWT     = 0b00001000,
        /// Page-level cache disable; indirectly determines the memory type used to
        /// access the page-directory-pointer table referenced by this entry.
        const PML4_PCD     = 0b00010000,
        /// Accessed; indicates whether this entry has been used for linear-address translation.
        const PML4_A       = 0b00100000,
        /// If IA32_EFER.NXE = 1, execute-disable
        /// If 1, instruction fetches are not allowed from the 512-GByte region.
        const PML4_XD      = 1 << 63,
    }
}

impl PML4Entry {
    pub fn new(&mut self, pdpt: PAddr) {
        assert!(pdpt % BASE_PAGE_SIZE == 0);
        self.bits = pdpt;
    }
}

impl fmt::Debug for PML4Entry {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.bits)
    }
}

bitflags! {
    flags PDPTEntry: u64 {
        /// Present; must be 1 to map a 1-GByte page or reference a page directory.
        const PDPT_P       = 0b00000001,
        /// Read/write; if 0, writes may not be allowed to the 1-GByte region controlled by this entry
        const PDPT_RW      = 0b00000010,
        /// User/supervisor; user-mode accesses are not allowed to the 1-GByte region controlled by this entry.
        const PDPT_US      = 0b00000100,
        /// Page-level write-through.
        const PDPT_PWT     = 0b00001000,
        /// Page-level cache disable.
        const PDPT_PCD     = 0b00010000,
        /// Accessed; if PDPT_PS set indicates whether software has accessed the 1-GByte page
        /// else indicates whether this entry has been used for linear-address translation
        const PDPT_A       = 0b00100000,
        /// Dirty; if PDPT_PS indicates whether software has written to the 1-GByte page referenced by this entry.
        /// else ignored.
        const PDPT_D       = 0b01000000,
        /// Page size; if set this entry maps a 1-GByte page; otherwise, this entry references a page directory.
        /// if not PDPT_PS this is ignored.
        const PDPT_PS      = 0b10000000,
        /// Global; if PDPT_PS && CR4.PGE = 1, determines whether the translation is global; ignored otherwise
        /// if not PDPT_PS this is ignored.
        const PDPT_G       = 1<<8,
        /// Indirectly determines the memory type used to access the 1-GByte page referenced by this entry.
        const PDPT_PAT     = 1<<12,
        /// If IA32_EFER.NXE = 1, execute-disable
        /// If 1, instruction fetches are not allowed from the 512-GByte region.
        const PDPT_XD      = 1 << 63,
    }
}

impl PDPTEntry {
    pub fn new(&mut self, pd: PAddr) {
        assert!(pd % BASE_PAGE_SIZE == 0);
        self.bits = pd;
    }
}

impl fmt::Debug for PDPTEntry {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.bits)
    }
}

bitflags! {
    flags PDEntry: u64 {
        /// Present; must be 1 to map a 2-MByte page or reference a page table.
        const PD_P       = 0b00000001,
        /// Read/write; if 0, writes may not be allowed to the 2-MByte region controlled by this entry
        const PD_RW      = 0b00000010,
        /// User/supervisor; user-mode accesses are not allowed to the 2-MByte region controlled by this entry.
        const PD_US      = 0b00000100,
        /// Page-level write-through.
        const PD_PWT     = 0b00001000,
        /// Page-level cache disable.
        const PD_PCD     = 0b00010000,
        /// Accessed; if PD_PS set indicates whether software has accessed the 2-MByte page
        /// else indicates whether this entry has been used for linear-address translation
        const PD_A       = 0b00100000,
        /// Dirty; if PD_PS indicates whether software has written to the 2-MByte page referenced by this entry.
        /// else ignored.
        const PD_D       = 0b01000000,
        /// Page size; if set this entry maps a 2-MByte page; otherwise, this entry references a page directory.
        const PD_PS      = 0b10000000,
        /// Global; if PD_PS && CR4.PGE = 1, determines whether the translation is global; ignored otherwise
        /// if not PD_PS this is ignored.
        const PD_G       = 1<<8,
        /// Indirectly determines the memory type used to access the 2-MByte page referenced by this entry.
        /// if not PD_PS this is ignored.
        const PD_PAT     = 1<<12,
        /// If IA32_EFER.NXE = 1, execute-disable
        /// If 1, instruction fetches are not allowed from the 512-GByte region.
        const PD_XD      = 1 << 63,
    }
}

impl PDEntry {
    pub fn new(&mut self, pt: PAddr) {
        assert!(pt % BASE_PAGE_SIZE == 0);
        self.bits = pt;
    }
}

impl fmt::Debug for PDEntry {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.bits)
    }
}

bitflags! {
    flags PTEntry: u64 {
        /// Present; must be 1 to map a 4-KByte page.
        const PT_P       = 0b00000001,
        /// Read/write; if 0, writes may not be allowed to the 4-KByte region controlled by this entry
        const PT_RW      = 0b00000010,
        /// User/supervisor; user-mode accesses are not allowed to the 4-KByte region controlled by this entry.
        const PT_US      = 0b00000100,
        /// Page-level write-through.
        const PT_PWT     = 0b00001000,
        /// Page-level cache disable.
        const PT_PCD     = 0b00010000,
        /// Accessed; indicates whether software has accessed the 4-KByte page
        const PT_A       = 0b00100000,
        /// Dirty; indicates whether software has written to the 4-KByte page referenced by this entry.
        const PT_D       = 0b01000000,
        /// Global; if CR4.PGE = 1, determines whether the translation is global (see Section 4.10); ignored otherwise
        const PT_G       = 1<<8,
        /// If IA32_EFER.NXE = 1, execute-disable
        /// If 1, instruction fetches are not allowed from the 512-GByte region.
        const PT_XD      = 1 << 63,
    }
}

impl PTEntry {
    pub fn new(&mut self, page: PAddr) {
        assert!(page % BASE_PAGE_SIZE == 0);
        self.bits = page;
    }
}

impl fmt::Debug for PTEntry {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.bits)
    }
}
<commit_msg>Change new() to return PML4.<commit_after>/// The focus on this file is to describe the data-structures
/// for IA-32e paging mode.
use core::fmt;
use core::mem::{size_of};

pub type PAddr = u64;
pub type VAddr = usize;

pub const BASE_PAGE_SIZE: u64 = 4096; // 4 KiB
pub const LARGE_PAGE_SIZE: u64 = 1024*1024*2; // 2 MiB
pub const HUGE_PAGE_SIZE: u64 = 1024*1024*1024; // 1 GiB

/// A PML4 table.
/// In practice this has only 4 entries but it still needs to be the size of a 4K page.
pub type PML4  = [PML4Entry; 512];

/// A page directory pointer table.
pub type PDPT  = [PDPTEntry; 512];

/// A page directory.
pub type PD    = [PDEntry; 512];

/// A page table.
pub type PT    = [PTEntry; 512];

bitflags! {
    flags PML4Entry: u64 {
        /// Read/write; if 0, writes may not be allowed to the 512-GByte region
        /// controlled by this entry (see Section 4.6)
        const PML4_RW      = 0b00000010,
        /// User/supervisor; if 0, user-mode accesses are not allowed
        /// to the 512-GByte region controlled by this entry.
        const PML4_US      = 0b00000100,
        /// Page-level write-through; indirectly determines the memory type used to
        /// access the page-directory-pointer table referenced by this entry.
        const PML4_PWT     = 0b00001000,
        /// Page-level cache disable; indirectly determines the memory type used to
        /// access the page-directory-pointer table referenced by this entry.
        const PML4_PCD     = 0b00010000,
        /// Accessed; indicates whether this entry has been used for linear-address translation.
        const PML4_A       = 0b00100000,
        /// If IA32_EFER.NXE = 1, execute-disable
        /// If 1, instruction fetches are not allowed from the 512-GByte region.
        const PML4_XD      = 1 << 63,
    }
}

impl PML4Entry {
    pub fn new(pdpt: PAddr) -> PML4Entry {
        assert!(pdpt % BASE_PAGE_SIZE == 0);
        PML4Entry { bits: pdpt }
    }
}

impl fmt::Debug for PML4Entry {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.bits)
    }
}

bitflags! {
    flags PDPTEntry: u64 {
        /// Present; must be 1 to map a 1-GByte page or reference a page directory.
        const PDPT_P       = 0b00000001,
        /// Read/write; if 0, writes may not be allowed to the 1-GByte region controlled by this entry
        const PDPT_RW      = 0b00000010,
        /// User/supervisor; user-mode accesses are not allowed to the 1-GByte region controlled by this entry.
        const PDPT_US      = 0b00000100,
        /// Page-level write-through.
        const PDPT_PWT     = 0b00001000,
        /// Page-level cache disable.
        const PDPT_PCD     = 0b00010000,
        /// Accessed; if PDPT_PS set indicates whether software has accessed the 1-GByte page
        /// else indicates whether this entry has been used for linear-address translation
        const PDPT_A       = 0b00100000,
        /// Dirty; if PDPT_PS indicates whether software has written to the 1-GByte page referenced by this entry.
        /// else ignored.
        const PDPT_D       = 0b01000000,
        /// Page size; if set this entry maps a 1-GByte page; otherwise, this entry references a page directory.
        /// if not PDPT_PS this is ignored.
        const PDPT_PS      = 0b10000000,
        /// Global; if PDPT_PS && CR4.PGE = 1, determines whether the translation is global; ignored otherwise
        /// if not PDPT_PS this is ignored.
        const PDPT_G       = 1<<8,
        /// Indirectly determines the memory type used to access the 1-GByte page referenced by this entry.
        const PDPT_PAT     = 1<<12,
        /// If IA32_EFER.NXE = 1, execute-disable
        /// If 1, instruction fetches are not allowed from the 512-GByte region.
        const PDPT_XD      = 1 << 63,
    }
}

impl PDPTEntry {
    pub fn new(&mut self, pd: PAddr) {
        assert!(pd % BASE_PAGE_SIZE == 0);
        self.bits = pd;
    }
}

impl fmt::Debug for PDPTEntry {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.bits)
    }
}

bitflags! {
    flags PDEntry: u64 {
        /// Present; must be 1 to map a 2-MByte page or reference a page table.
        const PD_P       = 0b00000001,
        /// Read/write; if 0, writes may not be allowed to the 2-MByte region controlled by this entry
        const PD_RW      = 0b00000010,
        /// User/supervisor; user-mode accesses are not allowed to the 2-MByte region controlled by this entry.
        const PD_US      = 0b00000100,
        /// Page-level write-through.
        const PD_PWT     = 0b00001000,
        /// Page-level cache disable.
        const PD_PCD     = 0b00010000,
        /// Accessed; if PD_PS set indicates whether software has accessed the 2-MByte page
        /// else indicates whether this entry has been used for linear-address translation
        const PD_A       = 0b00100000,
        /// Dirty; if PD_PS indicates whether software has written to the 2-MByte page referenced by this entry.
        /// else ignored.
        const PD_D       = 0b01000000,
        /// Page size; if set this entry maps a 2-MByte page; otherwise, this entry references a page directory.
        const PD_PS      = 0b10000000,
        /// Global; if PD_PS && CR4.PGE = 1, determines whether the translation is global; ignored otherwise
        /// if not PD_PS this is ignored.
        const PD_G       = 1<<8,
        /// Indirectly determines the memory type used to access the 2-MByte page referenced by this entry.
        /// if not PD_PS this is ignored.
        const PD_PAT     = 1<<12,
        /// If IA32_EFER.NXE = 1, execute-disable
        /// If 1, instruction fetches are not allowed from the 512-GByte region.
        const PD_XD      = 1 << 63,
    }
}

impl PDEntry {
    pub fn new(&mut self, pt: PAddr) {
        assert!(pt % BASE_PAGE_SIZE == 0);
        self.bits = pt;
    }
}

impl fmt::Debug for PDEntry {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.bits)
    }
}

bitflags! {
    flags PTEntry: u64 {
        /// Present; must be 1 to map a 4-KByte page.
        const PT_P       = 0b00000001,
        /// Read/write; if 0, writes may not be allowed to the 4-KByte region controlled by this entry
        const PT_RW      = 0b00000010,
        /// User/supervisor; user-mode accesses are not allowed to the 4-KByte region controlled by this entry.
        const PT_US      = 0b00000100,
        /// Page-level write-through.
        const PT_PWT     = 0b00001000,
        /// Page-level cache disable.
        const PT_PCD     = 0b00010000,
        /// Accessed; indicates whether software has accessed the 4-KByte page
        const PT_A       = 0b00100000,
        /// Dirty; indicates whether software has written to the 4-KByte page referenced by this entry.
        const PT_D       = 0b01000000,
        /// Global; if CR4.PGE = 1, determines whether the translation is global (see Section 4.10); ignored otherwise
        const PT_G       = 1<<8,
        /// If IA32_EFER.NXE = 1, execute-disable
        /// If 1, instruction fetches are not allowed from the 512-GByte region.
        const PT_XD      = 1 << 63,
    }
}

impl PTEntry {
    pub fn new(&mut self, page: PAddr) {
        assert!(page % BASE_PAGE_SIZE == 0);
        self.bits = page;
    }
}

impl fmt::Debug for PTEntry {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.bits)
    }
}
<|endoftext|>


<commit_before>use heartbeats_simple_sys::pow::*;
use std::mem;
use std::io::{self, Write};
use std::fs::File;

pub type HeartbeatPowContext = heartbeat_pow_context;
pub type HeartbeatPowRecord = heartbeat_pow_record;
pub type HeartbeatPowWindowComplete = heartbeat_pow_window_complete;

/// Contains the Heartbeat and its window data buffer.
pub struct HeartbeatPow {
    pub hb: HeartbeatPowContext,
    pub hbr: Vec<HeartbeatPowRecord>,
    pub log: Option<File>,
}

impl HeartbeatPow {
    /// Allocate and initialize a new `Heartbeat`.
    pub fn new(window_size: usize,
               hwc_callback: Option<HeartbeatPowWindowComplete>,
               mut log: Option<File>) -> Result<HeartbeatPow, &'static str> {
        let mut hbr: Vec<HeartbeatPowRecord> = Vec::with_capacity(window_size);
        let hb: HeartbeatPowContext = unsafe {
            // must explicitly set size so we can read data later
            // (Rust isn't aware of native code modifying the buffer)
            hbr.set_len(window_size);
            let mut hb = mem::uninitialized();
            match heartbeat_pow_init(&mut hb,
                                     hbr.capacity() as u64,
                                     hbr.as_mut_ptr(),
                                     hwc_callback) {
                0 => hb,
                _ => return Err("Failed to initialize heartbeat")
            }
        };
        // write header to log file if there is one
        if let Some(ref mut l) = log {
            l.write_all(format!("{:6} {:6} \
                         {:11} {:11} {:11} \
                         {:15} {:15} {:20} {:20} \
                         {:15} {:15} {:15} \
                         {:15} {:15} {:15} {:15} \
                         {:15} {:15} {}\n",
                        "HB", "Tag",
                        "Global_Work", "Window_Work", "Work",
                        "Global_Time", "Window_Time", "Start_Time", "End_Time",
                        "Global_Perf", "Window_Perf", "Instant_Perf",
                        "Global_Energy", "Window_Energy", "Start_Energy", "End_Energy",
                        "Global_Pwr", "Window_Pwr", "Instant_Pwr").as_bytes()).unwrap()
        }
        Ok(HeartbeatPow { hb: hb, hbr: hbr, log: log, })
    }

    /// Issue a heartbeat
    pub fn heartbeat(&mut self,
                     tag: u64,
                     work: u64,
                     start_time: u64,
                     end_time: u64,
                     start_energy: u64,
                     end_energy: u64) {
        unsafe {
            heartbeat_pow(&mut self.hb, tag, work, start_time, end_time, start_energy, end_energy)
        }
    }

    fn write_log(r: &HeartbeatPowRecord, l: &mut File) -> io::Result<usize> {
        l.write(format!("{:<6} {:<6} \
                         {:<11} {:<11} {:<11} \
                         {:<15} {:<15} {:<20} {:<20} \
                         {:<15.6} {:<15.6} {:<15.6} \
                         {:<15} {:<15} {:<15} {:<15} \
                         {:<15.6} {:<15.6} {:<.6}\n",
                        r.id, r.user_tag,
                        r.wd.global, r.wd.window, r.work,
                        r.td.global, r.td.window, r.start_time, r.end_time,
                        r.perf.global, r.perf.window, r.perf.instant,
                        r.ed.global, r.ed.window, r.start_energy, r.end_energy,
                        r.pwr.global, r.pwr.window, r.pwr.instant).as_bytes())
    }

    /// Rust-only function that logs the buffer (up to buffer_index) to a file.
    pub fn log_to_buffer_index(&mut self) -> io::Result<()> {
        match self.log {
            Some(ref mut l) => {
                for i in 0..self.hb.ws.buffer_index {
                    match HeartbeatPow::write_log(self.hbr.get(i as usize).unwrap(), l) {
                        Ok(_) => (),
                        Err(e) => return Err(e),
                    }
                }
                l.flush()
            }
            None => Ok(())
        }
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use std::fs::File;

    #[test]
    fn test_simple() {
        const TIME_INC: u64 = 1000000000;
        const ENERGY_INC: u64 = 1000000;
        let mut hb = HeartbeatPow::new(5, None, None).unwrap();
        let mut start_time: u64 = 0;
        let mut end_time: u64 = TIME_INC;
        let mut start_energy: u64 = 0;
        let mut end_energy: u64 = ENERGY_INC;
        for tag in 0..10 {
            hb.heartbeat(tag, 1, start_time, end_time, start_energy, end_energy);
            start_time = end_time;
            end_time += TIME_INC;
            start_energy = end_energy;
            end_energy += ENERGY_INC;
        }
    }

    #[test]
    fn test_callback() {
        static mut received_cb: bool = false;
        extern fn callback(_hb: *const HeartbeatPowContext) {
            unsafe {
                received_cb = true;
            }
        }

        let mut hb = HeartbeatPow::new(1, Some(callback), None).unwrap();
        hb.heartbeat(0, 1, 0, 1000, 0, 0);
        unsafe {
            assert!(received_cb);
        }
    }

    #[test]
    fn test_file() {
        let mut hb = HeartbeatPow::new(5, None, Some(File::create("foo.log").unwrap())).unwrap();
        hb.heartbeat(0, 1, 0, 1000, 0, 0);
        hb.log_to_buffer_index().unwrap();
    }
}
<commit_msg>Re-export some structs and types from -sys dependency with camel case names<commit_after>use heartbeats_simple_sys::pow::{heartbeat_pow_init, heartbeat_pow};
use std::mem;
use std::io::{self, Write};
use std::fs::File;

pub use heartbeats_simple_sys::pow::heartbeat_pow_context as HeartbeatPowContext;
pub use heartbeats_simple_sys::pow::heartbeat_pow_record as HeartbeatPowRecord;
pub use heartbeats_simple_sys::pow::heartbeat_pow_window_complete as HeartbeatPowWindowComplete;

/// Contains the Heartbeat and its window data buffer.
pub struct HeartbeatPow {
    pub hb: HeartbeatPowContext,
    pub hbr: Vec<HeartbeatPowRecord>,
    pub log: Option<File>,
}

impl HeartbeatPow {
    /// Allocate and initialize a new `Heartbeat`.
    pub fn new(window_size: usize,
               hwc_callback: Option<HeartbeatPowWindowComplete>,
               mut log: Option<File>) -> Result<HeartbeatPow, &'static str> {
        let mut hbr: Vec<HeartbeatPowRecord> = Vec::with_capacity(window_size);
        let hb: HeartbeatPowContext = unsafe {
            // must explicitly set size so we can read data later
            // (Rust isn't aware of native code modifying the buffer)
            hbr.set_len(window_size);
            let mut hb = mem::uninitialized();
            match heartbeat_pow_init(&mut hb,
                                     hbr.capacity() as u64,
                                     hbr.as_mut_ptr(),
                                     hwc_callback) {
                0 => hb,
                _ => return Err("Failed to initialize heartbeat")
            }
        };
        // write header to log file if there is one
        if let Some(ref mut l) = log {
            l.write_all(format!("{:6} {:6} \
                         {:11} {:11} {:11} \
                         {:15} {:15} {:20} {:20} \
                         {:15} {:15} {:15} \
                         {:15} {:15} {:15} {:15} \
                         {:15} {:15} {}\n",
                        "HB", "Tag",
                        "Global_Work", "Window_Work", "Work",
                        "Global_Time", "Window_Time", "Start_Time", "End_Time",
                        "Global_Perf", "Window_Perf", "Instant_Perf",
                        "Global_Energy", "Window_Energy", "Start_Energy", "End_Energy",
                        "Global_Pwr", "Window_Pwr", "Instant_Pwr").as_bytes()).unwrap()
        }
        Ok(HeartbeatPow { hb: hb, hbr: hbr, log: log, })
    }

    /// Issue a heartbeat
    pub fn heartbeat(&mut self,
                     tag: u64,
                     work: u64,
                     start_time: u64,
                     end_time: u64,
                     start_energy: u64,
                     end_energy: u64) {
        unsafe {
            heartbeat_pow(&mut self.hb, tag, work, start_time, end_time, start_energy, end_energy)
        }
    }

    fn write_log(r: &HeartbeatPowRecord, l: &mut File) -> io::Result<usize> {
        l.write(format!("{:<6} {:<6} \
                         {:<11} {:<11} {:<11} \
                         {:<15} {:<15} {:<20} {:<20} \
                         {:<15.6} {:<15.6} {:<15.6} \
                         {:<15} {:<15} {:<15} {:<15} \
                         {:<15.6} {:<15.6} {:<.6}\n",
                        r.id, r.user_tag,
                        r.wd.global, r.wd.window, r.work,
                        r.td.global, r.td.window, r.start_time, r.end_time,
                        r.perf.global, r.perf.window, r.perf.instant,
                        r.ed.global, r.ed.window, r.start_energy, r.end_energy,
                        r.pwr.global, r.pwr.window, r.pwr.instant).as_bytes())
    }

    /// Rust-only function that logs the buffer (up to buffer_index) to a file.
    pub fn log_to_buffer_index(&mut self) -> io::Result<()> {
        match self.log {
            Some(ref mut l) => {
                for i in 0..self.hb.ws.buffer_index {
                    match HeartbeatPow::write_log(self.hbr.get(i as usize).unwrap(), l) {
                        Ok(_) => (),
                        Err(e) => return Err(e),
                    }
                }
                l.flush()
            }
            None => Ok(())
        }
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use std::fs::File;

    #[test]
    fn test_simple() {
        const TIME_INC: u64 = 1000000000;
        const ENERGY_INC: u64 = 1000000;
        let mut hb = HeartbeatPow::new(5, None, None).unwrap();
        let mut start_time: u64 = 0;
        let mut end_time: u64 = TIME_INC;
        let mut start_energy: u64 = 0;
        let mut end_energy: u64 = ENERGY_INC;
        for tag in 0..10 {
            hb.heartbeat(tag, 1, start_time, end_time, start_energy, end_energy);
            start_time = end_time;
            end_time += TIME_INC;
            start_energy = end_energy;
            end_energy += ENERGY_INC;
        }
    }

    #[test]
    fn test_callback() {
        static mut received_cb: bool = false;
        extern fn callback(_hb: *const HeartbeatPowContext) {
            unsafe {
                received_cb = true;
            }
        }

        let mut hb = HeartbeatPow::new(1, Some(callback), None).unwrap();
        hb.heartbeat(0, 1, 0, 1000, 0, 0);
        unsafe {
            assert!(received_cb);
        }
    }

    #[test]
    fn test_file() {
        let mut hb = HeartbeatPow::new(5, None, Some(File::create("foo.log").unwrap())).unwrap();
        hb.heartbeat(0, 1, 0, 1000, 0, 0);
        hb.log_to_buffer_index().unwrap();
    }
}
<|endoftext|>


<commit_before>use rustc_serialize::Decodable;

#[derive(Debug, RustcDecodable)]
pub struct User {
  pub id: String,
  pub username: String,
  pub url: String,
  pub imageUrl: String
}

#[derive(Debug, RustcDecodable)]
pub struct Data<D: Decodable> {
  pub data: D
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
pub enum ContentFormat {
  html, markdown
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
pub enum PublishStatus {
  public, draft, unlisted
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
pub enum License {
  cc40by,
  cc40bySa,
  cc40byNd,
  cc40byNc,
  cc40byNcNd,
  cc40byNcSa,
  cc40zero,
  publicDomain,
  allRightsReserved
}

#[derive(Debug, RustcEncodable)]
pub struct Post<'a> {
  title: &'a str,
//  #[serde(rename(json="contentFormat"))]
  content_format: ContentFormat,
  content: &'a str,
  tags: Option<Vec<&'a str>>,
 // #[serde(rename(json="canonicalUrl"))]
  canonicalUrl: Option<&'a str>,
 // #[serde(rename(json="publishStatus"))]
  publishStatus: Option<PublishStatus>,
  license: Option<License>
}
<commit_msg>some defaults<commit_after>use rustc_serialize::Decodable;
use std::default::Default;

#[derive(Debug, RustcDecodable)]
pub struct User {
  pub id: String,
  pub username: String,
  pub url: String,
  pub imageUrl: String
}

#[derive(Debug, RustcDecodable)]
pub struct Data<D: Decodable> {
  pub data: D
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
pub enum ContentFormat {
  html, markdown
}

impl Default for ContentFormat {
  fn default() -> ContentFormat {
    ContentFormat::markdown
  }
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
pub enum PublishStatus {
  public, draft, unlisted
}

impl Default for PublishStatus {
  fn default() -> PublishStatus {
    PublishStatus::public
  }
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
pub enum License {
  cc40by,
  cc40bySa,
  cc40byNd,
  cc40byNc,
  cc40byNcNd,
  cc40byNcSa,
  cc40zero,
  publicDomain,
  allRightsReserved
}

impl Default for License {
  fn default() -> License {
    License::allRightsReserved
  }
}

#[derive(Debug, RustcEncodable)]
pub struct Post<'a> {
  title: &'a str,
//  #[serde(rename(json="contentFormat"))]
  content_format: ContentFormat,
  content: &'a str,
  tags: Option<Vec<&'a str>>,
 // #[serde(rename(json="canonicalUrl"))]
  canonicalUrl: Option<&'a str>,
 // #[serde(rename(json="publishStatus"))]
  publishStatus: Option<PublishStatus>,
  license: Option<License>
}
<|endoftext|>