<commit_before>//! Convenience functions and types for working with [`std::path::Path`].
//!
//! This module deliberately ignores Window's prefixes for now, but I would welcome a change that
//! adds it.
//!
//! [`std::path::Path`]: https://doc.rust-lang.org/std/path/struct.Path.html

use std::ffi::OsString;
use std::iter::FromIterator;
use std::path::{Component, Path};
use std::slice;
use std::vec;

/// An iterator with `peek()` and `peek2()` calls that return optional references to the next
/// element or the one after.
///
/// This struct is created by the [`peek2able()`] extension method on [`Iterator`] provided by this
/// module's [`IteratorExt`].
///
/// [`peek2able()`]: trait.IteratorExt.html#method.peek2able
/// [`Iterator`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html
/// [`IteratorExt`]: trait.IteratorExt.html
#[derive(Debug)]
pub struct Peek2able<I: Iterator> {
    // iter is the original iterator that we now have a Peek2able of.
    iter: I,
    // peek1 is the stashed value corresponding to the first lookahead from a peek or peek2 call,
    // or the second value from a peek2 call after next has been called once.
    peek1: Option<Option<I::Item>>,
    // peek2 is the stashed value corresponding to the second lookahead from a `.peek2()` call.
    peek2: Option<Option<I::Item>>,
}

/// An extension to add two-element lookahead to an iterator.
pub trait IteratorExt<I: Iterator> {
    /// Creates an iterator that can look at he next two elments from the iterator without
    /// consuming it.
    ///
    /// Adds [`peek()`] and [`peek2()`] methods to an iterator.
    ///
    /// Note that the underlying iterator is still advanced when either [`peek()`] or [`peek2()`]
    /// is called for the first time. In order to peek, [`next()`] is called, hence any side
    /// effects of the [`next()`] method will occur.
    ///
    /// [`next()`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#tymethod.next
    /// [`peek()`]: struct.Peek2able.html#method.peek
    /// [`peek2()`]: struct.Peek2able.html#method.peek2
    fn peek2able(self) -> Peek2able<I>;
}

impl<I: Iterator> IteratorExt<I> for I {
    fn peek2able(self) -> Peek2able<I> {
        Peek2able {
            iter: self,
            peek1: None,
            peek2: None,
        }
    }
}

impl<I: Iterator> Iterator for Peek2able<I> {
    type Item = I::Item;

    fn next(&mut self) -> Option<I::Item> {
        match self.peek1.take() {
            Some(v) => {
                self.peek1 = self.peek2.take();
                v
            }
            None => self.iter.next(),
        }
    }
}

impl<I: Iterator> Peek2able<I> {
    /// Returns a reference to the next `.next()` value without advancing the iterator.
    pub fn peek(&mut self) -> Option<&I::Item> {
        if self.peek1.is_none() {
            self.peek1 = Some(self.iter.next());
        }
        match self.peek1 {
            Some(Some(ref value)) => Some(value),
            Some(None) => None,
            _ => unreachable!(),
        }
    }
    /// Returns a reference to what would be the next second `.next()` value without advancing the
    /// iterator.
    ///
    /// # Example
    ///
    /// Basic usage:
    ///
    /// ```
    /// use rsfs::path_parts::IteratorExt;
    ///
    /// let xs = [1, 2, 3, 4];
    ///
    /// let mut iter = xs.iter().peek2able();
    ///
    /// assert_eq!(iter.peek2(), Some(&&2));
    /// assert_eq!(iter.peek(), Some(&&1));
    /// assert_eq!(iter.next(), Some(&1));
    ///
    /// assert_eq!(iter.next(), Some(&2));
    ///
    /// // The iterator does not advance even if we `peek` or `peek2` multiple times
    /// assert_eq!(iter.peek(), Some(&&3));
    /// assert_eq!(iter.peek2(), Some(&&4));
    /// assert_eq!(iter.peek(), Some(&&3));
    /// assert_eq!(iter.peek2(), Some(&&4));
    ///
    /// assert_eq!(iter.next(), Some(&3));
    ///
    /// // `peek2()` will return `None` when the iterator is one away from the end
    /// assert_eq!(iter.peek2(), None);
    /// assert_eq!(iter.peek(), Some(&&4));
    ///
    /// assert_eq!(iter.next(), Some(&4));
    ///
    /// // After the iterator is finished, so are both `peek()` and `peek2()`
    /// assert_eq!(iter.peek2(), None);
    /// assert_eq!(iter.peek(), None);
    /// assert_eq!(iter.next(), None);
    /// ```
    pub fn peek2(&mut self) -> Option<&I::Item> {
        if self.peek1.is_none() {
            self.peek1 = Some(self.iter.next());
        }
        if self.peek2.is_none() {
            self.peek2 = Some(self.iter.next());
        }
        match self.peek2 {
            Some(Some(ref value)) => Some(value),
            Some(None) => None,
            _ => unreachable!(),
        }
    }
}

/// A simplified version of [`std::path::Component`].
///
/// [`std::path::Component`]: https://doc.rust-lang.org/std/path/enum.Component.html
#[derive(Debug, PartialEq)]
pub enum Part {
    /// A `..` in a path that could not be normalized away.
    ParentDir,
    /// A file or directory name.
    Normal(OsString),
}

impl Part {
    /// Borrows a `Normal` path part's `OsString` path.
    pub fn as_normal(&self) -> Option<&OsString> {
        match *self {
            Part::Normal(ref s) => Some(s),
            Part::ParentDir => None,
        }
    }
    /// Consumes a `Normal` path part into its `OsString` path.
    pub fn into_normal(self) -> Option<OsString> {
        match self {
            Part::Normal(s) => Some(s),
            Part::ParentDir => None,
        }
    }
}

/// Wraps information about a path and provides iterators over the components in that path.
///
/// This struct is created by the [`normalize`] function.
///
/// [`normalize`]: fn.normalize.html
#[derive(Debug)]
pub struct Parts {
    // at_root signifies whether the original path, normalized, began at root.
    at_root: bool,
    // parts contains all normal parts of a path and, if not at root, may begin with a few
    // parent directories.
    parts: Vec<Part>,
}

impl Parts {
    /// Returns whether the normalized original path began with the root directory.
    pub fn at_root(&self) -> bool {
        self.at_root
    }
}

/// An iterator that borrows from of a [`Parts`].
///
/// This struct is created by the `into_iter` method on [`Parts`] (provided by the [`IntoIterator`]
/// trait).
///
/// [`Parts`]: struct.Parts.html
/// [`IntoIterator`]: https://doc.rust-lang.org/std/iter/trait.IntoIterator.html
pub struct PartsIter<'a> {
    // inner is the remaining path parts yet to iterate over.
    inner: slice::Iter<'a, Part>,
}

impl<'a> IntoIterator for &'a mut Parts {
    type Item = &'a Part;
    type IntoIter = PartsIter<'a>;

    fn into_iter(self) -> Self::IntoIter {
        PartsIter { inner: self.parts.iter() }
    }
}

impl<'a> IntoIterator for &'a Parts {
    type Item = &'a Part;
    type IntoIter = PartsIter<'a>;

    fn into_iter(self) -> Self::IntoIter {
        PartsIter { inner: self.parts.iter() }
    }
}

impl<'a> Iterator for PartsIter<'a> {
    type Item = &'a Part;
    fn next(&mut self) -> Option<Self::Item> {
        self.inner.next()
    }
}

/// An iterator that moves out of a [`Parts`].
///
/// This struct is created by the `into_iter` method on [`Parts`] (provided by the [`IntoIterator`]
/// trait).
///
/// [`Parts`]: struct.Parts.html
/// [`IntoIterator`]: https://doc.rust-lang.org/std/iter/trait.IntoIterator.html
#[derive(Debug)]
pub struct PartsIntoIter {
    // inner is the remaining path parts yet to iterate over.
    inner: vec::IntoIter<Part>,
}

impl IntoIterator for Parts {
    type Item = Part;
    type IntoIter = PartsIntoIter;

    fn into_iter(self) -> Self::IntoIter {
        PartsIntoIter { inner: self.parts.into_iter() }
    }
}

impl Iterator for PartsIntoIter {
    type Item = Part;
    fn next(&mut self) -> Option<Self::Item> {
        self.inner.next()
    }
}

impl FromIterator<Part> for Parts {
    fn from_iter<I: IntoIterator<Item = Part>>(iter: I) -> Parts {
        let mut parts = Parts {
            at_root: false,
            parts: Vec::new(),
        };
        for part in iter {
            parts.parts.push(part)
        }
        parts
    }
}

/// Returns the shortest [`Parts`] equivalent to path purely by lexical parsing.
///
/// - replaces multiple path separators with one
/// - eliminates each `.`
/// - replaces `..` with the non `..` that preceeds it
///
/// Effectively, this is [`std::fs::canonicalize`] except for this operates on a potential path.
///
/// [`Parts`]: struct.Parts.html
/// [`std::fs::canonicalize`]: https://doc.rust-lang.org/std/fs/fn.canonicalize.html
pub fn normalize<P: AsRef<Path>>(path: &P) -> Parts {
    let mut ps = Parts {
        at_root: false,
        parts: Vec::new(),
    };
    for comp in path.as_ref().components() {
        match comp {
            Component::RootDir => ps.at_root = true,
            Component::ParentDir => {
                if ps.at_root || ps.parts.last().map_or(false, |last| *last != Part::ParentDir) {
                    ps.parts.pop();
                } else {
                    ps.parts.push(Part::ParentDir);
                }
            }
            Component::Normal(p) => {
                ps.parts.push(Part::Normal(p.to_os_string()));
            }
            _ => (),
        }
    }
    ps
}
<commit_msg>path_parts: add ability to get Parts from a lone Part<commit_after>//! Convenience functions and types for working with [`std::path::Path`].
//!
//! This module deliberately ignores Window's prefixes for now, but I would welcome a change that
//! adds it.
//!
//! [`std::path::Path`]: https://doc.rust-lang.org/std/path/struct.Path.html

use std::ffi::OsString;
use std::iter::FromIterator;
use std::path::{Component, Path};
use std::slice;
use std::vec;

