<commit_before>use std::fmt::{self, Debug, Display};
use std::mem;

use serde::ser::{Serialize, Serializer, SerializeStruct};
use serde::de::{self, Deserialize, Deserializer, DeserializeSeed, IntoDeserializer, MapAccess, Unexpected, Visitor};
use serde::de::value::BorrowedStrDeserializer;

use error::Error;

/// Reference to a range of bytes encompassing a single valid JSON value in the
/// input data.
///
/// A `RawValue` can be used to defer parsing parts of a payload until later,
/// or to avoid parsing it at all in the case that part of the payload just
/// needs to be transferred verbatim into a different output object.
///
/// When serializing, a value of this type will retain its original formatting
/// and will not be minified or pretty-printed.
///
/// # Example
///
/// ```
/// #[macro_use]
/// extern crate serde_derive;
/// extern crate serde_json;
///
/// use serde_json::{Result, value::RawValue};
///
/// #[derive(Deserialize)]
/// struct Input<'a> {
///     code: u32,
///     #[serde(borrow)]
///     payload: &'a RawValue,
/// }
///
/// #[derive(Serialize)]
/// struct Output<'a> {
///     info: (u32, &'a RawValue),
/// }
///
/// // Efficiently rearrange JSON input containing separate "code" and "payload"
/// // keys into a single "info" key holding an array of code and payload.
/// //
/// // This could be done equivalently using serde_json::Value as the type for
/// // payload, but &RawValue will perform netter because it does not require
/// // memory allocation. The correct range of bytes is borrowed from the input
/// // data and pasted verbatim into the output.
/// fn rearrange(input: &str) -> Result<String> {
///     let input: Input = serde_json::from_str(input)?;
///
///     let output = Output {
///         info: (input.code, input.payload),
///     };
///
///     serde_json::to_string(&output)
/// }
///
/// fn main() -> Result<()> {
///     let out = rearrange(r#" {"code": 200, "payload": {}} "#)?;
///
///     assert_eq!(out, r#"{"info":[200,{}]}"#);
///
///     Ok(())
/// }
/// ```
///
/// # Note
///
/// `RawValue` is only available if serde\_json is built with the `"raw_value"`
/// feature.
///
/// ```toml
/// [dependencies]
/// serde_json = { version = "1.0", features = ["raw_value"] }
/// ```
#[repr(C)]
pub struct RawValue {
    json: str,
}

impl RawValue {
    fn from_borrowed(json: &str) -> &Self {
        unsafe { mem::transmute::<&str, &RawValue>(json) }
    }

    fn from_owned(json: Box<str>) -> Box<Self> {
        unsafe { mem::transmute::<Box<str>, Box<RawValue>>(json) }
    }
}

impl Clone for Box<RawValue> {
    fn clone(&self) -> Self {
        (**self).to_owned()
    }
}

impl ToOwned for RawValue {
    type Owned = Box<RawValue>;

    fn to_owned(&self) -> Self::Owned {
        RawValue::from_owned(self.json.to_owned().into_boxed_str())
    }
}

impl Debug for RawValue {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        formatter
            .debug_tuple("RawValue")
            .field(&format_args!("{}", &self.json))
            .finish()
    }
}

impl Display for RawValue {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str(&self.json)
    }
}

impl RawValue {
    /// Access the JSON text underlying a raw value.
    ///
    /// # Example
    ///
    /// ```
    /// #[macro_use]
    /// extern crate serde_derive;
    /// extern crate serde_json;
    ///
    /// use serde_json::{Result, value::RawValue};
    ///
    /// #[derive(Deserialize)]
    /// struct Response<'a> {
    ///     code: u32,
    ///     #[serde(borrow)]
    ///     payload: &'a RawValue,
    /// }
    ///
    /// fn process(input: &str) -> Result<()> {
    ///     let response: Response = serde_json::from_str(input)?;
    ///
    ///     let payload = response.payload.get();
    ///     if payload.starts_with('{') {
    ///         // handle a payload which is a JSON map
    ///     } else {
    ///         // handle any other type
    ///     }
    ///
    ///     Ok(())
    /// }
    ///
    /// fn main() -> Result<()> {
    ///     process(r#" {"code": 200, "payload": {}} "#)?;
    ///     Ok(())
    /// }
    /// ```
    pub fn get(&self) -> &str {
        &self.json
    }
}

pub const TOKEN: &'static str = "$serde_json::private::RawValue";

impl Serialize for RawValue {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        let mut s = serializer.serialize_struct(TOKEN, 1)?;
        s.serialize_field(TOKEN, &self.json)?;
        s.end()
    }
}

impl<'de: 'a, 'a> Deserialize<'de> for &'a RawValue {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        struct ReferenceVisitor;

        impl<'de> Visitor<'de> for ReferenceVisitor {
            type Value = &'de RawValue;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                write!(formatter, "any valid JSON value")
            }

            fn visit_map<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
            where
                V: MapAccess<'de>,
            {
                let value = visitor.next_key::<RawKey>()?;
                if value.is_none() {
                    return Err(de::Error::invalid_type(Unexpected::Map, &self));
                }
                visitor.next_value_seed(ReferenceFromString)
            }
        }

        deserializer.deserialize_newtype_struct(TOKEN, ReferenceVisitor)
    }
}

impl<'de> Deserialize<'de> for Box<RawValue> {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        struct BoxedVisitor;

        impl<'de> Visitor<'de> for BoxedVisitor {
            type Value = Box<RawValue>;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                write!(formatter, "any valid JSON value")
            }

            fn visit_map<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
            where
                V: MapAccess<'de>,
            {
                let value = visitor.next_key::<RawKey>()?;
                if value.is_none() {
                    return Err(de::Error::invalid_type(Unexpected::Map, &self));
                }
                visitor.next_value_seed(BoxedFromString)
            }
        }

        deserializer.deserialize_newtype_struct(TOKEN, BoxedVisitor)
    }
}

struct RawKey;

impl<'de> Deserialize<'de> for RawKey {
    fn deserialize<D>(deserializer: D) -> Result<RawKey, D::Error>
    where
        D: Deserializer<'de>,
    {
        struct FieldVisitor;

        impl<'de> Visitor<'de> for FieldVisitor {
            type Value = ();

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                formatter.write_str("raw value")
            }

            fn visit_str<E>(self, s: &str) -> Result<(), E>
            where
                E: de::Error,
            {
                if s == TOKEN {
                    Ok(())
                } else {
                    Err(de::Error::custom("unexpected raw value"))
                }
            }
        }

        deserializer.deserialize_identifier(FieldVisitor)?;
        Ok(RawKey)
    }
}

pub struct ReferenceFromString;

impl<'de> DeserializeSeed<'de> for ReferenceFromString {
    type Value = &'de RawValue;

    fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
    where
        D: Deserializer<'de>,
    {
        deserializer.deserialize_str(self)
    }
}

impl<'de> Visitor<'de> for ReferenceFromString {
    type Value = &'de RawValue;

    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        formatter.write_str("raw value")
    }

    fn visit_borrowed_str<E>(self, s: &'de str) -> Result<Self::Value, E>
    where
        E: de::Error,
    {
        Ok(RawValue::from_borrowed(s))
    }
}

pub struct BoxedFromString;

impl<'de> DeserializeSeed<'de> for BoxedFromString {
    type Value = Box<RawValue>;

    fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
    where
        D: Deserializer<'de>,
    {
        deserializer.deserialize_str(self)
    }
}

impl<'de> Visitor<'de> for BoxedFromString {
    type Value = Box<RawValue>;

    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        formatter.write_str("raw value")
    }

    fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
    where
        E: de::Error,
    {
        self.visit_string(s.to_owned())
    }

    fn visit_string<E>(self, s: String) -> Result<Self::Value, E>
    where
        E: de::Error,
    {
        Ok(RawValue::from_owned(s.into_boxed_str()))
    }
}

struct RawKeyDeserializer;

impl<'de> Deserializer<'de> for RawKeyDeserializer {
    type Error = Error;

    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
    where
        V: de::Visitor<'de>,
    {
        visitor.visit_borrowed_str(TOKEN)
    }

    forward_to_deserialize_any! {
        bool u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 f32 f64 char str string seq
        bytes byte_buf map struct option unit newtype_struct ignored_any
        unit_struct tuple_struct tuple enum identifier
    }
}

pub struct OwnedRawDeserializer {
    pub raw_value: Option<String>,
}

impl<'de> MapAccess<'de> for OwnedRawDeserializer {
    type Error = Error;

    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error>
    where
        K: de::DeserializeSeed<'de>,
    {
        if self.raw_value.is_none() {
            return Ok(None);
        }
        seed.deserialize(RawKeyDeserializer).map(Some)
    }

    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Error>
    where
        V: de::DeserializeSeed<'de>,
    {
        seed.deserialize(self.raw_value.take().unwrap().into_deserializer())
    }
}

pub struct BorrowedRawDeserializer<'de> {
    pub raw_value: Option<&'de str>,
}

impl<'de> MapAccess<'de> for BorrowedRawDeserializer<'de> {
    type Error = Error;

    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error>
    where
        K: de::DeserializeSeed<'de>,
    {
        if self.raw_value.is_none() {
            return Ok(None);
        }
        seed.deserialize(RawKeyDeserializer).map(Some)
    }

    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Error>
    where
        V: de::DeserializeSeed<'de>,
    {
        seed.deserialize(BorrowedStrDeserializer::new(self.raw_value.take().unwrap()))
    }
}
<commit_msg>Document RawValue ownership<commit_after>use std::fmt::{self, Debug, Display};
use std::mem;

use serde::ser::{Serialize, Serializer, SerializeStruct};
use serde::de::{self, Deserialize, Deserializer, DeserializeSeed, IntoDeserializer, MapAccess, Unexpected, Visitor};
use serde::de::value::BorrowedStrDeserializer;

use error::Error;

