<commit_before>//! Ratio (dimensionless quantity).

#[cfg(feature = "std")]
use super::angle::{Angle, radian};

quantity! {
    /// Ratio (dimensionless quantity).
    quantity: Ratio; "ratio";
    /// Dimension of ratio, 1 (dimensionless).
    dimension: ISQ<
        Z0,     // length
        Z0,     // mass
        Z0,     // time
        Z0,     // electric current
        Z0,     // thermodynamic temperature
        Z0,     // amount of substance
        Z0>;    // luminous intensity
    units {
        @ratio: 1.0; "", "", "";
        @part_per_hundred: 1.0_E-2; "parts per hundred", "part per hundred", "parts per hundred";
        @percent: 1.0_E-2; "%", "percent", "percent";
        @part_per_thousand: 1.0_E-3; "parts per thousand", "part per thousand",
            "parts per thousand";
        @per_mille: 1.0_E-3; "‰", "per mille", "per mille";
        @part_per_ten_thousand: 1.0_E-4; "parts per ten thousand", "part per then thousand",
            "parts per ten thousand"; // ‱, doesn't display properly.
        @basis_point: 1.0_E-4; "bp", "basis point", "basis points";
        @part_per_million: 1.0_E-6; "ppm", "part per million", "parts per million";
        @part_per_billion: 1.0_E-9; "ppb", "part per billion", "parts per billion";
        @part_per_trillion: 1.0_E-12; "ppt", "part per trillion", "parts per trillion";
        @part_per_quadrillion: 1.0_E-15; "ppq", "part per quadrillion", "parts per quadrillion";
    }
}

/// Implementation of various stdlib functions.
#[cfg(feature = "std")]
impl<U, V> Ratio<U, V>
where
    U: crate::si::Units<V> + ?Sized,
    V: crate::num::Float + crate::Conversion<V>,
    radian: crate::Conversion<V, T = V::T>,
    ratio: crate::Conversion<V, T = V::T>,
{
    /// Computes the value of the inverse cosine of the ratio.
    #[inline(always)]
    pub fn acos(self) -> Angle<U, V> {
        Angle::new::<radian>(self.value.acos())
    }

    /// Computes the value of the inverse hyperbolic cosine of the ratio.
    #[inline(always)]
    pub fn acosh(self) -> Angle<U, V> {
        Angle::new::<radian>(self.value.acosh())
    }

    /// Computes the value of the inverse sine of the ratio.
    #[inline(always)]
    pub fn asin(self) -> Angle<U, V> {
        Angle::new::<radian>(self.value.asin())
    }

    /// Computes the value of the inverse hyperbolic sine of the ratio.
    #[inline(always)]
    pub fn asinh(self) -> Angle<U, V> {
        Angle::new::<radian>(self.value.asinh())
    }

    /// Computes the value of the inverse tangent of the ratio.
    #[inline(always)]
    pub fn atan(self) -> Angle<U, V> {
        Angle::new::<radian>(self.value.atan())
    }

    /// Computes the value of the inverse hyperbolic tangent of the ratio.
    #[inline(always)]
    pub fn atanh(self) -> Angle<U, V> {
        Angle::new::<radian>(self.value.atanh())
    }

    /// Returns `e^(self)`, (the exponential function).
    #[must_use = "method returns a new number and does not mutate the original value"]
    #[inline(always)]
    pub fn exp(self) -> Ratio<U, V> {
        Ratio::new::<ratio>(self.value.exp())
    }

    /// Returns 2^(self).
    #[must_use = "method returns a new number and does not mutate the original value"]
    #[inline(always)]
    pub fn exp2(self) -> Ratio<U, V> {
        Ratio::new::<ratio>(self.value.exp2())
    }

    /// Returns the natural logarithm of the number.
    #[must_use = "method returns a new number and does not mutate the original value"]
    #[inline(always)]
    pub fn ln(self) -> Ratio<U, V> {
        Ratio::new::<ratio>(self.value.ln())
    }

    /// Returns the base 2 logarithm of the number.
    #[must_use = "method returns a new number and does not mutate the original value"]
    #[inline(always)]
    pub fn log2(self) -> Ratio<U, V> {
        Ratio::new::<ratio>(self.value.log2())
    }

    /// Returns the base 10 logarithm of the number.
    #[must_use = "method returns a new number and does not mutate the original value"]
    #[inline(always)]
    pub fn log10(self) -> Ratio<U, V> {
        Ratio::new::<ratio>(self.value.log10())
    }

    /// Returns e^(self) - 1 in a way that is accurate even if the number is close to zero.
    #[must_use = "method returns a new number and does not mutate the original value"]
    #[inline(always)]
    pub fn exp_m1(self) -> Ratio<U, V> {
        Ratio::new::<ratio>(self.value.exp_m1())
    }

    /// Returns ln(1+n) (natural logarithm) more accurately than if the
    /// operations were performed separately.
    #[must_use = "method returns a new number and does not mutate the original value"]
    #[inline(always)]
    pub fn ln_1p(self) -> Ratio<U, V> {
        Ratio::new::<ratio>(self.value.ln_1p())
    }
}

mod convert {
    use super::*;

    impl<U, V> From<V> for Ratio<U, V>
    where
        U: crate::si::Units<V> + ?Sized,
        V: crate::num::Num + crate::Conversion<V>,
    {
        fn from(t: V) -> Self {
            Ratio {
                dimension: crate::lib::marker::PhantomData,
                units: crate::lib::marker::PhantomData,
                value: t,
            }
        }
    }

    storage_types! {
        use super::*;

        impl<U> From<Ratio<U, V>> for V
        where
            U: crate::si::Units<V> + ?Sized,
            V: crate::num::Num + crate::Conversion<V>,
        {
            fn from(t: Ratio<U, V>) -> Self {
                t.value
            }
        }
    }
}

#[cfg(test)]
mod tests {
    storage_types! {
        use crate::num::{FromPrimitive, One};
        use crate::si::quantities::*;
        use crate::si::ratio as r;
        use crate::tests::Test;

        #[test]
        fn from() {
            let r1: Ratio<V> = Ratio::<V>::from(V::one());
            let r2: Ratio<V> = V::one().into();
            let _: V = V::from(r1);
            let _: V = r2.into();
        }

        #[test]
        fn check_units() {
            Test::assert_eq(&Ratio::new::<r::ratio>(V::one() / V::from_f64(1.0_E2).unwrap()),
                &Ratio::new::<r::part_per_hundred>(V::one()));
            Test::assert_eq(&Ratio::new::<r::ratio>(V::one() / V::from_f64(1.0_E2).unwrap()),
                &Ratio::new::<r::percent>(V::one()));
            Test::assert_eq(&Ratio::new::<r::ratio>(V::one() / V::from_f64(1.0_E3).unwrap()),
                &Ratio::new::<r::part_per_thousand>(V::one()));
            Test::assert_eq(&Ratio::new::<r::ratio>(V::one() / V::from_f64(1.0_E3).unwrap()),
                &Ratio::new::<r::per_mille>(V::one()));
            Test::assert_eq(&Ratio::new::<r::ratio>(V::one() / V::from_f64(1.0_E4).unwrap()),
                &Ratio::new::<r::part_per_ten_thousand>(V::one()));
            Test::assert_eq(&Ratio::new::<r::ratio>(V::one() / V::from_f64(1.0_E4).unwrap()),
                &Ratio::new::<r::basis_point>(V::one()));
            Test::assert_eq(&Ratio::new::<r::ratio>(V::one() / V::from_f64(1.0_E6).unwrap()),
                &Ratio::new::<r::part_per_million>(V::one()));
            Test::assert_eq(&Ratio::new::<r::ratio>(V::one() / V::from_f64(1.0_E9).unwrap()),
                &Ratio::new::<r::part_per_billion>(V::one()));
            Test::assert_eq(&Ratio::new::<r::ratio>(V::one()
                    / V::from_f64(1.0_E12).unwrap()),
                &Ratio::new::<r::part_per_trillion>(V::one()));
            Test::assert_eq(&Ratio::new::<r::ratio>(V::one()
                    / V::from_f64(1.0_E15).unwrap()),
                &Ratio::new::<r::part_per_quadrillion>(V::one()));
        }
    }

    #[cfg(feature = "std")]
    mod float {
        storage_types! {
            types: Float;

            use crate::si::angle as a;
            use crate::si::ratio as r;
            use crate::si::quantities::*;
            use crate::tests::Test;

            quickcheck! {
                fn acos(x: V) -> bool {
                    Test::eq(&x.acos(), &Ratio::from(x).acos().get::<a::radian>())
                }

                fn acosh(x: V) -> bool {
                    Test::eq(&x.acosh(), &Ratio::from(x).acosh().get::<a::radian>())
                }

                fn asin(x: V) -> bool {
                    Test::eq(&x.asin(), &Ratio::from(x).asin().get::<a::radian>())
                }

                fn asinh(x: V) -> bool {
                    Test::eq(&x.asinh(), &Ratio::from(x).asinh().get::<a::radian>())
                }

                fn atan(x: V) -> bool {
                    Test::eq(&x.atan(), &Ratio::from(x).atan().get::<a::radian>())
                }

                fn atanh(x: V) -> bool {
                    Test::eq(&x.atanh(), &Ratio::from(x).atanh().get::<a::radian>())
                }

                fn exp(x: V) -> bool {
                    Test::eq(&x.exp(), &Ratio::from(x).exp().get::<r::ratio>())
                }

                fn exp2(x: V) -> bool {
                    Test::eq(&x.exp2(), &Ratio::from(x).exp2().get::<r::ratio>())
                }

                fn ln(x: V) -> bool {
                    Test::eq(&x.ln(), &Ratio::from(x).ln().get::<r::ratio>())
                }

                fn log2(x: V) -> bool {
                    Test::eq(&x.log2(), &Ratio::from(x).log2().get::<r::ratio>())
                }

                fn log10(x: V) -> bool {
                    Test::eq(&x.log10(), &Ratio::from(x).log10().get::<r::ratio>())
                }

                fn exp_m1(x: V) -> bool {
                    Test::eq(&x.exp_m1(), &Ratio::from(x).exp_m1().get::<r::ratio>())
                }

                fn ln_1p(x: V) -> bool {
                    Test::eq(&x.ln_1p(), &Ratio::from(x).ln_1p().get::<r::ratio>())
                }
            }
        }
    }
}
<commit_msg>Add one-arg log function<commit_after>//! Ratio (dimensionless quantity).

#[cfg(feature = "std")]
use super::angle::{Angle, radian};

quantity! {
    /// Ratio (dimensionless quantity).
    quantity: Ratio; "ratio";
    /// Dimension of ratio, 1 (dimensionless).
    dimension: ISQ<
        Z0,     // length
        Z0,     // mass
        Z0,     // time
        Z0,     // electric current
        Z0,     // thermodynamic temperature
        Z0,     // amount of substance
        Z0>;    // luminous intensity
    units {
        @ratio: 1.0; "", "", "";
        @part_per_hundred: 1.0_E-2; "parts per hundred", "part per hundred", "parts per hundred";
        @percent: 1.0_E-2; "%", "percent", "percent";
        @part_per_thousand: 1.0_E-3; "parts per thousand", "part per thousand",
            "parts per thousand";
        @per_mille: 1.0_E-3; "‰", "per mille", "per mille";
        @part_per_ten_thousand: 1.0_E-4; "parts per ten thousand", "part per then thousand",
            "parts per ten thousand"; // ‱, doesn't display properly.
        @basis_point: 1.0_E-4; "bp", "basis point", "basis points";
        @part_per_million: 1.0_E-6; "ppm", "part per million", "parts per million";
        @part_per_billion: 1.0_E-9; "ppb", "part per billion", "parts per billion";
        @part_per_trillion: 1.0_E-12; "ppt", "part per trillion", "parts per trillion";
        @part_per_quadrillion: 1.0_E-15; "ppq", "part per quadrillion", "parts per quadrillion";
    }
}