/// An iterator with `peek()` and `peek2()` calls that return optional references to the next
/// element or the one after.
///
/// This struct is created by the [`peek2able()`] extension method on [`Iterator`] provided by this
/// module's [`IteratorExt`].
///
/// [`peek2able()`]: trait.IteratorExt.html#method.peek2able
/// [`Iterator`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html
/// [`IteratorExt`]: trait.IteratorExt.html
#[derive(Debug)]
pub struct Peek2able<I: Iterator> {
    // iter is the original iterator that we now have a Peek2able of.
    iter: I,
    // peek1 is the stashed value corresponding to the first lookahead from a peek or peek2 call,
    // or the second value from a peek2 call after next has been called once.
    peek1: Option<Option<I::Item>>,
    // peek2 is the stashed value corresponding to the second lookahead from a `.peek2()` call.
    peek2: Option<Option<I::Item>>,
}

/// An extension to add two-element lookahead to an iterator.
pub trait IteratorExt<I: Iterator> {
    /// Creates an iterator that can look at he next two elments from the iterator without
    /// consuming it.
    ///
    /// Adds [`peek()`] and [`peek2()`] methods to an iterator.
    ///
    /// Note that the underlying iterator is still advanced when either [`peek()`] or [`peek2()`]
    /// is called for the first time. In order to peek, [`next()`] is called, hence any side
    /// effects of the [`next()`] method will occur.
    ///
    /// [`next()`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#tymethod.next
    /// [`peek()`]: struct.Peek2able.html#method.peek
    /// [`peek2()`]: struct.Peek2able.html#method.peek2
    fn peek2able(self) -> Peek2able<I>;
}

impl<I: Iterator> IteratorExt<I> for I {
    fn peek2able(self) -> Peek2able<I> {
        Peek2able {
            iter: self,
            peek1: None,
            peek2: None,
        }
    }
}

impl<I: Iterator> Iterator for Peek2able<I> {
    type Item = I::Item;

    fn next(&mut self) -> Option<I::Item> {
        match self.peek1.take() {
            Some(v) => {
                self.peek1 = self.peek2.take();
                v
            }
            None => self.iter.next(),
        }
    }
}

impl<I: Iterator> Peek2able<I> {
    /// Returns a reference to the next `.next()` value without advancing the iterator.
    pub fn peek(&mut self) -> Option<&I::Item> {
        if self.peek1.is_none() {
            self.peek1 = Some(self.iter.next());
        }
        match self.peek1 {
            Some(Some(ref value)) => Some(value),
            Some(None) => None,
            _ => unreachable!(),
        }
    }
    /// Returns a reference to what would be the next second `.next()` value without advancing the
    /// iterator.
    ///
    /// # Example
    ///
    /// Basic usage:
    ///
    /// ```
    /// use rsfs::path_parts::IteratorExt;
    ///
    /// let xs = [1, 2, 3, 4];
    ///
    /// let mut iter = xs.iter().peek2able();
    ///
    /// assert_eq!(iter.peek2(), Some(&&2));
    /// assert_eq!(iter.peek(), Some(&&1));
    /// assert_eq!(iter.next(), Some(&1));
    ///
    /// assert_eq!(iter.next(), Some(&2));
    ///
    /// // The iterator does not advance even if we `peek` or `peek2` multiple times
    /// assert_eq!(iter.peek(), Some(&&3));
    /// assert_eq!(iter.peek2(), Some(&&4));
    /// assert_eq!(iter.peek(), Some(&&3));
    /// assert_eq!(iter.peek2(), Some(&&4));
    ///
    /// assert_eq!(iter.next(), Some(&3));
    ///
    /// // `peek2()` will return `None` when the iterator is one away from the end
    /// assert_eq!(iter.peek2(), None);
    /// assert_eq!(iter.peek(), Some(&&4));
    ///
    /// assert_eq!(iter.next(), Some(&4));
    ///
    /// // After the iterator is finished, so are both `peek()` and `peek2()`
    /// assert_eq!(iter.peek2(), None);
    /// assert_eq!(iter.peek(), None);
    /// assert_eq!(iter.next(), None);
    /// ```
    pub fn peek2(&mut self) -> Option<&I::Item> {
        if self.peek1.is_none() {
            self.peek1 = Some(self.iter.next());
        }
        if self.peek2.is_none() {
            self.peek2 = Some(self.iter.next());
        }
        match self.peek2 {
            Some(Some(ref value)) => Some(value),
            Some(None) => None,
            _ => unreachable!(),
        }
    }
}

/// A simplified version of [`std::path::Component`].
///
/// [`std::path::Component`]: https://doc.rust-lang.org/std/path/enum.Component.html
#[derive(Debug, PartialEq)]
pub enum Part {
    /// A `..` in a path that could not be normalized away.
    ParentDir,
    /// A file or directory name.
    Normal(OsString),
}

impl Part {
    /// Borrows a `Normal` path part's `OsString` path.
    pub fn as_normal(&self) -> Option<&OsString> {
        match *self {
            Part::Normal(ref s) => Some(s),
            Part::ParentDir => None,
        }
    }
    /// Consumes a `Normal` path part into its `OsString` path.
    pub fn into_normal(self) -> Option<OsString> {
        match self {
            Part::Normal(s) => Some(s),
            Part::ParentDir => None,
        }
    }
}

/// Wraps information about a path and provides iterators over the components in that path.
///
/// This struct is created by the [`normalize`] function.
///
/// [`normalize`]: fn.normalize.html
#[derive(Debug)]
pub struct Parts {
    // at_root signifies whether the original path, normalized, began at root.
    at_root: bool,
    // parts contains all normal parts of a path and, if not at root, may begin with a few
    // parent directories.
    parts: Vec<Part>,
}

impl From<Part> for Parts {
    fn from(p: Part) -> Parts {
        Parts { at_root: false, parts: vec![p] }
    }
}

impl Parts {
    /// Returns whether the normalized original path began with the root directory.
    pub fn at_root(&self) -> bool {
        self.at_root
    }
}

/// An iterator that borrows from of a [`Parts`].
///
/// This struct is created by the `into_iter` method on [`Parts`] (provided by the [`IntoIterator`]
/// trait).
///
/// [`Parts`]: struct.Parts.html
/// [`IntoIterator`]: https://doc.rust-lang.org/std/iter/trait.IntoIterator.html
pub struct PartsIter<'a> {
    // inner is the remaining path parts yet to iterate over.
    inner: slice::Iter<'a, Part>,
}

impl<'a> IntoIterator for &'a mut Parts {
    type Item = &'a Part;
    type IntoIter = PartsIter<'a>;

    fn into_iter(self) -> Self::IntoIter {
        PartsIter { inner: self.parts.iter() }
    }
}

impl<'a> IntoIterator for &'a Parts {
    type Item = &'a Part;
    type IntoIter = PartsIter<'a>;

    fn into_iter(self) -> Self::IntoIter {
        PartsIter { inner: self.parts.iter() }
    }
}

impl<'a> Iterator for PartsIter<'a> {
    type Item = &'a Part;
    fn next(&mut self) -> Option<Self::Item> {
        self.inner.next()
    }
}

/// An iterator that moves out of a [`Parts`].
///
/// This struct is created by the `into_iter` method on [`Parts`] (provided by the [`IntoIterator`]
/// trait).
///
/// [`Parts`]: struct.Parts.html
/// [`IntoIterator`]: https://doc.rust-lang.org/std/iter/trait.IntoIterator.html
#[derive(Debug)]
pub struct PartsIntoIter {
    // inner is the remaining path parts yet to iterate over.
    inner: vec::IntoIter<Part>,
}

impl IntoIterator for Parts {
    type Item = Part;
    type IntoIter = PartsIntoIter;

    fn into_iter(self) -> Self::IntoIter {
        PartsIntoIter { inner: self.parts.into_iter() }
    }
}

impl Iterator for PartsIntoIter {
    type Item = Part;
    fn next(&mut self) -> Option<Self::Item> {
        self.inner.next()
    }
}

impl FromIterator<Part> for Parts {
    fn from_iter<I: IntoIterator<Item = Part>>(iter: I) -> Parts {
        let mut parts = Parts {
            at_root: false,
            parts: Vec::new(),
        };
        for part in iter {
            parts.parts.push(part)
        }
        parts
    }
}

/// Returns the shortest [`Parts`] equivalent to path purely by lexical parsing.
///
/// - replaces multiple path separators with one
/// - eliminates each `.`
/// - replaces `..` with the non `..` that preceeds it
///
/// Effectively, this is [`std::fs::canonicalize`] except for this operates on a potential path.
///
/// [`Parts`]: struct.Parts.html
/// [`std::fs::canonicalize`]: https://doc.rust-lang.org/std/fs/fn.canonicalize.html
pub fn normalize<P: AsRef<Path>>(path: &P) -> Parts {
    let mut ps = Parts {
        at_root: false,
        parts: Vec::new(),
    };
    for comp in path.as_ref().components() {
        match comp {
            Component::RootDir => ps.at_root = true,
            Component::ParentDir => {
                if ps.at_root || ps.parts.last().map_or(false, |last| *last != Part::ParentDir) {
                    ps.parts.pop();
                } else {
                    ps.parts.push(Part::ParentDir);
                }
            }
            Component::Normal(p) => {
                ps.parts.push(Part::Normal(p.to_os_string()));
            }
            _ => (),
        }
    }
    ps
}
<|endoftext|>


<commit_before>pub fn clean_string(mut input: String) -> String {
    input = String::from(input.trim());

    if input == "" {
        return input;
    }

    // remove line-comments
    let mut last = '\0';
    let mut len = input.len();
    for (i, c) in input.chars().enumerate() {
        if last == '/' && c == '/' {
            len = i-1;
            break;
        }
        last = c;
    }

    input.truncate(len);

    input
}

pub fn add_semicolon(mut input: String) -> String {
    if !input.ends_with(';') && !input.ends_with("*/") && !input.ends_with('}') {
        input.push_str(";")
    }
    input
}
<commit_msg>Unescape strings when preprocessing.<commit_after>use unescape::unescape;

pub fn clean_string(mut input: String) -> String {
    input = String::from(input.trim());
    input = unescape(&input).unwrap_or(String::from(""));

    if input == "" {
        return input;
    }

    // remove line-comments
    let mut last = '\0';
    let mut len = input.len();
    for (i, c) in input.chars().enumerate() {
        if last == '/' && c == '/' {
            len = i-1;
            break;
        }
        last = c;
    }

    input.truncate(len);

    input
}

pub fn add_semicolon(mut input: String) -> String {
    if !input.ends_with(';') && !input.ends_with("*/") && !input.ends_with('}') {
        input.push_str(";")
    }
    input
}
<|endoftext|>