/// Reference to a range of bytes encompassing a single valid JSON value in the
/// input data.
///
/// A `RawValue` can be used to defer parsing parts of a payload until later,
/// or to avoid parsing it at all in the case that part of the payload just
/// needs to be transferred verbatim into a different output object.
///
/// When serializing, a value of this type will retain its original formatting
/// and will not be minified or pretty-printed.
///
/// # Example
///
/// ```
/// #[macro_use]
/// extern crate serde_derive;
/// extern crate serde_json;
///
/// use serde_json::{Result, value::RawValue};
///
/// #[derive(Deserialize)]
/// struct Input<'a> {
///     code: u32,
///     #[serde(borrow)]
///     payload: &'a RawValue,
/// }
///
/// #[derive(Serialize)]
/// struct Output<'a> {
///     info: (u32, &'a RawValue),
/// }
///
/// // Efficiently rearrange JSON input containing separate "code" and "payload"
/// // keys into a single "info" key holding an array of code and payload.
/// //
/// // This could be done equivalently using serde_json::Value as the type for
/// // payload, but &RawValue will perform netter because it does not require
/// // memory allocation. The correct range of bytes is borrowed from the input
/// // data and pasted verbatim into the output.
/// fn rearrange(input: &str) -> Result<String> {
///     let input: Input = serde_json::from_str(input)?;
///
///     let output = Output {
///         info: (input.code, input.payload),
///     };
///
///     serde_json::to_string(&output)
/// }
///
/// fn main() -> Result<()> {
///     let out = rearrange(r#" {"code": 200, "payload": {}} "#)?;
///
///     assert_eq!(out, r#"{"info":[200,{}]}"#);
///
///     Ok(())
/// }
/// ```
///
/// # Ownership
///
/// The typical usage of `RawValue` will be in the borrowed form:
///
/// ```
/// # #[macro_use]
/// # extern crate serde_derive;
/// # extern crate serde_json;
/// #
/// # use serde_json::value::RawValue;
/// #
/// #[derive(Deserialize)]
/// struct SomeStruct<'a> {
///     #[serde(borrow)]
///     raw_value: &'a RawValue,
/// }
/// #
/// # fn main() {}
/// ```
///
/// The borrowed form is suitable when deserializing through
/// [`serde_json::from_str`] and [`serde_json::from_slice`] which support
/// borrowing from the input data without memory allocation.
///
/// When deserializing through [`serde_json::from_reader`] you will need to use
/// the boxed form of `RawValue` instead. This is almost as efficient but
/// involves buffering the raw value from the I/O stream into memory.
///
/// [`serde_json::from_str`]: ../fn.from_str.html
/// [`serde_json::from_slice`]: ../fn.from_slice.html
/// [`serde_json::from_reader`]: ../fn.from_reader.html
///
/// ```
/// # #[macro_use]
/// # extern crate serde_derive;
/// # extern crate serde_json;
/// #
/// # use serde_json::value::RawValue;
/// #
/// #[derive(Deserialize)]
/// struct SomeStruct {
///     raw_value: Box<RawValue>,
/// }
/// #
/// # fn main() {}
/// ```
///
/// # Note
///
/// `RawValue` is only available if serde\_json is built with the `"raw_value"`
/// feature.
///
/// ```toml
/// [dependencies]
/// serde_json = { version = "1.0", features = ["raw_value"] }
/// ```
#[repr(C)]
pub struct RawValue {
    json: str,
}

impl RawValue {
    fn from_borrowed(json: &str) -> &Self {
        unsafe { mem::transmute::<&str, &RawValue>(json) }
    }

    fn from_owned(json: Box<str>) -> Box<Self> {
        unsafe { mem::transmute::<Box<str>, Box<RawValue>>(json) }
    }
}

impl Clone for Box<RawValue> {
    fn clone(&self) -> Self {
        (**self).to_owned()
    }
}

impl ToOwned for RawValue {
    type Owned = Box<RawValue>;

    fn to_owned(&self) -> Self::Owned {
        RawValue::from_owned(self.json.to_owned().into_boxed_str())
    }
}

impl Debug for RawValue {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        formatter
            .debug_tuple("RawValue")
            .field(&format_args!("{}", &self.json))
            .finish()
    }
}

impl Display for RawValue {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str(&self.json)
    }
}

impl RawValue {
    /// Access the JSON text underlying a raw value.
    ///
    /// # Example
    ///
    /// ```
    /// #[macro_use]
    /// extern crate serde_derive;
    /// extern crate serde_json;
    ///
    /// use serde_json::{Result, value::RawValue};
    ///
    /// #[derive(Deserialize)]
    /// struct Response<'a> {
    ///     code: u32,
    ///     #[serde(borrow)]
    ///     payload: &'a RawValue,
    /// }
    ///
    /// fn process(input: &str) -> Result<()> {
    ///     let response: Response = serde_json::from_str(input)?;
    ///
    ///     let payload = response.payload.get();
    ///     if payload.starts_with('{') {
    ///         // handle a payload which is a JSON map
    ///     } else {
    ///         // handle any other type
    ///     }
    ///
    ///     Ok(())
    /// }
    ///
    /// fn main() -> Result<()> {
    ///     process(r#" {"code": 200, "payload": {}} "#)?;
    ///     Ok(())
    /// }
    /// ```
    pub fn get(&self) -> &str {
        &self.json
    }
}

pub const TOKEN: &'static str = "$serde_json::private::RawValue";

impl Serialize for RawValue {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        let mut s = serializer.serialize_struct(TOKEN, 1)?;
        s.serialize_field(TOKEN, &self.json)?;
        s.end()
    }
}

impl<'de: 'a, 'a> Deserialize<'de> for &'a RawValue {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        struct ReferenceVisitor;

        impl<'de> Visitor<'de> for ReferenceVisitor {
            type Value = &'de RawValue;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                write!(formatter, "any valid JSON value")
            }

            fn visit_map<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
            where
                V: MapAccess<'de>,
            {
                let value = visitor.next_key::<RawKey>()?;
                if value.is_none() {
                    return Err(de::Error::invalid_type(Unexpected::Map, &self));
                }
                visitor.next_value_seed(ReferenceFromString)
            }
        }

        deserializer.deserialize_newtype_struct(TOKEN, ReferenceVisitor)
    }
}

impl<'de> Deserialize<'de> for Box<RawValue> {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        struct BoxedVisitor;

        impl<'de> Visitor<'de> for BoxedVisitor {
            type Value = Box<RawValue>;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                write!(formatter, "any valid JSON value")
            }

            fn visit_map<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
            where
                V: MapAccess<'de>,
            {
                let value = visitor.next_key::<RawKey>()?;
                if value.is_none() {
                    return Err(de::Error::invalid_type(Unexpected::Map, &self));
                }
                visitor.next_value_seed(BoxedFromString)
            }
        }

        deserializer.deserialize_newtype_struct(TOKEN, BoxedVisitor)
    }
}

struct RawKey;

impl<'de> Deserialize<'de> for RawKey {
    fn deserialize<D>(deserializer: D) -> Result<RawKey, D::Error>
    where
        D: Deserializer<'de>,
    {
        struct FieldVisitor;

        impl<'de> Visitor<'de> for FieldVisitor {
            type Value = ();

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                formatter.write_str("raw value")
            }

            fn visit_str<E>(self, s: &str) -> Result<(), E>
            where
                E: de::Error,
            {
                if s == TOKEN {
                    Ok(())
                } else {
                    Err(de::Error::custom("unexpected raw value"))
                }
            }
        }

        deserializer.deserialize_identifier(FieldVisitor)?;
        Ok(RawKey)
    }
}

pub struct ReferenceFromString;

impl<'de> DeserializeSeed<'de> for ReferenceFromString {
    type Value = &'de RawValue;

    fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
    where
        D: Deserializer<'de>,
    {
        deserializer.deserialize_str(self)
    }
}

impl<'de> Visitor<'de> for ReferenceFromString {
    type Value = &'de RawValue;

    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        formatter.write_str("raw value")
    }

    fn visit_borrowed_str<E>(self, s: &'de str) -> Result<Self::Value, E>
    where
        E: de::Error,
    {
        Ok(RawValue::from_borrowed(s))
    }
}

pub struct BoxedFromString;

impl<'de> DeserializeSeed<'de> for BoxedFromString {
    type Value = Box<RawValue>;

    fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
    where
        D: Deserializer<'de>,
    {
        deserializer.deserialize_str(self)
    }
}

impl<'de> Visitor<'de> for BoxedFromString {
    type Value = Box<RawValue>;

    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        formatter.write_str("raw value")
    }

    fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
    where
        E: de::Error,
    {
        self.visit_string(s.to_owned())
    }

    fn visit_string<E>(self, s: String) -> Result<Self::Value, E>
    where
        E: de::Error,
    {
        Ok(RawValue::from_owned(s.into_boxed_str()))
    }
}

struct RawKeyDeserializer;

impl<'de> Deserializer<'de> for RawKeyDeserializer {
    type Error = Error;

    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
    where
        V: de::Visitor<'de>,
    {
        visitor.visit_borrowed_str(TOKEN)
    }

    forward_to_deserialize_any! {
        bool u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 f32 f64 char str string seq
        bytes byte_buf map struct option unit newtype_struct ignored_any
        unit_struct tuple_struct tuple enum identifier
    }
}

pub struct OwnedRawDeserializer {
    pub raw_value: Option<String>,
}

impl<'de> MapAccess<'de> for OwnedRawDeserializer {
    type Error = Error;

    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error>
    where
        K: de::DeserializeSeed<'de>,
    {
        if self.raw_value.is_none() {
            return Ok(None);
        }
        seed.deserialize(RawKeyDeserializer).map(Some)
    }

    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Error>
    where
        V: de::DeserializeSeed<'de>,
    {
        seed.deserialize(self.raw_value.take().unwrap().into_deserializer())
    }
}

pub struct BorrowedRawDeserializer<'de> {
    pub raw_value: Option<&'de str>,
}

impl<'de> MapAccess<'de> for BorrowedRawDeserializer<'de> {
    type Error = Error;

    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error>
    where
        K: de::DeserializeSeed<'de>,
    {
        if self.raw_value.is_none() {
            return Ok(None);
        }
        seed.deserialize(RawKeyDeserializer).map(Some)
    }

    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Error>
    where
        V: de::DeserializeSeed<'de>,
    {
        seed.deserialize(BorrowedStrDeserializer::new(self.raw_value.take().unwrap()))
    }
}
<|endoftext|>


<commit_before>use aabb::AABB;
use nalgebra::{Vector3, Point3, Norm};

/// A struct which defines a ray and some of its cached values.
#[derive(Debug)]
pub struct Ray {
    /// The ray origin.
    pub origin: Point3<f32>,

    /// The ray direction.
    pub direction: Vector3<f32>,

    /// Inverse (1/x) ray direction. Cached for use in [`AABB`] intersections.
    ///
    /// [`AABB`]: struct.AABB.html
    ///
    inv_direction: Vector3<f32>,

