<commit_before>use std::cmp::Ordering;
use std::collections::{HashMap, HashSet};
use std::ops::Range;
use std::rc::Rc;

use core::{Dependency, PackageId, PackageIdSpec, Registry, Summary};
use core::interning::InternedString;
use util::{CargoError, CargoResult};

pub struct RegistryQueryer<'a> {
    pub registry: &'a mut (Registry + 'a),
    replacements: &'a [(PackageIdSpec, Dependency)],
    try_to_use: &'a HashSet<&'a PackageId>,
    // TODO: with nll the Rc can be removed
    cache: HashMap<Dependency, Rc<Vec<Candidate>>>,
    // If set the list of dependency candidates will be sorted by minimal
    // versions first. That allows `cargo update -Z minimal-versions` which will
    // specify minimum dependency versions to be used.
    minimal_versions: bool,
}

impl<'a> RegistryQueryer<'a> {
    pub fn new(
        registry: &'a mut Registry,
        replacements: &'a [(PackageIdSpec, Dependency)],
        try_to_use: &'a HashSet<&'a PackageId>,
        minimal_versions: bool,
    ) -> Self {
        RegistryQueryer {
            registry,
            replacements,
            cache: HashMap::new(),
            try_to_use,
            minimal_versions,
        }
    }

    /// Queries the `registry` to return a list of candidates for `dep`.
    ///
    /// This method is the location where overrides are taken into account. If
    /// any candidates are returned which match an override then the override is
    /// applied by performing a second query for what the override should
    /// return.
    pub fn query(&mut self, dep: &Dependency) -> CargoResult<Rc<Vec<Candidate>>> {
        if let Some(out) = self.cache.get(dep).cloned() {
            return Ok(out);
        }

        let mut ret = Vec::new();
        self.registry.query(dep, &mut |s| {
            ret.push(Candidate {
                summary: s,
                replace: None,
            });
        })?;
        for candidate in ret.iter_mut() {
            let summary = &candidate.summary;

            let mut potential_matches = self.replacements
                .iter()
                .filter(|&&(ref spec, _)| spec.matches(summary.package_id()));

            let &(ref spec, ref dep) = match potential_matches.next() {
                None => continue,
                Some(replacement) => replacement,
            };
            debug!("found an override for {} {}", dep.name(), dep.version_req());

            let mut summaries = self.registry.query_vec(dep)?.into_iter();
            let s = summaries.next().ok_or_else(|| {
                format_err!(
                    "no matching package for override `{}` found\n\
                     location searched: {}\n\
                     version required: {}",
                    spec,
                    dep.source_id(),
                    dep.version_req()
                )
            })?;
            let summaries = summaries.collect::<Vec<_>>();
            if !summaries.is_empty() {
                let bullets = summaries
                    .iter()
                    .map(|s| format!("  * {}", s.package_id()))
                    .collect::<Vec<_>>();
                bail!(
                    "the replacement specification `{}` matched \
                     multiple packages:\n  * {}\n{}",
                    spec,
                    s.package_id(),
                    bullets.join("\n")
                );
            }

            // The dependency should be hard-coded to have the same name and an
            // exact version requirement, so both of these assertions should
            // never fail.
            assert_eq!(s.version(), summary.version());
            assert_eq!(s.name(), summary.name());

            let replace = if s.source_id() == summary.source_id() {
                debug!("Preventing\n{:?}\nfrom replacing\n{:?}", summary, s);
                None
            } else {
                Some(s)
            };
            let matched_spec = spec.clone();

            // Make sure no duplicates
            if let Some(&(ref spec, _)) = potential_matches.next() {
                bail!(
                    "overlapping replacement specifications found:\n\n  \
                     * {}\n  * {}\n\nboth specifications match: {}",
                    matched_spec,
                    spec,
                    summary.package_id()
                );
            }

            for dep in summary.dependencies() {
                debug!("\t{} => {}", dep.name(), dep.version_req());
            }

            candidate.replace = replace;
        }

        // When we attempt versions for a package we'll want to do so in a
        // sorted fashion to pick the "best candidates" first. Currently we try
        // prioritized summaries (those in `try_to_use`) and failing that we
        // list everything from the maximum version to the lowest version.
        ret.sort_unstable_by(|a, b| {
            let a_in_previous = self.try_to_use.contains(a.summary.package_id());
            let b_in_previous = self.try_to_use.contains(b.summary.package_id());
            let previous_cmp = a_in_previous.cmp(&b_in_previous).reverse();
            match previous_cmp {
                Ordering::Equal => {
                    let cmp = a.summary.version().cmp(b.summary.version());
                    if self.minimal_versions {
                        // Lower version ordered first.
                        cmp
                    } else {
                        // Higher version ordered first.
                        cmp.reverse()
                    }
                }
                _ => previous_cmp,
            }
        });

        let out = Rc::new(ret);

        self.cache.insert(dep.clone(), out.clone());

        Ok(out)
    }
}

#[derive(Clone, Copy)]
pub enum Method<'a> {
    Everything, // equivalent to Required { dev_deps: true, all_features: true, .. }
    Required {
        dev_deps: bool,
        features: &'a [InternedString],
        all_features: bool,
        uses_default_features: bool,
    },
}

impl<'r> Method<'r> {
    pub fn split_features(features: &[String]) -> Vec<InternedString> {
        features
            .iter()
            .flat_map(|s| s.split_whitespace())
            .flat_map(|s| s.split(','))
            .filter(|s| !s.is_empty())
            .map(|s| InternedString::new(s))
            .collect::<Vec<InternedString>>()
    }
}

#[derive(Clone)]
pub struct Candidate {
    pub summary: Summary,
    pub replace: Option<Summary>,
}

#[derive(Clone)]
pub struct DepsFrame {
    pub parent: Summary,
    pub just_for_error_messages: bool,
    pub remaining_siblings: RcVecIter<DepInfo>,
}

impl DepsFrame {
    /// Returns the least number of candidates that any of this frame's siblings
    /// has.
    ///
    /// The `remaining_siblings` array is already sorted with the smallest
    /// number of candidates at the front, so we just return the number of
    /// candidates in that entry.
    fn min_candidates(&self) -> usize {
        self.remaining_siblings
            .clone()
            .next()
            .map(|(_, (_, candidates, _))| candidates.len())
            .unwrap_or(0)
    }

    pub fn flatten<'s>(&'s self) -> impl Iterator<Item=(&PackageId, Dependency)> + 's {
        self.remaining_siblings
            .clone()
            .map(move |(_, (d, _, _))| (self.parent.package_id(), d))
    }
}

impl PartialEq for DepsFrame {
    fn eq(&self, other: &DepsFrame) -> bool {
        self.just_for_error_messages == other.just_for_error_messages
            && self.min_candidates() == other.min_candidates()
    }
}

impl Eq for DepsFrame {}

impl PartialOrd for DepsFrame {
    fn partial_cmp(&self, other: &DepsFrame) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl Ord for DepsFrame {
    fn cmp(&self, other: &DepsFrame) -> Ordering {
        self.just_for_error_messages
            .cmp(&other.just_for_error_messages)
            .then_with(||
            // the frame with the sibling that has the least number of candidates
            // needs to get bubbled up to the top of the heap we use below, so
            // reverse comparison here.
            self.min_candidates().cmp(&other.min_candidates()).reverse())
    }
}

// Information about the dependencies for a crate, a tuple of:
//
// (dependency info, candidates, features activated)
pub type DepInfo = (Dependency, Rc<Vec<Candidate>>, Rc<Vec<InternedString>>);

pub type ActivateResult<T> = Result<T, ActivateError>;

pub enum ActivateError {
    Fatal(CargoError),
    Conflict(PackageId, ConflictReason),
}

impl From<::failure::Error> for ActivateError {
    fn from(t: ::failure::Error) -> Self {
        ActivateError::Fatal(t)
    }
}

impl From<(PackageId, ConflictReason)> for ActivateError {
    fn from(t: (PackageId, ConflictReason)) -> Self {
        ActivateError::Conflict(t.0, t.1)
    }
}

/// All possible reasons that a package might fail to activate.
///
/// We maintain a list of conflicts for error reporting as well as backtracking
/// purposes. Each reason here is why candidates may be rejected or why we may
/// fail to resolve a dependency.
#[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq)]
pub enum ConflictReason {
    /// There was a semver conflict, for example we tried to activate a package
    /// 1.0.2 but 1.1.0 was already activated (aka a compatible semver version
    /// is already activated)
    Semver,

    /// The `links` key is being violated. For example one crate in the
    /// dependency graph has `links = "foo"` but this crate also had that, and
    /// we're only allowed one per dependency graph.
    Links(String),

    /// A dependency listed features that weren't actually available on the
    /// candidate. For example we tried to activate feature `foo` but the
    /// candidate we're activating didn't actually have the feature `foo`.
    MissingFeatures(String),
}

impl ConflictReason {
    pub fn is_links(&self) -> bool {
        if let ConflictReason::Links(_) = *self {
            return true;
        }
        false
    }

    pub fn is_missing_features(&self) -> bool {
        if let ConflictReason::MissingFeatures(_) = *self {
            return true;
        }
        false
    }
}

pub struct RcVecIter<T> {
    vec: Rc<Vec<T>>,
    rest: Range<usize>,
}

impl<T> RcVecIter<T> {
    pub fn new(vec: Rc<Vec<T>>) -> RcVecIter<T> {
        RcVecIter {
            rest: 0..vec.len(),
            vec,
        }
    }
}

// Not derived to avoid `T: Clone`
impl<T> Clone for RcVecIter<T> {
    fn clone(&self) -> RcVecIter<T> {
        RcVecIter {
            vec: self.vec.clone(),
            rest: self.rest.clone(),
        }
    }
}

impl<T> Iterator for RcVecIter<T>
where
    T: Clone,
{
    type Item = (usize, T);

    fn next(&mut self) -> Option<(usize, T)> {
        self.rest
            .next()
            .and_then(|i| self.vec.get(i).map(|val| (i, val.clone())))
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        // rest is a std::ops::Range, which is an ExactSizeIterator.
        self.rest.size_hint()
    }
}

impl<T: Clone> ExactSizeIterator for RcVecIter<T> {}

pub struct RcList<T> {
    pub head: Option<Rc<(T, RcList<T>)>>,
}

impl<T> RcList<T> {
    pub fn new() -> RcList<T> {
        RcList { head: None }
    }

    pub fn push(&mut self, data: T) {
        let node = Rc::new((
            data,
            RcList {
                head: self.head.take(),
            },
        ));
        self.head = Some(node);
    }
}

// Not derived to avoid `T: Clone`
impl<T> Clone for RcList<T> {
    fn clone(&self) -> RcList<T> {
        RcList {
            head: self.head.clone(),
        }
    }
}

// Avoid stack overflows on drop by turning recursion into a loop
impl<T> Drop for RcList<T> {
    fn drop(&mut self) {
        let mut cur = self.head.take();
        while let Some(head) = cur {
            match Rc::try_unwrap(head) {
                Ok((_data, mut next)) => cur = next.head.take(),
                Err(_) => break,
            }
        }
    }
}

pub enum GraphNode {
    Add(PackageId),
    Link(PackageId, PackageId, Dependency),
}
<commit_msg>remove all 4 RC clones in min_candidates. allowing it to be inlined<commit_after>use std::cmp::Ordering;
use std::collections::{HashMap, HashSet};
use std::ops::Range;
use std::rc::Rc;

use core::interning::InternedString;
use core::{Dependency, PackageId, PackageIdSpec, Registry, Summary};
use util::{CargoError, CargoResult};

pub struct RegistryQueryer<'a> {
    pub registry: &'a mut (Registry + 'a),
    replacements: &'a [(PackageIdSpec, Dependency)],
    try_to_use: &'a HashSet<&'a PackageId>,
    // TODO: with nll the Rc can be removed
    cache: HashMap<Dependency, Rc<Vec<Candidate>>>,
    // If set the list of dependency candidates will be sorted by minimal
    // versions first. That allows `cargo update -Z minimal-versions` which will
    // specify minimum dependency versions to be used.
    minimal_versions: bool,
}