<commit_before>// Copyright 2013-2014 The CGMath Developers. For a full listing of the authors,
// refer to the Cargo.toml file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use num_traits::Zero;
use num_traits::cast;

use structure::Angle;

use angle::Rad;
use matrix::Matrix4;
use num::BaseFloat;

/// Create a perspective projection matrix.
///
/// This is the equivalent to the [gluPerspective]
/// (http://www.opengl.org/sdk/docs/man2/xhtml/gluPerspective.xml) function.
pub fn perspective<S: BaseFloat, A: Into<Rad<S>>>(
    fovy: A,
    aspect: S,
    near: S,
    far: S,
) -> Matrix4<S> {
    PerspectiveFov {
        fovy: fovy.into(),
        aspect: aspect,
        near: near,
        far: far,
    }.into()
}

/// Create a perspective matrix from a view frustum.
///
/// This is the equivalent of the now deprecated [glFrustum]
/// (http://www.opengl.org/sdk/docs/man2/xhtml/glFrustum.xml) function.
pub fn frustum<S: BaseFloat>(left: S, right: S, bottom: S, top: S, near: S, far: S) -> Matrix4<S> {
    Perspective {
        left: left,
        right: right,
        bottom: bottom,
        top: top,
        near: near,
        far: far,
    }.into()
}

/// Create an orthographic projection matrix.
///
/// This is the equivalent of the now deprecated [glOrtho]
/// (http://www.opengl.org/sdk/docs/man2/xhtml/glOrtho.xml) function.
pub fn ortho<S: BaseFloat>(left: S, right: S, bottom: S, top: S, near: S, far: S) -> Matrix4<S> {
    Ortho {
        left: left,
        right: right,
        bottom: bottom,
        top: top,
        near: near,
        far: far,
    }.into()
}

/// A perspective projection based on a vertical field-of-view angle.
#[derive(Copy, Clone, Debug, PartialEq)]
#[cfg_attr(feature = "rustc-serialize", derive(RustcEncodable, RustcDecodable))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct PerspectiveFov<S> {
    pub fovy: Rad<S>,
    pub aspect: S,
    pub near: S,
    pub far: S,
}

impl<S: BaseFloat> PerspectiveFov<S> {
    pub fn to_perspective(&self) -> Perspective<S> {
        let two: S = cast(2).unwrap();
        let angle = self.fovy / two;
        let ymax = self.near * Rad::tan(angle);
        let xmax = ymax * self.aspect;

        Perspective {
            left: -xmax,
            right: xmax,
            bottom: -ymax,
            top: ymax,
            near: self.near.clone(),
            far: self.far.clone(),
        }
    }
}

impl<S: BaseFloat> From<PerspectiveFov<S>> for Matrix4<S> {
    fn from(persp: PerspectiveFov<S>) -> Matrix4<S> {
        assert!(
            persp.fovy > Rad::zero(),
            "The vertical field of view cannot be below zero, found: {:?}",
            persp.fovy
        );
        assert!(
            persp.fovy < Rad::turn_div_2(),
            "The vertical field of view cannot be greater than a half turn, found: {:?}",
            persp.fovy
        );
        assert!(
            persp.aspect > S::zero(),
            "The aspect ratio cannot be below zero, found: {:?}",
            persp.aspect
        );
        assert!(
            persp.near > S::zero(),
            "The near plane distance cannot be below zero, found: {:?}",
            persp.near
        );
        assert!(
            persp.far > S::zero(),
            "The far plane distance cannot be below zero, found: {:?}",
            persp.far
        );
        assert!(
            persp.far > persp.near,
            "The far plane cannot be closer than the near plane, found: far: {:?}, near: {:?}",
            persp.far,
            persp.near
        );

        let two: S = cast(2).unwrap();
        let f = Rad::cot(persp.fovy / two);

        let c0r0 = f / persp.aspect;
        let c0r1 = S::zero();
        let c0r2 = S::zero();
        let c0r3 = S::zero();

        let c1r0 = S::zero();
        let c1r1 = f;
        let c1r2 = S::zero();
        let c1r3 = S::zero();

        let c2r0 = S::zero();
        let c2r1 = S::zero();
        let c2r2 = (persp.far + persp.near) / (persp.near - persp.far);
        let c2r3 = -S::one();

        let c3r0 = S::zero();
        let c3r1 = S::zero();
        let c3r2 = (two * persp.far * persp.near) / (persp.near - persp.far);
        let c3r3 = S::zero();

        #[cfg_attr(rustfmt, rustfmt_skip)]
        Matrix4::new(
            c0r0, c0r1, c0r2, c0r3,
            c1r0, c1r1, c1r2, c1r3,
            c2r0, c2r1, c2r2, c2r3,
            c3r0, c3r1, c3r2, c3r3,
        )
    }
}

/// A perspective projection with arbitrary left/right/bottom/top distances
#[derive(Copy, Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Perspective<S> {
    pub left: S,
    pub right: S,
    pub bottom: S,
    pub top: S,
    pub near: S,
    pub far: S,
}

impl<S: BaseFloat> From<Perspective<S>> for Matrix4<S> {
    fn from(persp: Perspective<S>) -> Matrix4<S> {
        assert!(
            persp.left <= persp.right,
            "`left` cannot be greater than `right`, found: left: {:?} right: {:?}",
            persp.left,
            persp.right
        );
        assert!(
            persp.bottom <= persp.top,
            "`bottom` cannot be greater than `top`, found: bottom: {:?} top: {:?}",
            persp.bottom,
            persp.top
        );
        assert!(
            persp.near <= persp.far,
            "`near` cannot be greater than `far`, found: near: {:?} far: {:?}",
            persp.near,
            persp.far
        );

        let two: S = cast(2i8).unwrap();

        let c0r0 = (two * persp.near) / (persp.right - persp.left);
        let c0r1 = S::zero();
        let c0r2 = S::zero();
        let c0r3 = S::zero();

        let c1r0 = S::zero();
        let c1r1 = (two * persp.near) / (persp.top - persp.bottom);
        let c1r2 = S::zero();
        let c1r3 = S::zero();

        let c2r0 = (persp.right + persp.left) / (persp.right - persp.left);
        let c2r1 = (persp.top + persp.bottom) / (persp.top - persp.bottom);
        let c2r2 = -(persp.far + persp.near) / (persp.far - persp.near);
        let c2r3 = -S::one();

        let c3r0 = S::zero();
        let c3r1 = S::zero();
        let c3r2 = -(two * persp.far * persp.near) / (persp.far - persp.near);
        let c3r3 = S::zero();

        #[cfg_attr(rustfmt, rustfmt_skip)]
        Matrix4::new(
            c0r0, c0r1, c0r2, c0r3,
            c1r0, c1r1, c1r2, c1r3,
            c2r0, c2r1, c2r2, c2r3,
            c3r0, c3r1, c3r2, c3r3,
        )
    }
}

/// An orthographic projection with arbitrary left/right/bottom/top distances
#[derive(Copy, Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Ortho<S> {
    pub left: S,
    pub right: S,
    pub bottom: S,
    pub top: S,
    pub near: S,
    pub far: S,
}

impl<S: BaseFloat> From<Ortho<S>> for Matrix4<S> {
    fn from(ortho: Ortho<S>) -> Matrix4<S> {
        let two: S = cast(2).unwrap();

        let c0r0 = two / (ortho.right - ortho.left);
        let c0r1 = S::zero();
        let c0r2 = S::zero();
        let c0r3 = S::zero();

        let c1r0 = S::zero();
        let c1r1 = two / (ortho.top - ortho.bottom);
        let c1r2 = S::zero();
        let c1r3 = S::zero();

        let c2r0 = S::zero();
        let c2r1 = S::zero();
        let c2r2 = -two / (ortho.far - ortho.near);
        let c2r3 = S::zero();

        let c3r0 = -(ortho.right + ortho.left) / (ortho.right - ortho.left);
        let c3r1 = -(ortho.top + ortho.bottom) / (ortho.top - ortho.bottom);
        let c3r2 = -(ortho.far + ortho.near) / (ortho.far - ortho.near);
        let c3r3 = S::one();

        #[cfg_attr(rustfmt, rustfmt_skip)]
        Matrix4::new(
            c0r0, c0r1, c0r2, c0r3,
            c1r0, c1r1, c1r2, c1r3,
            c2r0, c2r1, c2r2, c2r3,
            c3r0, c3r1, c3r2, c3r3,
        )
    }
}
<commit_msg>Fix links to OpenGL API in docs<commit_after>// Copyright 2013-2014 The CGMath Developers. For a full listing of the authors,
// refer to the Cargo.toml file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use num_traits::Zero;
use num_traits::cast;

use structure::Angle;

use angle::Rad;
use matrix::Matrix4;
use num::BaseFloat;

/// Create a perspective projection matrix.
///
/// This is the equivalent to the [`gluPerspective`] function.
///
/// [`gluPerspective`]: https://www.opengl.org/sdk/docs/man2/xhtml/gluPerspective.xml
pub fn perspective<S: BaseFloat, A: Into<Rad<S>>>(
    fovy: A,
    aspect: S,
    near: S,
    far: S,
) -> Matrix4<S> {
    PerspectiveFov {
        fovy: fovy.into(),
        aspect: aspect,
        near: near,
        far: far,
    }.into()
}

/// Create a perspective matrix from a view frustum.
///
/// This is the equivalent of the now deprecated [`glFrustum`] function.
///
/// [`glFrustum`]: http://www.opengl.org/sdk/docs/man2/xhtml/glFrustum.xml
pub fn frustum<S: BaseFloat>(left: S, right: S, bottom: S, top: S, near: S, far: S) -> Matrix4<S> {
    Perspective {
        left: left,
        right: right,
        bottom: bottom,
        top: top,
        near: near,
        far: far,
    }.into()
}

/// Create an orthographic projection matrix.
///
/// This is the equivalent of the now deprecated [`glOrtho`] function.
///
/// [`glOrtho`]: http://www.opengl.org/sdk/docs/man2/xhtml/glOrtho.xml
pub fn ortho<S: BaseFloat>(left: S, right: S, bottom: S, top: S, near: S, far: S) -> Matrix4<S> {
    Ortho {
        left: left,
        right: right,
        bottom: bottom,
        top: top,
        near: near,
        far: far,
    }.into()
}

/// A perspective projection based on a vertical field-of-view angle.
#[derive(Copy, Clone, Debug, PartialEq)]
#[cfg_attr(feature = "rustc-serialize", derive(RustcEncodable, RustcDecodable))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct PerspectiveFov<S> {
    pub fovy: Rad<S>,
    pub aspect: S,
    pub near: S,
    pub far: S,
}