/// Implementation of various stdlib functions.
#[cfg(feature = "std")]
impl<U, V> Ratio<U, V>
where
    U: crate::si::Units<V> + ?Sized,
    V: crate::num::Float + crate::Conversion<V>,
    radian: crate::Conversion<V, T = V::T>,
    ratio: crate::Conversion<V, T = V::T>,
{
    /// Computes the value of the inverse cosine of the ratio.
    #[inline(always)]
    pub fn acos(self) -> Angle<U, V> {
        Angle::new::<radian>(self.value.acos())
    }

    /// Computes the value of the inverse hyperbolic cosine of the ratio.
    #[inline(always)]
    pub fn acosh(self) -> Angle<U, V> {
        Angle::new::<radian>(self.value.acosh())
    }

    /// Computes the value of the inverse sine of the ratio.
    #[inline(always)]
    pub fn asin(self) -> Angle<U, V> {
        Angle::new::<radian>(self.value.asin())
    }

    /// Computes the value of the inverse hyperbolic sine of the ratio.
    #[inline(always)]
    pub fn asinh(self) -> Angle<U, V> {
        Angle::new::<radian>(self.value.asinh())
    }

    /// Computes the value of the inverse tangent of the ratio.
    #[inline(always)]
    pub fn atan(self) -> Angle<U, V> {
        Angle::new::<radian>(self.value.atan())
    }

    /// Computes the value of the inverse hyperbolic tangent of the ratio.
    #[inline(always)]
    pub fn atanh(self) -> Angle<U, V> {
        Angle::new::<radian>(self.value.atanh())
    }

    /// Returns `e^(self)`, (the exponential function).
    #[must_use = "method returns a new number and does not mutate the original value"]
    #[inline(always)]
    pub fn exp(self) -> Ratio<U, V> {
        Ratio::new::<ratio>(self.value.exp())
    }

    /// Returns 2^(self).
    #[must_use = "method returns a new number and does not mutate the original value"]
    #[inline(always)]
    pub fn exp2(self) -> Ratio<U, V> {
        Ratio::new::<ratio>(self.value.exp2())
    }

    /// Returns the natural logarithm of the number.
    #[must_use = "method returns a new number and does not mutate the original value"]
    #[inline(always)]
    pub fn ln(self) -> Ratio<U, V> {
        Ratio::new::<ratio>(self.value.ln())
    }

    /// Returns the logarithm of the number with respect to an arbitrary base.
    ///
    /// The result might not be correctly rounded owing to implementation
    /// details; self.log2() can produce more accurate results for base 2, and
    /// self.log10() can produce more accurate results for base 10.
    #[must_use = "method returns a new number and does not mutate the original value"]
    #[inline(always)]
    pub fn log(self, base: V) -> Ratio<U, V> {
        Ratio::new::<ratio>(self.value.log(base))
    }

    /// Returns the base 2 logarithm of the number.
    #[must_use = "method returns a new number and does not mutate the original value"]
    #[inline(always)]
    pub fn log2(self) -> Ratio<U, V> {
        Ratio::new::<ratio>(self.value.log2())
    }

    /// Returns the base 10 logarithm of the number.
    #[must_use = "method returns a new number and does not mutate the original value"]
    #[inline(always)]
    pub fn log10(self) -> Ratio<U, V> {
        Ratio::new::<ratio>(self.value.log10())
    }

    /// Returns e^(self) - 1 in a way that is accurate even if the number is close to zero.
    #[must_use = "method returns a new number and does not mutate the original value"]
    #[inline(always)]
    pub fn exp_m1(self) -> Ratio<U, V> {
        Ratio::new::<ratio>(self.value.exp_m1())
    }

    /// Returns ln(1+n) (natural logarithm) more accurately than if the
    /// operations were performed separately.
    #[must_use = "method returns a new number and does not mutate the original value"]
    #[inline(always)]
    pub fn ln_1p(self) -> Ratio<U, V> {
        Ratio::new::<ratio>(self.value.ln_1p())
    }
}

mod convert {
    use super::*;

    impl<U, V> From<V> for Ratio<U, V>
    where
        U: crate::si::Units<V> + ?Sized,
        V: crate::num::Num + crate::Conversion<V>,
    {
        fn from(t: V) -> Self {
            Ratio {
                dimension: crate::lib::marker::PhantomData,
                units: crate::lib::marker::PhantomData,
                value: t,
            }
        }
    }

    storage_types! {
        use super::*;

        impl<U> From<Ratio<U, V>> for V
        where
            U: crate::si::Units<V> + ?Sized,
            V: crate::num::Num + crate::Conversion<V>,
        {
            fn from(t: Ratio<U, V>) -> Self {
                t.value
            }
        }
    }
}

#[cfg(test)]
mod tests {
    storage_types! {
        use crate::num::{FromPrimitive, One};
        use crate::si::quantities::*;
        use crate::si::ratio as r;
        use crate::tests::Test;

        #[test]
        fn from() {
            let r1: Ratio<V> = Ratio::<V>::from(V::one());
            let r2: Ratio<V> = V::one().into();
            let _: V = V::from(r1);
            let _: V = r2.into();
        }

        #[test]
        fn check_units() {
            Test::assert_eq(&Ratio::new::<r::ratio>(V::one() / V::from_f64(1.0_E2).unwrap()),
                &Ratio::new::<r::part_per_hundred>(V::one()));
            Test::assert_eq(&Ratio::new::<r::ratio>(V::one() / V::from_f64(1.0_E2).unwrap()),
                &Ratio::new::<r::percent>(V::one()));
            Test::assert_eq(&Ratio::new::<r::ratio>(V::one() / V::from_f64(1.0_E3).unwrap()),
                &Ratio::new::<r::part_per_thousand>(V::one()));
            Test::assert_eq(&Ratio::new::<r::ratio>(V::one() / V::from_f64(1.0_E3).unwrap()),
                &Ratio::new::<r::per_mille>(V::one()));
            Test::assert_eq(&Ratio::new::<r::ratio>(V::one() / V::from_f64(1.0_E4).unwrap()),
                &Ratio::new::<r::part_per_ten_thousand>(V::one()));
            Test::assert_eq(&Ratio::new::<r::ratio>(V::one() / V::from_f64(1.0_E4).unwrap()),
                &Ratio::new::<r::basis_point>(V::one()));
            Test::assert_eq(&Ratio::new::<r::ratio>(V::one() / V::from_f64(1.0_E6).unwrap()),
                &Ratio::new::<r::part_per_million>(V::one()));
            Test::assert_eq(&Ratio::new::<r::ratio>(V::one() / V::from_f64(1.0_E9).unwrap()),
                &Ratio::new::<r::part_per_billion>(V::one()));
            Test::assert_eq(&Ratio::new::<r::ratio>(V::one()
                    / V::from_f64(1.0_E12).unwrap()),
                &Ratio::new::<r::part_per_trillion>(V::one()));
            Test::assert_eq(&Ratio::new::<r::ratio>(V::one()
                    / V::from_f64(1.0_E15).unwrap()),
                &Ratio::new::<r::part_per_quadrillion>(V::one()));
        }
    }