impl<'a> RegistryQueryer<'a> {
    pub fn new(
        registry: &'a mut Registry,
        replacements: &'a [(PackageIdSpec, Dependency)],
        try_to_use: &'a HashSet<&'a PackageId>,
        minimal_versions: bool,
    ) -> Self {
        RegistryQueryer {
            registry,
            replacements,
            cache: HashMap::new(),
            try_to_use,
            minimal_versions,
        }
    }

    /// Queries the `registry` to return a list of candidates for `dep`.
    ///
    /// This method is the location where overrides are taken into account. If
    /// any candidates are returned which match an override then the override is
    /// applied by performing a second query for what the override should
    /// return.
    pub fn query(&mut self, dep: &Dependency) -> CargoResult<Rc<Vec<Candidate>>> {
        if let Some(out) = self.cache.get(dep).cloned() {
            return Ok(out);
        }

        let mut ret = Vec::new();
        self.registry.query(dep, &mut |s| {
            ret.push(Candidate {
                summary: s,
                replace: None,
            });
        })?;
        for candidate in ret.iter_mut() {
            let summary = &candidate.summary;

            let mut potential_matches = self.replacements
                .iter()
                .filter(|&&(ref spec, _)| spec.matches(summary.package_id()));

            let &(ref spec, ref dep) = match potential_matches.next() {
                None => continue,
                Some(replacement) => replacement,
            };
            debug!("found an override for {} {}", dep.name(), dep.version_req());

            let mut summaries = self.registry.query_vec(dep)?.into_iter();
            let s = summaries.next().ok_or_else(|| {
                format_err!(
                    "no matching package for override `{}` found\n\
                     location searched: {}\n\
                     version required: {}",
                    spec,
                    dep.source_id(),
                    dep.version_req()
                )
            })?;
            let summaries = summaries.collect::<Vec<_>>();
            if !summaries.is_empty() {
                let bullets = summaries
                    .iter()
                    .map(|s| format!("  * {}", s.package_id()))
                    .collect::<Vec<_>>();
                bail!(
                    "the replacement specification `{}` matched \
                     multiple packages:\n  * {}\n{}",
                    spec,
                    s.package_id(),
                    bullets.join("\n")
                );
            }

            // The dependency should be hard-coded to have the same name and an
            // exact version requirement, so both of these assertions should
            // never fail.
            assert_eq!(s.version(), summary.version());
            assert_eq!(s.name(), summary.name());

            let replace = if s.source_id() == summary.source_id() {
                debug!("Preventing\n{:?}\nfrom replacing\n{:?}", summary, s);
                None
            } else {
                Some(s)
            };
            let matched_spec = spec.clone();

            // Make sure no duplicates
            if let Some(&(ref spec, _)) = potential_matches.next() {
                bail!(
                    "overlapping replacement specifications found:\n\n  \
                     * {}\n  * {}\n\nboth specifications match: {}",
                    matched_spec,
                    spec,
                    summary.package_id()
                );
            }

            for dep in summary.dependencies() {
                debug!("\t{} => {}", dep.name(), dep.version_req());
            }

            candidate.replace = replace;
        }

        // When we attempt versions for a package we'll want to do so in a
        // sorted fashion to pick the "best candidates" first. Currently we try
        // prioritized summaries (those in `try_to_use`) and failing that we
        // list everything from the maximum version to the lowest version.
        ret.sort_unstable_by(|a, b| {
            let a_in_previous = self.try_to_use.contains(a.summary.package_id());
            let b_in_previous = self.try_to_use.contains(b.summary.package_id());
            let previous_cmp = a_in_previous.cmp(&b_in_previous).reverse();
            match previous_cmp {
                Ordering::Equal => {
                    let cmp = a.summary.version().cmp(b.summary.version());
                    if self.minimal_versions {
                        // Lower version ordered first.
                        cmp
                    } else {
                        // Higher version ordered first.
                        cmp.reverse()
                    }
                }
                _ => previous_cmp,
            }
        });

        let out = Rc::new(ret);

        self.cache.insert(dep.clone(), out.clone());

        Ok(out)
    }
}

#[derive(Clone, Copy)]
pub enum Method<'a> {
    Everything, // equivalent to Required { dev_deps: true, all_features: true, .. }
    Required {
        dev_deps: bool,
        features: &'a [InternedString],
        all_features: bool,
        uses_default_features: bool,
    },
}

impl<'r> Method<'r> {
    pub fn split_features(features: &[String]) -> Vec<InternedString> {
        features
            .iter()
            .flat_map(|s| s.split_whitespace())
            .flat_map(|s| s.split(','))
            .filter(|s| !s.is_empty())
            .map(|s| InternedString::new(s))
            .collect::<Vec<InternedString>>()
    }
}

#[derive(Clone)]
pub struct Candidate {
    pub summary: Summary,
    pub replace: Option<Summary>,
}

#[derive(Clone)]
pub struct DepsFrame {
    pub parent: Summary,
    pub just_for_error_messages: bool,
    pub remaining_siblings: RcVecIter<DepInfo>,
}

impl DepsFrame {
    /// Returns the least number of candidates that any of this frame's siblings
    /// has.
    ///
    /// The `remaining_siblings` array is already sorted with the smallest
    /// number of candidates at the front, so we just return the number of
    /// candidates in that entry.
    fn min_candidates(&self) -> usize {
        self.remaining_siblings
            .peek()
            .map(|(_, (_, candidates, _))| candidates.len())
            .unwrap_or(0)
    }

    pub fn flatten<'s>(&'s self) -> impl Iterator<Item = (&PackageId, Dependency)> + 's {
        self.remaining_siblings
            .clone()
            .map(move |(_, (d, _, _))| (self.parent.package_id(), d))
    }
}

impl PartialEq for DepsFrame {
    fn eq(&self, other: &DepsFrame) -> bool {
        self.just_for_error_messages == other.just_for_error_messages
            && self.min_candidates() == other.min_candidates()
    }
}

impl Eq for DepsFrame {}

impl PartialOrd for DepsFrame {
    fn partial_cmp(&self, other: &DepsFrame) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl Ord for DepsFrame {
    fn cmp(&self, other: &DepsFrame) -> Ordering {
        self.just_for_error_messages
            .cmp(&other.just_for_error_messages)
            .then_with(||
            // the frame with the sibling that has the least number of candidates
            // needs to get bubbled up to the top of the heap we use below, so
            // reverse comparison here.
            self.min_candidates().cmp(&other.min_candidates()).reverse())
    }
}

// Information about the dependencies for a crate, a tuple of:
//
// (dependency info, candidates, features activated)
pub type DepInfo = (Dependency, Rc<Vec<Candidate>>, Rc<Vec<InternedString>>);

pub type ActivateResult<T> = Result<T, ActivateError>;

pub enum ActivateError {
    Fatal(CargoError),
    Conflict(PackageId, ConflictReason),
}

impl From<::failure::Error> for ActivateError {
    fn from(t: ::failure::Error) -> Self {
        ActivateError::Fatal(t)
    }
}

impl From<(PackageId, ConflictReason)> for ActivateError {
    fn from(t: (PackageId, ConflictReason)) -> Self {
        ActivateError::Conflict(t.0, t.1)
    }
}

/// All possible reasons that a package might fail to activate.
///
/// We maintain a list of conflicts for error reporting as well as backtracking
/// purposes. Each reason here is why candidates may be rejected or why we may
/// fail to resolve a dependency.
#[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq)]
pub enum ConflictReason {
    /// There was a semver conflict, for example we tried to activate a package
    /// 1.0.2 but 1.1.0 was already activated (aka a compatible semver version
    /// is already activated)
    Semver,

    /// The `links` key is being violated. For example one crate in the
    /// dependency graph has `links = "foo"` but this crate also had that, and
    /// we're only allowed one per dependency graph.
    Links(String),

    /// A dependency listed features that weren't actually available on the
    /// candidate. For example we tried to activate feature `foo` but the
    /// candidate we're activating didn't actually have the feature `foo`.
    MissingFeatures(String),
}

impl ConflictReason {
    pub fn is_links(&self) -> bool {
        if let ConflictReason::Links(_) = *self {
            return true;
        }
        false
    }

    pub fn is_missing_features(&self) -> bool {
        if let ConflictReason::MissingFeatures(_) = *self {
            return true;
        }
        false
    }
}

pub struct RcVecIter<T> {
    vec: Rc<Vec<T>>,
    rest: Range<usize>,
}

impl<T> RcVecIter<T> {
    pub fn new(vec: Rc<Vec<T>>) -> RcVecIter<T> {
        RcVecIter {
            rest: 0..vec.len(),
            vec,
        }
    }

    fn peek(&self) -> Option<(usize, &T)> {
        self.rest
            .clone()
            .next()
            .and_then(|i| self.vec.get(i).map(|val| (i, &*val)))
    }
}

// Not derived to avoid `T: Clone`
impl<T> Clone for RcVecIter<T> {
    fn clone(&self) -> RcVecIter<T> {
        RcVecIter {
            vec: self.vec.clone(),
            rest: self.rest.clone(),
        }
    }
}

impl<T> Iterator for RcVecIter<T>
where
    T: Clone,
{
    type Item = (usize, T);

    fn next(&mut self) -> Option<Self::Item> {
        self.rest
            .next()
            .and_then(|i| self.vec.get(i).map(|val| (i, val.clone())))
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        // rest is a std::ops::Range, which is an ExactSizeIterator.
        self.rest.size_hint()
    }
}

impl<T: Clone> ExactSizeIterator for RcVecIter<T> {}

pub struct RcList<T> {
    pub head: Option<Rc<(T, RcList<T>)>>,
}

impl<T> RcList<T> {
    pub fn new() -> RcList<T> {
        RcList { head: None }
    }