    /// Sign of the direction. 0 means positive, 1 means negative.
    /// Cached for use in [`AABB`] intersections.
    ///
    /// [`AABB`]: struct.AABB.html
    ///
    sign: Vector3<usize>,
}

impl Ray {
    /// Creates a new [`Ray`] from an `origin` and a `direction`.
    /// `direction` will be normalized.
    ///
    /// # Examples
    /// ```
    /// use bvh::ray::Ray;
    /// use bvh::nalgebra::{Point3,Vector3};
    ///
    /// let origin = Point3::new(0.0,0.0,0.0);
    /// let direction = Vector3::new(1.0,0.0,0.0);
    /// let ray = Ray::new(origin, direction);
    ///
    /// assert_eq!(ray.origin, origin);
    /// assert_eq!(ray.direction, direction);
    /// ```
    ///
    /// [`Ray`]: struct.Ray.html
    ///
    pub fn new(origin: Point3<f32>, direction: Vector3<f32>) -> Ray {
        let direction = direction.normalize();
        Ray {
            origin: origin,
            direction: direction,
            inv_direction: Vector3::new(1.0 / direction.x, 1.0 / direction.y, 1.0 / direction.z),
            sign: Vector3::new((direction.x < 0.0) as usize,
                               (direction.y < 0.0) as usize,
                               (direction.z < 0.0) as usize),
        }
    }

    /// Tests the intersection of a [`Ray`] with an [`AABB`] using the optimized algorithm
    /// from [this paper](http://www.cs.utah.edu/~awilliam/box/box.pdf).
    ///
    /// # Examples
    /// ```
    /// use bvh::aabb::AABB;
    /// use bvh::ray::Ray;
    /// use bvh::nalgebra::{Point3,Vector3};
    ///
    /// let origin = Point3::new(0.0,0.0,0.0);
    /// let direction = Vector3::new(1.0,0.0,0.0);
    /// let ray = Ray::new(origin, direction);
    ///
    /// let point1 = Point3::new(99.9,-1.0,-1.0);
    /// let point2 = Point3::new(100.1,1.0,1.0);
    /// let aabb = AABB::with_bounds(point1, point2);
    ///
    /// assert!(ray.intersects_aabb(&aabb));
    /// ```
    ///
    /// [`Ray`]: struct.Ray.html
    /// [`AABB`]: struct.AABB.html
    ///
    pub fn intersects_aabb(&self, aabb: &AABB) -> bool {
        let mut ray_min = (aabb[self.sign.x].x - self.origin.x) * self.inv_direction.x;
        let mut ray_max = (aabb[1 - self.sign.x].x - self.origin.x) * self.inv_direction.x;

        let y_min = (aabb[self.sign.y].y - self.origin.y) * self.inv_direction.y;
        let y_max = (aabb[1 - self.sign.y].y - self.origin.y) * self.inv_direction.y;

        if (ray_min > y_max) || (y_min > ray_max) {
            return false;
        }

        if y_min > ray_min {
            ray_min = y_min;
        }
        if y_max < ray_max {
            ray_max = y_max;
        }

        let z_min = (aabb[self.sign.z].z - self.origin.z) * self.inv_direction.z;
        let z_max = (aabb[1 - self.sign.z].z - self.origin.z) * self.inv_direction.z;

        if (ray_min > z_max) || (z_min > ray_max) {
            return false;
        }

        // Only required for bounded intersection intervals.
        // if z_min > ray_min {
        // ray_min = z_min;
        // }

        if z_max < ray_max {
            ray_max = z_max;
        }

        ray_max > 0.0
    }

    /// Naive implementation of a [`Ray`]/[`AABB`] intersection algorithm.
    ///
    /// # Examples
    /// ```
    /// use bvh::aabb::AABB;
    /// use bvh::ray::Ray;
    /// use bvh::nalgebra::{Point3,Vector3};
    ///
    /// let origin = Point3::new(0.0,0.0,0.0);
    /// let direction = Vector3::new(1.0,0.0,0.0);
    /// let ray = Ray::new(origin, direction);
    ///
    /// let point1 = Point3::new(99.9,-1.0,-1.0);
    /// let point2 = Point3::new(100.1,1.0,1.0);
    /// let aabb = AABB::with_bounds(point1, point2);
    ///
    /// assert!(ray.intersects_aabb_naive(&aabb));
    /// ```
    ///
    /// [`Ray`]: struct.Ray.html
    /// [`AABB`]: struct.AABB.html
    ///
    pub fn intersects_aabb_naive(&self, aabb: &AABB) -> bool {
        let hit_min_x = (aabb.min.x - self.origin.x) * self.inv_direction.x;
        let hit_max_x = (aabb.max.x - self.origin.x) * self.inv_direction.x;

        let hit_min_y = (aabb.min.y - self.origin.y) * self.inv_direction.y;
        let hit_max_y = (aabb.max.y - self.origin.y) * self.inv_direction.y;

        let hit_min_z = (aabb.min.z - self.origin.z) * self.inv_direction.z;
        let hit_max_z = (aabb.max.z - self.origin.z) * self.inv_direction.z;

        let x_entry = hit_min_x.min(hit_max_x);
        let y_entry = hit_min_y.min(hit_max_y);
        let z_entry = hit_min_z.min(hit_max_z);
        let x_exit = hit_min_x.max(hit_max_x);
        let y_exit = hit_min_y.max(hit_max_y);
        let z_exit = hit_min_z.max(hit_max_z);

        let latest_entry = x_entry.max(y_entry).max(z_entry);
        let earliest_exit = x_exit.min(y_exit).min(z_exit);

        latest_entry < earliest_exit && earliest_exit > 0.0
    }

    /// Implementation of the algorithm described [here]
    /// (https://tavianator.com/fast-branchless-raybounding-box-intersections/).
    ///
    /// # Examples
    /// ```
    /// use bvh::aabb::AABB;
    /// use bvh::ray::Ray;
    /// use bvh::nalgebra::{Point3,Vector3};
    ///
    /// let origin = Point3::new(0.0,0.0,0.0);
    /// let direction = Vector3::new(1.0,0.0,0.0);
    /// let ray = Ray::new(origin, direction);
    ///
    /// let point1 = Point3::new(99.9,-1.0,-1.0);
    /// let point2 = Point3::new(100.1,1.0,1.0);
    /// let aabb = AABB::with_bounds(point1, point2);
    ///
    /// assert!(ray.intersects_aabb_branchless(&aabb));
    /// ```
    ///
    /// [`Ray`]: struct.Ray.html
    /// [`AABB`]: struct.AABB.html
    ///
    pub fn intersects_aabb_branchless(&self, aabb: &AABB) -> bool {
        let tx1 = (aabb.min.x - self.origin.x) * self.inv_direction.x;
        let tx2 = (aabb.max.x - self.origin.x) * self.inv_direction.x;

        let mut tmin = tx1.min(tx2);
        let mut tmax = tx1.max(tx2);

        let ty1 = (aabb.min.y - self.origin.y) * self.inv_direction.y;
        let ty2 = (aabb.max.y - self.origin.y) * self.inv_direction.y;

        tmin = tmin.max(ty1.min(ty2));
        tmax = tmax.min(ty1.max(ty2));

        let tz1 = (aabb.min.z - self.origin.z) * self.inv_direction.z;
        let tz2 = (aabb.max.z - self.origin.z) * self.inv_direction.z;

        tmin = tmin.max(tz1.min(tz2));
        tmax = tmax.min(tz1.max(tz2));

        tmax >= tmin && tmax >= 0.0
    }
}

#[cfg(test)]
mod tests {
    use ray::Ray;
    use aabb::AABB;
    use nalgebra::{Point3, Vector3};
    use rand::{Rng, StdRng, SeedableRng};

    type TupleVec = (f32, f32, f32);

    fn tuple_to_point(tpl: &TupleVec) -> Point3<f32> {
        Point3::new(tpl.0, tpl.1, tpl.2)
    }

    fn tuple_to_vector(tpl: &TupleVec) -> Vector3<f32> {
        Vector3::new(tpl.0, tpl.1, tpl.2)
    }

    /// Generates a random `Ray` which points at at a random `AABB`.
    fn gen_ray_to_aabb(data: (TupleVec, TupleVec, TupleVec)) -> (Ray, AABB) {
        // Generate a random AABB
        let aabb = AABB::empty()
            .grow(&tuple_to_point(&data.0))
            .grow(&tuple_to_point(&data.1));

        // Get its center
        let center = aabb.center();

        // Generate random ray pointing at the center
        let pos = tuple_to_point(&data.2);
        let ray = Ray::new(pos, center - pos);
        (ray, aabb)
    }

    /// Test whether a `Ray` which points at the center of an `AABB` intersects it.
    /// Uses the optimized algorithm.
    quickcheck!{
        fn test_ray_points_at_aabb_center(data: (TupleVec, TupleVec, TupleVec)) -> bool {
            let (ray, aabb) = gen_ray_to_aabb(data);
            ray.intersects_aabb(&aabb)
        }
    }

    /// Test whether a `Ray` which points at the center of an `AABB` intersects it.
    /// Uses the naive algorithm.
    quickcheck!{
        fn test_ray_points_at_aabb_center_naive(data: (TupleVec, TupleVec, TupleVec)) -> bool {
            let (ray, aabb) = gen_ray_to_aabb(data);
            ray.intersects_aabb_naive(&aabb)
        }
    }

    /// Test whether a `Ray` which points at the center of an `AABB` intersects it.
    /// Uses the branchless algorithm.
    quickcheck!{
        fn test_ray_points_at_aabb_center_branchless(data: (TupleVec, TupleVec, TupleVec)) -> bool {
            let (ray, aabb) = gen_ray_to_aabb(data);
            ray.intersects_aabb_branchless(&aabb)
        }
    }

    /// Test whether a `Ray` which points away from the center of an `AABB`
    /// does not intersect it, unless its origin is inside the `AABB`.
    /// Uses the optimized algorithm.
    quickcheck!{
        fn test_ray_points_from_aabb_center(data: (TupleVec, TupleVec, TupleVec)) -> bool {
            let (mut ray, aabb) = gen_ray_to_aabb(data);

            // Invert the direction of the ray
            ray.direction = -ray.direction;
            ray.inv_direction = -ray.inv_direction;
            !ray.intersects_aabb(&aabb) || aabb.contains(&ray.origin)
        }
    }