    #[cfg(feature = "std")]
    mod float {
        storage_types! {
            types: Float;

            use crate::si::angle as a;
            use crate::si::ratio as r;
            use crate::si::quantities::*;
            use crate::tests::Test;

            quickcheck! {
                fn acos(x: V) -> bool {
                    Test::eq(&x.acos(), &Ratio::from(x).acos().get::<a::radian>())
                }

                fn acosh(x: V) -> bool {
                    Test::eq(&x.acosh(), &Ratio::from(x).acosh().get::<a::radian>())
                }

                fn asin(x: V) -> bool {
                    Test::eq(&x.asin(), &Ratio::from(x).asin().get::<a::radian>())
                }

                fn asinh(x: V) -> bool {
                    Test::eq(&x.asinh(), &Ratio::from(x).asinh().get::<a::radian>())
                }

                fn atan(x: V) -> bool {
                    Test::eq(&x.atan(), &Ratio::from(x).atan().get::<a::radian>())
                }

                fn atanh(x: V) -> bool {
                    Test::eq(&x.atanh(), &Ratio::from(x).atanh().get::<a::radian>())
                }

                fn exp(x: V) -> bool {
                    Test::eq(&x.exp(), &Ratio::from(x).exp().get::<r::ratio>())
                }

                fn exp2(x: V) -> bool {
                    Test::eq(&x.exp2(), &Ratio::from(x).exp2().get::<r::ratio>())
                }

                fn ln(x: V) -> bool {
                    Test::eq(&x.ln(), &Ratio::from(x).ln().get::<r::ratio>())
                }

                fn log(x: V, y: V) -> bool {
                    Test::eq(&x.log(y), &Ratio::from(x).log(y).get::<r::ratio>())
                }

                fn log2(x: V) -> bool {
                    Test::eq(&x.log2(), &Ratio::from(x).log2().get::<r::ratio>())
                }

                fn log10(x: V) -> bool {
                    Test::eq(&x.log10(), &Ratio::from(x).log10().get::<r::ratio>())
                }

                fn exp_m1(x: V) -> bool {
                    Test::eq(&x.exp_m1(), &Ratio::from(x).exp_m1().get::<r::ratio>())
                }

                fn ln_1p(x: V) -> bool {
                    Test::eq(&x.ln_1p(), &Ratio::from(x).ln_1p().get::<r::ratio>())
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>//! Contains code to handle an IPC channel which is issuing commands.

use std::io::Error as IOError;
use std::io::prelude::*;

use std::mem::transmute;

use rustc_serialize::Encodable;
use rustc_serialize::json::{Json, ToJson, Encoder, encode, ParserError, EncoderError};

use unix_socket::UnixStream;

/// Reasons a client message might be erroneous
#[derive(Debug)]
enum ResponseError {
    /// Connection was closed
    ConnectionClosed,
    /// Some bytes dun goofed
    InvalidString,
    /// There were IO issues
    IO(IOError),
    /// Json was invalid
    InvalidJson(ParserError),
    /// Couldn't format Json server-side
    UnableToFormat(EncoderError)
}

/// Receives a packet from the given stream.
fn receive_packet(stream: &mut Read) -> Result<Json, ResponseError> {
    let mut buffer = [0u8; 4];
    try!(stream.read_exact(&mut buffer).map_err(ResponseError::IO));
    // This is what the byteorder crate does (needs testing)
    let len = u32::from_be(unsafe { buffer.as_ptr() as *const u32 } as u32);
    trace!("Listening for packet of length {}", len);
    return Json::from_reader(&mut stream.take(len as u64))
        .map_err(ResponseError::InvalidJson);
}

fn write_packet(stream: &mut Write, packet: &Json) -> Result<(), ResponseError> {
    let json_string = try!(encode(packet).map_err(ResponseError::UnableToFormat));
    trace!("Writing packet of length {}: {}", json_string.len(), json_string);
    if json_string.len() as u32 > ::std::u32::MAX {
        panic!("Attempted to send reply too big for the channel!");
    }
    let len_bytes = unsafe { transmute::<_, [u8; 4]>(json_string.len()) };
    stream.write_all(&len_bytes);
    stream.write_all(json_string.as_bytes()).map_err(ResponseError::IO)
}

pub fn handle_client(mut stream: UnixStream) {
    println!("Starting connection.");

    // Listen for starting connection
}

fn command(mut stream: UnixStream) {

}

fn event(mut stream: UnixStream) {

}
<commit_msg>Fix mem::transmute size mismatch<commit_after>//! Contains code to handle an IPC channel which is issuing commands.

use std::io::Error as IOError;
use std::io::prelude::*;

use std::mem::transmute;

use rustc_serialize::Encodable;
use rustc_serialize::json::{Json, ToJson, Encoder, encode, ParserError, EncoderError};

use unix_socket::UnixStream;

/// Reasons a client message might be erroneous
#[derive(Debug)]
enum ResponseError {
    /// Connection was closed
    ConnectionClosed,
    /// Some bytes dun goofed
    InvalidString,
    /// There were IO issues
    IO(IOError),
    /// Json was invalid
    InvalidJson(ParserError),
    /// Couldn't format Json server-side
    UnableToFormat(EncoderError)
}

/// Receives a packet from the given stream.
fn receive_packet(stream: &mut Read) -> Result<Json, ResponseError> {
    let mut buffer = [0u8; 4];
    try!(stream.read_exact(&mut buffer).map_err(ResponseError::IO));
    // This is what the byteorder crate does (needs testing)
    let len = u32::from_be(unsafe { buffer.as_ptr() as *const u32 } as u32);
    trace!("Listening for packet of length {}", len);
    return Json::from_reader(&mut stream.take(len as u64))
        .map_err(ResponseError::InvalidJson);
}

fn write_packet(stream: &mut Write, packet: &Json) -> Result<(), ResponseError> {
    let json_string = try!(encode(packet).map_err(ResponseError::UnableToFormat));
    trace!("Writing packet of length {}: {}", json_string.len(), json_string);
    if json_string.len() > ::std::u32::MAX as usize {
        panic!("Attempted to send reply too big for the channel!");
    }
    let _len = json_string.len() as u32;
    let len_bytes = unsafe { transmute::<_, [u8; 4]>(_len) };
    stream.write_all(&len_bytes);
    stream.write_all(json_string.as_bytes()).map_err(ResponseError::IO)
}

pub fn handle_client(mut stream: UnixStream) {
    println!("Starting connection.");

    // Listen for starting connection
}

fn command(mut stream: UnixStream) {

}

fn event(mut stream: UnixStream) {

}
<|endoftext|>


<commit_before>//! Support for project-related template files and generation.  Used to
//! implementing things like the `new` command.

use handlebars as hb;
use include_dir::{include_dir, Dir, DirEntry};
use serde::Serialize;
use std::collections::BTreeMap;
use std::fmt;
use std::fs;
use std::io;
use std::path::{Path, PathBuf, MAIN_SEPARATOR};

use crate::errors::*;
use crate::util::ConductorPathExt;

/// A data directory, built into our app at compile-time.
static DATA: Dir = include_dir!("data");

/// Escape double quotes and backslashes in a string that we're rendering,
/// which should work well more-or-less well enough for all the formats
/// we're generating.
///
/// If we need to add new formats, we can add more escape functions and
/// switch between them based on file extension.
fn escape_double_quotes(data: &str) -> String {
    data.replace(r#"\"#, r#"\\"#).replace(r#"""#, r#"\""#)
}

/// A set of files which can be generated.
pub struct Template {
    /// The name used to create this template.
    name: String,
    /// File data associated with this template.
    files: BTreeMap<PathBuf, String>,
}

impl Template {
    /// Create a new template, loading it from a subdirectory of `data/`
    /// specified by `template_name`.
    pub fn new<S: Into<String>>(name: S) -> Result<Template> {
        // We need to be careful to respect MAIN_SEPARATOR on Windows.
        let name = name.into();
        let s = MAIN_SEPARATOR;
        let prefix = format!("templates{}{}{}", s, &name, s);
        let glob = format!("{}**{}*", prefix, s);
        let sep_underscore = format!("{}_", s);

        // Iterate over all matching files built into this library at compile time.
        let mut files = BTreeMap::new();
        for entry in DATA.find(&glob)? {
            if let DirEntry::File(file) = entry {
                trace!("checking template path {} in prefix {}", file.path, prefix);
                assert!(file.path.starts_with(&prefix));
                let rel: &str = &file.path[prefix.len()..];
                // Make sure it doesn't belong to a child template.
                if !rel.starts_with('_') && !rel.contains(&sep_underscore) {
                    // Load this file and add it to our list.
                    let raw_data = file.contents().to_owned();
                    let data = String::from_utf8(raw_data)?;
                    files.insert(Path::new(rel).to_owned(), data);
                }
            }
        }

        Ok(Template { name, files })
    }

    /// Generate this template into `target_dir`, passing `data` to the
    /// Handlebars templates, and writing progress messages to `out`.
    pub fn generate<T>(
        &mut self,
        target_dir: &Path,
        data: &T,
        out: &mut dyn io::Write,
    ) -> Result<()>
    where
        T: Serialize + fmt::Debug,
    {
        debug!("Generating {} with {:?}", &self.name, data);
        for (rel_path, tmpl) in &self.files {
            let path = target_dir.join(rel_path);
            debug!("Output {}", path.display());
            writeln!(out, "Generating: {}", rel_path.display())?;
            let mkerr = || ErrorKind::CouldNotWriteFile(path.clone());

            // Make sure our parent directory exists.
            path.with_guaranteed_parent()?;

            // Create our output file.
            let out = fs::File::create(&path).chain_err(&mkerr)?;
            let mut writer = io::BufWriter::new(out);

            // Render our template to the file.
            // Create our Handlebars template engine.
            let mut hb = hb::Handlebars::new();
            hb.register_escape_fn(escape_double_quotes);
            hb.render_template_to_write(tmpl, &data, &mut writer)
                .chain_err(&mkerr)?;
        }
        Ok(())
    }
}

#[test]
fn loads_correct_files_for_template() {
    let tmpl = Template::new("test_tmpl").unwrap();
    let keys: Vec<_> = tmpl.files.keys().cloned().collect();
    assert!(keys.contains(&Path::new("test.txt").to_owned()));
    assert!(keys.contains(&Path::new("nested").join("nested.txt")));
    assert!(!keys.contains(&Path::new("_child_tmpl").join("child.txt")));
}
<commit_msg>windows: Keep trying to fix templates<commit_after>//! Support for project-related template files and generation.  Used to
//! implementing things like the `new` command.

use handlebars as hb;
use include_dir::{include_dir, Dir, DirEntry};
use serde::Serialize;
use std::collections::BTreeMap;
use std::fmt;
use std::fs;
use std::io;
use std::path::{Path, PathBuf, MAIN_SEPARATOR};

use crate::errors::*;
use crate::util::ConductorPathExt;

/// A data directory, built into our app at compile-time.
static DATA: Dir = include_dir!("data");

/// Escape double quotes and backslashes in a string that we're rendering,
/// which should work well more-or-less well enough for all the formats
/// we're generating.
///
/// If we need to add new formats, we can add more escape functions and
/// switch between them based on file extension.
fn escape_double_quotes(data: &str) -> String {
    data.replace(r#"\"#, r#"\\"#).replace(r#"""#, r#"\""#)
}

/// A set of files which can be generated.
pub struct Template {
    /// The name used to create this template.
    name: String,
    /// File data associated with this template.
    files: BTreeMap<PathBuf, String>,
}

impl Template {
    /// Create a new template, loading it from a subdirectory of `data/`
    /// specified by `template_name`.
    pub fn new(name: &str) -> Result<Template> {
        // We need to be careful to respect MAIN_SEPARATOR on Windows.
        let s = MAIN_SEPARATOR;
        let name = name.replace('/', &s.to_string());
        let prefix = format!("templates{}{}{}", s, &name, s);
        let glob = format!("{}**{}*", prefix, s);
        let sep_underscore = format!("{}_", s);

        // Iterate over all matching files built into this library at compile time.
        let mut files = BTreeMap::new();
        for entry in DATA.find(&glob)? {
            if let DirEntry::File(file) = entry {
                trace!("checking template path {} in prefix {}", file.path, prefix);
                assert!(file.path.starts_with(&prefix));
                let rel: &str = &file.path[prefix.len()..];
                // Make sure it doesn't belong to a child template.
                if !rel.starts_with('_') && !rel.contains(&sep_underscore) {
                    // Load this file and add it to our list.
                    let raw_data = file.contents().to_owned();
                    let data = String::from_utf8(raw_data)?;
                    files.insert(Path::new(rel).to_owned(), data);
                }
            }
        }

        Ok(Template { name, files })
    }

    /// Generate this template into `target_dir`, passing `data` to the
    /// Handlebars templates, and writing progress messages to `out`.
    pub fn generate<T>(
        &mut self,
        target_dir: &Path,
        data: &T,
        out: &mut dyn io::Write,
    ) -> Result<()>
    where
        T: Serialize + fmt::Debug,
    {
        debug!("Generating {} with {:?}", &self.name, data);
        for (rel_path, tmpl) in &self.files {
            let path = target_dir.join(rel_path);
            debug!("Output {}", path.display());
            writeln!(out, "Generating: {}", rel_path.display())?;
            let mkerr = || ErrorKind::CouldNotWriteFile(path.clone());

            // Make sure our parent directory exists.
            path.with_guaranteed_parent()?;

            // Create our output file.
            let out = fs::File::create(&path).chain_err(&mkerr)?;
            let mut writer = io::BufWriter::new(out);

            // Render our template to the file.
            // Create our Handlebars template engine.
            let mut hb = hb::Handlebars::new();
            hb.register_escape_fn(escape_double_quotes);
            hb.render_template_to_write(tmpl, &data, &mut writer)
                .chain_err(&mkerr)?;
        }
        Ok(())
    }
}

#[test]
fn loads_correct_files_for_template() {
    let tmpl = Template::new("test_tmpl").unwrap();
    let keys: Vec<_> = tmpl.files.keys().cloned().collect();
    assert!(keys.contains(&Path::new("test.txt").to_owned()));
    assert!(keys.contains(&Path::new("nested").join("nested.txt")));
    assert!(!keys.contains(&Path::new("_child_tmpl").join("child.txt")));
}
<|endoftext|>


<commit_before>use super::{attr, elem, EncodeContext, ToHtml};
use chrono::{DateTime, Datelike};
use stencila_schema::*;

/// Encode a `Date` to HTML
///
/// Takes a similar approach to the encoding of `Cite` nodes in that it encodes parts
/// of the date as spans which the theme can choose to reorder and/or hide.
impl ToHtml for Date {
    fn to_html(&self, _context: &EncodeContext) -> String {
        let content = match DateTime::parse_from_rfc3339(&self.value) {
            Ok(datetime) => [
                elem("span", &[], &datetime.year().to_string()),
                elem("span", &[], &datetime.month().to_string()),
                elem("span", &[], &datetime.day().to_string()),
            ]
            .concat(),
            Err(error) => {
                tracing::warn!("While parsing date `{}`: {}", self.value, error);
                self.value.clone()
            }
        };
        elem("time", &[attr("datetime", &self.value)], &content)
    }
}

/// Encode a dependency of an executable code node
impl ToHtml for CodeExecutableCodeDependencies {
    fn to_html(&self, _context: &EncodeContext) -> String {
        let (node_type, id, execute_required, execute_status, name) = match self {
            CodeExecutableCodeDependencies::CodeChunk(CodeChunk {
                id,
                execute_required,
                execute_status,
                ..
            }) => ("CodeChunk", id, execute_required, execute_status, None),
            CodeExecutableCodeDependencies::Parameter(Parameter { id, name, .. }) => {
                ("Parameter", id, &None, &None, Some(name.as_str()))
            },
            // `CodeExpression` nodes should not assign anything so should not actually be a
            // `CodeExecutableCodeDependencies` variant; so just ignore.
            CodeExecutableCodeDependencies::CodeExpression(..) => return "".to_string()
        };
        elem(
            "stencila-code-dependency",
            &[
                attr("node-type", node_type),
                id.as_ref()
                    .map_or("".to_string(), |value| attr("node-id", value.as_str())),
                name.as_ref()
                    .map_or("".to_string(), |value| attr("node-label", value)),
                execute_required.as_ref().map_or("".to_string(), |value| {
                    attr("execute-required", value.as_ref())
                }),
                execute_status.as_ref().map_or("".to_string(), |value| {
                    attr("execute-status", value.as_ref())
                }),
            ],
            "",
        )
    }
}

/// Encode a dependent of an executable code node
///
/// As for dependencies, encode as a

impl ToHtml for CodeExecutableCodeDependents {
    fn to_html(&self, _context: &EncodeContext) -> String {
        let (node_type, id, execute_required, execute_status) = match self {
            CodeExecutableCodeDependents::CodeChunk(CodeChunk {
                id,
                execute_required,
                execute_status,
                ..
            }) => ("CodeChunk", id, execute_required, execute_status),
            CodeExecutableCodeDependents::CodeExpression(CodeExpression {
                id,
                execute_required,
                execute_status,
                ..
            }) => ("CodeExpression", id, execute_required, execute_status),
        };
        elem(
            "stencila-code-dependent",
            &[
                attr("node-type", node_type),
                id.as_ref()
                    .map_or("".to_string(), |value| attr("node-id", value.as_str())),
                execute_required.as_ref().map_or("".to_string(), |value| {
                    attr("execute-required", value.as_ref())
                }),
                execute_status.as_ref().map_or("".to_string(), |value| {
                    attr("execute-status", value.as_ref())
                }),
            ],
            "",
        )
    }
}
<commit_msg>fix(HTML encoding): Use existing attribute names when encoding attributes for code dependencies<commit_after>use super::{attr, elem, EncodeContext, ToHtml};
use chrono::{DateTime, Datelike};
use stencila_schema::*;

/// Encode a `Date` to HTML
///
/// Takes a similar approach to the encoding of `Cite` nodes in that it encodes parts
/// of the date as spans which the theme can choose to reorder and/or hide.
impl ToHtml for Date {
    fn to_html(&self, _context: &EncodeContext) -> String {
        let content = match DateTime::parse_from_rfc3339(&self.value) {
            Ok(datetime) => [
                elem("span", &[], &datetime.year().to_string()),
                elem("span", &[], &datetime.month().to_string()),
                elem("span", &[], &datetime.day().to_string()),
            ]
            .concat(),
            Err(error) => {
                tracing::warn!("While parsing date `{}`: {}", self.value, error);
                self.value.clone()
            }
        };
        elem("time", &[attr("datetime", &self.value)], &content)
    }
}

/// Encode a dependency of an executable code node
impl ToHtml for CodeExecutableCodeDependencies {
    fn to_html(&self, _context: &EncodeContext) -> String {
        let (node_type, id, execute_required, execute_status, programming_language, name) =
            match self {
                CodeExecutableCodeDependencies::CodeChunk(CodeChunk {
                    id,
                    programming_language,
                    execute_required,
                    execute_status,
                    ..
                }) => (
                    "CodeChunk",
                    id,
                    execute_required,
                    execute_status,
                    Some(programming_language),
                    None,
                ),
                CodeExecutableCodeDependencies::Parameter(Parameter { id, name, .. }) => {
                    ("Parameter", id, &None, &None, None, Some(name.as_str()))
                }
                // `CodeExpression` nodes should not assign anything so should not actually be a
                // `CodeExecutableCodeDependencies` variant; so just ignore.
                CodeExecutableCodeDependencies::CodeExpression(..) => return "".to_string(),
            };
        elem(
            "stencila-code-dependency",
            &[
                attr("node-type", node_type),
                id.as_ref()
                    .map_or("".to_string(), |value| attr("node-id", value.as_str())),
                execute_required.as_ref().map_or("".to_string(), |value| {
                    attr("execute-required", value.as_ref())
                }),
                execute_status.as_ref().map_or("".to_string(), |value| {
                    attr("execute-status", value.as_ref())
                }),
                programming_language
                    .as_ref()
                    .map_or("".to_string(), |value| attr("programming-language", value)),
                name.as_ref()
                    .map_or("".to_string(), |value| attr("name", value)),
            ],
            "",
        )
    }
}

/// Encode a dependent of an executable code node
///
/// As for dependencies, encode as a

impl ToHtml for CodeExecutableCodeDependents {
    fn to_html(&self, _context: &EncodeContext) -> String {
        let (node_type, id, execute_required, execute_status, programming_language) = match self {
            CodeExecutableCodeDependents::CodeChunk(CodeChunk {
                id,
                programming_language,
                execute_required,
                execute_status,
                ..
            }) => (
                "CodeChunk",
                id,
                execute_required,
                execute_status,
                programming_language,
            ),
            CodeExecutableCodeDependents::CodeExpression(CodeExpression {
                id,
                programming_language,
                execute_required,
                execute_status,
                ..
            }) => (
                "CodeExpression",
                id,
                execute_required,
                execute_status,
                programming_language,
            ),
        };
        elem(
            "stencila-code-dependent",
            &[
                attr("node-type", node_type),
                id.as_ref()
                    .map_or("".to_string(), |value| attr("node-id", value.as_str())),
                execute_required.as_ref().map_or("".to_string(), |value| {
                    attr("execute-required", value.as_ref())
                }),
                execute_status.as_ref().map_or("".to_string(), |value| {
                    attr("execute-status", value.as_ref())
                }),
                attr("programming-language", programming_language),
            ],
            "",
        )
    }
}
<|endoftext|>


<commit_before>// Copyright (C) 2016, 2017 Élisabeth HENRY.
//
// This file is part of Crowbook.
//
// Crowbook is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 2.1 of the License, or
// (at your option) any later version.
//
// Caribon is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received ba copy of the GNU Lesser General Public License
// along with Crowbook.  If not, see <http://www.gnu.org/licenses/>.

use error::{Error, Result, Source};
use html::HtmlRenderer;
use html::Highlight;
use book::{Book, compile_str};
use token::Token;
use renderer::Renderer;
use book_renderer::BookRenderer;
use parser::Parser;
use text_view::view_as_text;

use rustc_serialize::base64::{self, ToBase64};

use std::convert::{AsMut, AsRef};
use std::io;
use std::mem;

/// Interactive fiction HTML renderer
///
/// Renders a standalone, self-contained HTML file
pub struct HtmlIfRenderer<'a> {
    html: HtmlRenderer<'a>,
    n_fn: u32,
    curr_init: String,
    fn_defs: String,
}

impl<'a> HtmlIfRenderer<'a> {
    /// Creates a new HtmlIfRenderer
    pub fn new(book: &'a Book) -> Result<HtmlIfRenderer<'a>> {
        let mut html = HtmlRenderer::new(book,
                                         book.options
                                         .get_str("html.highlight.theme")
                                         .unwrap_or_else(|_| book.options.get_str("rendering.highlight.theme").unwrap()))?;
        html.handler.set_images_mapping(true);
        html.handler.set_base64(true);
        Ok(
            HtmlIfRenderer {
                html: html,
                n_fn: 0,
                curr_init: String::new(),
                fn_defs: String::new(),
            }
        )
    }

    /// Renders a token
    ///
    /// Used by render_token implementation of Renderer trait. Separate function
    /// because we need to be able to call it from other renderers.
    ///
    /// See http://lise-henry.github.io/articles/rust_inheritance.html
    #[doc(hidden)]
    pub fn static_render_token<T>(this: &mut T, token: &Token) -> Result<String>
    where T: AsMut<HtmlIfRenderer<'a>>+AsRef<HtmlIfRenderer<'a>> +
        AsMut<HtmlRenderer<'a>>+AsRef<HtmlRenderer<'a>> + Renderer
    {
        match *token {
            Token::CodeBlock(ref language, ref v) if language == "" => {
                let mut html_if: &mut HtmlIfRenderer = this.as_mut();
                let code = view_as_text(v);
                let id = html_if.n_fn;
                html_if.fn_defs
                    .push_str(&format!("function fn_{id}() {{
    {code}
}}\n",
                                       id = id,
                                       code = code));
                html_if.curr_init
                    .push_str(&format!("    result = fn_{id}();
    if (result != undefined) {{
        document.getElementById(\"result_{id}\").innerHTML = fn_{id}();
    }}\n",
                                       id = id));
                let content = format!("

\n",
                                      (html_if.n_fn));
                html_if.n_fn += 1;
                Ok(content)

            },
            _ => HtmlRenderer::static_render_token(this, token)
        }
    }

    /// Render books as a standalone HTML file
    pub fn render_book(&mut self) -> Result<String> {
        let mut content = String::new();

        let mut titles = vec![];
        let mut chapters = vec![];
        let render_notes_chapter = true;

        for (i, chapter) in self.html.book.chapters.iter().enumerate() {
            self.html.handler.add_link(chapter.filename.as_ref(),
                                       format!("#chapter-{}", i));
        }

        for (i, chapter) in self.html.book.chapters.iter().enumerate() {
            let n = chapter.number;
            let v = &chapter.content;
            self.html.chapter_config(i, n, String::new());

            let mut title = String::new();
            for token in v {
                match *token {
                    Token::Header(1, ref vec) => {
                        if self.html.current_hide || self.html.current_numbering == 0 {
                            title = self.html.render_vec(vec)?;
                        } else {
                            title = self.html
                                .book
                                .get_chapter_header(self.html.current_chapter[1] + 1,
                                                    self.html.render_vec(vec)?,
                                                    |s| {
                                                        self.render_vec(&Parser::new()
                                                            .parse_inline(s)?)
                                                    })?
                                .text;
                        }
                        break;
                    }
                    _ => {
                        continue;
                    }
                }
            }
            titles.push(title);

            chapters.push(format!("

  {}

",
                                  i,
                                  HtmlRenderer::render_html(self, v, render_notes_chapter)?));
            self.fn_defs.push_str(&format!("initFns.push(function () {{
    {code}
}})\n",
                                           code = self.curr_init));
            self.curr_init = String::new();
        }

        self.html.source = Source::empty();

        for chapter in &chapters {
            content.push_str(chapter);
        }
        self.html.render_end_notes(&mut content);

        // Render the CSS
        let template_css = compile_str(self.html.book.get_template("html.css")?
                                       .as_ref(),
                                       &self.html.book.source,
                                       "html.css")?;
        let mut data = self.html
            .book
            .get_metadata(|s| self.render_vec(&Parser::new().parse_inline(s)?))?
            .insert_str("colours",
                        self.html.book.get_template("html.css.colours")?);
        if let Ok(html_css_add) = self.html.book.options.get_str("html.css.add") {
            data = data.insert_str("additional_code", html_css_add);
        }
        let data = data.build();
        let mut res: Vec<u8> = vec![];
        template_css.render_data(&mut res, &data)?;
        let css = String::from_utf8_lossy(&res);

        // Render the JS
        let template_js =
            compile_str(self.html.book.get_template("html.if.js")?.as_ref(),
                        &self.html.book.source,
                        "html.standalone.js")?;
        let data = self.html.book.get_metadata(|s| Ok(s.to_owned()))?
            .insert_bool("one_chapter", true)
            .insert_str("js_prelude", mem::replace(&mut self.fn_defs, String::new()))
            .insert_str("common_script",
                        self.html.book.get_template("html.js").unwrap().as_ref())
            .build();
        let mut res: Vec<u8> = vec![];
        template_js.render_data(&mut res, &data)?;
        let js = String::from_utf8_lossy(&res);

        // Render the HTML document
        let mut mapbuilder = self.html
            .book
            .get_metadata(|s| self.render_vec(&Parser::new().parse_inline(s)?))?
            .insert_str("content", content)
            .insert_str("script", js)
            .insert_bool(self.html.book.options.get_str("lang").unwrap(), true)
            .insert_bool("one_chapter", true)
            .insert_str("style", css.as_ref())
            .insert_str("print_style",
                        self.html.book.get_template("html.css.print").unwrap())
            .insert_str("footer", HtmlRenderer::get_footer(self)?)
            .insert_str("header", HtmlRenderer::get_header(self)?)
            .insert_bool("has_toc", false);
        if let Ok(favicon) = self.html.book.options.get_path("html.icon") {
                let favicon = self.html.handler.map_image(&self.html.book.source, favicon)?;
                mapbuilder = mapbuilder.insert_str("favicon", format!("<link rel = \"icon\" href = \"{}\">", favicon));
            }
        if self.html.highlight == Highlight::Js {
            let highlight_js = self.html.book.get_template("html.highlight.js")?
                .as_bytes()
                .to_base64(base64::STANDARD);
            let highlight_js = format!("data:text/javascript;base64,{}", highlight_js);
            mapbuilder = mapbuilder.insert_bool("highlight_code", true)
                .insert_str("highlight_css",
                            self.html.book.get_template("html.highlight.css")?)
                .insert_str("highlight_js", highlight_js);
        }
        let data = mapbuilder.build();
        let template = compile_str(self.html.book.get_template("html.standalone.template")?
                                   .as_ref(),
                                   &self.html.book.source,
                                   "html.standalone.template")?;
        let mut res = vec![];
        template.render_data(&mut res, &data)?;
        Ok(String::from_utf8_lossy(&res).into_owned())
    }
}

derive_html!{HtmlIfRenderer<'a>, HtmlIfRenderer::static_render_token}

pub struct HtmlIf {}

impl BookRenderer for HtmlIf {
    fn render(&self, book: &Book, to: &mut io::Write) -> Result<()> {
        let mut html = HtmlIfRenderer::new(book)?;
        let result = html.render_book()?;
        to.write_all(result.as_bytes())
            .map_err(|e| {
                Error::render(&book.source,
                              lformat!("problem when writing interactive fiction: {error}", error = e))
            })?;
        Ok(())
    }
}
<commit_msg>Add support for Markdown inside javascript element<commit_after>// Copyright (C) 2016, 2017 Élisabeth HENRY.
//
// This file is part of Crowbook.
//
// Crowbook is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 2.1 of the License, or
// (at your option) any later version.
//
// Caribon is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received ba copy of the GNU Lesser General Public License
// along with Crowbook.  If not, see <http://www.gnu.org/licenses/>.

use error::{Error, Result, Source};
use html::HtmlRenderer;
use html::Highlight;
use book::{Book, compile_str};
use token::Token;
use renderer::Renderer;
use book_renderer::BookRenderer;
use parser::Parser;
use text_view::view_as_text;

use rustc_serialize::base64::{self, ToBase64};

use std::convert::{AsMut, AsRef};
use std::io;
use std::mem;

/// Interactive fiction HTML renderer
///
/// Renders a standalone, self-contained HTML file
pub struct HtmlIfRenderer<'a> {
    html: HtmlRenderer<'a>,
    n_fn: u32,
    curr_init: String,
    fn_defs: String,
}

impl<'a> HtmlIfRenderer<'a> {
    /// Creates a new HtmlIfRenderer
    pub fn new(book: &'a Book) -> Result<HtmlIfRenderer<'a>> {
        let mut html = HtmlRenderer::new(book,
                                         book.options
                                         .get_str("html.highlight.theme")
                                         .unwrap_or_else(|_| book.options.get_str("rendering.highlight.theme").unwrap()))?;
        html.handler.set_images_mapping(true);
        html.handler.set_base64(true);
        Ok(
            HtmlIfRenderer {
                html: html,
                n_fn: 0,
                curr_init: String::new(),
                fn_defs: String::new(),
            }
        )
    }

    /// Renders a token
    ///
    /// Used by render_token implementation of Renderer trait. Separate function
    /// because we need to be able to call it from other renderers.
    ///
    /// See http://lise-henry.github.io/articles/rust_inheritance.html
    #[doc(hidden)]
    pub fn static_render_token<T>(this: &mut T, token: &Token) -> Result<String>
    where T: AsMut<HtmlIfRenderer<'a>>+AsRef<HtmlIfRenderer<'a>> +
        AsMut<HtmlRenderer<'a>>+AsRef<HtmlRenderer<'a>> + Renderer
    {
        match *token {
            Token::CodeBlock(ref language, ref v) if language == "" => {
                let mut html_if: &mut HtmlIfRenderer = this.as_mut();
                let code = view_as_text(v);
                let mut gen_code = String::new();
                let mut i = 0;
                while let Some(begin) = code[i..].find("@\"") {
                    let begin = i + begin;
                    if let Some(len) = code[begin..].find("\"@") {
                        let end = begin + len;
                        gen_code.push_str(&code[i..begin]);
                        gen_code.push('"');
                        gen_code.push_str(&html_if.render_vec(
                            &Parser::new()
                                .parse(&code[begin+2..end])?)?
                                          .replace('"', "\\\"")
                                          .replace('\n', "\\\n"));
                        gen_code.push('"');
                        i = end + 2;
                    }  else {
                        gen_code.push_str(&code[i..begin+2]);
                        i = begin + 2;
                    }
                }
                gen_code.push_str(&code[i..]);
                let id = html_if.n_fn;
                html_if.fn_defs
                    .push_str(&format!("function fn_{id}() {{
    {code}
}}\n",
                                       id = id,
                                       code = gen_code));
                html_if.curr_init
                    .push_str(&format!("    result = fn_{id}();
    if (result != undefined) {{
        document.getElementById(\"result_{id}\").innerHTML = fn_{id}();
    }}\n",
                                       id = id));
                let content = format!("

\n",
                                      (html_if.n_fn));
                html_if.n_fn += 1;
                Ok(content)

            },
            _ => HtmlRenderer::static_render_token(this, token)
        }
    }

    /// Render books as a standalone HTML file
    pub fn render_book(&mut self) -> Result<String> {
        let mut content = String::new();

        let mut titles = vec![];
        let mut chapters = vec![];
        let render_notes_chapter = true;

        for (i, chapter) in self.html.book.chapters.iter().enumerate() {
            self.html.handler.add_link(chapter.filename.as_ref(),
                                       format!("#chapter-{}", i));
        }

        for (i, chapter) in self.html.book.chapters.iter().enumerate() {
            let n = chapter.number;
            let v = &chapter.content;
            self.html.chapter_config(i, n, String::new());

            let mut title = String::new();
            for token in v {
                match *token {
                    Token::Header(1, ref vec) => {
                        if self.html.current_hide || self.html.current_numbering == 0 {
                            title = self.html.render_vec(vec)?;
                        } else {
                            title = self.html
                                .book
                                .get_chapter_header(self.html.current_chapter[1] + 1,
                                                    self.html.render_vec(vec)?,
                                                    |s| {
                                                        self.render_vec(&Parser::new()
                                                            .parse_inline(s)?)
                                                    })?
                                .text;
                        }
                        break;
                    }
                    _ => {
                        continue;
                    }
                }
            }
            titles.push(title);

            chapters.push(format!("

  {}

",
                                  i,
                                  HtmlRenderer::render_html(self, v, render_notes_chapter)?));
            self.fn_defs.push_str(&format!("initFns.push(function () {{
    {code}
}})\n",
                                           code = self.curr_init));
            self.curr_init = String::new();
        }