    pub fn push(&mut self, data: T) {
        let node = Rc::new((
            data,
            RcList {
                head: self.head.take(),
            },
        ));
        self.head = Some(node);
    }
}

// Not derived to avoid `T: Clone`
impl<T> Clone for RcList<T> {
    fn clone(&self) -> RcList<T> {
        RcList {
            head: self.head.clone(),
        }
    }
}

// Avoid stack overflows on drop by turning recursion into a loop
impl<T> Drop for RcList<T> {
    fn drop(&mut self) {
        let mut cur = self.head.take();
        while let Some(head) = cur {
            match Rc::try_unwrap(head) {
                Ok((_data, mut next)) => cur = next.head.take(),
                Err(_) => break,
            }
        }
    }
}

pub enum GraphNode {
    Add(PackageId),
    Link(PackageId, PackageId, Dependency),
}
<|endoftext|>


<commit_before>// Copyright (c) 2015, Mikhail Vorotilov
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this
//   list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
//   this list of conditions and the following disclaimer in the documentation
//   and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

use super::super::FloatType;
use super::super::Roots;

/// Solves a quadratic equation a2*x^2 + a1*x + a0 = 0.
///
/// In case two roots are present, the first returned root is less than the second one.
///
/// # Examples
///
/// ```
/// use roots::Roots;
/// use roots::find_roots_quadratic;
///
/// let no_roots = find_roots_quadratic(1f32, 0f32, 1f32);
/// // Returns Roots::No([]) as 'x^2 + 1 = 0' has no roots
///
/// let one_root = find_roots_quadratic(1f64, 0f64, 0f64);
/// // Returns Roots::One([0f64]) as 'x^2 = 0' has one root 0
///
/// let two_roots = find_roots_quadratic(1f32, 0f32, -1f32);
/// // Returns Roots::Two([-1f32,1f32]) as 'x^2 - 1 = 0' has roots -1 and 1
/// ```
pub fn find_roots_quadratic<F: FloatType>(a2: F, a1: F, a0: F) -> Roots<F> {
    // Handle non-standard cases
    if a2 == F::zero() {
        // a2 = 0; a1*x+a0=0; solve linear equation
        super::linear::find_roots_linear(a1, a0)
    } else {
        // Rust lacks a simple way to convert an integer constant to generic type F
        let a2x2 = F::two() * a2;
        let discriminant = a1 * a1 - F::four() * a2 * a0;
        if discriminant < F::zero() {
            Roots::No([])
        } else {
            if discriminant == F::zero() {
                Roots::One([-a1 / a2x2])
            } else {
                let sq = discriminant.sqrt();
                Roots::Two([(-a1 - sq) / a2x2, (-a1 + sq) / a2x2])
            }
        }
    }
}

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

    #[test]
    fn test_find_roots_quadratic() {
        assert_eq!(find_roots_quadratic(0f32, 0f32, 0f32), Roots::One([0f32]));
        assert_eq!(find_roots_quadratic(1f32, 0f32, 1f32), Roots::No([]));
        assert_eq!(find_roots_quadratic(1f64, 0f64, -1f64),
                   Roots::Two([-1f64, 1f64]));
    }
}
<commit_msg>Add tests for special cases of quadratic equations.<commit_after>// Copyright (c) 2015, Mikhail Vorotilov
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this
//   list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
//   this list of conditions and the following disclaimer in the documentation
//   and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

use super::super::FloatType;
use super::super::Roots;

/// Solves a quadratic equation a2*x^2 + a1*x + a0 = 0.
///
/// In case two roots are present, the first returned root is less than the second one.
///
/// # Examples
///
/// ```
/// use roots::Roots;
/// use roots::find_roots_quadratic;
///
/// let no_roots = find_roots_quadratic(1f32, 0f32, 1f32);
/// // Returns Roots::No([]) as 'x^2 + 1 = 0' has no roots
///
/// let one_root = find_roots_quadratic(1f64, 0f64, 0f64);
/// // Returns Roots::One([0f64]) as 'x^2 = 0' has one root 0
///
/// let two_roots = find_roots_quadratic(1f32, 0f32, -1f32);
/// // Returns Roots::Two([-1f32,1f32]) as 'x^2 - 1 = 0' has roots -1 and 1
/// ```
pub fn find_roots_quadratic<F: FloatType>(a2: F, a1: F, a0: F) -> Roots<F> {
    // Handle non-standard cases
    if a2 == F::zero() {
        // a2 = 0; a1*x+a0=0; solve linear equation
        super::linear::find_roots_linear(a1, a0)
    } else {
        // Rust lacks a simple way to convert an integer constant to generic type F
        let a2x2 = F::two() * a2;
        let discriminant = a1 * a1 - F::four() * a2 * a0;
        if discriminant < F::zero() {
            Roots::No([])
        } else {
            if discriminant == F::zero() {
                Roots::One([-a1 / a2x2])
            } else {
                let sq = discriminant.sqrt();
                Roots::Two([(-a1 - sq) / a2x2, (-a1 + sq) / a2x2])
            }
        }
    }
}

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

    #[test]
    fn test_find_roots_quadratic() {
        assert_eq!(find_roots_quadratic(0f32, 0f32, 0f32), Roots::One([0f32]));
        assert_eq!(find_roots_quadratic(1f32, 0f32, 1f32), Roots::No([]));
        assert_eq!(find_roots_quadratic(1f64, 0f64, -1f64),
                   Roots::Two([-1f64, 1f64]));
    }

    #[test]
    fn test_find_roots_quadratic_small_a2() {
        assert_eq!(find_roots_quadratic(1e-20f32, -1f32, -1e-30f32),
                   Roots::Two([-1e-30f32, 1e20f32]));
        assert_eq!(find_roots_quadratic(-1e-20f32, 1f32, 1e-30f32),
                   Roots::Two([-1e-30f32, 1e20f32]));
        assert_eq!(find_roots_quadratic(1e-20f32, -1f32, 1f32),
                   Roots::Two([1f32, 1e20f32]));
        assert_eq!(find_roots_quadratic(-1e-20f32, 1f32, 1f32),
                   Roots::Two([-1f32, 1e20f32]));
        assert_eq!(find_roots_quadratic(-1e-20f32, 1f32, -1f32),
                   Roots::Two([1f32, 1e20f32]));
    }

    #[test]
    fn test_find_roots_quadratic_big_a1() {
        assert_eq!(find_roots_quadratic(1f32, -1e15f32, -1f32),
                   Roots::Two([-1e-15f32, 1e15f32]));
        assert_eq!(find_roots_quadratic(-1f32, 1e15f32, 1f32),
                   Roots::Two([-1e-15f32, 1e15f32]));
    }
}
<|endoftext|>


<commit_before>
#[derive(rustc_serialize)]
<commit_msg>Don't actually need seperate mod for toml file<commit_after><|endoftext|>


<commit_before>// Copyright (C) 2019 Inderjit Gill

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
#![allow(dead_code)]
#![cfg_attr(feature = "cargo-clippy", allow(clippy::many_single_char_names, clippy::too_many_arguments))]

mod utils;

use cfg_if::cfg_if;
use wasm_bindgen::prelude::*;

use sen_core;

cfg_if! {
    // When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
    // allocator.
    if #[cfg(feature = "wee_alloc")] {
        extern crate wee_alloc;
        #[global_allocator]
        static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
    }
}

#[wasm_bindgen]
extern "C" {
    #[wasm_bindgen(js_namespace = console)]
    fn log(s: &str);
}

#[wasm_bindgen]
#[derive(Default)]
pub struct Bridge {
    vm: sen_core::Vm,
    env: sen_core::Env,

    source_buffer: String,
    out_source_buffer: String,
    traits_buffer: String,
    genotype_buffer: String,

    genotype_list: Option<Vec<sen_core::Genotype>>,

    // temporary, these will all be removed eventually
    trait_list: Option<sen_core::TraitList>,
}

#[wasm_bindgen]
impl Bridge {
    #[wasm_bindgen(constructor)]
    pub fn new() -> Bridge {
        Bridge {
            vm: sen_core::Vm::new(),
            env: sen_core::Env::new(),

            source_buffer: "source buffer".to_string(),
            out_source_buffer: "out_source buffer".to_string(),
            traits_buffer: "traits buffer".to_string(),
            genotype_buffer: "genotype buffer".to_string(),

            genotype_list: None,

            trait_list: None,
        }
    }

    pub fn get_genotype_buffer_string(&self) -> String {
        log("get_genotype_buffer_string");
        self.genotype_buffer.to_string()
    }

    pub fn set_genotype_buffer_string(&mut self, s: &str) {
        log("set_genotype_buffer_string");
        self.genotype_buffer = s.to_string();
    }

    pub fn get_traits_buffer_string(&self) -> String {
        log("get_traits_buffer_string");
        self.traits_buffer.to_string()
    }

    pub fn set_traits_buffer_string(&mut self, s: &str) {
        log("set_traits_buffer_string");
        self.traits_buffer = s.to_string();
    }

    pub fn get_out_source_buffer_string(&self) -> String {
        log("get_out_source_buffer_string");
        self.out_source_buffer.to_string()
    }

    pub fn set_out_source_buffer_string(&mut self, s: &str) {
        log("set_out_source_buffer_string");
        self.out_source_buffer = s.to_string();
    }

    pub fn get_source_buffer_string(&self) -> String {
        log("get_source_buffer_string");
        self.source_buffer.to_string()
    }

    pub fn set_source_buffer_string(&mut self, s: &str) {
        log("set_source_buffer_string");
        self.source_buffer = s.to_string();
    }

    pub fn sen_startup(&self) {
        log("sen_startup");
    }

    pub fn sen_shutdown(&self) {
        log("sen_shutdown");
    }

    pub fn compile_to_render_packets(&mut self) -> i32 {
        if let Ok(res) = sen_core::compile_to_render_packets(&mut self.vm, &self.source_buffer) {
            res
        } else {
            0
        }
    }

    pub fn get_render_packet_geo_len(&self, packet_number: usize) -> usize {
        self.vm.get_render_packet_geo_len(packet_number)
    }

    pub fn get_render_packet_geo_ptr(&self, packet_number: usize) -> *const f32 {
        self.vm.get_render_packet_geo_ptr(packet_number)
    }

    // todo: is bool the best return type?
    pub fn build_traits(&mut self) -> bool {
        if let Ok(trait_list) = sen_core::build_traits(&self.source_buffer) {
            self.trait_list = Some(trait_list);
            // todo: serialize trait_list
            true
        } else {
            false
        }
    }

    pub fn single_genotype_from_seed(&mut self, seed: i32) -> bool {
        // todo: deserialize trait_list from traits_buffer
        // for the moment using self.trait_list THIS IS WRONG!!!
        if let Some(ref trait_list) = self.trait_list {
            if let Ok(genotype) = sen_core::Genotype::build_from_seed(trait_list, seed) {
                self.genotype_list = Some(vec![genotype]);
                return true
            }
        }
        false
    }

    // todo: is bool the best return type?
    pub fn create_initial_generation(&mut self, population_size: i32, seed: i32) -> bool {
        // todo: deserialize trait_list from traits_buffer
        // for the moment using self.trait_list THIS IS WRONG!!!
        if let Some(ref trait_list) = self.trait_list {
            if let Ok(genotype_list) = sen_core::Genotype::build_genotypes(&trait_list, population_size, seed) {
                self.genotype_list = Some(genotype_list);
                return true
            }
        }

        false
    }

    pub fn genotype_move_to_buffer(&mut self, index: usize) -> bool {
        if let Some(ref genotype_list) = self.genotype_list {
            if let Some(ref _genotype) = genotype_list.get(index) {
                // todo: serialize into genotype_buffer
                unimplemented!();
                // return true
            }
        }
        false
    }

    pub fn script_cleanup(&self) {
        log("script_cleanup");
    }

    pub fn use_genotype_when_compiling(&self, use_genotype: bool) {
        if use_genotype {
            log("use_genotype_when_compiling : using");
        } else {
            log("use_genotype_when_compiling : not using genotype");
        }

    }

    pub fn next_generation_prepare(&self) {
        log("next_generation_prepare");
    }