    /// Test whether a `Ray` which points away from the center of an `AABB`
    /// does not intersect it, unless its origin is inside the `AABB`.
    /// Uses the naive algorithm.
    quickcheck!{
        fn test_ray_points_from_aabb_center_naive(data: (TupleVec, TupleVec, TupleVec)) -> bool {
            let (mut ray, aabb) = gen_ray_to_aabb(data);

             // Invert the ray direction
            ray.direction = -ray.direction;
            ray.inv_direction = -ray.inv_direction;
            !ray.intersects_aabb_naive(&aabb) || aabb.contains(&ray.origin)
        }
    }

    /// Test whether a `Ray` which points away from the center of an `AABB`
    /// does not intersect it, unless its origin is inside the `AABB`.
    /// Uses the branchless algorithm.
    quickcheck!{
        fn test_ray_points_from_aabb_center_branchless(data: (TupleVec, TupleVec, TupleVec)) -> bool {
            let (mut ray, aabb) = gen_ray_to_aabb(data);
    // Invert the ray direction
            ray.direction = -ray.direction;
            ray.inv_direction = -ray.inv_direction;
            !ray.intersects_aabb_branchless(&aabb) || aabb.contains(&ray.origin)
        }
    }

    /// Generates some random `Ray`/`AABB` pairs.
    fn gen_random_ray_aabb(rng: &mut StdRng) -> (Ray, AABB) {
        let a = tuple_to_point(&rng.gen::<TupleVec>());
        let b = tuple_to_point(&rng.gen::<TupleVec>());
        let c = tuple_to_point(&rng.gen::<TupleVec>());
        let d = tuple_to_vector(&rng.gen::<TupleVec>());

        let aabb = AABB::empty().grow(&a).grow(&b);
        let ray = Ray::new(c, d);
        (ray, aabb)
    }

    #[bench]
    /// Benchmark for the optimized intersection algorithm.
    fn bench_intersects_aabb(b: &mut ::test::Bencher) {
        let seed = [0];
        let mut rng = StdRng::from_seed(&seed);

        b.iter(|| {
            let one_thousand = ::test::black_box(1000);
            for _ in 0..one_thousand {
                let (ray, aabb) = gen_random_ray_aabb(&mut rng);
                ray.intersects_aabb(&aabb);
            }
        });
    }

    #[bench]
    /// Benchmark for the naive intersection algorithm.
    fn bench_intersects_aabb_naive(b: &mut ::test::Bencher) {
        let seed = [0];
        let mut rng = StdRng::from_seed(&seed);

        b.iter(|| {
            let one_thousand = ::test::black_box(1000);
            for _ in 0..one_thousand {
                let (ray, aabb) = gen_random_ray_aabb(&mut rng);
                ray.intersects_aabb_naive(&aabb);
            }
        });
    }

    #[bench]
    /// Benchmark for the branchless intersection algorithm.
    fn bench_intersects_aabb_branchless(b: &mut ::test::Bencher) {
        let seed = [0];
        let mut rng = StdRng::from_seed(&seed);

        b.iter(|| {
            let one_thousand = ::test::black_box(1000);
            for _ in 0..one_thousand {
                let (ray, aabb) = gen_random_ray_aabb(&mut rng);
                ray.intersects_aabb_branchless(&aabb);
            }
        });
    }
}
<commit_msg>Add comments and fix formatting<commit_after>use aabb::AABB;
use nalgebra::{Vector3, Point3, Norm};

/// A struct which defines a ray and some of its cached values.
#[derive(Debug)]
pub struct Ray {
    /// The ray origin.
    pub origin: Point3<f32>,

    /// The ray direction.
    pub direction: Vector3<f32>,

    /// Inverse (1/x) ray direction. Cached for use in [`AABB`] intersections.
    ///
    /// [`AABB`]: struct.AABB.html
    ///
    inv_direction: Vector3<f32>,

    /// Sign of the direction. 0 means positive, 1 means negative.
    /// Cached for use in [`AABB`] intersections.
    ///
    /// [`AABB`]: struct.AABB.html
    ///
    sign: Vector3<usize>,
}

impl Ray {
    /// Creates a new [`Ray`] from an `origin` and a `direction`.
    /// `direction` will be normalized.
    ///
    /// # Examples
    /// ```
    /// use bvh::ray::Ray;
    /// use bvh::nalgebra::{Point3,Vector3};
    ///
    /// let origin = Point3::new(0.0,0.0,0.0);
    /// let direction = Vector3::new(1.0,0.0,0.0);
    /// let ray = Ray::new(origin, direction);
    ///
    /// assert_eq!(ray.origin, origin);
    /// assert_eq!(ray.direction, direction);
    /// ```
    ///
    /// [`Ray`]: struct.Ray.html
    ///
    pub fn new(origin: Point3<f32>, direction: Vector3<f32>) -> Ray {
        let direction = direction.normalize();
        Ray {
            origin: origin,
            direction: direction,
            inv_direction: Vector3::new(1.0 / direction.x, 1.0 / direction.y, 1.0 / direction.z),
            sign: Vector3::new((direction.x < 0.0) as usize,
                               (direction.y < 0.0) as usize,
                               (direction.z < 0.0) as usize),
        }
    }

    /// Tests the intersection of a [`Ray`] with an [`AABB`] using the optimized algorithm
    /// from [this paper](http://www.cs.utah.edu/~awilliam/box/box.pdf).
    ///
    /// # Examples
    /// ```
    /// use bvh::aabb::AABB;
    /// use bvh::ray::Ray;
    /// use bvh::nalgebra::{Point3,Vector3};
    ///
    /// let origin = Point3::new(0.0,0.0,0.0);
    /// let direction = Vector3::new(1.0,0.0,0.0);
    /// let ray = Ray::new(origin, direction);
    ///
    /// let point1 = Point3::new(99.9,-1.0,-1.0);
    /// let point2 = Point3::new(100.1,1.0,1.0);
    /// let aabb = AABB::with_bounds(point1, point2);
    ///
    /// assert!(ray.intersects_aabb(&aabb));
    /// ```
    ///
    /// [`Ray`]: struct.Ray.html
    /// [`AABB`]: struct.AABB.html
    ///
    pub fn intersects_aabb(&self, aabb: &AABB) -> bool {
        let mut ray_min = (aabb[self.sign.x].x - self.origin.x) * self.inv_direction.x;
        let mut ray_max = (aabb[1 - self.sign.x].x - self.origin.x) * self.inv_direction.x;

        let y_min = (aabb[self.sign.y].y - self.origin.y) * self.inv_direction.y;
        let y_max = (aabb[1 - self.sign.y].y - self.origin.y) * self.inv_direction.y;

        if (ray_min > y_max) || (y_min > ray_max) {
            return false;
        }

        if y_min > ray_min {
            ray_min = y_min;
        }
        // Using the following solution significantly decreases the performance
        // ray_min = ray_min.max(y_min);

        if y_max < ray_max {
            ray_max = y_max;
        }
        // Using the following solution significantly decreases the performance
        // ray_max = ray_max.min(y_max);

        let z_min = (aabb[self.sign.z].z - self.origin.z) * self.inv_direction.z;
        let z_max = (aabb[1 - self.sign.z].z - self.origin.z) * self.inv_direction.z;

        if (ray_min > z_max) || (z_min > ray_max) {
            return false;
        }

        // Only required for bounded intersection intervals.
        // if z_min > ray_min {
        // ray_min = z_min;
        // }

        if z_max < ray_max {
            ray_max = z_max;
        }
        // Using the following solution significantly decreases the performance
        // ray_max = ray_max.min(y_max);

        ray_max > 0.0
    }

    /// Naive implementation of a [`Ray`]/[`AABB`] intersection algorithm.
    ///
    /// # Examples
    /// ```
    /// use bvh::aabb::AABB;
    /// use bvh::ray::Ray;
    /// use bvh::nalgebra::{Point3,Vector3};
    ///
    /// let origin = Point3::new(0.0,0.0,0.0);
    /// let direction = Vector3::new(1.0,0.0,0.0);
    /// let ray = Ray::new(origin, direction);
    ///
    /// let point1 = Point3::new(99.9,-1.0,-1.0);
    /// let point2 = Point3::new(100.1,1.0,1.0);
    /// let aabb = AABB::with_bounds(point1, point2);
    ///
    /// assert!(ray.intersects_aabb_naive(&aabb));
    /// ```
    ///
    /// [`Ray`]: struct.Ray.html
    /// [`AABB`]: struct.AABB.html
    ///
    pub fn intersects_aabb_naive(&self, aabb: &AABB) -> bool {
        let hit_min_x = (aabb.min.x - self.origin.x) * self.inv_direction.x;
        let hit_max_x = (aabb.max.x - self.origin.x) * self.inv_direction.x;

        let hit_min_y = (aabb.min.y - self.origin.y) * self.inv_direction.y;
        let hit_max_y = (aabb.max.y - self.origin.y) * self.inv_direction.y;

        let hit_min_z = (aabb.min.z - self.origin.z) * self.inv_direction.z;
        let hit_max_z = (aabb.max.z - self.origin.z) * self.inv_direction.z;

        let x_entry = hit_min_x.min(hit_max_x);
        let y_entry = hit_min_y.min(hit_max_y);
        let z_entry = hit_min_z.min(hit_max_z);
        let x_exit = hit_min_x.max(hit_max_x);
        let y_exit = hit_min_y.max(hit_max_y);
        let z_exit = hit_min_z.max(hit_max_z);

        let latest_entry = x_entry.max(y_entry).max(z_entry);
        let earliest_exit = x_exit.min(y_exit).min(z_exit);

        latest_entry < earliest_exit && earliest_exit > 0.0
    }