        self.html.source = Source::empty();

        for chapter in &chapters {
            content.push_str(chapter);
        }
        self.html.render_end_notes(&mut content);

        // Render the CSS
        let template_css = compile_str(self.html.book.get_template("html.css")?
                                       .as_ref(),
                                       &self.html.book.source,
                                       "html.css")?;
        let mut data = self.html
            .book
            .get_metadata(|s| self.render_vec(&Parser::new().parse_inline(s)?))?
            .insert_str("colours",
                        self.html.book.get_template("html.css.colours")?);
        if let Ok(html_css_add) = self.html.book.options.get_str("html.css.add") {
            data = data.insert_str("additional_code", html_css_add);
        }
        let data = data.build();
        let mut res: Vec<u8> = vec![];
        template_css.render_data(&mut res, &data)?;
        let css = String::from_utf8_lossy(&res);

        // Render the JS
        let template_js =
            compile_str(self.html.book.get_template("html.if.js")?.as_ref(),
                        &self.html.book.source,
                        "html.standalone.js")?;
        let data = self.html.book.get_metadata(|s| Ok(s.to_owned()))?
            .insert_bool("one_chapter", true)
            .insert_str("js_prelude", mem::replace(&mut self.fn_defs, String::new()))
            .insert_str("common_script",
                        self.html.book.get_template("html.js").unwrap().as_ref())
            .build();
        let mut res: Vec<u8> = vec![];
        template_js.render_data(&mut res, &data)?;
        let js = String::from_utf8_lossy(&res);