    pub fn next_generation_add_genotype(&self) {
        log("next_generation_add_genotype");
    }

    pub fn next_generation_build(&self, _parent_size: i32, _population_size: i32, _mutation_rate: f32, _rng: i32) -> bool {
        log("next_generation_build");
        false
    }

    pub fn unparse_with_genotype(&self) {
        log("unparse_with_genotype");
    }

    pub fn simplify_script(&self) {
        log("simplify_script");
    }
}
<commit_msg>compile_to_render_packets logs vm.debug_str<commit_after>// Copyright (C) 2019 Inderjit Gill

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
#![allow(dead_code)]
#![cfg_attr(feature = "cargo-clippy", allow(clippy::many_single_char_names, clippy::too_many_arguments))]

mod utils;

use cfg_if::cfg_if;
use wasm_bindgen::prelude::*;

use sen_core;

cfg_if! {
    // When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
    // allocator.
    if #[cfg(feature = "wee_alloc")] {
        extern crate wee_alloc;
        #[global_allocator]
        static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
    }
}

#[wasm_bindgen]
extern "C" {
    #[wasm_bindgen(js_namespace = console)]
    fn log(s: &str);
}

#[wasm_bindgen]
#[derive(Default)]
pub struct Bridge {
    vm: sen_core::Vm,
    env: sen_core::Env,

    source_buffer: String,
    out_source_buffer: String,
    traits_buffer: String,
    genotype_buffer: String,

    genotype_list: Option<Vec<sen_core::Genotype>>,

    // temporary, these will all be removed eventually
    trait_list: Option<sen_core::TraitList>,
}

#[wasm_bindgen]
impl Bridge {
    #[wasm_bindgen(constructor)]
    pub fn new() -> Bridge {
        Bridge {
            vm: sen_core::Vm::new(),
            env: sen_core::Env::new(),

            source_buffer: "source buffer".to_string(),
            out_source_buffer: "out_source buffer".to_string(),
            traits_buffer: "traits buffer".to_string(),
            genotype_buffer: "genotype buffer".to_string(),

            genotype_list: None,

            trait_list: None,
        }
    }

    pub fn get_genotype_buffer_string(&self) -> String {
        log("get_genotype_buffer_string");
        self.genotype_buffer.to_string()
    }

    pub fn set_genotype_buffer_string(&mut self, s: &str) {
        log("set_genotype_buffer_string");
        self.genotype_buffer = s.to_string();
    }

    pub fn get_traits_buffer_string(&self) -> String {
        log("get_traits_buffer_string");
        self.traits_buffer.to_string()
    }

    pub fn set_traits_buffer_string(&mut self, s: &str) {
        log("set_traits_buffer_string");
        self.traits_buffer = s.to_string();
    }

    pub fn get_out_source_buffer_string(&self) -> String {
        log("get_out_source_buffer_string");
        self.out_source_buffer.to_string()
    }

    pub fn set_out_source_buffer_string(&mut self, s: &str) {
        log("set_out_source_buffer_string");
        self.out_source_buffer = s.to_string();
    }

    pub fn get_source_buffer_string(&self) -> String {
        log("get_source_buffer_string");
        self.source_buffer.to_string()
    }

    pub fn set_source_buffer_string(&mut self, s: &str) {
        log("set_source_buffer_string");
        self.source_buffer = s.to_string();
    }

    pub fn sen_startup(&self) {
        log("sen_startup");
    }

    pub fn sen_shutdown(&self) {
        log("sen_shutdown");
    }

    pub fn compile_to_render_packets(&mut self) -> i32 {
        let num_render_packets = if let Ok(res) = sen_core::compile_to_render_packets(&mut self.vm, &self.source_buffer) {
            res
        } else {
            0
        };

        log(&self.vm.debug_str);
        self.vm.debug_str_clear();

        num_render_packets
    }

    pub fn get_render_packet_geo_len(&self, packet_number: usize) -> usize {
        self.vm.get_render_packet_geo_len(packet_number)
    }

    pub fn get_render_packet_geo_ptr(&self, packet_number: usize) -> *const f32 {
        self.vm.get_render_packet_geo_ptr(packet_number)
    }

    // todo: is bool the best return type?
    pub fn build_traits(&mut self) -> bool {
        if let Ok(trait_list) = sen_core::build_traits(&self.source_buffer) {
            self.trait_list = Some(trait_list);
            // todo: serialize trait_list
            true
        } else {
            false
        }
    }

    pub fn single_genotype_from_seed(&mut self, seed: i32) -> bool {
        // todo: deserialize trait_list from traits_buffer
        // for the moment using self.trait_list THIS IS WRONG!!!
        if let Some(ref trait_list) = self.trait_list {
            if let Ok(genotype) = sen_core::Genotype::build_from_seed(trait_list, seed) {
                self.genotype_list = Some(vec![genotype]);
                return true
            }
        }
        false
    }

    // todo: is bool the best return type?
    pub fn create_initial_generation(&mut self, population_size: i32, seed: i32) -> bool {
        // todo: deserialize trait_list from traits_buffer
        // for the moment using self.trait_list THIS IS WRONG!!!
        if let Some(ref trait_list) = self.trait_list {
            if let Ok(genotype_list) = sen_core::Genotype::build_genotypes(&trait_list, population_size, seed) {
                self.genotype_list = Some(genotype_list);
                return true
            }
        }

        false
    }

    pub fn genotype_move_to_buffer(&mut self, index: usize) -> bool {
        if let Some(ref genotype_list) = self.genotype_list {
            if let Some(ref _genotype) = genotype_list.get(index) {
                // todo: serialize into genotype_buffer
                unimplemented!();
                // return true
            }
        }
        false
    }

    pub fn script_cleanup(&self) {
        log("script_cleanup");
    }

    pub fn use_genotype_when_compiling(&self, use_genotype: bool) {
        if use_genotype {
            log("use_genotype_when_compiling : using");
        } else {
            log("use_genotype_when_compiling : not using genotype");
        }

    }

    pub fn next_generation_prepare(&self) {
        log("next_generation_prepare");
    }

    pub fn next_generation_add_genotype(&self) {
        log("next_generation_add_genotype");
    }

    pub fn next_generation_build(&self, _parent_size: i32, _population_size: i32, _mutation_rate: f32, _rng: i32) -> bool {
        log("next_generation_build");
        false
    }

    pub fn unparse_with_genotype(&self) {
        log("unparse_with_genotype");
    }

    pub fn simplify_script(&self) {
        log("simplify_script");
    }
}
<|endoftext|>


<commit_before>use luminance::{Dim2, Flat, Framebuffer, Mode, Pipe, Pipeline, RGBA32F, RawTexture, RenderCommand,
                ShadingCommand, Tess, TessRender, Texture, Unit, Uniform};

use color::ColorAlpha;
use resource::Res;
use scene::Scene;
use shader::Program;

pub type Texture2D<A> = Texture<Flat, Dim2, A>;

const FORWARD_SOURCE: &'static Uniform<Unit> = &Uniform::new(0);

/// The forward compositor.
///
/// This compositor is a very simple one: it forwards a render to the screen. It can also create an
/// empty render – it basically cleans the screen with the color of your choice.
pub struct Forward {
  framebuffer: Framebuffer<Flat, Dim2, (), ()>,
  program: Res<Program>,
  quad: Tess
}

impl Forward {
  pub fn new(w: u32, h: u32, scene: &mut Scene) -> Self {
    let program = scene.get("spectra/compositors/forward.glsl", vec![FORWARD_SOURCE.sem("source")]).unwrap();

    Forward {
      framebuffer: Framebuffer::default((w, h)),
      program: program,
      quad: Tess::attributeless(Mode::TriangleStrip, 4),
    }
  }

  /// Display a texture onto screen.
  pub fn texture_screen(&self, source: &Texture2D<RGBA32F>) {
    let textures: &[&RawTexture] = &[source];
    let tess_render = TessRender::one_whole(&self.quad);

    Pipeline::new(&self.framebuffer, [0., 0., 0., 0.], textures, &[], vec![
      Pipe::empty()
        .uniforms(&[FORWARD_SOURCE.alter(Unit::new(0))])
        .unwrap(ShadingCommand::new(&self.program.borrow(), vec![
          Pipe::new(RenderCommand::new(None, true, vec![
            Pipe::new(tess_render)]))
          ]))
    ]).run();
  }

  /// Render a screen to screen with a given color.
  pub fn color_screen(&self, clear_color: ColorAlpha) {
    Pipeline::new(&self.framebuffer, *clear_color.as_ref(), &[], &[], vec![]).run();
  }
}
<commit_msg>Typo.<commit_after>use luminance::{Dim2, Flat, Framebuffer, Mode, Pipe, Pipeline, RGBA32F, RawTexture, RenderCommand,
                ShadingCommand, Tess, TessRender, Texture, Unit, Uniform};

use color::ColorAlpha;
use resource::Res;
use scene::Scene;
use shader::Program;

pub type Texture2D<A> = Texture<Flat, Dim2, A>;

const FORWARD_SOURCE: &'static Uniform<Unit> = &Uniform::new(0);

/// The forward compositor.
///
/// This compositor is a very simple one: it forwards a render to the screen. It can also create an
/// empty render – it basically cleans the screen with the color of your choice.
pub struct Forward {
  framebuffer: Framebuffer<Flat, Dim2, (), ()>,
  program: Res<Program>,
  quad: Tess
}

impl Forward {
  pub fn new(w: u32, h: u32, scene: &mut Scene) -> Self {
    let program = scene.get("spectra/compositors/forward.glsl", vec![FORWARD_SOURCE.sem("source")]).unwrap();

    Forward {
      framebuffer: Framebuffer::default((w, h)),
      program: program,
      quad: Tess::attributeless(Mode::TriangleStrip, 4),
    }
  }

  /// Display a texture onto screen.
  pub fn texture_screen(&self, source: &Texture2D<RGBA32F>) {
    let textures: &[&RawTexture] = &[source];
    let tess_render = TessRender::one_whole(&self.quad);

    Pipeline::new(&self.framebuffer, [0., 0., 0., 0.], textures, &[], vec![
      Pipe::empty()
        .uniforms(&[FORWARD_SOURCE.alter(Unit::new(0))])
        .unwrap(ShadingCommand::new(&self.program.borrow(), vec![
          Pipe::new(RenderCommand::new(None, true, vec![
            Pipe::new(tess_render)]))
          ]))
    ]).run();
  }

  /// Clear the screen with a given color.
  pub fn color_screen(&self, clear_color: ColorAlpha) {
    Pipeline::new(&self.framebuffer, *clear_color.as_ref(), &[], &[], vec![]).run();
  }
}
<|endoftext|>


<commit_before>#![crate_type = "lib"]
#![crate_name = "coinaddress"]

//! Functions for validating the base58 hash checksums, including specifically
//! the bitcoin and litecoin addresses.

#![feature(test)]
#![feature(rustc_private)]

extern crate num;
extern crate rustc;
extern crate test;

use num::bigint::BigUint;
use num::Zero;
use std::num::{from_uint, from_int, ToPrimitive};
use rustc::util::sha2::{Sha256, Digest};

#[derive(PartialEq, Debug, Copy)]
pub enum ValidationError {
    /// Given address is too short to be valid
    TooShort,
    /// Encoding is not a valid base58
    InvalidEncoding,
    /// Computed hash does not match the embedded one
    HashMismatch,