    /// Implementation of the algorithm described [here]
    /// (https://tavianator.com/fast-branchless-raybounding-box-intersections/).
    ///
    /// # Examples
    /// ```
    /// use bvh::aabb::AABB;
    /// use bvh::ray::Ray;
    /// use bvh::nalgebra::{Point3,Vector3};
    ///
    /// let origin = Point3::new(0.0,0.0,0.0);
    /// let direction = Vector3::new(1.0,0.0,0.0);
    /// let ray = Ray::new(origin, direction);
    ///
    /// let point1 = Point3::new(99.9,-1.0,-1.0);
    /// let point2 = Point3::new(100.1,1.0,1.0);
    /// let aabb = AABB::with_bounds(point1, point2);
    ///
    /// assert!(ray.intersects_aabb_branchless(&aabb));
    /// ```
    ///
    /// [`Ray`]: struct.Ray.html
    /// [`AABB`]: struct.AABB.html
    ///
    pub fn intersects_aabb_branchless(&self, aabb: &AABB) -> bool {
        let tx1 = (aabb.min.x - self.origin.x) * self.inv_direction.x;
        let tx2 = (aabb.max.x - self.origin.x) * self.inv_direction.x;

        let mut tmin = tx1.min(tx2);
        let mut tmax = tx1.max(tx2);

        let ty1 = (aabb.min.y - self.origin.y) * self.inv_direction.y;
        let ty2 = (aabb.max.y - self.origin.y) * self.inv_direction.y;

        tmin = tmin.max(ty1.min(ty2));
        tmax = tmax.min(ty1.max(ty2));

        let tz1 = (aabb.min.z - self.origin.z) * self.inv_direction.z;
        let tz2 = (aabb.max.z - self.origin.z) * self.inv_direction.z;

        tmin = tmin.max(tz1.min(tz2));
        tmax = tmax.min(tz1.max(tz2));

        tmax >= tmin && tmax >= 0.0
    }
}

#[cfg(test)]
mod tests {
    use ray::Ray;
    use aabb::AABB;
    use nalgebra::{Point3, Vector3};
    use rand::{Rng, StdRng, SeedableRng};

    type TupleVec = (f32, f32, f32);

    fn tuple_to_point(tpl: &TupleVec) -> Point3<f32> {
        Point3::new(tpl.0, tpl.1, tpl.2)
    }

    fn tuple_to_vector(tpl: &TupleVec) -> Vector3<f32> {
        Vector3::new(tpl.0, tpl.1, tpl.2)
    }

    /// Generates a random `Ray` which points at at a random `AABB`.
    fn gen_ray_to_aabb(data: (TupleVec, TupleVec, TupleVec)) -> (Ray, AABB) {
        // Generate a random AABB
        let aabb = AABB::empty()
            .grow(&tuple_to_point(&data.0))
            .grow(&tuple_to_point(&data.1));

        // Get its center
        let center = aabb.center();

        // Generate random ray pointing at the center
        let pos = tuple_to_point(&data.2);
        let ray = Ray::new(pos, center - pos);
        (ray, aabb)
    }

    /// Test whether a `Ray` which points at the center of an `AABB` intersects it.
    /// Uses the optimized algorithm.
    quickcheck!{
        fn test_ray_points_at_aabb_center(data: (TupleVec, TupleVec, TupleVec)) -> bool {
            let (ray, aabb) = gen_ray_to_aabb(data);
            ray.intersects_aabb(&aabb)
        }
    }

    /// Test whether a `Ray` which points at the center of an `AABB` intersects it.
    /// Uses the naive algorithm.
    quickcheck!{
        fn test_ray_points_at_aabb_center_naive(data: (TupleVec, TupleVec, TupleVec)) -> bool {
            let (ray, aabb) = gen_ray_to_aabb(data);
            ray.intersects_aabb_naive(&aabb)
        }
    }

    /// Test whether a `Ray` which points at the center of an `AABB` intersects it.
    /// Uses the branchless algorithm.
    quickcheck!{
        fn test_ray_points_at_aabb_center_branchless(data: (TupleVec, TupleVec, TupleVec)) -> bool {
            let (ray, aabb) = gen_ray_to_aabb(data);
            ray.intersects_aabb_branchless(&aabb)
        }
    }

    /// Test whether a `Ray` which points away from the center of an `AABB`
    /// does not intersect it, unless its origin is inside the `AABB`.
    /// Uses the optimized algorithm.
    quickcheck!{
        fn test_ray_points_from_aabb_center(data: (TupleVec, TupleVec, TupleVec)) -> bool {
            let (mut ray, aabb) = gen_ray_to_aabb(data);

            // Invert the direction of the ray
            ray.direction = -ray.direction;
            ray.inv_direction = -ray.inv_direction;
            !ray.intersects_aabb(&aabb) || aabb.contains(&ray.origin)
        }
    }

    /// Test whether a `Ray` which points away from the center of an `AABB`
    /// does not intersect it, unless its origin is inside the `AABB`.
    /// Uses the naive algorithm.
    quickcheck!{
        fn test_ray_points_from_aabb_center_naive(data: (TupleVec, TupleVec, TupleVec)) -> bool {
            let (mut ray, aabb) = gen_ray_to_aabb(data);

             // Invert the ray direction
            ray.direction = -ray.direction;
            ray.inv_direction = -ray.inv_direction;
            !ray.intersects_aabb_naive(&aabb) || aabb.contains(&ray.origin)
        }
    }

    /// Test whether a `Ray` which points away from the center of an `AABB`
    /// does not intersect it, unless its origin is inside the `AABB`.
    /// Uses the branchless algorithm.
    quickcheck!{
        fn test_ray_points_from_aabb_center_branchless(data: (TupleVec, TupleVec, TupleVec))
                                                       -> bool {
            let (mut ray, aabb) = gen_ray_to_aabb(data);
            // Invert the ray direction
            ray.direction = -ray.direction;
            ray.inv_direction = -ray.inv_direction;
            !ray.intersects_aabb_branchless(&aabb) || aabb.contains(&ray.origin)
        }
    }

    /// Generates some random deterministic `Ray`/`AABB` pairs.
    fn gen_random_ray_aabb(rng: &mut StdRng) -> (Ray, AABB) {
        let a = tuple_to_point(&rng.gen::<TupleVec>());
        let b = tuple_to_point(&rng.gen::<TupleVec>());
        let c = tuple_to_point(&rng.gen::<TupleVec>());
        let d = tuple_to_vector(&rng.gen::<TupleVec>());

        let aabb = AABB::empty().grow(&a).grow(&b);
        let ray = Ray::new(c, d);
        (ray, aabb)
    }

    #[bench]
    /// Benchmark for the optimized intersection algorithm.
    fn bench_intersects_aabb(b: &mut ::test::Bencher) {
        let seed = [0];
        let mut rng = StdRng::from_seed(&seed);

        b.iter(|| {
            let one_thousand = ::test::black_box(1000);
            for _ in 0..one_thousand {
                let (ray, aabb) = gen_random_ray_aabb(&mut rng);
                ray.intersects_aabb(&aabb);
            }
        });
    }

    #[bench]
    /// Benchmark for the naive intersection algorithm.
    fn bench_intersects_aabb_naive(b: &mut ::test::Bencher) {
        let seed = [0];
        let mut rng = StdRng::from_seed(&seed);

        b.iter(|| {
            let one_thousand = ::test::black_box(1000);
            for _ in 0..one_thousand {
                let (ray, aabb) = gen_random_ray_aabb(&mut rng);
                ray.intersects_aabb_naive(&aabb);
            }
        });
    }

    #[bench]
    /// Benchmark for the branchless intersection algorithm.
    fn bench_intersects_aabb_branchless(b: &mut ::test::Bencher) {
        let seed = [0];
        let mut rng = StdRng::from_seed(&seed);

        b.iter(|| {
            let one_thousand = ::test::black_box(1000);
            for _ in 0..one_thousand {
                let (ray, aabb) = gen_random_ray_aabb(&mut rng);
                ray.intersects_aabb_branchless(&aabb);
            }
        });
    }
}
<|endoftext|>


<commit_before>use std::fmt::{Display, Formatter, Error};

#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum SeqElem {
    Plus(i32),
    Mult(i32),
    Div(i32),
    Mod(i32),
    Const(i32),
}

impl Display for SeqElem {
    fn fmt(&self, mut fmt: &mut Formatter) -> Result<(), Error> {
        match *self {
            SeqElem::Plus(i) if i < 0 => write!(fmt, "- {}", i.abs()),
            SeqElem::Plus(i) => write!(fmt, "+ {}", i),
            SeqElem::Mult(i) => write!(fmt, "* {}", i),
            SeqElem::Div(i) => write!(fmt, "/ {}", i),
            SeqElem::Mod(i) => write!(fmt, "% {}", i),
            SeqElem::Const(i) => write!(fmt, "= {}", i),
        }
    }
}

pub struct Seq(Vec<SeqElem>);

impl Seq {
    pub fn new(elems: Vec<SeqElem>) -> Seq {
        Seq(elems)
    }
}

impl Display for Seq {
    fn fmt(&self, mut fmt: &mut Formatter) -> Result<(), Error> {
        for (i, elem) in self.0.iter().enumerate() {
            if i != 0 {
                try!(write!(fmt, ", "));
            }

            try!(write!(fmt, "{}", elem));
        }

        Ok(())
    }
}

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

    #[test]
    fn fmt_seq_elem_plus() {
        assert_eq!("+ 0", format!("{}", Plus(0)));
        assert_eq!("+ 4", format!("{}", Plus(4)));
    }

    #[test]
    fn fmt_seq_elem_minus() {
        assert_eq!("- 1", format!("{}", Plus(-1)));
        assert_eq!("- 4", format!("{}", Plus(-4)));
    }

    #[test]
    fn fmt_seq_elem_mult() {
        assert_eq!("* -4", format!("{}", Mult(-4)));
        assert_eq!("* 4", format!("{}", Mult(4)));
    }

    #[test]
    fn fmt_seq_elem_div() {
        assert_eq!("/ -4", format!("{}", Div(-4)));
        assert_eq!("/ 4", format!("{}", Div(4)));
    }

    #[test]
    fn fmt_seq_elem_mod() {
        assert_eq!("% -4", format!("{}", Mod(-4)));
        assert_eq!("% 4", format!("{}", Mod(4)));
    }

    #[test]
    fn fmt_seq_elem_const() {
        assert_eq!("= -4", format!("{}", Const(0)));
        assert_eq!("= 4", format!("{}", Const(4)));
    }

    #[test]
    fn fmt_seq() {
        assert_eq!("", format!("{}", Seq(Vec::new())));
        assert_eq!("+ 4", format!("{}", Seq(vec![Plus(4)])));
        assert_eq!("+ 4, % -6", format!("{}", Seq::new(vec![Plus(4), Mod(-6)])));
        assert_eq!("+ 4, % -6, - 12, * 42, / 3, = 9", format!("{}", Seq(vec![Plus(4), Mod(-6), Plus(-12), Mult(42), Div(3), Const(9)])));
    }
}
<commit_msg>change return type of constructor to Self<commit_after>use std::fmt::{Display, Formatter, Error};