        // Render the HTML document
        let mut mapbuilder = self.html
            .book
            .get_metadata(|s| self.render_vec(&Parser::new().parse_inline(s)?))?
            .insert_str("content", content)
            .insert_str("script", js)
            .insert_bool(self.html.book.options.get_str("lang").unwrap(), true)
            .insert_bool("one_chapter", true)
            .insert_str("style", css.as_ref())
            .insert_str("print_style",
                        self.html.book.get_template("html.css.print").unwrap())
            .insert_str("footer", HtmlRenderer::get_footer(self)?)
            .insert_str("header", HtmlRenderer::get_header(self)?)
            .insert_bool("has_toc", false);
        if let Ok(favicon) = self.html.book.options.get_path("html.icon") {
                let favicon = self.html.handler.map_image(&self.html.book.source, favicon)?;
                mapbuilder = mapbuilder.insert_str("favicon", format!("<link rel = \"icon\" href = \"{}\">", favicon));
            }
        if self.html.highlight == Highlight::Js {
            let highlight_js = self.html.book.get_template("html.highlight.js")?
                .as_bytes()
                .to_base64(base64::STANDARD);
            let highlight_js = format!("data:text/javascript;base64,{}", highlight_js);
            mapbuilder = mapbuilder.insert_bool("highlight_code", true)
                .insert_str("highlight_css",
                            self.html.book.get_template("html.highlight.css")?)
                .insert_str("highlight_js", highlight_js);
        }
        let data = mapbuilder.build();
        let template = compile_str(self.html.book.get_template("html.standalone.template")?
                                   .as_ref(),
                                   &self.html.book.source,
                                   "html.standalone.template")?;
        let mut res = vec![];
        template.render_data(&mut res, &data)?;
        Ok(String::from_utf8_lossy(&res).into_owned())
    }
}