    // currency specific
    /// This address is not a bitcoin address (testnet or real).
    /// May happen when attempting to validate btc address
    NotBitcoin,
    /// This address is not a litecoin address.
    /// May happen when attempting to validate ltc address
    NotLitecoin,
}

static BASE58_CHARS: &'static str = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";

fn decode_base58(bc: &str) -> Option<BigUint> {
    let mut res: BigUint = Zero::zero();
    let b58: BigUint = from_int(58).unwrap();

    for c in bc.chars() {
        match BASE58_CHARS.find(c) {
            None => {
                return None
            },
            Some(x) => {
                res = res * &b58 + from_uint::<BigUint>(x).unwrap();
            }
        }
    }
    Some(res)
}

fn bigint_to_bytes(n: BigUint) -> Vec<u8> {
    let mut res: Vec<u8> = Vec::new();
    let mut tmp = n;
    let b256: BigUint = from_int(256).unwrap();

    while !tmp.is_zero() {
        res.insert(0, (&tmp % &b256).to_u8().unwrap());
        tmp = tmp / &b256;
    }

    if res.len() == 0 {
        return vec!(0);
    }

    res
}

fn pad_to(v: Vec<u8>, len: usize) -> Vec<u8> {
    let mut tmp: Vec<u8> = v;
    while tmp.len() < len {
        tmp.insert(0, 0)
    }
    tmp
}

fn double_sha256(chunk: &[u8]) -> Vec<u8> {
    let mut hash = Sha256::new();
    hash.input(chunk);
    let mut hash2 = Sha256::new();
    hash2.input(hash.result_bytes().as_slice());
    hash2.result_bytes()
}

/// Validate provided generic base58 hash.
/// Returns the hash version/type if correct and an error otherwise.
pub fn validate_base58_hash(addr: &str) -> Result<usize, ValidationError> {
    if addr.len() == 0 {
        return Err(ValidationError::TooShort);
    }

    let big = match decode_base58(addr) {
        None => return Err(ValidationError::InvalidEncoding),
        Some(x) => x
    };
    let bytes = bigint_to_bytes(big);
    let padded = pad_to(bytes, 25);

    let hash = double_sha256(&padded[0 .. padded.len() - 4]);
    let short_hash = &hash[0..4];
    let known = &padded[padded.len()-4 .. padded.len()];
    if short_hash.as_slice() == known {
        Ok(padded[0] as usize)
    } else {
        Err(ValidationError::HashMismatch)
    }
}

/// Validate bitcoin address checksum.
/// Returns the hash version/type if correct and an error otherwise.
pub fn validate_btc_address(addr: &str) -> Result<usize, ValidationError> {
    match validate_base58_hash(addr) {
        Ok(0) => Ok(0),      // real address
        Ok(5) => Ok(5),      // script hash
        Ok(111) => Ok(111),  // testnet address
        Ok(_) => Err(ValidationError::NotBitcoin),
        Err(x) => Err(x)
    }
}

/// Validate litecoin address checksum.
/// Returns the hash version/type if correct and an error otherwise.
pub fn validate_ltc_address(addr: &str) -> Result<usize, ValidationError> {
    match validate_base58_hash(addr) {
        Ok(48) => Ok(48),      // real address
        Ok(111) => Ok(111),    // testnet address
        Ok(_) => Err(ValidationError::NotLitecoin),
        Err(x) => Err(x)
    }
}

#[test]
fn test_decoding() {
    use std::num::from_str_radix;

    assert_eq!(decode_base58("1"), from_int(0));
    assert_eq!(decode_base58("1AaZz"), from_int(0x1C8485));
    assert_eq!(decode_base58("AO"), None);
    assert_eq!(decode_base58("1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i"), from_str_radix("65A16059864A2FDBC7C99A4723A8395BC6F188EBC046B2FF", 16).ok());
}

#[test]
fn test_to_bytes() {
    assert_eq!(bigint_to_bytes(Zero::zero()), vec!(0));
    assert_eq!(bigint_to_bytes(from_int(1).unwrap()), vec!(1));
    assert_eq!(bigint_to_bytes(from_int(256).unwrap()), vec!(1, 0));
}

#[test]
fn test_validate_hash() {
    assert_eq!(validate_base58_hash("17VZNX1SN5NtKa8UQFxwQbFeFc3iqRYhem"), Ok(0));
    assert_eq!(validate_base58_hash("mipcBbFg9gMiCh81Kj8tqqdgoZub1ZJRfn"), Ok(111));
    assert_eq!(validate_base58_hash("17VZNX1SN5NtKa8UQFxwQbFeFc3iqRYheX"), Err(ValidationError::HashMismatch));
    assert_eq!(validate_base58_hash("17VZNX1SN5NtKa8UQFxwQbFeFc3iqRYh  "), Err(ValidationError::InvalidEncoding));
    assert_eq!(validate_base58_hash("1"), Err(ValidationError::HashMismatch));
    assert_eq!(validate_base58_hash(""), Err(ValidationError::TooShort));
}

#[test]
fn test_validate_btc_address() {
    assert_eq!(validate_btc_address("17VZNX1SN5NtKa8UQFxwQbFeFc3iqRYhem"), Ok(0));
    assert_eq!(validate_btc_address("3EktnHQD7RiAE6uzMj2ZifT9YgRrkSgzQX"), Ok(5));
    assert_eq!(validate_btc_address("mipcBbFg9gMiCh81Kj8tqqdgoZub1ZJRfn"), Ok(111));
    assert_eq!(validate_btc_address("LRELGDJyeCPRDXz4Dh1kWorMN9hTBB7CEz"), Err(ValidationError::NotBitcoin));
}

#[test]
fn test_validate_ltc_address() {
    assert_eq!(validate_ltc_address("LRELGDJyeCPRDXz4Dh1kWorMN9hTBB7CEz"), Ok(48));
    assert_eq!(validate_ltc_address("muen9zszN6rVwXaFw48xh6YkdUSjJcfzek"), Ok(111));
    assert_eq!(validate_ltc_address("17VZNX1SN5NtKa8UQFxwQbFeFc3iqRYhem"), Err(ValidationError::NotLitecoin));
}

#[bench]
fn bench_validate_hash(b: &mut test::Bencher) {
    b.iter(|| {
        validate_base58_hash("17VZNX1SN5NtKa8UQFxwQbFeFc3iqRYhem")
    })
}
<commit_msg>No more Copy trait<commit_after>#![crate_type = "lib"]
#![crate_name = "coinaddress"]

//! Functions for validating the base58 hash checksums, including specifically
//! the bitcoin and litecoin addresses.

#![feature(test)]
#![feature(rustc_private)]

extern crate num;
extern crate rustc;
extern crate test;

use num::bigint::BigUint;
use num::Zero;
use std::num::{from_uint, from_int, ToPrimitive};
use rustc::util::sha2::{Sha256, Digest};

#[derive(PartialEq, Debug)]
pub enum ValidationError {
    /// Given address is too short to be valid
    TooShort,
    /// Encoding is not a valid base58
    InvalidEncoding,
    /// Computed hash does not match the embedded one
    HashMismatch,

    // currency specific
    /// This address is not a bitcoin address (testnet or real).
    /// May happen when attempting to validate btc address
    NotBitcoin,
    /// This address is not a litecoin address.
    /// May happen when attempting to validate ltc address
    NotLitecoin,
}

static BASE58_CHARS: &'static str = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";

fn decode_base58(bc: &str) -> Option<BigUint> {
    let mut res: BigUint = Zero::zero();
    let b58: BigUint = from_int(58).unwrap();

    for c in bc.chars() {
        match BASE58_CHARS.find(c) {
            None => {
                return None
            },
            Some(x) => {
                res = res * &b58 + from_uint::<BigUint>(x).unwrap();
            }
        }
    }
    Some(res)
}

fn bigint_to_bytes(n: BigUint) -> Vec<u8> {
    let mut res: Vec<u8> = Vec::new();
    let mut tmp = n;
    let b256: BigUint = from_int(256).unwrap();

    while !tmp.is_zero() {
        res.insert(0, (&tmp % &b256).to_u8().unwrap());
        tmp = tmp / &b256;
    }

    if res.len() == 0 {
        return vec!(0);
    }

    res
}

fn pad_to(v: Vec<u8>, len: usize) -> Vec<u8> {
    let mut tmp: Vec<u8> = v;
    while tmp.len() < len {
        tmp.insert(0, 0)
    }
    tmp
}

fn double_sha256(chunk: &[u8]) -> Vec<u8> {
    let mut hash = Sha256::new();
    hash.input(chunk);
    let mut hash2 = Sha256::new();
    hash2.input(hash.result_bytes().as_slice());
    hash2.result_bytes()
}

/// Validate provided generic base58 hash.
/// Returns the hash version/type if correct and an error otherwise.
pub fn validate_base58_hash(addr: &str) -> Result<usize, ValidationError> {
    if addr.len() == 0 {
        return Err(ValidationError::TooShort);
    }

    let big = match decode_base58(addr) {
        None => return Err(ValidationError::InvalidEncoding),
        Some(x) => x
    };
    let bytes = bigint_to_bytes(big);
    let padded = pad_to(bytes, 25);

    let hash = double_sha256(&padded[0 .. padded.len() - 4]);
    let short_hash = &hash[0..4];
    let known = &padded[padded.len()-4 .. padded.len()];
    if short_hash.as_slice() == known {
        Ok(padded[0] as usize)
    } else {
        Err(ValidationError::HashMismatch)
    }
}

/// Validate bitcoin address checksum.
/// Returns the hash version/type if correct and an error otherwise.
pub fn validate_btc_address(addr: &str) -> Result<usize, ValidationError> {
    match validate_base58_hash(addr) {
        Ok(0) => Ok(0),      // real address
        Ok(5) => Ok(5),      // script hash
        Ok(111) => Ok(111),  // testnet address
        Ok(_) => Err(ValidationError::NotBitcoin),
        Err(x) => Err(x)
    }
}

/// Validate litecoin address checksum.
/// Returns the hash version/type if correct and an error otherwise.
pub fn validate_ltc_address(addr: &str) -> Result<usize, ValidationError> {
    match validate_base58_hash(addr) {
        Ok(48) => Ok(48),      // real address
        Ok(111) => Ok(111),    // testnet address
        Ok(_) => Err(ValidationError::NotLitecoin),
        Err(x) => Err(x)
    }
}

#[test]
fn test_decoding() {
    use std::num::from_str_radix;

    assert_eq!(decode_base58("1"), from_int(0));
    assert_eq!(decode_base58("1AaZz"), from_int(0x1C8485));
    assert_eq!(decode_base58("AO"), None);
    assert_eq!(decode_base58("1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i"), from_str_radix("65A16059864A2FDBC7C99A4723A8395BC6F188EBC046B2FF", 16).ok());
}

#[test]
fn test_to_bytes() {
    assert_eq!(bigint_to_bytes(Zero::zero()), vec!(0));
    assert_eq!(bigint_to_bytes(from_int(1).unwrap()), vec!(1));
    assert_eq!(bigint_to_bytes(from_int(256).unwrap()), vec!(1, 0));
}