impl<S: BaseFloat> PerspectiveFov<S> {
    pub fn to_perspective(&self) -> Perspective<S> {
        let two: S = cast(2).unwrap();
        let angle = self.fovy / two;
        let ymax = self.near * Rad::tan(angle);
        let xmax = ymax * self.aspect;

        Perspective {
            left: -xmax,
            right: xmax,
            bottom: -ymax,
            top: ymax,
            near: self.near.clone(),
            far: self.far.clone(),
        }
    }
}

impl<S: BaseFloat> From<PerspectiveFov<S>> for Matrix4<S> {
    fn from(persp: PerspectiveFov<S>) -> Matrix4<S> {
        assert!(
            persp.fovy > Rad::zero(),
            "The vertical field of view cannot be below zero, found: {:?}",
            persp.fovy
        );
        assert!(
            persp.fovy < Rad::turn_div_2(),
            "The vertical field of view cannot be greater than a half turn, found: {:?}",
            persp.fovy
        );
        assert!(
            persp.aspect > S::zero(),
            "The aspect ratio cannot be below zero, found: {:?}",
            persp.aspect
        );
        assert!(
            persp.near > S::zero(),
            "The near plane distance cannot be below zero, found: {:?}",
            persp.near
        );
        assert!(
            persp.far > S::zero(),
            "The far plane distance cannot be below zero, found: {:?}",
            persp.far
        );
        assert!(
            persp.far > persp.near,
            "The far plane cannot be closer than the near plane, found: far: {:?}, near: {:?}",
            persp.far,
            persp.near
        );

        let two: S = cast(2).unwrap();
        let f = Rad::cot(persp.fovy / two);

        let c0r0 = f / persp.aspect;
        let c0r1 = S::zero();
        let c0r2 = S::zero();
        let c0r3 = S::zero();

        let c1r0 = S::zero();
        let c1r1 = f;
        let c1r2 = S::zero();
        let c1r3 = S::zero();

        let c2r0 = S::zero();
        let c2r1 = S::zero();
        let c2r2 = (persp.far + persp.near) / (persp.near - persp.far);
        let c2r3 = -S::one();

        let c3r0 = S::zero();
        let c3r1 = S::zero();
        let c3r2 = (two * persp.far * persp.near) / (persp.near - persp.far);
        let c3r3 = S::zero();

        #[cfg_attr(rustfmt, rustfmt_skip)]
        Matrix4::new(
            c0r0, c0r1, c0r2, c0r3,
            c1r0, c1r1, c1r2, c1r3,
            c2r0, c2r1, c2r2, c2r3,
            c3r0, c3r1, c3r2, c3r3,
        )
    }
}

/// A perspective projection with arbitrary left/right/bottom/top distances
#[derive(Copy, Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Perspective<S> {
    pub left: S,
    pub right: S,
    pub bottom: S,
    pub top: S,
    pub near: S,
    pub far: S,
}

impl<S: BaseFloat> From<Perspective<S>> for Matrix4<S> {
    fn from(persp: Perspective<S>) -> Matrix4<S> {
        assert!(
            persp.left <= persp.right,
            "`left` cannot be greater than `right`, found: left: {:?} right: {:?}",
            persp.left,
            persp.right
        );
        assert!(
            persp.bottom <= persp.top,
            "`bottom` cannot be greater than `top`, found: bottom: {:?} top: {:?}",
            persp.bottom,
            persp.top
        );
        assert!(
            persp.near <= persp.far,
            "`near` cannot be greater than `far`, found: near: {:?} far: {:?}",
            persp.near,
            persp.far
        );

        let two: S = cast(2i8).unwrap();

        let c0r0 = (two * persp.near) / (persp.right - persp.left);
        let c0r1 = S::zero();
        let c0r2 = S::zero();
        let c0r3 = S::zero();

        let c1r0 = S::zero();
        let c1r1 = (two * persp.near) / (persp.top - persp.bottom);
        let c1r2 = S::zero();
        let c1r3 = S::zero();

        let c2r0 = (persp.right + persp.left) / (persp.right - persp.left);
        let c2r1 = (persp.top + persp.bottom) / (persp.top - persp.bottom);
        let c2r2 = -(persp.far + persp.near) / (persp.far - persp.near);
        let c2r3 = -S::one();

        let c3r0 = S::zero();
        let c3r1 = S::zero();
        let c3r2 = -(two * persp.far * persp.near) / (persp.far - persp.near);
        let c3r3 = S::zero();

        #[cfg_attr(rustfmt, rustfmt_skip)]
        Matrix4::new(
            c0r0, c0r1, c0r2, c0r3,
            c1r0, c1r1, c1r2, c1r3,
            c2r0, c2r1, c2r2, c2r3,
            c3r0, c3r1, c3r2, c3r3,
        )
    }
}

/// An orthographic projection with arbitrary left/right/bottom/top distances
#[derive(Copy, Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Ortho<S> {
    pub left: S,
    pub right: S,
    pub bottom: S,
    pub top: S,
    pub near: S,
    pub far: S,
}

impl<S: BaseFloat> From<Ortho<S>> for Matrix4<S> {
    fn from(ortho: Ortho<S>) -> Matrix4<S> {
        let two: S = cast(2).unwrap();

        let c0r0 = two / (ortho.right - ortho.left);
        let c0r1 = S::zero();
        let c0r2 = S::zero();
        let c0r3 = S::zero();

        let c1r0 = S::zero();
        let c1r1 = two / (ortho.top - ortho.bottom);
        let c1r2 = S::zero();
        let c1r3 = S::zero();

        let c2r0 = S::zero();
        let c2r1 = S::zero();
        let c2r2 = -two / (ortho.far - ortho.near);
        let c2r3 = S::zero();

        let c3r0 = -(ortho.right + ortho.left) / (ortho.right - ortho.left);
        let c3r1 = -(ortho.top + ortho.bottom) / (ortho.top - ortho.bottom);
        let c3r2 = -(ortho.far + ortho.near) / (ortho.far - ortho.near);
        let c3r3 = S::one();

        #[cfg_attr(rustfmt, rustfmt_skip)]
        Matrix4::new(
            c0r0, c0r1, c0r2, c0r3,
            c1r0, c1r1, c1r2, c1r3,
            c2r0, c2r1, c2r2, c2r3,
            c3r0, c3r1, c3r2, c3r3,
        )
    }
}
<|endoftext|>


<commit_before>mod pool;

pub use self::pool::LeasedItem;
use self::pool::Pool;
use crate::core::Segment;
use crate::directory::Directory;
use crate::directory::WatchHandle;
use crate::directory::META_LOCK;
use crate::Index;
use crate::Searcher;
use crate::SegmentReader;
use std::convert::TryInto;
use std::sync::Arc;

/// Defines when a new version of the index should be reloaded.
///
/// Regardless of whether you search and index in the same process, tantivy does not necessarily
/// reflects the change that are commited to your index. `ReloadPolicy` precisely helps you define
/// when you want your index to be reloaded.
#[derive(Clone, Copy)]
pub enum ReloadPolicy {
    /// The index is entirely reloaded manually.
    /// All updates of the index should be manual.
    ///
    /// No change is reflected automatically. You are required to call `.load_seacher()` manually.
    Manual,
    /// The index is reloaded within milliseconds after a new commit is available.
    /// This is made possible by watching changes in the `meta.json` file.
    OnCommit, // TODO add NEAR_REAL_TIME(target_ms)
}

/// `IndexReader` builder
///
/// It makes it possible to set the following values.
///
/// - `num_searchers` (by default, the number of detected CPU threads):
///
///   When `num_searchers` queries are requested at the same time, the `num_searchers` will block
///   until the one of the searcher in-use gets released.
/// - `reload_policy` (by default `ReloadPolicy::OnCommit`):
///
///   See [`ReloadPolicy`](./enum.ReloadPolicy.html) for more details.
#[derive(Clone)]
pub struct IndexReaderBuilder {
    num_searchers: usize,
    reload_policy: ReloadPolicy,
    index: Index,
}

impl IndexReaderBuilder {
    pub(crate) fn new(index: Index) -> IndexReaderBuilder {
        IndexReaderBuilder {
            num_searchers: num_cpus::get(),
            reload_policy: ReloadPolicy::OnCommit,
            index,
        }
    }

    /// Builds the reader.
    ///
    /// Building the reader is a non-trivial operation that requires
    /// to open different segment readers. It may take hundreds of milliseconds
    /// of time and it may return an error.
    pub fn try_into(self) -> crate::Result<IndexReader> {
        let inner_reader = InnerIndexReader {
            index: self.index,
            num_searchers: self.num_searchers,
            searcher_pool: Pool::new(),
        };
        inner_reader.reload()?;
        let inner_reader_arc = Arc::new(inner_reader);
        let watch_handle_opt: Option<WatchHandle>;
        match self.reload_policy {
            ReloadPolicy::Manual => {
                // No need to set anything...
                watch_handle_opt = None;
            }
            ReloadPolicy::OnCommit => {
                let inner_reader_arc_clone = inner_reader_arc.clone();
                let callback = move || {
                    if let Err(err) = inner_reader_arc_clone.reload() {
                        error!(
                            "Error while loading searcher after commit was detected. {:?}",
                            err
                        );
                    }
                };
                let watch_handle = inner_reader_arc
                    .index
                    .directory()
                    .watch(Box::new(callback))?;
                watch_handle_opt = Some(watch_handle);
            }
        }
        Ok(IndexReader {
            inner: inner_reader_arc,
            watch_handle_opt,
        })
    }

    /// Sets the reload_policy.
    ///
    /// See [`ReloadPolicy`](./enum.ReloadPolicy.html) for more details.
    pub fn reload_policy(mut self, reload_policy: ReloadPolicy) -> IndexReaderBuilder {
        self.reload_policy = reload_policy;
        self
    }

    /// Sets the number of `Searcher` in the searcher pool.
    pub fn num_searchers(mut self, num_searchers: usize) -> IndexReaderBuilder {
        self.num_searchers = num_searchers;
        self
    }
}

impl TryInto<IndexReader> for IndexReaderBuilder {
    type Error = crate::TantivyError;

    fn try_into(self) -> crate::Result<IndexReader> {
        IndexReaderBuilder::try_into(self)
    }
}

struct InnerIndexReader {
    num_searchers: usize,
    searcher_pool: Pool<Searcher>,
    index: Index,
}