#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum SeqElem {
    Plus(i32),
    Mult(i32),
    Div(i32),
    Mod(i32),
    Const(i32),
}

impl Display for SeqElem {
    fn fmt(&self, mut fmt: &mut Formatter) -> Result<(), Error> {
        match *self {
            SeqElem::Plus(i) if i < 0 => write!(fmt, "- {}", i.abs()),
            SeqElem::Plus(i) => write!(fmt, "+ {}", i),
            SeqElem::Mult(i) => write!(fmt, "* {}", i),
            SeqElem::Div(i) => write!(fmt, "/ {}", i),
            SeqElem::Mod(i) => write!(fmt, "% {}", i),
            SeqElem::Const(i) => write!(fmt, "= {}", i),
        }
    }
}

pub struct Seq(Vec<SeqElem>);

impl Seq {
    pub fn new(elems: Vec<SeqElem>) -> Self {
        Seq(elems)
    }
}

impl Display for Seq {
    fn fmt(&self, mut fmt: &mut Formatter) -> Result<(), Error> {
        for (i, elem) in self.0.iter().enumerate() {
            if i != 0 {
                try!(write!(fmt, ", "));
            }

            try!(write!(fmt, "{}", elem));
        }

        Ok(())
    }
}

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

    #[test]
    fn fmt_seq_elem_plus() {
        assert_eq!("+ 0", format!("{}", Plus(0)));
        assert_eq!("+ 4", format!("{}", Plus(4)));
    }

    #[test]
    fn fmt_seq_elem_minus() {
        assert_eq!("- 1", format!("{}", Plus(-1)));
        assert_eq!("- 4", format!("{}", Plus(-4)));
    }

    #[test]
    fn fmt_seq_elem_mult() {
        assert_eq!("* -4", format!("{}", Mult(-4)));
        assert_eq!("* 4", format!("{}", Mult(4)));
    }

    #[test]
    fn fmt_seq_elem_div() {
        assert_eq!("/ -4", format!("{}", Div(-4)));
        assert_eq!("/ 4", format!("{}", Div(4)));
    }

    #[test]
    fn fmt_seq_elem_mod() {
        assert_eq!("% -4", format!("{}", Mod(-4)));
        assert_eq!("% 4", format!("{}", Mod(4)));
    }

    #[test]
    fn fmt_seq_elem_const() {
        assert_eq!("= -4", format!("{}", Const(0)));
        assert_eq!("= 4", format!("{}", Const(4)));
    }

    #[test]
    fn fmt_seq() {
        assert_eq!("", format!("{}", Seq(Vec::new())));
        assert_eq!("+ 4", format!("{}", Seq(vec![Plus(4)])));
        assert_eq!("+ 4, % -6", format!("{}", Seq::new(vec![Plus(4), Mod(-6)])));
        assert_eq!("+ 4, % -6, - 12, * 42, / 3, = 9", format!("{}", Seq(vec![Plus(4), Mod(-6), Plus(-12), Mult(42), Div(3), Const(9)])));
    }
}
<|endoftext|>


<commit_before>use std::env;
use std::fs::File;
use std::io::prelude::*;

fn main() {
    if let Some(path) = env::args().nth(1) {
        let mut contents = String::new();
        match File::open(path) {
            Ok(mut file) => {
                match file.read_to_string(&mut contents) {
                    Ok(_) => println!("Would read and eval here."),
                    Err(_) => println!("Found the file but failed to read it."),
                }
            }
            Err(_) => println!("Failed to open the file for reading."),
        };
    } else {
        println!("Please provide a path to some brainfuck source as the first argument.")
    }
}

mod brainfuck {
    pub type Pointer = u32;

    #[derive(PartialEq)]
    #[derive(Debug)]
    pub enum Command {
        IncrementPointer,
        DecrementPointer,
        IncrementValue,
        DecrementValue,
        OutputValue,
        InputValue,
        ForwardsTo(Pointer),
        BackwardsTo(Pointer)
    }

    #[derive(PartialEq)]
    #[derive(Debug)]
    pub enum ReadResult {
        Program(Vec<Command>),
        UnmatchedJump
    }

    pub fn read(source: &str) -> ReadResult {
        let mut program: Vec<Command> = vec![];

        // find braces first

        return ReadResult::Program(program)
    }

    // pub fn eval(program: Vec<Command>) {
    // }
}

#[cfg(test)]
mod tests {
    use brainfuck::*;
    use brainfuck::Command::*;
    use brainfuck::ReadResult::*;

    #[test]
    fn read_empty() {
        let source = "";
        let expected = Program(vec![]);
        let actual = read(source);
        assert_eq!(expected, actual);
    }

    #[test]
    fn read_simple() {
        let source = "+>-<.,<.-+>,";
        let expected = Program(vec![
            IncrementValue,
            IncrementPointer,
            DecrementValue,
            DecrementPointer,
            OutputValue,
            InputValue,
            DecrementPointer,
            OutputValue,
            DecrementValue,
            IncrementValue,
            IncrementPointer,
            InputValue
        ]);
        let actual = read(source);
        assert_eq!(expected, actual);
    }

    #[test]
    fn read_garbage() {
        let source = ",.+lol,hey.>there<";
        let expected = Program(vec![
            InputValue,
            OutputValue,
            IncrementValue,
            InputValue,
            OutputValue,
            IncrementPointer,
            DecrementPointer
        ]);
        let actual = read(source);
        assert_eq!(expected, actual);
    }

    #[test]
    fn read_loop() {
        let source = "[->+<]";
        let expected = Program(vec![
            ForwardsTo(5),
            DecrementValue,
            IncrementPointer,
            IncrementValue,
            DecrementPointer,
            BackwardsTo(0)
        ]);
        let actual = read(source);
        assert_eq!(expected, actual);
    }

    #[test]
    fn read_bad_loop() {
        let source = "[,.[,.>+-][./.[]]";
        let expected = UnmatchedJump;
        let actual = read(source);
        assert_eq!(expected, actual);
    }
}
<commit_msg>Almost finished reading, need to swap loops<commit_after>use std::env;
use std::fs::File;
use std::io::prelude::*;

fn main() {
    if let Some(path) = env::args().nth(1) {
        let mut contents = String::new();
        match File::open(path) {
            Ok(mut file) => {
                match file.read_to_string(&mut contents) {
                    Ok(_) => println!("Would read and eval here."),
                    Err(_) => println!("Found the file but failed to read it."),
                }
            }
            Err(_) => println!("Failed to open the file for reading."),
        };
    } else {
        println!("Please provide a path to some brainfuck source as the first argument.")
    }
}

mod brainfuck {
    pub type Pointer = usize;

    #[derive(PartialEq)]
    #[derive(Debug)]
    pub enum Command {
        IncrementPointer,
        DecrementPointer,
        IncrementValue,
        DecrementValue,
        OutputValue,
        InputValue,
        ForwardsTo(Pointer),
        BackwardsTo(Pointer),
    }

    #[derive(PartialEq)]
    #[derive(Debug)]
    pub enum ReadResult {
        Program(Vec<Command>),
        UnmatchedJump,
    }

    pub fn read(source: &str) -> ReadResult {
        let mut loops: Vec<usize> = vec![];
        let mut loop_closes: usize = 0;
        let mut position: usize = 0;
        let program: Vec<Command> = source
            .chars()
            .filter_map(|token| {
                let command = match token {
                    '>' => Some(Command::IncrementPointer),
                    '<' => Some(Command::DecrementPointer),
                    '+' => Some(Command::IncrementValue),
                    '-' => Some(Command::DecrementValue),
                    '.' => Some(Command::OutputValue),
                    ',' => Some(Command::InputValue),
                    '[' => {
                        loops.push(position);
                        Some(Command::BackwardsTo(position))
                    }
                    ']' => {
                        loop_closes += 1;
                        Some(Command::ForwardsTo(position))
                    }
                    _ => None,
                };

                if command.is_some() {
                    position += 1;
                }

                command
            })
            .collect();

        if loops.len() != loop_closes {
            ReadResult::UnmatchedJump
        } else {
            ReadResult::Program(program)
        }
    }

    // pub fn eval(program: Vec<Command>) {
    // }
}

#[cfg(test)]
mod tests {
    use brainfuck::*;
    use brainfuck::Command::*;
    use brainfuck::ReadResult::*;

    #[test]
    fn read_empty() {
        let source = "";
        let expected = Program(vec![]);
        let actual = read(source);
        assert_eq!(expected, actual);
    }

    #[test]
    fn read_simple() {
        let source = "+>-<.,<.-+>,";
        let expected = Program(vec![IncrementValue,
                                    IncrementPointer,
                                    DecrementValue,
                                    DecrementPointer,
                                    OutputValue,
                                    InputValue,
                                    DecrementPointer,
                                    OutputValue,
                                    DecrementValue,
                                    IncrementValue,
                                    IncrementPointer,
                                    InputValue]);
        let actual = read(source);
        assert_eq!(expected, actual);
    }

    #[test]
    fn read_garbage() {
        let source = ",.+lol,hey.>there<";
        let expected = Program(vec![InputValue,
                                    OutputValue,
                                    IncrementValue,
                                    InputValue,
                                    OutputValue,
                                    IncrementPointer,
                                    DecrementPointer]);
        let actual = read(source);
        assert_eq!(expected, actual);
    }

    #[test]
    fn read_loop() {
        let source = "[->+<]";
        let expected = Program(vec![ForwardsTo(5),
                                    DecrementValue,
                                    IncrementPointer,
                                    IncrementValue,
                                    DecrementPointer,
                                    BackwardsTo(0)]);
        let actual = read(source);
        assert_eq!(expected, actual);
    }

    #[test]
    fn read_bad_loop() {
        let source = "[,.[,.>+-][./.[]]";
        let expected = UnmatchedJump;
        let actual = read(source);
        assert_eq!(expected, actual);
    }
}
<|endoftext|>


<commit_before>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with
// this file, You can obtain one at https://mozilla.org/MPL/2.0/.

/// An element of the [Table of contents](struct.Toc.html)
///
/// # Example
///
/// ```
/// use epub_builder::TocElement;
/// TocElement::new("chapter_1.xhtml", "Chapter 1")
///     .child(TocElement::new("chapter_1.xhtml#1", "Chapter 1, section 1")
///               .child(TocElement::new("chapter_1.xhtml#1-1", "Chapter 1, section 1, subsection 1")));
/// ```
#[derive(Debug, Clone)]
pub struct TocElement {
    /// The level. 0: part, 1: chapter, 2: section, ...
    pub level: i32,
    /// The link
    pub url: String,
    /// Title of this entry
    pub title: String,
    /// Inner elements
    pub children: Vec<TocElement>,
}