#[test]
fn test_validate_hash() {
    assert_eq!(validate_base58_hash("17VZNX1SN5NtKa8UQFxwQbFeFc3iqRYhem"), Ok(0));
    assert_eq!(validate_base58_hash("mipcBbFg9gMiCh81Kj8tqqdgoZub1ZJRfn"), Ok(111));
    assert_eq!(validate_base58_hash("17VZNX1SN5NtKa8UQFxwQbFeFc3iqRYheX"), Err(ValidationError::HashMismatch));
    assert_eq!(validate_base58_hash("17VZNX1SN5NtKa8UQFxwQbFeFc3iqRYh  "), Err(ValidationError::InvalidEncoding));
    assert_eq!(validate_base58_hash("1"), Err(ValidationError::HashMismatch));
    assert_eq!(validate_base58_hash(""), Err(ValidationError::TooShort));
}

#[test]
fn test_validate_btc_address() {
    assert_eq!(validate_btc_address("17VZNX1SN5NtKa8UQFxwQbFeFc3iqRYhem"), Ok(0));
    assert_eq!(validate_btc_address("3EktnHQD7RiAE6uzMj2ZifT9YgRrkSgzQX"), Ok(5));
    assert_eq!(validate_btc_address("mipcBbFg9gMiCh81Kj8tqqdgoZub1ZJRfn"), Ok(111));
    assert_eq!(validate_btc_address("LRELGDJyeCPRDXz4Dh1kWorMN9hTBB7CEz"), Err(ValidationError::NotBitcoin));
}

#[test]
fn test_validate_ltc_address() {
    assert_eq!(validate_ltc_address("LRELGDJyeCPRDXz4Dh1kWorMN9hTBB7CEz"), Ok(48));
    assert_eq!(validate_ltc_address("muen9zszN6rVwXaFw48xh6YkdUSjJcfzek"), Ok(111));
    assert_eq!(validate_ltc_address("17VZNX1SN5NtKa8UQFxwQbFeFc3iqRYhem"), Err(ValidationError::NotLitecoin));
}

#[bench]
fn bench_validate_hash(b: &mut test::Bencher) {
    b.iter(|| {
        validate_base58_hash("17VZNX1SN5NtKa8UQFxwQbFeFc3iqRYhem")
    })
}
<|endoftext|>


<commit_before>//! Output Merger (OM) stage description.
//! The final stage in a pipeline that creates pixel colors from
//! the input shader results, depth/stencil information, etc.

use super::graphics::StencilValue;
use super::State;

/// A pixel-wise comparison function.
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum Comparison {
    /// `false`
    Never = 0,
    /// `x < y`
    Less = 1,
    /// `x == y`
    Equal = 2,
    /// `x <= y`
    LessEqual = 3,
    /// `x > y`
    Greater = 4,
    /// `x != y`
    NotEqual = 5,
    /// `x >= y`
    GreaterEqual = 6,
    /// `true`
    Always = 7,
}

bitflags!(
    /// Target output color mask.
    #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
    pub struct ColorMask: u8 {
        /// Red mask
        const RED     = 0x1;
        /// Green mask
        const GREEN   = 0x2;
        /// Blue mask
        const BLUE    = 0x4;
        /// Alpha channel mask
        const ALPHA   = 0x8;
        /// Mask for RGB channels
        const COLOR   = 0x7;
        /// Mask all channels
        const ALL     = 0xF;
        /// Mask no channels.
        const NONE    = 0x0;
    }
);

impl Default for ColorMask {
    fn default() -> Self {
        Self::ALL
    }
}

/// Defines the possible blending factors.
/// During blending, the source or destination fragment may be
/// multiplied by a factor to produce the final result.
#[allow(missing_docs)]
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum Factor {
    Zero = 0,
    One = 1,
    SrcColor = 2,
    OneMinusSrcColor = 3,
    DstColor = 4,
    OneMinusDstColor = 5,
    SrcAlpha = 6,
    OneMinusSrcAlpha = 7,
    DstAlpha = 8,
    OneMinusDstAlpha = 9,
    ConstColor = 10,
    OneMinusConstColor = 11,
    ConstAlpha = 12,
    OneMinusConstAlpha = 13,
    SrcAlphaSaturate = 14,
    Src1Color = 15,
    OneMinusSrc1Color = 16,
    Src1Alpha = 17,
    OneMinusSrc1Alpha = 18,
}

/// Blending operations.
#[allow(missing_docs)]
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum BlendOp {
    /// Adds source and destination.
    /// Source and destination are multiplied by factors before addition.
    Add { src: Factor, dst: Factor },
    /// Subtracts destination from source.
    /// Source and destination are multiplied by factors before subtraction.
    Sub { src: Factor, dst: Factor },
    /// Subtracts source from destination.
    /// Source and destination are multiplied by factors before subtraction.
    RevSub { src: Factor, dst: Factor },
    /// Component-wise minimum value of source and destination.
    Min,
    /// Component-wise maximum value of source and destination.
    Max,
}

impl BlendOp {
    /// Replace the destination value with the source.
    pub const REPLACE: Self = BlendOp::Add {
        src: Factor::One,
        dst: Factor::Zero,
    };
    /// Add the source and destination together.
    pub const ADD: Self = BlendOp::Add {
        src: Factor::One,
        dst: Factor::One,
    };
    /// Alpha blend the source and destination together.
    pub const ALPHA: Self = BlendOp::Add {
        src: Factor::SrcAlpha,
        dst: Factor::OneMinusSrcAlpha,
    };
    /// Alpha blend a premultiplied-alpha source with the destination.
    pub const PREMULTIPLIED_ALPHA: Self = BlendOp::Add {
        src: Factor::One,
        dst: Factor::OneMinusSrcAlpha,
    };
}

/// Specifies whether to use blending, and if so,
/// which operatiosn to use for color and alpha channels.
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum BlendState {
    /// Enabled blending
    On {
        /// The blend operation to use for the color channels.
        color: BlendOp,
        /// The blend operation to use for the alpha channel.
        alpha: BlendOp,
    },
    /// Disabled blending
    Off,
}

impl BlendState {
    /// Additive blending
    pub const ADD: Self = BlendState::On {
        color: BlendOp::ADD,
        alpha: BlendOp::ADD,
    };
    /// Multiplicative blending
    pub const MULTIPLY: Self = BlendState::On {
        color: BlendOp::Add {
            src: Factor::Zero,
            dst: Factor::SrcColor,
        },
        alpha: BlendOp::Add {
            src: Factor::Zero,
            dst: Factor::SrcAlpha,
        },
    };
    /// Alpha blending.
    pub const ALPHA: Self = BlendState::On {
        color: BlendOp::ALPHA,
        alpha: BlendOp::PREMULTIPLIED_ALPHA,
    };
    /// Pre-multiplied alpha blending.
    pub const PREMULTIPLIED_ALPHA: Self = BlendState::On {
        color: BlendOp::PREMULTIPLIED_ALPHA,
        alpha: BlendOp::PREMULTIPLIED_ALPHA,
    };
}

impl Default for BlendState {
    fn default() -> Self {
        BlendState::Off
    }
}

/// PSO color target descriptor.
#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct ColorBlendDesc(pub ColorMask, pub BlendState);

impl ColorBlendDesc {
    /// Empty blend descriptor just writes out the color without blending.
    pub const EMPTY: Self = ColorBlendDesc(ColorMask::ALL, BlendState::Off);
}

/// Depth test state.
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum DepthTest {
    /// Enabled depth testing.
    On {
        /// Comparison function to use.
        fun: Comparison,
        /// Specify whether to write to the depth buffer or not.
        write: bool,
    },
    /// Disabled depth testing.
    Off,
}

impl Default for DepthTest {
    fn default() -> Self {
        DepthTest::Off
    }
}

impl DepthTest {
    /// A depth test that always fails.
    pub const FAIL: Self = DepthTest::On {
        fun: Comparison::Never,
        write: false,
    };
    /// A depth test that always succeeds but doesn't
    /// write to the depth buffer
    // DOC TODO: Not a terribly helpful description there...
    pub const PASS_TEST: Self = DepthTest::On {
        fun: Comparison::Always,
        write: false,
    };
    /// A depth test that always succeeds and writes its result
    /// to the depth buffer.
    pub const PASS_WRITE: Self = DepthTest::On {
        fun: Comparison::Always,
        write: true,
    };
}

/// The operation to use for stencil masking.
#[repr(u8)]
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum StencilOp {
    /// Keep the current value in the stencil buffer (no change).
    Keep = 0,
    /// Set the value in the stencil buffer to zero.
    Zero = 1,
    /// Set the stencil buffer value to `reference` from `StencilFace`.
    Replace = 2,
    /// Increment the stencil buffer value, clamping to its maximum value.
    IncrementClamp = 3,
    /// Decrement the stencil buffer value, clamping to its minimum value.
    DecrementClamp = 4,
    /// Bitwise invert the current value in the stencil buffer.
    Invert = 5,
    /// Increment the stencil buffer value, wrapping around to 0 on overflow.
    IncrementWrap = 6,
    /// Decrement the stencil buffer value, wrapping around to the maximum value on overflow.
    DecrementWrap = 7,
}

/// Complete stencil state for a given side of a face.
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct StencilFace {
    /// Comparison function to use to determine if the stencil test passes.
    pub fun: Comparison,
    /// A mask that is ANDd with both the stencil buffer value and the reference value when they
    /// are read before doing the stencil test.
    pub mask_read: State<StencilValue>,
    /// A mask that is ANDd with the stencil value before writing to the stencil buffer.
    pub mask_write: State<StencilValue>,
    /// What operation to do if the stencil test fails.
    pub op_fail: StencilOp,
    /// What operation to do if the stencil test passes but the depth test fails.
    pub op_depth_fail: StencilOp,
    /// What operation to do if both the depth and stencil test pass.
    pub op_pass: StencilOp,
    /// The reference value used for stencil tests.
    pub reference: State<StencilValue>,
}

impl Default for StencilFace {
    fn default() -> StencilFace {
        StencilFace {
            fun: Comparison::Never,
            mask_read: State::Static(!0),
            mask_write: State::Static(!0),
            op_fail: StencilOp::Keep,
            op_depth_fail: StencilOp::Keep,
            op_pass: StencilOp::Keep,
            reference: State::Static(0),
        }
    }
}

/// Defines a stencil test. Stencil testing is an operation
/// performed to cull fragments;
/// the new fragment is tested against the value held in the
/// stencil buffer, and if the test fails the fragment is
/// discarded.
#[allow(missing_docs)]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum StencilTest {
    On {
        front: StencilFace,
        back: StencilFace,
    },
    Off,
}

impl Default for StencilTest {
    fn default() -> Self {
        StencilTest::Off
    }
}

/// PSO depth-stencil target descriptor.
#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct DepthStencilDesc {
    /// Optional depth testing/writing.
    pub depth: DepthTest,
    /// Enable depth bounds testing.
    pub depth_bounds: bool,
    /// Stencil test/write.
    pub stencil: StencilTest,
}

bitflags!(
    /// Face.
    #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
    pub struct Face: u32 {
        /// Empty face. TODO: remove when constexpr are stabilized to use empty()
        const NONE = 0x0;
        /// Front face.
        const FRONT = 0x1;
        /// Back face.
        const BACK = 0x2;
    }
);
<commit_msg>[hal] Fix typo in documentation<commit_after>//! Output Merger (OM) stage description.
//! The final stage in a pipeline that creates pixel colors from
//! the input shader results, depth/stencil information, etc.