impl InnerIndexReader {
    fn reload(&self) -> crate::Result<()> {
        let segment_readers: Vec<SegmentReader> = {
            let _meta_lock = self.index.directory().acquire_lock(&META_LOCK)?;
            let searchable_segments = self.searchable_segments()?;
            searchable_segments
                .iter()
                .map(SegmentReader::open)
                .collect::<crate::Result<_>>()?
        };
        let schema = self.index.schema();
        let searchers = (0..self.num_searchers)
            .map(|_| Searcher::new(schema.clone(), self.index.clone(), segment_readers.clone()))
            .collect();
        self.searcher_pool.publish_new_generation(searchers);
        Ok(())
    }

    /// Returns the list of segments that are searchable
    fn searchable_segments(&self) -> crate::Result<Vec<Segment>> {
        self.index.searchable_segments()
    }

    fn searcher(&self) -> LeasedItem<Searcher> {
        self.searcher_pool.acquire()
    }
}

/// `IndexReader` is your entry point to read and search the index.
///
/// It controls when a new version of the index should be loaded and lends
/// you instances of `Searcher` for the last loaded version.
///
/// `Clone` does not clone the different pool of searcher. `IndexReader`
/// just wraps and `Arc`.
#[derive(Clone)]
pub struct IndexReader {
    inner: Arc<InnerIndexReader>,
    watch_handle_opt: Option<WatchHandle>,
}

impl IndexReader {
    #[cfg(test)]
    pub(crate) fn index(&self) -> Index {
        self.inner.index.clone()
    }

    /// Update searchers so that they reflect the state of the last
    /// `.commit()`.
    ///
    /// If you set up the `OnCommit` `ReloadPolicy` (which is the default)
    /// every commit should be rapidly reflected on your `IndexReader` and you should
    /// not need to call `reload()` at all.
    ///
    /// This automatic reload can take 10s of milliseconds to kick in however, and in unit tests
    /// it can be nice to deterministically force the reload of searchers.
    pub fn reload(&self) -> crate::Result<()> {
        self.inner.reload()
    }

    /// Returns a searcher
    ///
    /// This method should be called every single time a search
    /// query is performed.
    /// The searchers are taken from a pool of `num_searchers` searchers.
    /// If no searcher is available
    /// this may block.
    ///
    /// The same searcher must be used for a given query, as it ensures
    /// the use of a consistent segment set.
    pub fn searcher(&self) -> LeasedItem<Searcher> {
        self.inner.searcher()
    }
}
<commit_msg>Update mod.rs (#845)<commit_after>mod pool;

pub use self::pool::LeasedItem;
use self::pool::Pool;
use crate::core::Segment;
use crate::directory::Directory;
use crate::directory::WatchHandle;
use crate::directory::META_LOCK;
use crate::Index;
use crate::Searcher;
use crate::SegmentReader;
use std::convert::TryInto;
use std::sync::Arc;

/// Defines when a new version of the index should be reloaded.
///
/// Regardless of whether you search and index in the same process, tantivy does not necessarily
/// reflects the change that are commited to your index. `ReloadPolicy` precisely helps you define
/// when you want your index to be reloaded.
#[derive(Clone, Copy)]
pub enum ReloadPolicy {
    /// The index is entirely reloaded manually.
    /// All updates of the index should be manual.
    ///
    /// No change is reflected automatically. You are required to call `IndexReader::reload()` manually.
    Manual,
    /// The index is reloaded within milliseconds after a new commit is available.
    /// This is made possible by watching changes in the `meta.json` file.
    OnCommit, // TODO add NEAR_REAL_TIME(target_ms)
}

/// `IndexReader` builder
///
/// It makes it possible to set the following values.
///
/// - `num_searchers` (by default, the number of detected CPU threads):
///
///   When `num_searchers` queries are requested at the same time, the `num_searchers` will block
///   until the one of the searcher in-use gets released.
/// - `reload_policy` (by default `ReloadPolicy::OnCommit`):
///
///   See [`ReloadPolicy`](./enum.ReloadPolicy.html) for more details.
#[derive(Clone)]
pub struct IndexReaderBuilder {
    num_searchers: usize,
    reload_policy: ReloadPolicy,
    index: Index,
}

impl IndexReaderBuilder {
    pub(crate) fn new(index: Index) -> IndexReaderBuilder {
        IndexReaderBuilder {
            num_searchers: num_cpus::get(),
            reload_policy: ReloadPolicy::OnCommit,
            index,
        }
    }

    /// Builds the reader.
    ///
    /// Building the reader is a non-trivial operation that requires
    /// to open different segment readers. It may take hundreds of milliseconds
    /// of time and it may return an error.
    pub fn try_into(self) -> crate::Result<IndexReader> {
        let inner_reader = InnerIndexReader {
            index: self.index,
            num_searchers: self.num_searchers,
            searcher_pool: Pool::new(),
        };
        inner_reader.reload()?;
        let inner_reader_arc = Arc::new(inner_reader);
        let watch_handle_opt: Option<WatchHandle>;
        match self.reload_policy {
            ReloadPolicy::Manual => {
                // No need to set anything...
                watch_handle_opt = None;
            }
            ReloadPolicy::OnCommit => {
                let inner_reader_arc_clone = inner_reader_arc.clone();
                let callback = move || {
                    if let Err(err) = inner_reader_arc_clone.reload() {
                        error!(
                            "Error while loading searcher after commit was detected. {:?}",
                            err
                        );
                    }
                };
                let watch_handle = inner_reader_arc
                    .index
                    .directory()
                    .watch(Box::new(callback))?;
                watch_handle_opt = Some(watch_handle);
            }
        }
        Ok(IndexReader {
            inner: inner_reader_arc,
            watch_handle_opt,
        })
    }

    /// Sets the reload_policy.
    ///
    /// See [`ReloadPolicy`](./enum.ReloadPolicy.html) for more details.
    pub fn reload_policy(mut self, reload_policy: ReloadPolicy) -> IndexReaderBuilder {
        self.reload_policy = reload_policy;
        self
    }

    /// Sets the number of `Searcher` in the searcher pool.
    pub fn num_searchers(mut self, num_searchers: usize) -> IndexReaderBuilder {
        self.num_searchers = num_searchers;
        self
    }
}

impl TryInto<IndexReader> for IndexReaderBuilder {
    type Error = crate::TantivyError;

    fn try_into(self) -> crate::Result<IndexReader> {
        IndexReaderBuilder::try_into(self)
    }
}

struct InnerIndexReader {
    num_searchers: usize,
    searcher_pool: Pool<Searcher>,
    index: Index,
}

impl InnerIndexReader {
    fn reload(&self) -> crate::Result<()> {
        let segment_readers: Vec<SegmentReader> = {
            let _meta_lock = self.index.directory().acquire_lock(&META_LOCK)?;
            let searchable_segments = self.searchable_segments()?;
            searchable_segments
                .iter()
                .map(SegmentReader::open)
                .collect::<crate::Result<_>>()?
        };
        let schema = self.index.schema();
        let searchers = (0..self.num_searchers)
            .map(|_| Searcher::new(schema.clone(), self.index.clone(), segment_readers.clone()))
            .collect();
        self.searcher_pool.publish_new_generation(searchers);
        Ok(())
    }

    /// Returns the list of segments that are searchable
    fn searchable_segments(&self) -> crate::Result<Vec<Segment>> {
        self.index.searchable_segments()
    }

    fn searcher(&self) -> LeasedItem<Searcher> {
        self.searcher_pool.acquire()
    }
}

/// `IndexReader` is your entry point to read and search the index.
///
/// It controls when a new version of the index should be loaded and lends
/// you instances of `Searcher` for the last loaded version.
///
/// `Clone` does not clone the different pool of searcher. `IndexReader`
/// just wraps and `Arc`.
#[derive(Clone)]
pub struct IndexReader {
    inner: Arc<InnerIndexReader>,
    watch_handle_opt: Option<WatchHandle>,
}

impl IndexReader {
    #[cfg(test)]
    pub(crate) fn index(&self) -> Index {
        self.inner.index.clone()
    }

    /// Update searchers so that they reflect the state of the last
    /// `.commit()`.
    ///
    /// If you set up the `OnCommit` `ReloadPolicy` (which is the default)
    /// every commit should be rapidly reflected on your `IndexReader` and you should
    /// not need to call `reload()` at all.
    ///
    /// This automatic reload can take 10s of milliseconds to kick in however, and in unit tests
    /// it can be nice to deterministically force the reload of searchers.
    pub fn reload(&self) -> crate::Result<()> {
        self.inner.reload()
    }

    /// Returns a searcher
    ///
    /// This method should be called every single time a search
    /// query is performed.
    /// The searchers are taken from a pool of `num_searchers` searchers.
    /// If no searcher is available
    /// this may block.
    ///
    /// The same searcher must be used for a given query, as it ensures
    /// the use of a consistent segment set.
    pub fn searcher(&self) -> LeasedItem<Searcher> {
        self.inner.searcher()
    }
}
<|endoftext|>


<commit_before>// Rust Bitcoin Library
// Written in 2014 by
//     Andrew Poelstra <apoelstra@wpsoftware.net>
//
// To the extent possible under law, the author(s) have dedicated all
// copyright and related and neighboring rights to this software to
// the public domain worldwide. This software is distributed without
// any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication
// along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
//

//! # Floating-point decimal type
//!
//! `i64`-based floating-point decimal type designed to hold Bitcoin
//! amounts. For satoshi amounts (8 decimal places) the maximum
//! amounts that can be represented is ~92.25bn, well over the 21m
//! maximum number of bitcoin in existence. Be aware that some
//! altcoins with different granularity may require a wider type.
//!

use serde::{ser, de};
use strason::Json;

/// A fixed-point decimal type
#[derive(Copy, Clone, Debug, Eq, Ord)]
pub struct Decimal {
    mantissa: i64,
    exponent: usize,
}

impl PartialEq<Decimal> for Decimal {
    fn eq(&self, other: &Decimal) -> bool {
        use std::cmp::max;
        let exp = max(self.exponent(), other.exponent());
        self.integer_value(exp) == other.integer_value(exp)
    }
}

impl PartialOrd<Decimal> for Decimal {
    fn partial_cmp(&self, other: &Decimal) -> Option<::std::cmp::Ordering> {
        use std::cmp::max;
        let exp = max(self.exponent(), other.exponent());
        self.integer_value(exp).partial_cmp(&other.integer_value(exp))
    }
}

impl Decimal {
    /// Creates a new Decimal
    pub fn new(mantissa: i64, exponent: usize) -> Decimal {
        Decimal {
            mantissa: mantissa,
            exponent: exponent
        }
    }

    /// Returns the mantissa
    pub fn mantissa(&self) -> i64 { self.mantissa }
    /// Returns the exponent
    pub fn exponent(&self) -> usize { self.exponent }

    /// Get the decimal's value in an integer type, by multiplying
    /// by some power of ten to ensure the returned value is 10 **
    /// `exponent` types the actual value.
    pub fn integer_value(&self, exponent: usize) -> i64 {
        if exponent < self.exponent {
            self.mantissa / 10i64.pow((self.exponent - exponent) as u32)
        } else {
            self.mantissa * 10i64.pow((exponent - self.exponent) as u32)
        }
    }
}

impl ser::Serialize for Decimal {
    // Serialize through strason since it will not lose precision (when serializing
    // to strason itself, the value will be passed through; otherwise it will be
    // encoded as a string)
    fn serialize<S: ser::Serializer>(&self, s: &mut S) -> Result<(), S::Error> {
        let ten = 10i64.pow(self.exponent as u32);
        let int_part = self.mantissa / ten;
        let dec_part = (self.mantissa % ten).abs();
        println!("{}", format!("{}.{:02$}", int_part, dec_part, self.exponent));
        let json = Json::from_str(&format!("{}.{:02$}", int_part, dec_part, self.exponent)).unwrap();
        ser::Serialize::serialize(&json, s)
    }
}

impl de::Deserialize for Decimal {
    // Deserialize through strason for the same reason as in `Serialize`
    fn deserialize<D: de::Deserializer>(d: &mut D) -> Result<Decimal, D::Error> {
        let json: Json = try!(de::Deserialize::deserialize(d));
        match json.num() {
            Some(s) => {
                 // We know this will be a well-formed Json number, so we can
                 // be pretty lax about parsing
                 let mut negative = false;
                 let mut past_dec = false;
                 let mut exponent = 0;
                 let mut mantissa = 0i64;

                 for b in s.as_bytes() {
                     match *b {
                         b'-' => { negative = true; }
                         b'0'...b'9' => {
                             mantissa = 10 * mantissa + (b - b'0') as i64;
                             if past_dec { exponent += 1; }
                         }
                         b'.' => { past_dec = true; }
                         _ => { /* whitespace or something, just ignore it */ }
                     }
                 }
                 if negative { mantissa *= -1; }
                 Ok(Decimal {
                     mantissa: mantissa,
                     exponent: exponent,
                 })
            }
            None => Err(de::Error::syntax("expected decimal, got non-numeric"))
        }
    }
}

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

    #[test]
    fn integer_value() {
        let d = Decimal::new(12345678, 4);
        assert_eq!(d.mantissa(), 12345678);
        assert_eq!(d.exponent(), 4);

        assert_eq!(d.integer_value(0), 1234);
        assert_eq!(d.integer_value(1), 12345);
        assert_eq!(d.integer_value(2), 123456);
        assert_eq!(d.integer_value(3), 1234567);
        assert_eq!(d.integer_value(4), 12345678);
        assert_eq!(d.integer_value(5), 123456780);
        assert_eq!(d.integer_value(6), 1234567800);
        assert_eq!(d.integer_value(7), 12345678000);
        assert_eq!(d.integer_value(8), 123456780000);
    }

    macro_rules! deserialize_round_trip(
        ($dec:expr, $s:expr) => ({
            let d = $dec;
            let encoded = Json::from_serialize(&d).unwrap();
            assert_eq!(encoded, Json::from_reader(&$s[..]).unwrap());
            assert_eq!(encoded.to_bytes(), &$s[..]);

            let decoded: Decimal = encoded.into_deserialize().unwrap();
            assert_eq!(decoded, d);
        })
    );

    #[test]
    fn deserialize() {
        deserialize_round_trip!(Decimal::new(0, 0), b"0.0");

        deserialize_round_trip!(Decimal::new(123456789001, 8), b"1234.56789001");
        deserialize_round_trip!(Decimal::new(-123456789001, 8), b"-1234.56789001");
        deserialize_round_trip!(Decimal::new(123456789001, 1), b"12345678900.1");
        deserialize_round_trip!(Decimal::new(-123456789001, 1), b"-12345678900.1");
        deserialize_round_trip!(Decimal::new(123456789001, 0), b"123456789001.0");
        deserialize_round_trip!(Decimal::new(-123456789001, 0), b"-123456789001.0");

        deserialize_round_trip!(Decimal::new(123400000001, 8), b"1234.00000001");
        deserialize_round_trip!(Decimal::new(-123400000001, 8), b"-1234.00000001");
    }

    #[test]
    fn equality() {
        let d1 = Decimal::new(1234, 8);
        let d2 = Decimal::new(12340, 9);
        let d3 = Decimal::new(12340, 8);
        assert_eq!(d1, d1);
        assert_eq!(d1, d2);
        assert!(d1 != d3);
        assert!(d2 != d3);

        assert!(d1 <= d1);
        assert!(d2 <= d2);
        assert!(d3 <= d3);
        assert!(d1 <= d2);
        assert!(d1 <= d3);
        assert!(d3 > d1);
        assert!(d3 > d2);
    }

    #[test]
    fn json_parse() {
        let json = Json::from_str("0.00980000").unwrap();
        assert_eq!(json.to_bytes(), b"0.00980000");
        let dec: Decimal = json.into_deserialize().unwrap();
        assert_eq!(dec, Decimal::new(980000, 8));

        let json = Json::from_str("0.00980").unwrap();
        assert_eq!(json.to_bytes(), b"0.00980");
        let dec: Decimal = json.into_deserialize().unwrap();
        assert_eq!(dec, Decimal::new(98000, 7));
    }
}