derive_html!{HtmlIfRenderer<'a>, HtmlIfRenderer::static_render_token}

pub struct HtmlIf {}

impl BookRenderer for HtmlIf {
    fn render(&self, book: &Book, to: &mut io::Write) -> Result<()> {
        let mut html = HtmlIfRenderer::new(book)?;
        let result = html.render_book()?;
        to.write_all(result.as_bytes())
            .map_err(|e| {
                Error::render(&book.source,
                              lformat!("problem when writing interactive fiction: {error}", error = e))
            })?;
        Ok(())
    }
}
<|endoftext|>


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

//! Basic functions for dealing with memory
//!
//! This module contains functions for querying the size and alignment of
//! types, initializing and manipulating memory.

#![stable(feature = "rust1", since = "1.0.0")]

use marker::Sized;
use intrinsics;
use ptr;

#[stable(feature = "rust1", since = "1.0.0")]
pub use intrinsics::transmute;

/// Moves a thing into the void.
///
/// The forget function will take ownership of the provided value but neglect
/// to run any required cleanup or memory management operations on it.
///
/// This function is the unsafe version of the `drop` function because it does
/// not run any destructors.
#[stable(feature = "rust1", since = "1.0.0")]
pub use intrinsics::forget;

/// Returns the size of a type in bytes.
///
/// # Examples
///
/// ```
/// use std::mem;
///
/// assert_eq!(4, mem::size_of::<i32>());
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn size_of<T>() -> usize {
    unsafe { intrinsics::size_of::<T>() }
}

/// Returns the size of the type that `_val` points to in bytes.
///
/// # Examples
///
/// ```
/// use std::mem;
///
/// assert_eq!(4, mem::size_of_val(&5i32));
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn size_of_val<T>(_val: &T) -> usize {
    size_of::<T>()
}

/// Returns the ABI-required minimum alignment of a type
///
/// This is the alignment used for struct fields. It may be smaller than the preferred alignment.
///
/// # Examples
///
/// ```
/// use std::mem;
///
/// assert_eq!(4, mem::min_align_of::<i32>());
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn min_align_of<T>() -> usize {
    unsafe { intrinsics::min_align_of::<T>() }
}

/// Returns the ABI-required minimum alignment of the type of the value that `_val` points to
///
/// # Examples
///
/// ```
/// use std::mem;
///
/// assert_eq!(4, mem::min_align_of_val(&5i32));
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn min_align_of_val<T>(_val: &T) -> usize {
    min_align_of::<T>()
}

/// Returns the alignment in memory for a type.
///
/// This function will return the alignment, in bytes, of a type in memory. If the alignment
/// returned is adhered to, then the type is guaranteed to function properly.
///
/// # Examples
///
/// ```
/// use std::mem;
///
/// assert_eq!(4, mem::align_of::<i32>());
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn align_of<T>() -> usize {
    // We use the preferred alignment as the default alignment for a type. This
    // appears to be what clang migrated towards as well:
    //
    // http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20110725/044411.html
    unsafe { intrinsics::pref_align_of::<T>() }
}

/// Returns the alignment of the type of the value that `_val` points to.
///
/// This is similar to `align_of`, but function will properly handle types such as trait objects
/// (in the future), returning the alignment for an arbitrary value at runtime.
///
/// # Examples
///
/// ```
/// use std::mem;
///
/// assert_eq!(4, mem::align_of_val(&5i32));
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn align_of_val<T>(_val: &T) -> usize {
    align_of::<T>()
}

/// Create a value initialized to zero.
///
/// This function is similar to allocating space for a local variable and zeroing it out (an unsafe
/// operation).
///
/// Care must be taken when using this function, if the type `T` has a destructor and the value
/// falls out of scope (due to unwinding or returning) before being initialized, then the
/// destructor will run on zeroed data, likely leading to crashes.
///
/// This is useful for FFI functions sometimes, but should generally be avoided.
///
/// # Examples
///
/// ```
/// use std::mem;
///
/// let x: i32 = unsafe { mem::zeroed() };
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn zeroed<T>() -> T {
    intrinsics::init()
}

/// Create a value initialized to an unspecified series of bytes.
///
/// The byte sequence usually indicates that the value at the memory
/// in question has been dropped. Thus, *if* T carries a drop flag,
/// any associated destructor will not be run when the value falls out
/// of scope.
///
/// Some code at one time used the `zeroed` function above to
/// accomplish this goal.
///
/// This function is expected to be deprecated with the transition
/// to non-zeroing drop.
#[inline]
#[unstable(feature = "filling_drop")]
pub unsafe fn dropped<T>() -> T {
    let mut x: T = uninitialized();
    let p: *mut u8 = transmute(&mut x as *mut T);
    for i in 0..size_of::<T>() {
        *p.offset(i as isize) = POST_DROP_U8;
    }
    x
}

/// Create an uninitialized value.
///
/// Care must be taken when using this function, if the type `T` has a destructor and the value
/// falls out of scope (due to unwinding or returning) before being initialized, then the
/// destructor will run on uninitialized data, likely leading to crashes.
///
/// This is useful for FFI functions sometimes, but should generally be avoided.
///
/// # Examples
///
/// ```
/// use std::mem;
///
/// let x: i32 = unsafe { mem::uninitialized() };
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn uninitialized<T>() -> T {
    intrinsics::uninit()
}

/// Swap the values at two mutable locations of the same type, without deinitialising or copying
/// either one.
///
/// # Examples
///
/// ```
/// use std::mem;
///
/// let x = &mut 5;
/// let y = &mut 42;
///
/// mem::swap(x, y);
///
/// assert_eq!(42, *x);
/// assert_eq!(5, *y);
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn swap<T>(x: &mut T, y: &mut T) {
    unsafe {
        // Give ourselves some scratch space to work with
        let mut t: T = uninitialized();

        // Perform the swap, `&mut` pointers never alias
        ptr::copy_nonoverlapping(&mut t, &*x, 1);
        ptr::copy_nonoverlapping(x, &*y, 1);
        ptr::copy_nonoverlapping(y, &t, 1);

        // y and t now point to the same thing, but we need to completely forget `t`
        // because it's no longer relevant.
        forget(t);
    }
}

/// Replace the value at a mutable location with a new one, returning the old value, without
/// deinitialising or copying either one.
///
/// This is primarily used for transferring and swapping ownership of a value in a mutable
/// location.
///
/// # Examples
///
/// A simple example:
///
/// ```
/// use std::mem;
///
/// let mut v: Vec<i32> = Vec::new();
///
/// mem::replace(&mut v, Vec::new());
/// ```
///
/// This function allows consumption of one field of a struct by replacing it with another value.
/// The normal approach doesn't always work:
///
/// ```rust,ignore
/// struct Buffer<T> { buf: Vec<T> }
///
/// impl<T> Buffer<T> {
///     fn get_and_reset(&mut self) -> Vec<T> {
///         // error: cannot move out of dereference of `&mut`-pointer
///         let buf = self.buf;
///         self.buf = Vec::new();
///         buf
///     }
/// }
/// ```
///
/// Note that `T` does not necessarily implement `Clone`, so it can't even clone and reset
/// `self.buf`. But `replace` can be used to disassociate the original value of `self.buf` from
/// `self`, allowing it to be returned:
///
/// ```
/// use std::mem;
/// # struct Buffer<T> { buf: Vec<T> }
/// impl<T> Buffer<T> {
///     fn get_and_reset(&mut self) -> Vec<T> {
///         mem::replace(&mut self.buf, Vec::new())
///     }
/// }
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn replace<T>(dest: &mut T, mut src: T) -> T {
    swap(dest, &mut src);
    src
}

/// Disposes of a value.
///
/// This function can be used to destroy any value by allowing `drop` to take ownership of its
/// argument.
///
/// # Examples
///
/// ```
/// use std::cell::RefCell;
///
/// let x = RefCell::new(1);
///
/// let mut mutable_borrow = x.borrow_mut();
/// *mutable_borrow = 1;
///
/// drop(mutable_borrow); // relinquish the mutable borrow on this slot
///
/// let borrow = x.borrow();
/// println!("{}", *borrow);
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn drop<T>(_x: T) { }

macro_rules! repeat_u8_as_u32 {
    ($name:expr) => { (($name as u32) << 24 |
                       ($name as u32) << 16 |
                       ($name as u32) <<  8 |
                       ($name as u32)) }
}
macro_rules! repeat_u8_as_u64 {
    ($name:expr) => { ((repeat_u8_as_u32!($name) as u64) << 32 |
                       (repeat_u8_as_u32!($name) as u64)) }
}

// NOTE: Keep synchronized with values used in librustc_trans::trans::adt.
//
// In particular, the POST_DROP_U8 marker must never equal the
// DTOR_NEEDED_U8 marker.
//
// For a while pnkfelix was using 0xc1 here.
// But having the sign bit set is a pain, so 0x1d is probably better.
//
// And of course, 0x00 brings back the old world of zero'ing on drop.
#[cfg(not(stage0))] pub const POST_DROP_U8: u8 = 0x1d;
#[cfg(not(stage0))] pub const POST_DROP_U32: u32 = repeat_u8_as_u32!(POST_DROP_U8);
#[cfg(not(stage0))] pub const POST_DROP_U64: u64 = repeat_u8_as_u64!(POST_DROP_U8);

#[cfg(target_pointer_width = "32")]
#[cfg(not(stage0))] pub const POST_DROP_USIZE: usize = POST_DROP_U32 as usize;
#[cfg(target_pointer_width = "64")]
#[cfg(not(stage0))] pub const POST_DROP_USIZE: usize = POST_DROP_U64 as usize;

#[cfg(stage0)] pub const POST_DROP_U8: u8 = 0;
#[cfg(stage0)] pub const POST_DROP_U32: u32 = 0;
#[cfg(stage0)] pub const POST_DROP_U64: u64 = 0;
#[cfg(stage0)] pub const POST_DROP_USIZE: usize = 0;

/// Interprets `src` as `&U`, and then reads `src` without moving the contained value.
///
/// This function will unsafely assume the pointer `src` is valid for `sizeof(U)` bytes by
/// transmuting `&T` to `&U` and then reading the `&U`. It will also unsafely create a copy of the
/// contained value instead of moving out of `src`.
///
/// It is not a compile-time error if `T` and `U` have different sizes, but it is highly encouraged
/// to only invoke this function where `T` and `U` have the same size. This function triggers
/// undefined behavior if `U` is larger than `T`.
///
/// # Examples
///
/// ```
/// use std::mem;
///
/// let one = unsafe { mem::transmute_copy(&1) };
///
/// assert_eq!(1, one);
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
    // FIXME(#23542) Replace with type ascription.
    #![allow(trivial_casts)]
    ptr::read(src as *const T as *const U)
}

/// Transforms lifetime of the second pointer to match the first.
#[inline]
#[unstable(feature = "core",
           reason = "this function may be removed in the future due to its \
                     questionable utility")]
pub unsafe fn copy_lifetime<'a, S: ?Sized, T: ?Sized + 'a>(_ptr: &'a S,
                                                        ptr: &T) -> &'a T {
    transmute(ptr)
}

/// Transforms lifetime of the second mutable pointer to match the first.
#[inline]
#[unstable(feature = "core",
           reason = "this function may be removed in the future due to its \
                     questionable utility")]
pub unsafe fn copy_mut_lifetime<'a, S: ?Sized, T: ?Sized + 'a>(_ptr: &'a S,
                                                               ptr: &mut T)
                                                              -> &'a mut T
{
    transmute(ptr)
}
<commit_msg>A better `core::mem::dropped` implementation suggested by huonw on the PR.<commit_after>// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Basic functions for dealing with memory
//!
//! This module contains functions for querying the size and alignment of
//! types, initializing and manipulating memory.