use super::graphics::StencilValue;
use super::State;

/// A pixel-wise comparison function.
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum Comparison {
    /// `false`
    Never = 0,
    /// `x < y`
    Less = 1,
    /// `x == y`
    Equal = 2,
    /// `x <= y`
    LessEqual = 3,
    /// `x > y`
    Greater = 4,
    /// `x != y`
    NotEqual = 5,
    /// `x >= y`
    GreaterEqual = 6,
    /// `true`
    Always = 7,
}

bitflags!(
    /// Target output color mask.
    #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
    pub struct ColorMask: u8 {
        /// Red mask
        const RED     = 0x1;
        /// Green mask
        const GREEN   = 0x2;
        /// Blue mask
        const BLUE    = 0x4;
        /// Alpha channel mask
        const ALPHA   = 0x8;
        /// Mask for RGB channels
        const COLOR   = 0x7;
        /// Mask all channels
        const ALL     = 0xF;
        /// Mask no channels.
        const NONE    = 0x0;
    }
);

impl Default for ColorMask {
    fn default() -> Self {
        Self::ALL
    }
}

/// Defines the possible blending factors.
/// During blending, the source or destination fragment may be
/// multiplied by a factor to produce the final result.
#[allow(missing_docs)]
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum Factor {
    Zero = 0,
    One = 1,
    SrcColor = 2,
    OneMinusSrcColor = 3,
    DstColor = 4,
    OneMinusDstColor = 5,
    SrcAlpha = 6,
    OneMinusSrcAlpha = 7,
    DstAlpha = 8,
    OneMinusDstAlpha = 9,
    ConstColor = 10,
    OneMinusConstColor = 11,
    ConstAlpha = 12,
    OneMinusConstAlpha = 13,
    SrcAlphaSaturate = 14,
    Src1Color = 15,
    OneMinusSrc1Color = 16,
    Src1Alpha = 17,
    OneMinusSrc1Alpha = 18,
}

/// Blending operations.
#[allow(missing_docs)]
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum BlendOp {
    /// Adds source and destination.
    /// Source and destination are multiplied by factors before addition.
    Add { src: Factor, dst: Factor },
    /// Subtracts destination from source.
    /// Source and destination are multiplied by factors before subtraction.
    Sub { src: Factor, dst: Factor },
    /// Subtracts source from destination.
    /// Source and destination are multiplied by factors before subtraction.
    RevSub { src: Factor, dst: Factor },
    /// Component-wise minimum value of source and destination.
    Min,
    /// Component-wise maximum value of source and destination.
    Max,
}

impl BlendOp {
    /// Replace the destination value with the source.
    pub const REPLACE: Self = BlendOp::Add {
        src: Factor::One,
        dst: Factor::Zero,
    };
    /// Add the source and destination together.
    pub const ADD: Self = BlendOp::Add {
        src: Factor::One,
        dst: Factor::One,
    };
    /// Alpha blend the source and destination together.
    pub const ALPHA: Self = BlendOp::Add {
        src: Factor::SrcAlpha,
        dst: Factor::OneMinusSrcAlpha,
    };
    /// Alpha blend a premultiplied-alpha source with the destination.
    pub const PREMULTIPLIED_ALPHA: Self = BlendOp::Add {
        src: Factor::One,
        dst: Factor::OneMinusSrcAlpha,
    };
}

/// Specifies whether to use blending, and if so,
/// which operations to use for color and alpha channels.
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum BlendState {
    /// Enabled blending
    On {
        /// The blend operation to use for the color channels.
        color: BlendOp,
        /// The blend operation to use for the alpha channel.
        alpha: BlendOp,
    },
    /// Disabled blending
    Off,
}

impl BlendState {
    /// Additive blending
    pub const ADD: Self = BlendState::On {
        color: BlendOp::ADD,
        alpha: BlendOp::ADD,
    };
    /// Multiplicative blending
    pub const MULTIPLY: Self = BlendState::On {
        color: BlendOp::Add {
            src: Factor::Zero,
            dst: Factor::SrcColor,
        },
        alpha: BlendOp::Add {
            src: Factor::Zero,
            dst: Factor::SrcAlpha,
        },
    };
    /// Alpha blending.
    pub const ALPHA: Self = BlendState::On {
        color: BlendOp::ALPHA,
        alpha: BlendOp::PREMULTIPLIED_ALPHA,
    };
    /// Pre-multiplied alpha blending.
    pub const PREMULTIPLIED_ALPHA: Self = BlendState::On {
        color: BlendOp::PREMULTIPLIED_ALPHA,
        alpha: BlendOp::PREMULTIPLIED_ALPHA,
    };
}

impl Default for BlendState {
    fn default() -> Self {
        BlendState::Off
    }
}

/// PSO color target descriptor.
#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct ColorBlendDesc(pub ColorMask, pub BlendState);

impl ColorBlendDesc {
    /// Empty blend descriptor just writes out the color without blending.
    pub const EMPTY: Self = ColorBlendDesc(ColorMask::ALL, BlendState::Off);
}

/// Depth test state.
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum DepthTest {
    /// Enabled depth testing.
    On {
        /// Comparison function to use.
        fun: Comparison,
        /// Specify whether to write to the depth buffer or not.
        write: bool,
    },
    /// Disabled depth testing.
    Off,
}

impl Default for DepthTest {
    fn default() -> Self {
        DepthTest::Off
    }
}

impl DepthTest {
    /// A depth test that always fails.
    pub const FAIL: Self = DepthTest::On {
        fun: Comparison::Never,
        write: false,
    };
    /// A depth test that always succeeds but doesn't
    /// write to the depth buffer
    // DOC TODO: Not a terribly helpful description there...
    pub const PASS_TEST: Self = DepthTest::On {
        fun: Comparison::Always,
        write: false,
    };
    /// A depth test that always succeeds and writes its result
    /// to the depth buffer.
    pub const PASS_WRITE: Self = DepthTest::On {
        fun: Comparison::Always,
        write: true,
    };
}

/// The operation to use for stencil masking.
#[repr(u8)]
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum StencilOp {
    /// Keep the current value in the stencil buffer (no change).
    Keep = 0,
    /// Set the value in the stencil buffer to zero.
    Zero = 1,
    /// Set the stencil buffer value to `reference` from `StencilFace`.
    Replace = 2,
    /// Increment the stencil buffer value, clamping to its maximum value.
    IncrementClamp = 3,
    /// Decrement the stencil buffer value, clamping to its minimum value.
    DecrementClamp = 4,
    /// Bitwise invert the current value in the stencil buffer.
    Invert = 5,
    /// Increment the stencil buffer value, wrapping around to 0 on overflow.
    IncrementWrap = 6,
    /// Decrement the stencil buffer value, wrapping around to the maximum value on overflow.
    DecrementWrap = 7,
}

/// Complete stencil state for a given side of a face.
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct StencilFace {
    /// Comparison function to use to determine if the stencil test passes.
    pub fun: Comparison,
    /// A mask that is ANDd with both the stencil buffer value and the reference value when they
    /// are read before doing the stencil test.
    pub mask_read: State<StencilValue>,
    /// A mask that is ANDd with the stencil value before writing to the stencil buffer.
    pub mask_write: State<StencilValue>,
    /// What operation to do if the stencil test fails.
    pub op_fail: StencilOp,
    /// What operation to do if the stencil test passes but the depth test fails.
    pub op_depth_fail: StencilOp,
    /// What operation to do if both the depth and stencil test pass.
    pub op_pass: StencilOp,
    /// The reference value used for stencil tests.
    pub reference: State<StencilValue>,
}

impl Default for StencilFace {
    fn default() -> StencilFace {
        StencilFace {
            fun: Comparison::Never,
            mask_read: State::Static(!0),
            mask_write: State::Static(!0),
            op_fail: StencilOp::Keep,
            op_depth_fail: StencilOp::Keep,
            op_pass: StencilOp::Keep,
            reference: State::Static(0),
        }
    }
}

/// Defines a stencil test. Stencil testing is an operation
/// performed to cull fragments;
/// the new fragment is tested against the value held in the
/// stencil buffer, and if the test fails the fragment is
/// discarded.
#[allow(missing_docs)]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum StencilTest {
    On {
        front: StencilFace,
        back: StencilFace,
    },
    Off,
}

impl Default for StencilTest {
    fn default() -> Self {
        StencilTest::Off
    }
}

/// PSO depth-stencil target descriptor.
#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct DepthStencilDesc {
    /// Optional depth testing/writing.
    pub depth: DepthTest,
    /// Enable depth bounds testing.
    pub depth_bounds: bool,
    /// Stencil test/write.
    pub stencil: StencilTest,
}

bitflags!(
    /// Face.
    #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
    pub struct Face: u32 {
        /// Empty face. TODO: remove when constexpr are stabilized to use empty()
        const NONE = 0x0;
        /// Front face.
        const FRONT = 0x1;
        /// Back face.
        const BACK = 0x2;
    }
);
<|endoftext|>


<commit_before>use crate::ops::{Deref, DerefMut};
use crate::ptr;

/// A wrapper to inhibit compiler from automatically calling `T`’s destructor.
///
/// This wrapper is 0-cost.
///
/// `ManuallyDrop<T>` is subject to the same layout optimizations as `T`.
/// As a consequence, it has *no effect* on the assumptions that the compiler makes
/// about its contents. For example, initializing a `ManuallyDrop<&mut T>`
/// with [`mem::zeroed`] is undefined behavior.
/// If you need to handle uninitialized data, use [`MaybeUninit<T>`] instead.
///
/// # Examples
///
/// This wrapper can be used to enforce a particular drop order on fields, regardless
/// of how they are defined in the struct:
///
/// ```rust
/// use std::mem::ManuallyDrop;
/// struct Peach;
/// struct Banana;
/// struct Melon;
/// struct FruitBox {
///     // Immediately clear there’s something non-trivial going on with these fields.
///     peach: ManuallyDrop<Peach>,
///     melon: Melon, // Field that’s independent of the other two.
///     banana: ManuallyDrop<Banana>,
/// }
///
/// impl Drop for FruitBox {
///     fn drop(&mut self) {
///         unsafe {
///             // Explicit ordering in which field destructors are run specified in the intuitive
///             // location – the destructor of the structure containing the fields.
///             // Moreover, one can now reorder fields within the struct however much they want.
///             ManuallyDrop::drop(&mut self.peach);
///             ManuallyDrop::drop(&mut self.banana);
///         }
///         // After destructor for `FruitBox` runs (this function), the destructor for Melon gets
///         // invoked in the usual manner, as it is not wrapped in `ManuallyDrop`.
///     }
/// }
/// ```
///
/// However, care should be taken when using this pattern as it can lead to *leak amplification*.
/// In this example, if the `Drop` implementation for `Peach` were to panic, the `banana` field
/// would also be leaked.
///
/// In contrast, the automatically-generated compiler drop implementation would have ensured
/// that all fields are dropped even in the presence of panics. This is especially important when
/// working with [pinned] data, where reusing the memory without calling the destructor could lead
/// to Undefined Behaviour.
///
/// [`mem::zeroed`]: fn.zeroed.html
/// [`MaybeUninit<T>`]: union.MaybeUninit.html
/// [pinned]: ../pin/index.html
#[stable(feature = "manually_drop", since = "1.20.0")]
#[lang = "manually_drop"]
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct ManuallyDrop<T: ?Sized> {
    value: T,
}