<commit_msg>Add addition and subtraction impls to Decimal<commit_after>// Rust Bitcoin Library
// Written in 2014 by
//     Andrew Poelstra <apoelstra@wpsoftware.net>
//
// To the extent possible under law, the author(s) have dedicated all
// copyright and related and neighboring rights to this software to
// the public domain worldwide. This software is distributed without
// any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication
// along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
//

//! # Floating-point decimal type
//!
//! `i64`-based floating-point decimal type designed to hold Bitcoin
//! amounts. For satoshi amounts (8 decimal places) the maximum
//! amounts that can be represented is ~92.25bn, well over the 21m
//! maximum number of bitcoin in existence. Be aware that some
//! altcoins with different granularity may require a wider type.
//!

use std::ops;

use serde::{ser, de};
use strason::Json;

/// A fixed-point decimal type
#[derive(Copy, Clone, Debug, Eq, Ord)]
pub struct Decimal {
    mantissa: i64,
    exponent: usize,
}

impl PartialEq<Decimal> for Decimal {
    fn eq(&self, other: &Decimal) -> bool {
        use std::cmp::max;
        let exp = max(self.exponent(), other.exponent());
        self.integer_value(exp) == other.integer_value(exp)
    }
}

impl PartialOrd<Decimal> for Decimal {
    fn partial_cmp(&self, other: &Decimal) -> Option<::std::cmp::Ordering> {
        use std::cmp::max;
        let exp = max(self.exponent(), other.exponent());
        self.integer_value(exp).partial_cmp(&other.integer_value(exp))
    }
}

impl ops::Add for Decimal {
    type Output = Decimal;

    #[inline]
    fn add(self, other: Decimal) -> Decimal {
        if self.exponent > other.exponent {
            Decimal {
                mantissa: other.mantissa * 10i64.pow((self.exponent - other.exponent) as u32) + self.mantissa,
                exponent: self.exponent
            }
        } else {
            Decimal {
                mantissa: self.mantissa * 10i64.pow((other.exponent - self.exponent) as u32) + other.mantissa,
                exponent: other.exponent
            }
        }
    }
}

impl ops::Neg for Decimal {
    type Output = Decimal;
    #[inline]
    fn neg(self) -> Decimal { Decimal { mantissa: -self.mantissa, exponent: self.exponent } }
}

impl ops::Sub for Decimal {
    type Output = Decimal;
    #[inline]
    fn sub(self, other: Decimal) -> Decimal { self + (-other) }
}

impl Decimal {
    /// Creates a new Decimal
    pub fn new(mantissa: i64, exponent: usize) -> Decimal {
        Decimal {
            mantissa: mantissa,
            exponent: exponent
        }
    }

    /// Returns the mantissa
    pub fn mantissa(&self) -> i64 { self.mantissa }
    /// Returns the exponent
    pub fn exponent(&self) -> usize { self.exponent }

    /// Get the decimal's value in an integer type, by multiplying
    /// by some power of ten to ensure the returned value is 10 **
    /// `exponent` types the actual value.
    pub fn integer_value(&self, exponent: usize) -> i64 {
        if exponent < self.exponent {
            self.mantissa / 10i64.pow((self.exponent - exponent) as u32)
        } else {
            self.mantissa * 10i64.pow((exponent - self.exponent) as u32)
        }
    }
}

impl ser::Serialize for Decimal {
    // Serialize through strason since it will not lose precision (when serializing
    // to strason itself, the value will be passed through; otherwise it will be
    // encoded as a string)
    fn serialize<S: ser::Serializer>(&self, s: &mut S) -> Result<(), S::Error> {
        let ten = 10i64.pow(self.exponent as u32);
        let int_part = self.mantissa / ten;
        let dec_part = (self.mantissa % ten).abs();
        println!("{}", format!("{}.{:02$}", int_part, dec_part, self.exponent));
        let json = Json::from_str(&format!("{}.{:02$}", int_part, dec_part, self.exponent)).unwrap();
        ser::Serialize::serialize(&json, s)
    }
}