#![stable(feature = "rust1", since = "1.0.0")]

use marker::Sized;
use intrinsics;
use ptr;

#[stable(feature = "rust1", since = "1.0.0")]
pub use intrinsics::transmute;

/// Moves a thing into the void.
///
/// The forget function will take ownership of the provided value but neglect
/// to run any required cleanup or memory management operations on it.
///
/// This function is the unsafe version of the `drop` function because it does
/// not run any destructors.
#[stable(feature = "rust1", since = "1.0.0")]
pub use intrinsics::forget;

/// Returns the size of a type in bytes.
///
/// # Examples
///
/// ```
/// use std::mem;
///
/// assert_eq!(4, mem::size_of::<i32>());
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn size_of<T>() -> usize {
    unsafe { intrinsics::size_of::<T>() }
}

/// Returns the size of the type that `_val` points to in bytes.
///
/// # Examples
///
/// ```
/// use std::mem;
///
/// assert_eq!(4, mem::size_of_val(&5i32));
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn size_of_val<T>(_val: &T) -> usize {
    size_of::<T>()
}

/// Returns the ABI-required minimum alignment of a type
///
/// This is the alignment used for struct fields. It may be smaller than the preferred alignment.
///
/// # Examples
///
/// ```
/// use std::mem;
///
/// assert_eq!(4, mem::min_align_of::<i32>());
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn min_align_of<T>() -> usize {
    unsafe { intrinsics::min_align_of::<T>() }
}

/// Returns the ABI-required minimum alignment of the type of the value that `_val` points to
///
/// # Examples
///
/// ```
/// use std::mem;
///
/// assert_eq!(4, mem::min_align_of_val(&5i32));
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn min_align_of_val<T>(_val: &T) -> usize {
    min_align_of::<T>()
}

/// Returns the alignment in memory for a type.
///
/// This function will return the alignment, in bytes, of a type in memory. If the alignment
/// returned is adhered to, then the type is guaranteed to function properly.
///
/// # Examples
///
/// ```
/// use std::mem;
///
/// assert_eq!(4, mem::align_of::<i32>());
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn align_of<T>() -> usize {
    // We use the preferred alignment as the default alignment for a type. This
    // appears to be what clang migrated towards as well:
    //
    // http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20110725/044411.html
    unsafe { intrinsics::pref_align_of::<T>() }
}

/// Returns the alignment of the type of the value that `_val` points to.
///
/// This is similar to `align_of`, but function will properly handle types such as trait objects
/// (in the future), returning the alignment for an arbitrary value at runtime.
///
/// # Examples
///
/// ```
/// use std::mem;
///
/// assert_eq!(4, mem::align_of_val(&5i32));
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn align_of_val<T>(_val: &T) -> usize {
    align_of::<T>()
}

/// Create a value initialized to zero.
///
/// This function is similar to allocating space for a local variable and zeroing it out (an unsafe
/// operation).
///
/// Care must be taken when using this function, if the type `T` has a destructor and the value
/// falls out of scope (due to unwinding or returning) before being initialized, then the
/// destructor will run on zeroed data, likely leading to crashes.
///
/// This is useful for FFI functions sometimes, but should generally be avoided.
///
/// # Examples
///
/// ```
/// use std::mem;
///
/// let x: i32 = unsafe { mem::zeroed() };
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn zeroed<T>() -> T {
    intrinsics::init()
}

/// Create a value initialized to an unspecified series of bytes.
///
/// The byte sequence usually indicates that the value at the memory
/// in question has been dropped. Thus, *if* T carries a drop flag,
/// any associated destructor will not be run when the value falls out
/// of scope.
///
/// Some code at one time used the `zeroed` function above to
/// accomplish this goal.
///
/// This function is expected to be deprecated with the transition
/// to non-zeroing drop.
#[inline]
#[unstable(feature = "filling_drop")]
pub unsafe fn dropped<T>() -> T {
    #[cfg(stage0)]
    #[inline(always)]
    unsafe fn dropped_impl<T>() -> T { zeroed() }

    #[cfg(not(stage0))]
    #[inline(always)]
    unsafe fn dropped_impl<T>() -> T { intrinsics::init_dropped() }

    dropped_impl()
}

/// Create an uninitialized value.
///
/// Care must be taken when using this function, if the type `T` has a destructor and the value
/// falls out of scope (due to unwinding or returning) before being initialized, then the
/// destructor will run on uninitialized data, likely leading to crashes.
///
/// This is useful for FFI functions sometimes, but should generally be avoided.
///
/// # Examples
///
/// ```
/// use std::mem;
///
/// let x: i32 = unsafe { mem::uninitialized() };
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn uninitialized<T>() -> T {
    intrinsics::uninit()
}

/// Swap the values at two mutable locations of the same type, without deinitialising or copying
/// either one.
///
/// # Examples
///
/// ```
/// use std::mem;
///
/// let x = &mut 5;
/// let y = &mut 42;
///
/// mem::swap(x, y);
///
/// assert_eq!(42, *x);
/// assert_eq!(5, *y);
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn swap<T>(x: &mut T, y: &mut T) {
    unsafe {
        // Give ourselves some scratch space to work with
        let mut t: T = uninitialized();

        // Perform the swap, `&mut` pointers never alias
        ptr::copy_nonoverlapping(&mut t, &*x, 1);
        ptr::copy_nonoverlapping(x, &*y, 1);
        ptr::copy_nonoverlapping(y, &t, 1);

        // y and t now point to the same thing, but we need to completely forget `t`
        // because it's no longer relevant.
        forget(t);
    }
}

/// Replace the value at a mutable location with a new one, returning the old value, without
/// deinitialising or copying either one.
///
/// This is primarily used for transferring and swapping ownership of a value in a mutable
/// location.
///
/// # Examples
///
/// A simple example:
///
/// ```
/// use std::mem;
///
/// let mut v: Vec<i32> = Vec::new();
///
/// mem::replace(&mut v, Vec::new());
/// ```
///
/// This function allows consumption of one field of a struct by replacing it with another value.
/// The normal approach doesn't always work:
///
/// ```rust,ignore
/// struct Buffer<T> { buf: Vec<T> }
///
/// impl<T> Buffer<T> {
///     fn get_and_reset(&mut self) -> Vec<T> {
///         // error: cannot move out of dereference of `&mut`-pointer
///         let buf = self.buf;
///         self.buf = Vec::new();
///         buf
///     }
/// }
/// ```
///
/// Note that `T` does not necessarily implement `Clone`, so it can't even clone and reset
/// `self.buf`. But `replace` can be used to disassociate the original value of `self.buf` from
/// `self`, allowing it to be returned:
///
/// ```
/// use std::mem;
/// # struct Buffer<T> { buf: Vec<T> }
/// impl<T> Buffer<T> {
///     fn get_and_reset(&mut self) -> Vec<T> {
///         mem::replace(&mut self.buf, Vec::new())
///     }
/// }
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn replace<T>(dest: &mut T, mut src: T) -> T {
    swap(dest, &mut src);
    src
}

/// Disposes of a value.
///
/// This function can be used to destroy any value by allowing `drop` to take ownership of its
/// argument.
///
/// # Examples
///
/// ```
/// use std::cell::RefCell;
///
/// let x = RefCell::new(1);
///
/// let mut mutable_borrow = x.borrow_mut();
/// *mutable_borrow = 1;
///
/// drop(mutable_borrow); // relinquish the mutable borrow on this slot
///
/// let borrow = x.borrow();
/// println!("{}", *borrow);
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn drop<T>(_x: T) { }

macro_rules! repeat_u8_as_u32 {
    ($name:expr) => { (($name as u32) << 24 |
                       ($name as u32) << 16 |
                       ($name as u32) <<  8 |
                       ($name as u32)) }
}
macro_rules! repeat_u8_as_u64 {
    ($name:expr) => { ((repeat_u8_as_u32!($name) as u64) << 32 |
                       (repeat_u8_as_u32!($name) as u64)) }
}

// NOTE: Keep synchronized with values used in librustc_trans::trans::adt.
//
// In particular, the POST_DROP_U8 marker must never equal the
// DTOR_NEEDED_U8 marker.
//
// For a while pnkfelix was using 0xc1 here.
// But having the sign bit set is a pain, so 0x1d is probably better.
//
// And of course, 0x00 brings back the old world of zero'ing on drop.
#[cfg(not(stage0))] pub const POST_DROP_U8: u8 = 0x1d;
#[cfg(not(stage0))] pub const POST_DROP_U32: u32 = repeat_u8_as_u32!(POST_DROP_U8);
#[cfg(not(stage0))] pub const POST_DROP_U64: u64 = repeat_u8_as_u64!(POST_DROP_U8);

#[cfg(target_pointer_width = "32")]
#[cfg(not(stage0))] pub const POST_DROP_USIZE: usize = POST_DROP_U32 as usize;
#[cfg(target_pointer_width = "64")]
#[cfg(not(stage0))] pub const POST_DROP_USIZE: usize = POST_DROP_U64 as usize;

#[cfg(stage0)] pub const POST_DROP_U8: u8 = 0;
#[cfg(stage0)] pub const POST_DROP_U32: u32 = 0;
#[cfg(stage0)] pub const POST_DROP_U64: u64 = 0;
#[cfg(stage0)] pub const POST_DROP_USIZE: usize = 0;

/// Interprets `src` as `&U`, and then reads `src` without moving the contained value.
///
/// This function will unsafely assume the pointer `src` is valid for `sizeof(U)` bytes by
/// transmuting `&T` to `&U` and then reading the `&U`. It will also unsafely create a copy of the
/// contained value instead of moving out of `src`.
///
/// It is not a compile-time error if `T` and `U` have different sizes, but it is highly encouraged
/// to only invoke this function where `T` and `U` have the same size. This function triggers
/// undefined behavior if `U` is larger than `T`.
///
/// # Examples
///
/// ```
/// use std::mem;
///
/// let one = unsafe { mem::transmute_copy(&1) };
///
/// assert_eq!(1, one);
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
    // FIXME(#23542) Replace with type ascription.
    #![allow(trivial_casts)]
    ptr::read(src as *const T as *const U)
}

/// Transforms lifetime of the second pointer to match the first.
#[inline]
#[unstable(feature = "core",
           reason = "this function may be removed in the future due to its \
                     questionable utility")]
pub unsafe fn copy_lifetime<'a, S: ?Sized, T: ?Sized + 'a>(_ptr: &'a S,
                                                        ptr: &T) -> &'a T {
    transmute(ptr)
}

/// Transforms lifetime of the second mutable pointer to match the first.
#[inline]
#[unstable(feature = "core",
           reason = "this function may be removed in the future due to its \
                     questionable utility")]
pub unsafe fn copy_mut_lifetime<'a, S: ?Sized, T: ?Sized + 'a>(_ptr: &'a S,
                                                               ptr: &mut T)
                                                              -> &'a mut T
{
    transmute(ptr)
}
<|endoftext|>


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

pub fn solve(puzzle: &str) -> Option<HashMap<char, u8>> {
    unimplemented!()
}
<commit_msg>Remove unused variable from Alphametics stub<commit_after>use std::collections::HashMap;

pub fn solve(_: &str) -> Option<HashMap<char, u8>> {
    unimplemented!()
}
<|endoftext|>


<commit_before>struct Board {
    pieces: Vec<Vec<char>>,
    num_rows: usize,
    num_cols: usize
}