impl<T> ManuallyDrop<T> {
    /// Wrap a value to be manually dropped.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use std::mem::ManuallyDrop;
    /// ManuallyDrop::new(Box::new(()));
    /// ```
    #[stable(feature = "manually_drop", since = "1.20.0")]
    #[rustc_const_stable(feature = "const_manually_drop", since = "1.36.0")]
    #[inline(always)]
    pub const fn new(value: T) -> ManuallyDrop<T> {
        ManuallyDrop { value }
    }

    /// Extracts the value from the `ManuallyDrop` container.
    ///
    /// This allows the value to be dropped again.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use std::mem::ManuallyDrop;
    /// let x = ManuallyDrop::new(Box::new(()));
    /// let _: Box<()> = ManuallyDrop::into_inner(x); // This drops the `Box`.
    /// ```
    #[stable(feature = "manually_drop", since = "1.20.0")]
    #[rustc_const_stable(feature = "const_manually_drop", since = "1.36.0")]
    #[inline(always)]
    pub const fn into_inner(slot: ManuallyDrop<T>) -> T {
        slot.value
    }

    /// Takes the value from the `ManuallyDrop<T>` container out.
    ///
    /// This method is primarily intended for moving out values in drop.
    /// Instead of using [`ManuallyDrop::drop`] to manually drop the value,
    /// you can use this method to take the value and use it however desired.
    ///
    /// Whenever possible, it is preferable to use [`into_inner`][`ManuallyDrop::into_inner`]
    /// instead, which prevents duplicating the content of the `ManuallyDrop<T>`.
    ///
    /// # Safety
    ///
    /// This function semantically moves out the contained value without preventing further usage,
    /// leaving the state of this container unchanged.
    /// It is your responsibility to ensure that this `ManuallyDrop` is not used again.
    ///
    /// [`ManuallyDrop::drop`]: #method.drop
    /// [`ManuallyDrop::into_inner`]: #method.into_inner
    #[must_use = "if you don't need the value, you can use `ManuallyDrop::drop` instead"]
    #[stable(feature = "manually_drop_take", since = "1.42.0")]
    #[inline]
    pub unsafe fn take(slot: &mut ManuallyDrop<T>) -> T {
        ptr::read(&slot.value)
    }
}

impl<T: ?Sized> ManuallyDrop<T> {
    /// Manually drops the contained value. This is exactly equivalent to calling
    /// [`ptr::drop_in_place`] with a pointer to the contained value. As such, unless
    /// the contained value is a packed struct, the destructor will be called in-place
    /// without moving the value, and thus can be used to safely drop [pinned] data.
    ///
    /// If you have ownership of the value, you can use [`ManuallyDrop::into_inner`] instead.
    ///
    /// # Safety
    ///
    /// This function runs the destructor of the contained value. Other than changes made by
    /// the destructor itself, the memory is left unchanged, and so as far as the compiler is
    /// concerned still holds a bit-pattern which is valid for the type `T`.
    ///
    /// However, this "zombie" value should not be exposed to safe code, and this function
    /// should not be called more than once. To use a value after it's been dropped, or drop
    /// a value multiple times, can cause Undefined Behavior (depending on what `drop` does).
    /// This is normally prevented by the type system, but users of `ManuallyDrop` must
    /// uphold those guarantees without assistance from the compiler.
    ///
    /// [`ManuallyDrop::into_inner`]: #method.into_inner
    /// [`ptr::drop_in_place`]: ../ptr/fn.drop_in_place.html
    /// [pinned]: ../pin/index.html
    #[stable(feature = "manually_drop", since = "1.20.0")]
    #[inline]
    pub unsafe fn drop(slot: &mut ManuallyDrop<T>) {
        ptr::drop_in_place(&mut slot.value)
    }
}

#[stable(feature = "manually_drop", since = "1.20.0")]
impl<T: ?Sized> Deref for ManuallyDrop<T> {
    type Target = T;
    #[inline(always)]
    fn deref(&self) -> &T {
        &self.value
    }
}

#[stable(feature = "manually_drop", since = "1.20.0")]
impl<T: ?Sized> DerefMut for ManuallyDrop<T> {
    #[inline(always)]
    fn deref_mut(&mut self) -> &mut T {
        &mut self.value
    }
}
<commit_msg>Rollup merge of #72277 - RalfJung:manually-drop-docs, r=Mark-Simulacrum<commit_after>use crate::ops::{Deref, DerefMut};
use crate::ptr;

/// A wrapper to inhibit compiler from automatically calling `T`’s destructor.
/// This wrapper is 0-cost.
///
/// `ManuallyDrop<T>` is subject to the same layout optimizations as `T`.
/// As a consequence, it has *no effect* on the assumptions that the compiler makes
/// about its contents. For example, initializing a `ManuallyDrop<&mut T>`
/// with [`mem::zeroed`] is undefined behavior.
/// If you need to handle uninitialized data, use [`MaybeUninit<T>`] instead.
///
/// Note that accessing the value inside a `ManuallyDrop<T>` is safe.
/// This means that a `ManuallyDrop<T>` whose content has been dropped must not
/// be exposed through a public safe API.
/// Correspondingly, `ManuallyDrop::drop` is unsafe.
///
/// # Examples
///
/// This wrapper can be used to enforce a particular drop order on fields, regardless
/// of how they are defined in the struct:
///
/// ```rust
/// use std::mem::ManuallyDrop;
/// struct Peach;
/// struct Banana;
/// struct Melon;
/// struct FruitBox {
///     // Immediately clear there’s something non-trivial going on with these fields.
///     peach: ManuallyDrop<Peach>,
///     melon: Melon, // Field that’s independent of the other two.
///     banana: ManuallyDrop<Banana>,
/// }
///
/// impl Drop for FruitBox {
///     fn drop(&mut self) {
///         unsafe {
///             // Explicit ordering in which field destructors are run specified in the intuitive
///             // location – the destructor of the structure containing the fields.
///             // Moreover, one can now reorder fields within the struct however much they want.
///             ManuallyDrop::drop(&mut self.peach);
///             ManuallyDrop::drop(&mut self.banana);
///         }
///         // After destructor for `FruitBox` runs (this function), the destructor for Melon gets
///         // invoked in the usual manner, as it is not wrapped in `ManuallyDrop`.
///     }
/// }
/// ```
///
/// However, care should be taken when using this pattern as it can lead to *leak amplification*.
/// In this example, if the `Drop` implementation for `Peach` were to panic, the `banana` field
/// would also be leaked.
///
/// In contrast, the automatically-generated compiler drop implementation would have ensured
/// that all fields are dropped even in the presence of panics. This is especially important when
/// working with [pinned] data, where reusing the memory without calling the destructor could lead
/// to Undefined Behaviour.
///
/// [`mem::zeroed`]: fn.zeroed.html
/// [`MaybeUninit<T>`]: union.MaybeUninit.html
/// [pinned]: ../pin/index.html
#[stable(feature = "manually_drop", since = "1.20.0")]
#[lang = "manually_drop"]
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct ManuallyDrop<T: ?Sized> {
    value: T,
}

impl<T> ManuallyDrop<T> {
    /// Wrap a value to be manually dropped.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use std::mem::ManuallyDrop;
    /// ManuallyDrop::new(Box::new(()));
    /// ```
    #[stable(feature = "manually_drop", since = "1.20.0")]
    #[rustc_const_stable(feature = "const_manually_drop", since = "1.36.0")]
    #[inline(always)]
    pub const fn new(value: T) -> ManuallyDrop<T> {
        ManuallyDrop { value }
    }

    /// Extracts the value from the `ManuallyDrop` container.
    ///
    /// This allows the value to be dropped again.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use std::mem::ManuallyDrop;
    /// let x = ManuallyDrop::new(Box::new(()));
    /// let _: Box<()> = ManuallyDrop::into_inner(x); // This drops the `Box`.
    /// ```
    #[stable(feature = "manually_drop", since = "1.20.0")]
    #[rustc_const_stable(feature = "const_manually_drop", since = "1.36.0")]
    #[inline(always)]
    pub const fn into_inner(slot: ManuallyDrop<T>) -> T {
        slot.value
    }

    /// Takes the value from the `ManuallyDrop<T>` container out.
    ///
    /// This method is primarily intended for moving out values in drop.
    /// Instead of using [`ManuallyDrop::drop`] to manually drop the value,
    /// you can use this method to take the value and use it however desired.
    ///
    /// Whenever possible, it is preferable to use [`into_inner`][`ManuallyDrop::into_inner`]
    /// instead, which prevents duplicating the content of the `ManuallyDrop<T>`.
    ///
    /// # Safety
    ///
    /// This function semantically moves out the contained value without preventing further usage,
    /// leaving the state of this container unchanged.
    /// It is your responsibility to ensure that this `ManuallyDrop` is not used again.
    ///
    /// [`ManuallyDrop::drop`]: #method.drop
    /// [`ManuallyDrop::into_inner`]: #method.into_inner
    #[must_use = "if you don't need the value, you can use `ManuallyDrop::drop` instead"]
    #[stable(feature = "manually_drop_take", since = "1.42.0")]
    #[inline]
    pub unsafe fn take(slot: &mut ManuallyDrop<T>) -> T {
        ptr::read(&slot.value)
    }
}

impl<T: ?Sized> ManuallyDrop<T> {
    /// Manually drops the contained value. This is exactly equivalent to calling
    /// [`ptr::drop_in_place`] with a pointer to the contained value. As such, unless
    /// the contained value is a packed struct, the destructor will be called in-place
    /// without moving the value, and thus can be used to safely drop [pinned] data.
    ///
    /// If you have ownership of the value, you can use [`ManuallyDrop::into_inner`] instead.
    ///
    /// # Safety
    ///
    /// This function runs the destructor of the contained value. Other than changes made by
    /// the destructor itself, the memory is left unchanged, and so as far as the compiler is
    /// concerned still holds a bit-pattern which is valid for the type `T`.
    ///
    /// However, this "zombie" value should not be exposed to safe code, and this function
    /// should not be called more than once. To use a value after it's been dropped, or drop
    /// a value multiple times, can cause Undefined Behavior (depending on what `drop` does).
    /// This is normally prevented by the type system, but users of `ManuallyDrop` must
    /// uphold those guarantees without assistance from the compiler.
    ///
    /// [`ManuallyDrop::into_inner`]: #method.into_inner
    /// [`ptr::drop_in_place`]: ../ptr/fn.drop_in_place.html
    /// [pinned]: ../pin/index.html
    #[stable(feature = "manually_drop", since = "1.20.0")]
    #[inline]
    pub unsafe fn drop(slot: &mut ManuallyDrop<T>) {
        ptr::drop_in_place(&mut slot.value)
    }
}

#[stable(feature = "manually_drop", since = "1.20.0")]
impl<T: ?Sized> Deref for ManuallyDrop<T> {
    type Target = T;
    #[inline(always)]
    fn deref(&self) -> &T {
        &self.value
    }
}

#[stable(feature = "manually_drop", since = "1.20.0")]
impl<T: ?Sized> DerefMut for ManuallyDrop<T> {
    #[inline(always)]
    fn deref_mut(&mut self) -> &mut T {
        &mut self.value
    }
}
<|endoftext|>