impl TocElement {
    /// Creates a new element of the toc
    ///
    /// By default, the element's level is `1` and it has no children.
    pub fn new<S1: Into<String>, S2: Into<String>>(url: S1, title: S2) -> TocElement {
        TocElement {
            level: 1,
            url: url.into(),
            title: title.into(),
            children: vec![],
        }
    }

    /// Sets the level of a TocElement
    pub fn level(mut self, level: i32) -> Self {
        self.level = level;
        self
    }

    /// Change level, recursively, so the structure keeps having some sense
    fn level_up(&mut self, level: i32) {
        self.level = level;
        for mut child in &mut self.children {
            if child.level <= self.level {
                child.level_up(level + 1);
            }
        }
    }

    /// Add a child to this element.
    ///
    /// This adjust the level of the child to be the level of its parents, plus 1;
    /// this means that there is no point in manually setting the level to elements
    /// added with this method.
    ///
    /// # Example
    ///
    /// ```
    /// use epub_builder::TocElement;
    /// let elem = TocElement::new("foo.xhtml", "Foo")
    ///     .child(TocElement::new("bar.xhtml", "Bar")
    ///          .level(42));
    ///
    /// // `Bar`'s level wiss still be `2`.
    /// ```
    pub fn child(mut self, mut child: TocElement) -> Self {
        if child.level <= self.level {
            child.level_up(self.level + 1);
        }
        self.children.push(child);
        self
    }

    /// Add element to self or to children, according to its level
    ///
    /// This will adds `element` directly to `self` if its level is equal or less
    /// to the last children element; else it will insert it to the last child.
    ///
    /// See the `add` method of [`Toc](struct.toc.html).
    pub fn add(&mut self, element: TocElement) {
        let mut inserted = false;
        if let Some(ref mut last_elem) = self.children.last_mut() {
            if element.level > last_elem.level {
                last_elem.add(element.clone());
                inserted = true;
            }
        }
        if !inserted {
            self.children.push(element);
        }
    }

    /// Render element for Epub's toc.ncx format
    #[doc(hidden)]
    pub fn render_epub(&self, mut offset: u32) -> (u32, String) {
        offset += 1;
        let id = offset;
        let children = if self.children.is_empty() {
            String::new()
        } else {
            let mut output = String::new();
            for child in &self.children {
                let (n, s) = child.render_epub(offset);
                offset = n;
                output.push_str(&s);
            }
            output
        };
        (offset,
         format!("
<navPoint id=\"navPoint-{id}\">
  <navLabel>
   <text>{title}</text>
  </navLabel>
  <content src=\"{url}\" />
{children}
</navPoint>",
                 id = id,
                 title = self.title,
                 url = self.url,
                 children = children))

    }

    /// Render element as a list element
    #[doc(hidden)]
    pub fn render(&self, numbered: bool) -> String {
        if self.title.is_empty() {
            return String::new();
        }
        let children = if self.children.is_empty() {
            String::new()
        } else {
            let mut output = String::new();
            for child in &self.children {
                output.push_str(&child.render(numbered));
            }
            format!("\n<{oul}>{children}\n</{oul}>\n",
                    oul = if numbered { "ol" } else { "ul" },
                    children = output)
        };
        format!("
{title}{children}
\n",
                link = self.url,
                title = self.title,
                children = children)

    }
}

/// A Table Of Contents
///
/// It basically contains a list of [`TocElement`](struct.TocElement.html)s.
///
/// # Example
///
/// Creates a Toc, fills it, and render it to HTML:
///
/// ```
/// use epub_builder::{Toc, TocElement};
/// Toc::new()
///    // add a level-1 element
///    .add(TocElement::new("intro.xhtml", "Introduction"))
///    // add a level-1 element with children
///    .add(TocElement::new("chapter_1.xhtml", "Chapter 1")
///            .child(TocElement::new("chapter_1.xhtml#section1", "1.1: Some section"))
///            .child(TocElement::new("chapter_1.xhtml#section2", "1.2: another section")))
///    // add a level-2 element, which will thus get "attached" to previous level-1 element
///    .add(TocElement::new("chapter_1.xhtml#section3", "1.3: yet another section")
///            .level(2))
///    // render the toc (non-numbered list) and returns a string
///    .render(false);
/// ```
#[derive(Debug, Default)]
pub struct Toc {
    /// The elements composing the TOC
    pub elements: Vec<TocElement>,
}

impl Toc {
    /// Creates a new, empty, Toc
    pub fn new() -> Toc {
        Toc { elements: vec![] }
    }

    /// Returns `true` if the toc is empty, `false` else.
    ///
    /// Note that `empty` here means that the the toc has zero *or one*
    /// element, since it's still not worth displaying it in this case.
    pub fn is_empty(&self) -> bool {
        self.elements.len() <= 1
    }

    /// Adds a [`TocElement`](struct.TocElement.html) to the Toc.
    ///
    /// This will look at the element's level and will insert it as a child of the last
    /// element of the Toc that has an inferior level.
    ///
    /// # Example
    ///
    /// ```
    /// # use epub_builder::{Toc, TocElement};
    /// let mut toc = Toc::new();
    /// // Insert an element at default level (1)
    /// toc.add(TocElement::new("chapter_1.xhtml", "Chapter 1"));
    ///
    /// // Insert an element at level 2
    /// toc.add(TocElement::new("section_1.xhtml", "Section 1")
    ///           .level(2));
    /// // "Section 1" is now a child of "Chapter 1"
    /// ```
    ///
    /// There are some cases where this behaviour might not be what you want; however,
    /// it makes sure that the TOC can still be renderer correctly for HTML and EPUB.
    pub fn add(&mut self, element: TocElement) -> &mut Self {
        let mut inserted = false;
        if let Some(ref mut last_elem) = self.elements.last_mut() {
            if element.level > last_elem.level {
                last_elem.add(element.clone());
                inserted = true;
            }
        }
        if !inserted {
            self.elements.push(element);
        }

        self
    }

    /// Render the Toc in a toc.ncx compatible way, for EPUB.
    pub fn render_epub(&mut self) -> String {
        let mut output = String::new();
        let mut offset = 0;
        for elem in &self.elements {
            let (n, s) = elem.render_epub(offset);
            offset = n;
            output.push_str(&s);
        }
        output
    }

    /// Render the Toc in either
 or
 form (according to numbered)
    pub fn render(&mut self, numbered: bool) -> String {
        let mut output = String::new();
        for elem in &self.elements {
            output.push_str(&elem.render(numbered));
        }
        format!("<{oul}>\n{output}\n</{oul}>\n",
                output = output,
                oul = if numbered { "ol" } else { "ul" })
    }
}

/////////////////////////////////////////////////////////////////////////////////
///                                  TESTS                                     //
/////////////////////////////////////////////////////////////////////////////////

#[test]
fn toc_simple() {
    let mut toc = Toc::new();
    toc.add(TocElement::new("#1", "0.0.1").level(3));
    toc.add(TocElement::new("#2", "1").level(1));
    toc.add(TocElement::new("#3", "1.0.1").level(3));
    toc.add(TocElement::new("#4", "1.1").level(2));
    toc.add(TocElement::new("#5", "2"));
    let actual = toc.render(false);
    let expected = "

0.0.1

1

1.0.1

1.1

2

";
    assert_eq!(&actual, expected);
}

#[test]
fn toc_epub_simple() {
    let mut toc = Toc::new();
    toc.add(TocElement::new("#1", "1"));
    toc.add(TocElement::new("#2", "2"));
    let actual = toc.render_epub();
    let expected = "
<navPoint id=\"navPoint-1\">
  <navLabel>
   <text>1</text>
  </navLabel>
  <content src=\"#1\" />

</navPoint>
<navPoint id=\"navPoint-2\">
  <navLabel>
   <text>2</text>
  </navLabel>
  <content src=\"#2\" />

</navPoint>";
    assert_eq!(&actual, expected);
}

#[test]
fn toc_epub_simple_sublevels() {
    let mut toc = Toc::new();
    toc.add(TocElement::new("#1", "1"));
    toc.add(TocElement::new("#1.1", "1.1").level(2));
    toc.add(TocElement::new("#2", "2"));
    toc.add(TocElement::new("#2.1", "2.1").level(2));
    let actual = toc.render_epub();
    let expected = "
<navPoint id=\"navPoint-1\">
  <navLabel>
   <text>1</text>
  </navLabel>
  <content src=\"#1\" />

<navPoint id=\"navPoint-2\">
  <navLabel>
   <text>1.1</text>
  </navLabel>
  <content src=\"#1.1\" />

</navPoint>
</navPoint>
<navPoint id=\"navPoint-3\">
  <navLabel>
   <text>2</text>
  </navLabel>
  <content src=\"#2\" />

<navPoint id=\"navPoint-4\">
  <navLabel>
   <text>2.1</text>
  </navLabel>
  <content src=\"#2.1\" />

</navPoint>
</navPoint>";
    assert_eq!(&actual, expected);
}

#[test]
fn toc_epub_broken_sublevels() {
    let mut toc = Toc::new();
    toc.add(TocElement::new("#1.1", "1.1").level(2));
    toc.add(TocElement::new("#2", "2"));
    toc.add(TocElement::new("#2.1", "2.1").level(2));
    let actual = toc.render_epub();
    let expected = "
<navPoint id=\"navPoint-1\">
  <navLabel>
   <text>1.1</text>
  </navLabel>
  <content src=\"#1.1\" />

</navPoint>\n<navPoint id=\"navPoint-2\">
  <navLabel>
   <text>2</text>
  </navLabel>
  <content src=\"#2\" />

<navPoint id=\"navPoint-3\">
  <navLabel>
   <text>2.1</text>
  </navLabel>
  <content src=\"#2.1\" />

</navPoint>\n</navPoint>";
    assert_eq!(&actual, expected);
}
<commit_msg>Remove warning<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with
// this file, You can obtain one at https://mozilla.org/MPL/2.0/.