impl de::Deserialize for Decimal {
    // Deserialize through strason for the same reason as in `Serialize`
    fn deserialize<D: de::Deserializer>(d: &mut D) -> Result<Decimal, D::Error> {
        let json: Json = try!(de::Deserialize::deserialize(d));
        match json.num() {
            Some(s) => {
                 // We know this will be a well-formed Json number, so we can
                 // be pretty lax about parsing
                 let mut negative = false;
                 let mut past_dec = false;
                 let mut exponent = 0;
                 let mut mantissa = 0i64;

                 for b in s.as_bytes() {
                     match *b {
                         b'-' => { negative = true; }
                         b'0'...b'9' => {
                             mantissa = 10 * mantissa + (b - b'0') as i64;
                             if past_dec { exponent += 1; }
                         }
                         b'.' => { past_dec = true; }
                         _ => { /* whitespace or something, just ignore it */ }
                     }
                 }
                 if negative { mantissa *= -1; }
                 Ok(Decimal {
                     mantissa: mantissa,
                     exponent: exponent,
                 })
            }
            None => Err(de::Error::syntax("expected decimal, got non-numeric"))
        }
    }
}

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

    #[test]
    fn integer_value() {
        let d = Decimal::new(12345678, 4);
        assert_eq!(d.mantissa(), 12345678);
        assert_eq!(d.exponent(), 4);

        assert_eq!(d.integer_value(0), 1234);
        assert_eq!(d.integer_value(1), 12345);
        assert_eq!(d.integer_value(2), 123456);
        assert_eq!(d.integer_value(3), 1234567);
        assert_eq!(d.integer_value(4), 12345678);
        assert_eq!(d.integer_value(5), 123456780);
        assert_eq!(d.integer_value(6), 1234567800);
        assert_eq!(d.integer_value(7), 12345678000);
        assert_eq!(d.integer_value(8), 123456780000);
    }

    macro_rules! deserialize_round_trip(
        ($dec:expr, $s:expr) => ({
            let d = $dec;
            let encoded = Json::from_serialize(&d).unwrap();
            assert_eq!(encoded, Json::from_reader(&$s[..]).unwrap());
            assert_eq!(encoded.to_bytes(), &$s[..]);

            let decoded: Decimal = encoded.into_deserialize().unwrap();
            assert_eq!(decoded, d);
        })
    );

    #[test]
    fn deserialize() {
        deserialize_round_trip!(Decimal::new(0, 0), b"0.0");

        deserialize_round_trip!(Decimal::new(123456789001, 8), b"1234.56789001");
        deserialize_round_trip!(Decimal::new(-123456789001, 8), b"-1234.56789001");
        deserialize_round_trip!(Decimal::new(123456789001, 1), b"12345678900.1");
        deserialize_round_trip!(Decimal::new(-123456789001, 1), b"-12345678900.1");
        deserialize_round_trip!(Decimal::new(123456789001, 0), b"123456789001.0");
        deserialize_round_trip!(Decimal::new(-123456789001, 0), b"-123456789001.0");

        deserialize_round_trip!(Decimal::new(123400000001, 8), b"1234.00000001");
        deserialize_round_trip!(Decimal::new(-123400000001, 8), b"-1234.00000001");
    }

    #[test]
    fn equality() {
        let d1 = Decimal::new(1234, 8);
        let d2 = Decimal::new(12340, 9);
        let d3 = Decimal::new(12340, 8);
        assert_eq!(d1, d1);
        assert_eq!(d1, d2);
        assert!(d1 != d3);
        assert!(d2 != d3);

        assert!(d1 <= d1);
        assert!(d2 <= d2);
        assert!(d3 <= d3);
        assert!(d1 <= d2);
        assert!(d1 <= d3);
        assert!(d3 > d1);
        assert!(d3 > d2);
    }

    #[test]
    fn arithmetic() {
        let d1 = Decimal::new(5, 1);   //  0.5
        let d2 = Decimal::new(-2, 2);  // -0.02
        let d3 = Decimal::new(3, 0);   //  3.0

        assert_eq!(d1 + d2, Decimal::new(48, 2));
        assert_eq!(d1 - d2, Decimal::new(52, 2));
        assert_eq!(d1 + d3, Decimal::new(35, 1));
        assert_eq!(d1 - d3, Decimal::new(-25, 1));
        assert_eq!(d2 + d3, Decimal::new(298, 2));
        assert_eq!(d2 - d3, Decimal::new(-302, 2));
    }

    #[test]
    fn json_parse() {
        let json = Json::from_str("0.00980000").unwrap();
        assert_eq!(json.to_bytes(), b"0.00980000");
        let dec: Decimal = json.into_deserialize().unwrap();
        assert_eq!(dec, Decimal::new(980000, 8));

        let json = Json::from_str("0.00980").unwrap();
        assert_eq!(json.to_bytes(), b"0.00980");
        let dec: Decimal = json.into_deserialize().unwrap();
        assert_eq!(dec, Decimal::new(98000, 7));
    }
}

<|endoftext|>


<commit_before>/*
	Autor: Gustavo Michels de Camargo
	Projeto: Algoritmo estrural de um Grafo
*/

use std::{collections::HashMap};

// Matriz de Vector usada ara construir o Grafo.
type MatrizGrafo = Vec<Vec<isize>>;

// O dicionario serve para podermos dar entrada a qualquer String e ter como abstrair suas posições dentro
// da matriz numerica, isso serve apenas para fins de uso, não requerer transcrever um Nodo com X para valor numerico.
#[derive(PartialEq, Eq, Clone, Debug)]
struct Grafo {
	matriz: MatrizGrafo,
	dicionario: HashMap<String, usize>,
	bicondicional: bool
}

trait Projeto {
	// Geral
	fn new(tamanho: usize, tipo: &str) -> Grafo;

	// Funções envolvendo o dicionario - Usuario
	fn usr_pegar_indice(&self, chave: String) -> usize;
	fn usr_pegar_chave(&self, indice: usize) -> String;

	// Usuario
	fn usr_adicionar_conexao(&mut self, a: String, b: String, valor: isize);
	fn usr_remover_conexao(&mut self, a: String, b: String);
	fn usr_numero_conexoes(&self, no: String) -> usize;
	fn usr_verificar_se_existe_conexao(&self, a: String, b: String) -> bool;
	fn usr_conexoes(&self, a: String) -> Vec<String>;

	// Maquina / uso para os Algoritmos
	fn adicionar_conexao(&mut self, a: usize, b: usize, valor: isize);
	fn remover_conexao(&mut self, a: usize, b: usize);
	fn numero_conexoes(&self, no: usize) -> usize;
	fn verificar_se_existe_conexao(&self, a: usize, b: usize) -> bool;
	fn conexoes(&self, a: usize) -> Vec<usize>;
}

// Este é a implementação da "Classe" de um grafo.
impl Projeto for Grafo {
	// Tamanho: Numero Maximo de Vertices que a matriz pode usar de 0 até tamanho.
	// Em notação matematica relativa a limites: [0, tamanho).
	// Toda função que começa com 'usr_'(usr = usuario) é a versão da função que deve ser usada para interagir diretamente com o usuario.
	// As funções de mesmo nome mas sem 'usr_' deve ser usada apenas dentro dos algoritmos, como o Dijkstra para menor caminho entre dois nos.
	// Fiz assim para otimizar processamento e descartar necessidade de acessar e
	// consultar o dicionario o tempo todo quando se apenas tem como Objetivo encontrar um menor caminho com Dijkstra por exemplo.

	// Apenas essa função foge a regra por ser universal
	fn new(tamanho: usize, tipo: &str) -> Grafo {
		Grafo {
			matriz: vec![vec![-1; tamanho]; tamanho],
			dicionario: HashMap::new(),
			bicondicional: match tipo  {
				"->" => false, // Condicional
				"<->" | _ => true // Bicondicional
			}
		}
	}

	// ---- Funções para uso direto do usuario ----

	// Retorna o indice da matriz relacionada a chave
	fn usr_pegar_indice(&self, chave: String) -> usize {
		if self.dicionario.contains_key(&chave) {
			return (&self.dicionario.get(&chave)).unwrap().clone();
		}

		return 0;
	}

	// Retorna a chave do dicionario relacionada ao valor do indice da matriz do grafo
	fn usr_pegar_chave(&self, indice: usize) -> String {
		for (key, value) in self.dicionario.iter() {
			if *value == indice {
				return (*key).clone();
			}
		}

		return "".to_string();
	}

	// Conecta Dois vertices
	fn usr_adicionar_conexao(&mut self, a: String, b: String, valor: isize) {
		if !self.dicionario.contains_key(&a){
			let num: usize = self.dicionario.len();
			self.dicionario.insert(a.to_owned(), num);
		}

		if !self.dicionario.contains_key(&b){
			let num: usize = self.dicionario.len();
			self.dicionario.insert(b.to_owned(), num);
		}

		let (valor_a, valor_b): (usize, usize) = (self.usr_pegar_indice(a), self.usr_pegar_indice(b));

		self.matriz[valor_a][valor_b] = valor;

		if self.bicondicional {
			self.matriz[valor_b][valor_a] = valor;
		}

	}

	fn usr_remover_conexao(&mut self, a: String, b: String) {
		let (valor_a, valor_b): (usize, usize) = (self.usr_pegar_indice(a), self.usr_pegar_indice(b));

		self.matriz[valor_a][valor_b]  = -1;
		self.matriz[valor_b][valor_a]  = -1;
	}

	// Retorba o numero de vertices na qual ele se conecta
	fn usr_numero_conexoes(&self, no: String) -> usize {
		self.matriz[self.usr_pegar_indice(no)].iter()
						.filter(|x| **x >= 0)
						.collect::<Vec<&isize>>()
						.len() as usize | 0
	}

	// Verifica se dois nos estão conectados
	fn usr_verificar_se_existe_conexao(&self, a: String, b: String) -> bool {
		self.matriz[self.usr_pegar_indice(a)][self.usr_pegar_indice(b)]  >= 0
	}

	fn usr_conexoes(&self, a: String) -> Vec<String> {
		let mut result: Vec<String> = Vec::new();
		let a_value: usize = self.usr_pegar_indice(a);

		for i in 0..self.matriz[a_value].len() {
			if a_value != i && self.matriz[a_value][i] > -1 {
				result.push(self.usr_pegar_chave(i));
			}
		}

		return result;
	}

	// ---- Funções para uso direto dos algoritmos (tem melhor perfomance) ----

	// Retorna um array dos indice de todos os nos na qual o no 'a' se conecta
	// Esera usar esta função apenas para usos proprios dentro do Grafo, como em algoritmos tipo dijkstra
	// Conecta Dois vertices
	fn adicionar_conexao(&mut self, a: usize, b: usize, valor: isize) {
		self.matriz[a][b] = valor;

		if self.bicondicional {
			self.matriz[b][a] = valor;
		}
	}

	fn remover_conexao(&mut self, a: usize, b: usize) {
		self.matriz[a][b]  = -1;
		self.matriz[b][a]  = -1;
	}