impl Board {
    fn annotated(&self) -> Vec<String> {
        (0..self.num_rows).map(|y| self.annotated_row(y)).collect()
    }

    fn annotated_row(&self, y: usize) -> String {
        self.pieces[y]
                  .iter()
                  .enumerate()
                  .map(|(x,&c)| if c == ' ' {self.count_neighbouring_mines_char(x, y)} else {c})
                  .collect::<String>()
    }

    fn count_neighbouring_mines_char(&self, x: usize, y: usize) -> char {
        let mut count = 0;
        for x1 in neighbouring_points(x, self.num_cols) {
            for y1 in neighbouring_points(y, self.num_rows) {
                let piece = self.pieces[y1][x1];
                if piece == '*' {
                    count += 1;
                }
            }
        }
        if count == 0 {
            ' '
        } else {
            (('0' as u8) + count) as char
        }
    }
}

pub fn annotate(pieces: &[&str]) -> Vec<String> {
    let pieces_vec = pieces.iter().map(|&r| r.chars().collect()).collect();
    Board {pieces: pieces_vec, num_rows: pieces.len(), num_cols: pieces[0].len()}.annotated()
}

fn neighbouring_points(x: usize, limit: usize) -> Vec<usize> {
    let mut offsets = vec![x];
    if x >= 1 {
        offsets.push(x-1);
    }
    if x+2 <= limit {
        offsets.push(x+1);
    }
    offsets
}
<commit_msg>minesweeper: return empty vector if board has no rows<commit_after>struct Board {
    pieces: Vec<Vec<char>>,
    num_rows: usize,
    num_cols: usize
}

impl Board {
    fn annotated(&self) -> Vec<String> {
        (0..self.num_rows).map(|y| self.annotated_row(y)).collect()
    }

    fn annotated_row(&self, y: usize) -> String {
        self.pieces[y]
                  .iter()
                  .enumerate()
                  .map(|(x,&c)| if c == ' ' {self.count_neighbouring_mines_char(x, y)} else {c})
                  .collect::<String>()
    }

    fn count_neighbouring_mines_char(&self, x: usize, y: usize) -> char {
        let mut count = 0;
        for x1 in neighbouring_points(x, self.num_cols) {
            for y1 in neighbouring_points(y, self.num_rows) {
                let piece = self.pieces[y1][x1];
                if piece == '*' {
                    count += 1;
                }
            }
        }
        if count == 0 {
            ' '
        } else {
            (('0' as u8) + count) as char
        }
    }
}

pub fn annotate(pieces: &[&str]) -> Vec<String> {
    if pieces.len() == 0 {
        return Vec::new();
    }
    let pieces_vec = pieces.iter().map(|&r| r.chars().collect()).collect();
    Board {pieces: pieces_vec, num_rows: pieces.len(), num_cols: pieces[0].len()}.annotated()
}

fn neighbouring_points(x: usize, limit: usize) -> Vec<usize> {
    let mut offsets = vec![x];
    if x >= 1 {
        offsets.push(x-1);
    }
    if x+2 <= limit {
        offsets.push(x+1);
    }
    offsets
}
<|endoftext|>


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

#![feature(test)]

extern crate compiletest_rs as compiletest;
extern crate test;

use std::env::{set_var, var};
use std::ffi::OsStr;
use std::fs;
use std::io;
use std::path::{Path, PathBuf};

fn clippy_driver_path() -> PathBuf {
    if let Some(path) = option_env!("CLIPPY_DRIVER_PATH") {
        PathBuf::from(path)
    } else {
        PathBuf::from(concat!("target/", env!("PROFILE"), "/clippy-driver"))
    }
}

fn host_libs() -> PathBuf {
    if let Some(path) = option_env!("HOST_LIBS") {
        PathBuf::from(path)
    } else {
        Path::new("target").join(env!("PROFILE"))
    }
}

fn rustc_test_suite() -> Option<PathBuf> {
    option_env!("RUSTC_TEST_SUITE").map(PathBuf::from)
}

fn rustc_lib_path() -> PathBuf {
    option_env!("RUSTC_LIB_PATH").unwrap().into()
}

fn config(mode: &str, dir: PathBuf) -> compiletest::Config {
    let mut config = compiletest::Config::default();

    let cfg_mode = mode.parse().expect("Invalid mode");
    if let Ok(name) = var::<&str>("TESTNAME") {
        let s: String = name.to_owned();
        config.filter = Some(s)
    }

    if rustc_test_suite().is_some() {
        config.run_lib_path = rustc_lib_path();
        config.compile_lib_path = rustc_lib_path();
    }
    config.target_rustcflags = Some(format!("-L {0} -L {0}/deps -Dwarnings", host_libs().display()));

    config.mode = cfg_mode;
    config.build_base = if rustc_test_suite().is_some() {
        // we don't need access to the stderr files on travis
        let mut path = PathBuf::from(env!("OUT_DIR"));
        path.push("test_build_base");
        path
    } else {
        let mut path = std::env::current_dir().unwrap();
        path.push("target/debug/test_build_base");
        path
    };
    config.src_base = dir;
    config.rustc_path = clippy_driver_path();
    config
}

fn run_mode(mode: &str, dir: PathBuf) {
    compiletest::run_tests(&config(mode, dir));
}

fn run_ui_toml_tests(config: &compiletest::Config, mut tests: Vec<test::TestDescAndFn>) -> Result<bool, io::Error> {
    let mut result = true;
    let opts = compiletest::test_opts(config);
    for dir in fs::read_dir(&config.src_base)? {
        let dir = dir?;
        if !dir.file_type()?.is_dir() {
            continue;
        }
        let dir_path = dir.path();
        set_var("CARGO_MANIFEST_DIR", &dir_path);
        for file in fs::read_dir(&dir_path)? {
            let file = file?;
            let file_path = file.path();
            if !file.file_type()?.is_file() {
                continue;
            }
            if file_path.extension() != Some(OsStr::new("rs")) {
                continue;
            }
            let paths = compiletest::common::TestPaths {
                file: file_path,
                base: config.src_base.clone(),
                relative_dir: dir_path.file_name().unwrap().into(),
            };
            let test_name = compiletest::make_test_name(&config, &paths);
            let index = tests
                .iter()
                .position(|test| test.desc.name == test_name)
                .expect("The test should be in there");
            result &= test::run_tests_console(&opts, vec![tests.swap_remove(index)])?;
        }
    }
    Ok(result)
}

fn run_ui_toml() {
    let path = PathBuf::from("tests/ui-toml").canonicalize().unwrap();
    let config = config("ui", path);
    let tests = compiletest::make_tests(&config);

    let res = run_ui_toml_tests(&config, tests);
    match res {
        Ok(true) => {},
        Ok(false) => panic!("Some tests failed"),
        Err(e) => {
            println!("I/O failure during tests: {:?}", e);
        },
    }
}

fn prepare_env() {
    set_var("CLIPPY_DISABLE_DOCS_LINKS", "true");
    set_var("CLIPPY_TESTS", "true");
    //set_var("RUST_BACKTRACE", "0");
}

#[test]
fn compile_test() {
    prepare_env();
    run_mode("run-pass", "tests/run-pass".into());
    run_mode("ui", "tests/ui".into());
    run_ui_toml();
}
<commit_msg>compiletest: clean rmeta data (from "cargo check") before running compiletest.<commit_after>// Copyright 2014-2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(test)]

extern crate compiletest_rs as compiletest;
extern crate test;

use std::env::{set_var, var};
use std::ffi::OsStr;
use std::fs;
use std::io;
use std::path::{Path, PathBuf};

fn clippy_driver_path() -> PathBuf {
    if let Some(path) = option_env!("CLIPPY_DRIVER_PATH") {
        PathBuf::from(path)
    } else {
        PathBuf::from(concat!("target/", env!("PROFILE"), "/clippy-driver"))
    }
}

fn host_libs() -> PathBuf {
    if let Some(path) = option_env!("HOST_LIBS") {
        PathBuf::from(path)
    } else {
        Path::new("target").join(env!("PROFILE"))
    }
}

fn rustc_test_suite() -> Option<PathBuf> {
    option_env!("RUSTC_TEST_SUITE").map(PathBuf::from)
}

fn rustc_lib_path() -> PathBuf {
    option_env!("RUSTC_LIB_PATH").unwrap().into()
}

fn config(mode: &str, dir: PathBuf) -> compiletest::Config {
    let mut config = compiletest::Config::default();

    let cfg_mode = mode.parse().expect("Invalid mode");
    if let Ok(name) = var::<&str>("TESTNAME") {
        let s: String = name.to_owned();
        config.filter = Some(s)
    }

    if rustc_test_suite().is_some() {
        config.run_lib_path = rustc_lib_path();
        config.compile_lib_path = rustc_lib_path();
    }
    config.target_rustcflags = Some(format!("-L {0} -L {0}/deps -Dwarnings", host_libs().display()));

    config.mode = cfg_mode;
    config.build_base = if rustc_test_suite().is_some() {
        // we don't need access to the stderr files on travis
        let mut path = PathBuf::from(env!("OUT_DIR"));
        path.push("test_build_base");
        path
    } else {
        let mut path = std::env::current_dir().unwrap();
        path.push("target/debug/test_build_base");
        path
    };
    config.src_base = dir;
    config.rustc_path = clippy_driver_path();
    config
}

fn run_mode(mode: &str, dir: PathBuf) {
    let cfg = config(mode, dir);
    // clean rmeta data, otherwise "cargo check; cargo test" fails (#2896)
    cfg.clean_rmeta();
    compiletest::run_tests(&cfg);
}

fn run_ui_toml_tests(config: &compiletest::Config, mut tests: Vec<test::TestDescAndFn>) -> Result<bool, io::Error> {
    let mut result = true;
    let opts = compiletest::test_opts(config);
    for dir in fs::read_dir(&config.src_base)? {
        let dir = dir?;
        if !dir.file_type()?.is_dir() {
            continue;
        }
        let dir_path = dir.path();
        set_var("CARGO_MANIFEST_DIR", &dir_path);
        for file in fs::read_dir(&dir_path)? {
            let file = file?;
            let file_path = file.path();
            if !file.file_type()?.is_file() {
                continue;
            }
            if file_path.extension() != Some(OsStr::new("rs")) {
                continue;
            }
            let paths = compiletest::common::TestPaths {
                file: file_path,
                base: config.src_base.clone(),
                relative_dir: dir_path.file_name().unwrap().into(),
            };
            let test_name = compiletest::make_test_name(&config, &paths);
            let index = tests
                .iter()
                .position(|test| test.desc.name == test_name)
                .expect("The test should be in there");
            result &= test::run_tests_console(&opts, vec![tests.swap_remove(index)])?;
        }
    }
    Ok(result)
}

fn run_ui_toml() {
    let path = PathBuf::from("tests/ui-toml").canonicalize().unwrap();
    let config = config("ui", path);
    let tests = compiletest::make_tests(&config);

    let res = run_ui_toml_tests(&config, tests);
    match res {
        Ok(true) => {},
        Ok(false) => panic!("Some tests failed"),
        Err(e) => {
            println!("I/O failure during tests: {:?}", e);
        },
    }
}

fn prepare_env() {
    set_var("CLIPPY_DISABLE_DOCS_LINKS", "true");
    set_var("CLIPPY_TESTS", "true");
    //set_var("RUST_BACKTRACE", "0");
}

#[test]
fn compile_test() {
    prepare_env();
    run_mode("run-pass", "tests/run-pass".into());
    run_mode("ui", "tests/ui".into());
    run_ui_toml();
}
<|endoftext|>