/// An element of the [Table of contents](struct.Toc.html)
///
/// # Example
///
/// ```
/// use epub_builder::TocElement;
/// TocElement::new("chapter_1.xhtml", "Chapter 1")
///     .child(TocElement::new("chapter_1.xhtml#1", "Chapter 1, section 1")
///               .child(TocElement::new("chapter_1.xhtml#1-1", "Chapter 1, section 1, subsection 1")));
/// ```
#[derive(Debug, Clone)]
pub struct TocElement {
    /// The level. 0: part, 1: chapter, 2: section, ...
    pub level: i32,
    /// The link
    pub url: String,
    /// Title of this entry
    pub title: String,
    /// Inner elements
    pub children: Vec<TocElement>,
}

impl TocElement {
    /// Creates a new element of the toc
    ///
    /// By default, the element's level is `1` and it has no children.
    pub fn new<S1: Into<String>, S2: Into<String>>(url: S1, title: S2) -> TocElement {
        TocElement {
            level: 1,
            url: url.into(),
            title: title.into(),
            children: vec![],
        }
    }

    /// Sets the level of a TocElement
    pub fn level(mut self, level: i32) -> Self {
        self.level = level;
        self
    }

    /// Change level, recursively, so the structure keeps having some sense
    fn level_up(&mut self, level: i32) {
        self.level = level;
        for child in &mut self.children {
            if child.level <= self.level {
                child.level_up(level + 1);
            }
        }
    }

    /// Add a child to this element.
    ///
    /// This adjust the level of the child to be the level of its parents, plus 1;
    /// this means that there is no point in manually setting the level to elements
    /// added with this method.
    ///
    /// # Example
    ///
    /// ```
    /// use epub_builder::TocElement;
    /// let elem = TocElement::new("foo.xhtml", "Foo")
    ///     .child(TocElement::new("bar.xhtml", "Bar")
    ///          .level(42));
    ///
    /// // `Bar`'s level wiss still be `2`.
    /// ```
    pub fn child(mut self, mut child: TocElement) -> Self {
        if child.level <= self.level {
            child.level_up(self.level + 1);
        }
        self.children.push(child);
        self
    }

    /// Add element to self or to children, according to its level
    ///
    /// This will adds `element` directly to `self` if its level is equal or less
    /// to the last children element; else it will insert it to the last child.
    ///
    /// See the `add` method of [`Toc](struct.toc.html).
    pub fn add(&mut self, element: TocElement) {
        let mut inserted = false;
        if let Some(ref mut last_elem) = self.children.last_mut() {
            if element.level > last_elem.level {
                last_elem.add(element.clone());
                inserted = true;
            }
        }
        if !inserted {
            self.children.push(element);
        }
    }

    /// Render element for Epub's toc.ncx format
    #[doc(hidden)]
    pub fn render_epub(&self, mut offset: u32) -> (u32, String) {
        offset += 1;
        let id = offset;
        let children = if self.children.is_empty() {
            String::new()
        } else {
            let mut output = String::new();
            for child in &self.children {
                let (n, s) = child.render_epub(offset);
                offset = n;
                output.push_str(&s);
            }
            output
        };
        (offset,
         format!("
<navPoint id=\"navPoint-{id}\">
  <navLabel>
   <text>{title}</text>
  </navLabel>
  <content src=\"{url}\" />
{children}
</navPoint>",
                 id = id,
                 title = self.title,
                 url = self.url,
                 children = children))

    }

    /// Render element as a list element
    #[doc(hidden)]
    pub fn render(&self, numbered: bool) -> String {
        if self.title.is_empty() {
            return String::new();
        }
        let children = if self.children.is_empty() {
            String::new()
        } else {
            let mut output = String::new();
            for child in &self.children {
                output.push_str(&child.render(numbered));
            }
            format!("\n<{oul}>{children}\n</{oul}>\n",
                    oul = if numbered { "ol" } else { "ul" },
                    children = output)
        };
        format!("
{title}{children}
\n",
                link = self.url,
                title = self.title,
                children = children)

    }
}

/// A Table Of Contents
///
/// It basically contains a list of [`TocElement`](struct.TocElement.html)s.
///
/// # Example
///
/// Creates a Toc, fills it, and render it to HTML:
///
/// ```
/// use epub_builder::{Toc, TocElement};
/// Toc::new()
///    // add a level-1 element
///    .add(TocElement::new("intro.xhtml", "Introduction"))
///    // add a level-1 element with children
///    .add(TocElement::new("chapter_1.xhtml", "Chapter 1")
///            .child(TocElement::new("chapter_1.xhtml#section1", "1.1: Some section"))
///            .child(TocElement::new("chapter_1.xhtml#section2", "1.2: another section")))
///    // add a level-2 element, which will thus get "attached" to previous level-1 element
///    .add(TocElement::new("chapter_1.xhtml#section3", "1.3: yet another section")
///            .level(2))
///    // render the toc (non-numbered list) and returns a string
///    .render(false);
/// ```
#[derive(Debug, Default)]
pub struct Toc {
    /// The elements composing the TOC
    pub elements: Vec<TocElement>,
}

impl Toc {
    /// Creates a new, empty, Toc
    pub fn new() -> Toc {
        Toc { elements: vec![] }
    }

    /// Returns `true` if the toc is empty, `false` else.
    ///
    /// Note that `empty` here means that the the toc has zero *or one*
    /// element, since it's still not worth displaying it in this case.
    pub fn is_empty(&self) -> bool {
        self.elements.len() <= 1
    }

    /// Adds a [`TocElement`](struct.TocElement.html) to the Toc.
    ///
    /// This will look at the element's level and will insert it as a child of the last
    /// element of the Toc that has an inferior level.
    ///
    /// # Example
    ///
    /// ```
    /// # use epub_builder::{Toc, TocElement};
    /// let mut toc = Toc::new();
    /// // Insert an element at default level (1)
    /// toc.add(TocElement::new("chapter_1.xhtml", "Chapter 1"));
    ///
    /// // Insert an element at level 2
    /// toc.add(TocElement::new("section_1.xhtml", "Section 1")
    ///           .level(2));
    /// // "Section 1" is now a child of "Chapter 1"
    /// ```
    ///
    /// There are some cases where this behaviour might not be what you want; however,
    /// it makes sure that the TOC can still be renderer correctly for HTML and EPUB.
    pub fn add(&mut self, element: TocElement) -> &mut Self {
        let mut inserted = false;
        if let Some(ref mut last_elem) = self.elements.last_mut() {
            if element.level > last_elem.level {
                last_elem.add(element.clone());
                inserted = true;
            }
        }
        if !inserted {
            self.elements.push(element);
        }

        self
    }

    /// Render the Toc in a toc.ncx compatible way, for EPUB.
    pub fn render_epub(&mut self) -> String {
        let mut output = String::new();
        let mut offset = 0;
        for elem in &self.elements {
            let (n, s) = elem.render_epub(offset);
            offset = n;
            output.push_str(&s);
        }
        output
    }

    /// Render the Toc in either
 or
 form (according to numbered)
    pub fn render(&mut self, numbered: bool) -> String {
        let mut output = String::new();
        for elem in &self.elements {
            output.push_str(&elem.render(numbered));
        }
        format!("<{oul}>\n{output}\n</{oul}>\n",
                output = output,
                oul = if numbered { "ol" } else { "ul" })
    }
}

/////////////////////////////////////////////////////////////////////////////////
///                                  TESTS                                     //
/////////////////////////////////////////////////////////////////////////////////

#[test]
fn toc_simple() {
    let mut toc = Toc::new();
    toc.add(TocElement::new("#1", "0.0.1").level(3));
    toc.add(TocElement::new("#2", "1").level(1));
    toc.add(TocElement::new("#3", "1.0.1").level(3));
    toc.add(TocElement::new("#4", "1.1").level(2));
    toc.add(TocElement::new("#5", "2"));
    let actual = toc.render(false);
    let expected = "

0.0.1

1

1.0.1

1.1

2

";
    assert_eq!(&actual, expected);
}

#[test]
fn toc_epub_simple() {
    let mut toc = Toc::new();
    toc.add(TocElement::new("#1", "1"));
    toc.add(TocElement::new("#2", "2"));
    let actual = toc.render_epub();
    let expected = "
<navPoint id=\"navPoint-1\">
  <navLabel>
   <text>1</text>
  </navLabel>
  <content src=\"#1\" />

</navPoint>
<navPoint id=\"navPoint-2\">
  <navLabel>
   <text>2</text>
  </navLabel>
  <content src=\"#2\" />

</navPoint>";
    assert_eq!(&actual, expected);
}

#[test]
fn toc_epub_simple_sublevels() {
    let mut toc = Toc::new();
    toc.add(TocElement::new("#1", "1"));
    toc.add(TocElement::new("#1.1", "1.1").level(2));
    toc.add(TocElement::new("#2", "2"));
    toc.add(TocElement::new("#2.1", "2.1").level(2));
    let actual = toc.render_epub();
    let expected = "
<navPoint id=\"navPoint-1\">
  <navLabel>
   <text>1</text>
  </navLabel>
  <content src=\"#1\" />

<navPoint id=\"navPoint-2\">
  <navLabel>
   <text>1.1</text>
  </navLabel>
  <content src=\"#1.1\" />

</navPoint>
</navPoint>
<navPoint id=\"navPoint-3\">
  <navLabel>
   <text>2</text>
  </navLabel>
  <content src=\"#2\" />

<navPoint id=\"navPoint-4\">
  <navLabel>
   <text>2.1</text>
  </navLabel>
  <content src=\"#2.1\" />

</navPoint>
</navPoint>";
    assert_eq!(&actual, expected);
}

#[test]
fn toc_epub_broken_sublevels() {
    let mut toc = Toc::new();
    toc.add(TocElement::new("#1.1", "1.1").level(2));
    toc.add(TocElement::new("#2", "2"));
    toc.add(TocElement::new("#2.1", "2.1").level(2));
    let actual = toc.render_epub();
    let expected = "
<navPoint id=\"navPoint-1\">
  <navLabel>
   <text>1.1</text>
  </navLabel>
  <content src=\"#1.1\" />

</navPoint>\n<navPoint id=\"navPoint-2\">
  <navLabel>
   <text>2</text>
  </navLabel>
  <content src=\"#2\" />

<navPoint id=\"navPoint-3\">
  <navLabel>
   <text>2.1</text>
  </navLabel>
  <content src=\"#2.1\" />

</navPoint>\n</navPoint>";
    assert_eq!(&actual, expected);
}
<|endoftext|>