	// Retorba o numero de vertices na qual ele se conecta
	fn numero_conexoes(&self, no: usize) -> usize {
		self.matriz[no].iter()
						.filter(|x| **x >= 0)
						.collect::<Vec<&isize>>()
						.len() as usize | 0
	}

	fn verificar_se_existe_conexao(&self, a: usize, b: usize) -> bool {
		self.matriz[a][b]  >= 0
	}

	fn conexoes(&self, a: usize) -> Vec<usize> {
		let mut result: Vec<usize> = Vec::new();

		for i in 0..self.matriz[a].len() {
			if a != i && self.matriz[a][i] > -1 {
				result.push(i);
			}
		}
		return result;
	}

	// ---- Funções dos algoritmos ----

}

// Main
fn main() {
	// Grafo com no maximo mil vertices
	 // "->" =  Grafo condicional, "<->" = Grafo Bicondicional
	let mut grafo: Grafo = Grafo::new(1000, "->");

	grafo.usr_adicionar_conexao(0.to_string(), 1.to_string(), 1);
	grafo.usr_adicionar_conexao(1.to_string(), 2.to_string(), 1);
	grafo.usr_adicionar_conexao(2.to_string(), 3.to_string(), 1);
	grafo.usr_adicionar_conexao(3.to_string(), 0.to_string(), 1);

	println!("{:?}", grafo.conexoes(2));
}

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

	#[test]
	fn usr_numero_conexoes() {
		let mut grafo: Grafo = Grafo::new(1000, "->");

		for i in 1..1000 {
			grafo.usr_adicionar_conexao(0.to_string(), i.to_string(), 1);
		}

		assert_eq!(grafo.usr_numero_conexoes(0.to_string()), 999);
		assert_eq!(grafo.usr_numero_conexoes(0.to_string()), grafo.numero_conexoes(0));
	}

	#[test]
	fn numero_conexoes() {
		let mut grafo: Grafo = Grafo::new(1000, "<->");

		for i in 1..1000 {
			grafo.adicionar_conexao(0, i, 1);
		}

		assert_eq!(grafo.numero_conexoes(0), 999);
		assert_eq!(grafo.numero_conexoes(0), grafo.usr_numero_conexoes(0.to_string()));
	}
}
<commit_msg>Revisão dos comentarios 3<commit_after>/*
	Autor: Gustavo Michels de Camargo
	Projeto: Algoritmo estrural de um Grafo
*/

use std::{collections::HashMap};

// Matriz de Vector usada ara construir o Grafo.
type MatrizGrafo = Vec<Vec<isize>>;

// O dicionario serve para podermos dar entrada a qualquer String e ter como abstrair suas posições dentro
// da matriz numerica, isso serve apenas para fins de uso, não requerer transcrever um Nodo com X para valor numerico.
#[derive(PartialEq, Eq, Clone, Debug)]
struct Grafo {
	matriz: MatrizGrafo,
	dicionario: HashMap<String, usize>,
	bicondicional: bool
}

trait Projeto {
	// Geral
	fn new(tamanho: usize, tipo: &str) -> Grafo;

	// Funções envolvendo o dicionario - Usuario
	fn usr_pegar_indice(&self, chave: String) -> usize;
	fn usr_pegar_chave(&self, indice: usize) -> String;

	// Usuario
	fn usr_adicionar_conexao(&mut self, a: String, b: String, valor: isize);
	fn usr_remover_conexao(&mut self, a: String, b: String);
	fn usr_numero_conexoes(&self, no: String) -> usize;
	fn usr_verificar_se_existe_conexao(&self, a: String, b: String) -> bool;
	fn usr_conexoes(&self, a: String) -> Vec<String>;

	// Maquina / uso para os Algoritmos
	fn adicionar_conexao(&mut self, a: usize, b: usize, valor: isize);
	fn remover_conexao(&mut self, a: usize, b: usize);
	fn numero_conexoes(&self, no: usize) -> usize;
	fn verificar_se_existe_conexao(&self, a: usize, b: usize) -> bool;
	fn conexoes(&self, a: usize) -> Vec<usize>;
}

// Este é a implementação da "Classe" de um grafo.
impl Projeto for Grafo {
	// Tamanho: Numero Maximo de Vertices que a matriz pode usar de 0 até tamanho.
	// Em notação matematica relativa a limites: [0, tamanho).
	// Toda função que começa com 'usr_'(usr = usuario) é a versão da função que deve ser usada para interagir diretamente com o usuario.
	// As funções de mesmo nome mas sem 'usr_' deve ser usada apenas dentro dos algoritmos, como o Dijkstra para menor caminho entre dois nos.
	// Fiz assim para otimizar processamento e descartar necessidade de acessar e
	// consultar o dicionario o tempo todo quando se apenas tem como Objetivo encontrar um menor caminho com Dijkstra por exemplo.

	// Apenas essa função foge a regra por ser universal
	fn new(tamanho: usize, tipo: &str) -> Grafo {
		Grafo {
			matriz: vec![vec![-1; tamanho]; tamanho],
			dicionario: HashMap::new(),
			bicondicional: match tipo  {
				"->" => false, // Condicional
				"<->" | _ => true // Bicondicional
			}
		}
	}

	// ---- Funções para uso direto do usuario ----

	// Retorna o indice da matriz relacionada a chave
	fn usr_pegar_indice(&self, chave: String) -> usize {
		if self.dicionario.contains_key(&chave) {
			return (&self.dicionario.get(&chave)).unwrap().clone();
		}

		return 0;
	}

	// Retorna a chave do dicionario relacionada ao valor do indice da matriz do grafo
	fn usr_pegar_chave(&self, indice: usize) -> String {
		for (key, value) in self.dicionario.iter() {
			if *value == indice {
				return (*key).clone();
			}
		}

		return "".to_string();
	}

	// Conecta Dois vertices
	fn usr_adicionar_conexao(&mut self, a: String, b: String, valor: isize) {
		if !self.dicionario.contains_key(&a){
			let num: usize = self.dicionario.len();
			self.dicionario.insert(a.to_owned(), num);
		}

		if !self.dicionario.contains_key(&b){
			let num: usize = self.dicionario.len();
			self.dicionario.insert(b.to_owned(), num);
		}

		let (valor_a, valor_b): (usize, usize) = (self.usr_pegar_indice(a), self.usr_pegar_indice(b));

		self.matriz[valor_a][valor_b] = valor;

		if self.bicondicional {
			self.matriz[valor_b][valor_a] = valor;
		}

	}

	fn usr_remover_conexao(&mut self, a: String, b: String) {
		let (valor_a, valor_b): (usize, usize) = (self.usr_pegar_indice(a), self.usr_pegar_indice(b));

		self.matriz[valor_a][valor_b]  = -1;
		self.matriz[valor_b][valor_a]  = -1;
	}

	// Retorba o numero de vertices na qual ele se conecta
	fn usr_numero_conexoes(&self, no: String) -> usize {
		self.matriz[self.usr_pegar_indice(no)].iter()
						.filter(|x| **x >= 0)
						.collect::<Vec<&isize>>()
						.len() as usize | 0
	}

	// Verifica se dois nos estão conectados
	fn usr_verificar_se_existe_conexao(&self, a: String, b: String) -> bool {
		self.matriz[self.usr_pegar_indice(a)][self.usr_pegar_indice(b)]  >= 0
	}

	fn usr_conexoes(&self, a: String) -> Vec<String> {
		let mut result: Vec<String> = Vec::new();
		let a_value: usize = self.usr_pegar_indice(a);

		for i in 0..self.matriz[a_value].len() {
			if a_value != i && self.matriz[a_value][i] > -1 {
				result.push(self.usr_pegar_chave(i));
			}
		}

		return result;
	}

	// ---- Funções para uso direto dos algoritmos (tem melhor perfomance) ----

	// Retorna um array dos indice de todos os nos na qual o no 'a' se conecta
	// Espera se usar esta função apenas para usos proprios dentro do Grafo, como em algoritmos tipo dijkstra
	// Conecta Dois vertices
	fn adicionar_conexao(&mut self, a: usize, b: usize, valor: isize) {
		self.matriz[a][b] = valor;

		if self.bicondicional {
			self.matriz[b][a] = valor;
		}
	}

	fn remover_conexao(&mut self, a: usize, b: usize) {
		self.matriz[a][b]  = -1;
		self.matriz[b][a]  = -1;
	}

	// Retorba o numero de vertices na qual ele se conecta
	fn numero_conexoes(&self, no: usize) -> usize {
		self.matriz[no].iter()
						.filter(|x| **x >= 0)
						.collect::<Vec<&isize>>()
						.len() as usize | 0
	}

	fn verificar_se_existe_conexao(&self, a: usize, b: usize) -> bool {
		self.matriz[a][b]  >= 0
	}

	fn conexoes(&self, a: usize) -> Vec<usize> {
		let mut result: Vec<usize> = Vec::new();

		for i in 0..self.matriz[a].len() {
			if a != i && self.matriz[a][i] > -1 {
				result.push(i);
			}
		}
		return result;
	}

}

// Main
fn main() {
	// Grafo com no maximo mil vertices
	 // "->" =  Grafo condicional, "<->" = Grafo Bicondicional
	let mut grafo: Grafo = Grafo::new(1000, "->");

	grafo.usr_adicionar_conexao(0.to_string(), 1.to_string(), 1);
	grafo.usr_adicionar_conexao(1.to_string(), 2.to_string(), 1);
	grafo.usr_adicionar_conexao(2.to_string(), 3.to_string(), 1);
	grafo.usr_adicionar_conexao(3.to_string(), 0.to_string(), 1);

	println!("{:?}", grafo.conexoes(2));
}

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

	#[test]
	fn usr_numero_conexoes() {
		let mut grafo: Grafo = Grafo::new(1000, "->");

		for i in 1..1000 {
			grafo.usr_adicionar_conexao(0.to_string(), i.to_string(), 1);
		}

		assert_eq!(grafo.usr_numero_conexoes(0.to_string()), 999);
		assert_eq!(grafo.usr_numero_conexoes(0.to_string()), grafo.numero_conexoes(0));
	}

	#[test]
	fn numero_conexoes() {
		let mut grafo: Grafo = Grafo::new(1000, "<->");

		for i in 1..1000 {
			grafo.adicionar_conexao(0, i, 1);
		}

		assert_eq!(grafo.numero_conexoes(0), 999);
		assert_eq!(grafo.numero_conexoes(0), grafo.usr_numero_conexoes(0.to_string()));
	}
}
<|endoftext|>