<commit_before>use smallvec::smallvec;

use crate::traits::{Obligation, ObligationCause, PredicateObligation};
use rustc_data_structures::fx::FxHashSet;
use rustc_middle::ty::outlives::Component;
use rustc_middle::ty::{self, ToPredicate, TyCtxt, WithConstness};
use rustc_span::symbol::Ident;

pub fn anonymize_predicate<'tcx>(
    tcx: TyCtxt<'tcx>,
    pred: ty::Predicate<'tcx>,
) -> ty::Predicate<'tcx> {
    match *pred.kind() {
        ty::PredicateKind::ForAll(binder) => {
            let new = ty::PredicateKind::ForAll(tcx.anonymize_late_bound_regions(binder));
            tcx.reuse_or_mk_predicate(pred, new)
        }
        ty::PredicateKind::Atom(_) => pred,
    }
}

struct PredicateSet<'tcx> {
    tcx: TyCtxt<'tcx>,
    set: FxHashSet<ty::Predicate<'tcx>>,
}

impl PredicateSet<'tcx> {
    fn new(tcx: TyCtxt<'tcx>) -> Self {
        Self { tcx, set: Default::default() }
    }

    fn insert(&mut self, pred: ty::Predicate<'tcx>) -> bool {
        // We have to be careful here because we want
        //
        //    for<'a> Foo<&'a i32>
        //
        // and
        //
        //    for<'b> Foo<&'b i32>
        //
        // to be considered equivalent. So normalize all late-bound
        // regions before we throw things into the underlying set.
        self.set.insert(anonymize_predicate(self.tcx, pred))
    }
}

impl Extend<ty::Predicate<'tcx>> for PredicateSet<'tcx> {
    fn extend<I: IntoIterator<Item = ty::Predicate<'tcx>>>(&mut self, iter: I) {
        for pred in iter {
            self.insert(pred);
        }
    }

    fn extend_one(&mut self, pred: ty::Predicate<'tcx>) {
        self.insert(pred);
    }

    fn extend_reserve(&mut self, additional: usize) {
        Extend::<ty::Predicate<'tcx>>::extend_reserve(&mut self.set, additional);
    }
}

///////////////////////////////////////////////////////////////////////////
// `Elaboration` iterator
///////////////////////////////////////////////////////////////////////////

/// "Elaboration" is the process of identifying all the predicates that
/// are implied by a source predicate. Currently, this basically means
/// walking the "supertraits" and other similar assumptions. For example,
/// if we know that `T: Ord`, the elaborator would deduce that `T: PartialOrd`
/// holds as well. Similarly, if we have `trait Foo: 'static`, and we know that
/// `T: Foo`, then we know that `T: 'static`.
pub struct Elaborator<'tcx> {
    stack: Vec<PredicateObligation<'tcx>>,
    visited: PredicateSet<'tcx>,
}

pub fn elaborate_trait_ref<'tcx>(
    tcx: TyCtxt<'tcx>,
    trait_ref: ty::PolyTraitRef<'tcx>,
) -> Elaborator<'tcx> {
    elaborate_predicates(tcx, std::iter::once(trait_ref.without_const().to_predicate(tcx)))
}

pub fn elaborate_trait_refs<'tcx>(
    tcx: TyCtxt<'tcx>,
    trait_refs: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
) -> Elaborator<'tcx> {
    let predicates = trait_refs.map(|trait_ref| trait_ref.without_const().to_predicate(tcx));
    elaborate_predicates(tcx, predicates)
}

/// A specialized variant of `elaborate_trait_refs` that only elaborates trait references that may
/// define the given associated type `assoc_name`. It uses the
/// `super_predicates_that_define_assoc_type` query to avoid enumerating super-predicates that
/// aren't related to `assoc_item`.  This is used when resolving types like `Self::Item` or
/// `T::Item` and helps to avoid cycle errors (see e.g. #35237).
pub fn elaborate_trait_refs_that_define_assoc_type<'tcx>(
    tcx: TyCtxt<'tcx>,
    trait_refs: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
    assoc_name: Ident,
) -> FxHashSet<ty::PolyTraitRef<'tcx>> {
    let mut stack: Vec<_> = trait_refs.collect();
    let mut trait_refs = FxHashSet::default();

    while let Some(trait_ref) = stack.pop() {
        if trait_refs.insert(trait_ref) {
            let super_predicates =
                tcx.super_predicates_that_define_assoc_type((trait_ref.def_id(), Some(assoc_name)));
            for (super_predicate, _) in super_predicates.predicates {
                let bound_predicate = super_predicate.bound_atom();
                let subst_predicate = super_predicate
                    .subst_supertrait(tcx, &bound_predicate.rebind(trait_ref.skip_binder()));
                if let Some(binder) = subst_predicate.to_opt_poly_trait_ref() {
                    stack.push(binder.value);
                }
            }
        }
    }

    trait_refs
}

pub fn elaborate_predicates<'tcx>(
    tcx: TyCtxt<'tcx>,
    predicates: impl Iterator<Item = ty::Predicate<'tcx>>,
) -> Elaborator<'tcx> {
    let obligations = predicates
        .map(|predicate| {
            predicate_obligation(predicate, ty::ParamEnv::empty(), ObligationCause::dummy())
        })
        .collect();
    elaborate_obligations(tcx, obligations)
}

pub fn elaborate_obligations<'tcx>(
    tcx: TyCtxt<'tcx>,
    mut obligations: Vec<PredicateObligation<'tcx>>,
) -> Elaborator<'tcx> {
    let mut visited = PredicateSet::new(tcx);
    obligations.retain(|obligation| visited.insert(obligation.predicate));
    Elaborator { stack: obligations, visited }
}

fn predicate_obligation<'tcx>(
    predicate: ty::Predicate<'tcx>,
    param_env: ty::ParamEnv<'tcx>,
    cause: ObligationCause<'tcx>,
) -> PredicateObligation<'tcx> {
    Obligation { cause, param_env, recursion_depth: 0, predicate }
}

impl Elaborator<'tcx> {
    pub fn filter_to_traits(self) -> FilterToTraits<Self> {
        FilterToTraits::new(self)
    }

    fn elaborate(&mut self, obligation: &PredicateObligation<'tcx>) {
        let tcx = self.visited.tcx;

        let bound_predicate = obligation.predicate.bound_atom();
        match bound_predicate.skip_binder() {
            ty::PredicateAtom::Trait(data, _) => {
                // Get predicates declared on the trait.
                let predicates = tcx.super_predicates_of(data.def_id());

                let obligations = predicates.predicates.iter().map(|&(pred, _)| {
                    predicate_obligation(
                        pred.subst_supertrait(tcx, &bound_predicate.rebind(data.trait_ref)),
                        obligation.param_env,
                        obligation.cause.clone(),
                    )
                });
                debug!("super_predicates: data={:?}", data);

                // Only keep those bounds that we haven't already seen.
                // This is necessary to prevent infinite recursion in some
                // cases. One common case is when people define
                // `trait Sized: Sized { }` rather than `trait Sized { }`.
                let visited = &mut self.visited;
                let obligations = obligations.filter(|o| visited.insert(o.predicate));

                self.stack.extend(obligations);
            }
            ty::PredicateAtom::WellFormed(..) => {
                // Currently, we do not elaborate WF predicates,
                // although we easily could.
            }
            ty::PredicateAtom::ObjectSafe(..) => {
                // Currently, we do not elaborate object-safe
                // predicates.
            }
            ty::PredicateAtom::Subtype(..) => {
                // Currently, we do not "elaborate" predicates like `X <: Y`,
                // though conceivably we might.
            }
            ty::PredicateAtom::Projection(..) => {
                // Nothing to elaborate in a projection predicate.
            }
            ty::PredicateAtom::ClosureKind(..) => {
                // Nothing to elaborate when waiting for a closure's kind to be inferred.
            }
            ty::PredicateAtom::ConstEvaluatable(..) => {
                // Currently, we do not elaborate const-evaluatable
                // predicates.
            }
            ty::PredicateAtom::ConstEquate(..) => {
                // Currently, we do not elaborate const-equate
                // predicates.
            }
            ty::PredicateAtom::RegionOutlives(..) => {
                // Nothing to elaborate from `'a: 'b`.
            }
            ty::PredicateAtom::TypeOutlives(ty::OutlivesPredicate(ty_max, r_min)) => {
                // We know that `T: 'a` for some type `T`. We can
                // often elaborate this. For example, if we know that
                // `[U]: 'a`, that implies that `U: 'a`. Similarly, if
                // we know `&'a U: 'b`, then we know that `'a: 'b` and
                // `U: 'b`.
                //
                // We can basically ignore bound regions here. So for
                // example `for<'c> Foo<'a,'c>: 'b` can be elaborated to
                // `'a: 'b`.

                // Ignore `for<'a> T: 'a` -- we might in the future
                // consider this as evidence that `T: 'static`, but
                // I'm a bit wary of such constructions and so for now
                // I want to be conservative. --nmatsakis
                if r_min.is_late_bound() {
                    return;
                }

                let visited = &mut self.visited;
                let mut components = smallvec![];
                tcx.push_outlives_components(ty_max, &mut components);
                self.stack.extend(
                    components
                        .into_iter()
                        .filter_map(|component| match component {
                            Component::Region(r) => {
                                if r.is_late_bound() {
                                    None
                                } else {
                                    Some(ty::PredicateAtom::RegionOutlives(ty::OutlivesPredicate(
                                        r, r_min,
                                    )))
                                }
                            }

                            Component::Param(p) => {
                                let ty = tcx.mk_ty_param(p.index, p.name);
                                Some(ty::PredicateAtom::TypeOutlives(ty::OutlivesPredicate(
                                    ty, r_min,
                                )))
                            }

                            Component::UnresolvedInferenceVariable(_) => None,

                            Component::Projection(_) | Component::EscapingProjection(_) => {
                                // We can probably do more here. This
                                // corresponds to a case like `<T as
                                // Foo<'a>>::U: 'b`.
                                None
                            }
                        })
                        .map(|predicate_kind| predicate_kind.to_predicate(tcx))
                        .filter(|&predicate| visited.insert(predicate))
                        .map(|predicate| {
                            predicate_obligation(
                                predicate,
                                obligation.param_env,
                                obligation.cause.clone(),
                            )
                        }),
                );
            }
            ty::PredicateAtom::TypeWellFormedFromEnv(..) => {
                // Nothing to elaborate
            }
        }
    }
}

impl Iterator for Elaborator<'tcx> {
    type Item = PredicateObligation<'tcx>;

    fn size_hint(&self) -> (usize, Option<usize>) {
        (self.stack.len(), None)
    }

    fn next(&mut self) -> Option<Self::Item> {
        // Extract next item from top-most stack frame, if any.
        if let Some(obligation) = self.stack.pop() {
            self.elaborate(&obligation);
            Some(obligation)
        } else {
            None
        }
    }
}

///////////////////////////////////////////////////////////////////////////
// Supertrait iterator
///////////////////////////////////////////////////////////////////////////

pub type Supertraits<'tcx> = FilterToTraits<Elaborator<'tcx>>;

pub fn supertraits<'tcx>(
    tcx: TyCtxt<'tcx>,
    trait_ref: ty::PolyTraitRef<'tcx>,
) -> Supertraits<'tcx> {
    elaborate_trait_ref(tcx, trait_ref).filter_to_traits()
}

pub fn transitive_bounds<'tcx>(
    tcx: TyCtxt<'tcx>,
    bounds: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
) -> Supertraits<'tcx> {
    elaborate_trait_refs(tcx, bounds).filter_to_traits()
}

pub fn transitive_bounds_that_define_assoc_type<'tcx>(
    tcx: TyCtxt<'tcx>,
    bounds: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
    assoc_name: Ident,
) -> FxHashSet<ty::PolyTraitRef<'tcx>> {
    elaborate_trait_refs_that_define_assoc_type(tcx, bounds, assoc_name)
}

///////////////////////////////////////////////////////////////////////////
// Other
///////////////////////////////////////////////////////////////////////////

/// A filter around an iterator of predicates that makes it yield up
/// just trait references.
pub struct FilterToTraits<I> {
    base_iterator: I,
}

impl<I> FilterToTraits<I> {
    fn new(base: I) -> FilterToTraits<I> {
        FilterToTraits { base_iterator: base }
    }
}

impl<'tcx, I: Iterator<Item = PredicateObligation<'tcx>>> Iterator for FilterToTraits<I> {
    type Item = ty::PolyTraitRef<'tcx>;

    fn next(&mut self) -> Option<ty::PolyTraitRef<'tcx>> {
        while let Some(obligation) = self.base_iterator.next() {
            if let Some(data) = obligation.predicate.to_opt_poly_trait_ref() {
                return Some(data.value);
            }
        }
        None
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let (_, upper) = self.base_iterator.size_hint();
        (0, upper)
    }
}
<commit_msg>Inline elaborate_trait_refs_that_define_assoc_type into transitive_bounds_that_define_assoc_type<commit_after>use smallvec::smallvec;

use crate::traits::{Obligation, ObligationCause, PredicateObligation};
use rustc_data_structures::fx::FxHashSet;
use rustc_middle::ty::outlives::Component;
use rustc_middle::ty::{self, ToPredicate, TyCtxt, WithConstness};
use rustc_span::symbol::Ident;

pub fn anonymize_predicate<'tcx>(
    tcx: TyCtxt<'tcx>,
    pred: ty::Predicate<'tcx>,
) -> ty::Predicate<'tcx> {
    match *pred.kind() {
        ty::PredicateKind::ForAll(binder) => {
            let new = ty::PredicateKind::ForAll(tcx.anonymize_late_bound_regions(binder));
            tcx.reuse_or_mk_predicate(pred, new)
        }
        ty::PredicateKind::Atom(_) => pred,
    }
}

struct PredicateSet<'tcx> {
    tcx: TyCtxt<'tcx>,
    set: FxHashSet<ty::Predicate<'tcx>>,
}

impl PredicateSet<'tcx> {
    fn new(tcx: TyCtxt<'tcx>) -> Self {
        Self { tcx, set: Default::default() }
    }

    fn insert(&mut self, pred: ty::Predicate<'tcx>) -> bool {
        // We have to be careful here because we want
        //
        //    for<'a> Foo<&'a i32>
        //
        // and
        //
        //    for<'b> Foo<&'b i32>
        //
        // to be considered equivalent. So normalize all late-bound
        // regions before we throw things into the underlying set.
        self.set.insert(anonymize_predicate(self.tcx, pred))
    }
}

impl Extend<ty::Predicate<'tcx>> for PredicateSet<'tcx> {
    fn extend<I: IntoIterator<Item = ty::Predicate<'tcx>>>(&mut self, iter: I) {
        for pred in iter {
            self.insert(pred);
        }
    }

    fn extend_one(&mut self, pred: ty::Predicate<'tcx>) {
        self.insert(pred);
    }

    fn extend_reserve(&mut self, additional: usize) {
        Extend::<ty::Predicate<'tcx>>::extend_reserve(&mut self.set, additional);
    }
}

///////////////////////////////////////////////////////////////////////////
// `Elaboration` iterator
///////////////////////////////////////////////////////////////////////////

/// "Elaboration" is the process of identifying all the predicates that
/// are implied by a source predicate. Currently, this basically means
/// walking the "supertraits" and other similar assumptions. For example,
/// if we know that `T: Ord`, the elaborator would deduce that `T: PartialOrd`
/// holds as well. Similarly, if we have `trait Foo: 'static`, and we know that
/// `T: Foo`, then we know that `T: 'static`.
pub struct Elaborator<'tcx> {
    stack: Vec<PredicateObligation<'tcx>>,
    visited: PredicateSet<'tcx>,
}

pub fn elaborate_trait_ref<'tcx>(
    tcx: TyCtxt<'tcx>,
    trait_ref: ty::PolyTraitRef<'tcx>,
) -> Elaborator<'tcx> {
    elaborate_predicates(tcx, std::iter::once(trait_ref.without_const().to_predicate(tcx)))
}

pub fn elaborate_trait_refs<'tcx>(
    tcx: TyCtxt<'tcx>,
    trait_refs: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
) -> Elaborator<'tcx> {
    let predicates = trait_refs.map(|trait_ref| trait_ref.without_const().to_predicate(tcx));
    elaborate_predicates(tcx, predicates)
}

pub fn elaborate_predicates<'tcx>(
    tcx: TyCtxt<'tcx>,
    predicates: impl Iterator<Item = ty::Predicate<'tcx>>,
) -> Elaborator<'tcx> {
    let obligations = predicates
        .map(|predicate| {
            predicate_obligation(predicate, ty::ParamEnv::empty(), ObligationCause::dummy())
        })
        .collect();
    elaborate_obligations(tcx, obligations)
}

pub fn elaborate_obligations<'tcx>(
    tcx: TyCtxt<'tcx>,
    mut obligations: Vec<PredicateObligation<'tcx>>,
) -> Elaborator<'tcx> {
    let mut visited = PredicateSet::new(tcx);
    obligations.retain(|obligation| visited.insert(obligation.predicate));
    Elaborator { stack: obligations, visited }
}

fn predicate_obligation<'tcx>(
    predicate: ty::Predicate<'tcx>,
    param_env: ty::ParamEnv<'tcx>,
    cause: ObligationCause<'tcx>,
) -> PredicateObligation<'tcx> {
    Obligation { cause, param_env, recursion_depth: 0, predicate }
}

impl Elaborator<'tcx> {
    pub fn filter_to_traits(self) -> FilterToTraits<Self> {
        FilterToTraits::new(self)
    }

    fn elaborate(&mut self, obligation: &PredicateObligation<'tcx>) {
        let tcx = self.visited.tcx;

        let bound_predicate = obligation.predicate.bound_atom();
        match bound_predicate.skip_binder() {
            ty::PredicateAtom::Trait(data, _) => {
                // Get predicates declared on the trait.
                let predicates = tcx.super_predicates_of(data.def_id());

                let obligations = predicates.predicates.iter().map(|&(pred, _)| {
                    predicate_obligation(
                        pred.subst_supertrait(tcx, &bound_predicate.rebind(data.trait_ref)),
                        obligation.param_env,
                        obligation.cause.clone(),
                    )
                });
                debug!("super_predicates: data={:?}", data);

                // Only keep those bounds that we haven't already seen.
                // This is necessary to prevent infinite recursion in some
                // cases. One common case is when people define
                // `trait Sized: Sized { }` rather than `trait Sized { }`.
                let visited = &mut self.visited;
                let obligations = obligations.filter(|o| visited.insert(o.predicate));

                self.stack.extend(obligations);
            }
            ty::PredicateAtom::WellFormed(..) => {
                // Currently, we do not elaborate WF predicates,
                // although we easily could.
            }
            ty::PredicateAtom::ObjectSafe(..) => {
                // Currently, we do not elaborate object-safe
                // predicates.
            }
            ty::PredicateAtom::Subtype(..) => {
                // Currently, we do not "elaborate" predicates like `X <: Y`,
                // though conceivably we might.
            }
            ty::PredicateAtom::Projection(..) => {
                // Nothing to elaborate in a projection predicate.
            }
            ty::PredicateAtom::ClosureKind(..) => {
                // Nothing to elaborate when waiting for a closure's kind to be inferred.
            }
            ty::PredicateAtom::ConstEvaluatable(..) => {
                // Currently, we do not elaborate const-evaluatable
                // predicates.
            }
            ty::PredicateAtom::ConstEquate(..) => {
                // Currently, we do not elaborate const-equate
                // predicates.
            }
            ty::PredicateAtom::RegionOutlives(..) => {
                // Nothing to elaborate from `'a: 'b`.
            }
            ty::PredicateAtom::TypeOutlives(ty::OutlivesPredicate(ty_max, r_min)) => {
                // We know that `T: 'a` for some type `T`. We can
                // often elaborate this. For example, if we know that
                // `[U]: 'a`, that implies that `U: 'a`. Similarly, if
                // we know `&'a U: 'b`, then we know that `'a: 'b` and
                // `U: 'b`.
                //
                // We can basically ignore bound regions here. So for
                // example `for<'c> Foo<'a,'c>: 'b` can be elaborated to
                // `'a: 'b`.

                // Ignore `for<'a> T: 'a` -- we might in the future
                // consider this as evidence that `T: 'static`, but
                // I'm a bit wary of such constructions and so for now
                // I want to be conservative. --nmatsakis
                if r_min.is_late_bound() {
                    return;
                }

                let visited = &mut self.visited;
                let mut components = smallvec![];
                tcx.push_outlives_components(ty_max, &mut components);
                self.stack.extend(
                    components
                        .into_iter()
                        .filter_map(|component| match component {
                            Component::Region(r) => {
                                if r.is_late_bound() {
                                    None
                                } else {
                                    Some(ty::PredicateAtom::RegionOutlives(ty::OutlivesPredicate(
                                        r, r_min,
                                    )))
                                }
                            }

                            Component::Param(p) => {
                                let ty = tcx.mk_ty_param(p.index, p.name);
                                Some(ty::PredicateAtom::TypeOutlives(ty::OutlivesPredicate(
                                    ty, r_min,
                                )))
                            }

                            Component::UnresolvedInferenceVariable(_) => None,

                            Component::Projection(_) | Component::EscapingProjection(_) => {
                                // We can probably do more here. This
                                // corresponds to a case like `<T as
                                // Foo<'a>>::U: 'b`.
                                None
                            }
                        })
                        .map(|predicate_kind| predicate_kind.to_predicate(tcx))
                        .filter(|&predicate| visited.insert(predicate))
                        .map(|predicate| {
                            predicate_obligation(
                                predicate,
                                obligation.param_env,
                                obligation.cause.clone(),
                            )
                        }),
                );
            }
            ty::PredicateAtom::TypeWellFormedFromEnv(..) => {
                // Nothing to elaborate
            }
        }
    }
}

impl Iterator for Elaborator<'tcx> {
    type Item = PredicateObligation<'tcx>;

    fn size_hint(&self) -> (usize, Option<usize>) {
        (self.stack.len(), None)
    }

    fn next(&mut self) -> Option<Self::Item> {
        // Extract next item from top-most stack frame, if any.
        if let Some(obligation) = self.stack.pop() {
            self.elaborate(&obligation);
            Some(obligation)
        } else {
            None
        }
    }
}

///////////////////////////////////////////////////////////////////////////
// Supertrait iterator
///////////////////////////////////////////////////////////////////////////

pub type Supertraits<'tcx> = FilterToTraits<Elaborator<'tcx>>;

pub fn supertraits<'tcx>(
    tcx: TyCtxt<'tcx>,
    trait_ref: ty::PolyTraitRef<'tcx>,
) -> Supertraits<'tcx> {
    elaborate_trait_ref(tcx, trait_ref).filter_to_traits()
}

pub fn transitive_bounds<'tcx>(
    tcx: TyCtxt<'tcx>,
    bounds: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
) -> Supertraits<'tcx> {
    elaborate_trait_refs(tcx, bounds).filter_to_traits()
}

/// A specialized variant of `elaborate_trait_refs` that only elaborates trait references that may
/// define the given associated type `assoc_name`. It uses the
/// `super_predicates_that_define_assoc_type` query to avoid enumerating super-predicates that
/// aren't related to `assoc_item`.  This is used when resolving types like `Self::Item` or
/// `T::Item` and helps to avoid cycle errors (see e.g. #35237).
pub fn transitive_bounds_that_define_assoc_type<'tcx>(
    tcx: TyCtxt<'tcx>,
    bounds: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
    assoc_name: Ident,
) -> FxHashSet<ty::PolyTraitRef<'tcx>> {
    let mut stack: Vec<_> = bounds.collect();
    let mut trait_refs = FxHashSet::default();

    while let Some(trait_ref) = stack.pop() {
        if trait_refs.insert(trait_ref) {
            let super_predicates =
                tcx.super_predicates_that_define_assoc_type((trait_ref.def_id(), Some(assoc_name)));
            for (super_predicate, _) in super_predicates.predicates {
                let bound_predicate = super_predicate.bound_atom();
                let subst_predicate = super_predicate
                    .subst_supertrait(tcx, &bound_predicate.rebind(trait_ref.skip_binder()));
                if let Some(binder) = subst_predicate.to_opt_poly_trait_ref() {
                    stack.push(binder.value);
                }
            }
        }
    }

    trait_refs
}

///////////////////////////////////////////////////////////////////////////
// Other
///////////////////////////////////////////////////////////////////////////

/// A filter around an iterator of predicates that makes it yield up
/// just trait references.
pub struct FilterToTraits<I> {
    base_iterator: I,
}

impl<I> FilterToTraits<I> {
    fn new(base: I) -> FilterToTraits<I> {
        FilterToTraits { base_iterator: base }
    }
}

impl<'tcx, I: Iterator<Item = PredicateObligation<'tcx>>> Iterator for FilterToTraits<I> {
    type Item = ty::PolyTraitRef<'tcx>;

    fn next(&mut self) -> Option<ty::PolyTraitRef<'tcx>> {
        while let Some(obligation) = self.base_iterator.next() {
            if let Some(data) = obligation.predicate.to_opt_poly_trait_ref() {
                return Some(data.value);
            }
        }
        None
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let (_, upper) = self.base_iterator.size_hint();
        (0, upper)
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2017-2019 Rene van der Meer
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

// i2c_ds3231.rs - Sets and retrieves the time on a DS3231 RTC using I2C.

use std::error::Error;
use std::thread::sleep;
use std::time::Duration;

use rppal::i2c::I2c;

// DS3231 I2C default slave address.
const ADDR_DS3231: u16 = 0x68;

// DS3231 register addresses.
const REG_SECONDS: usize = 0x00;
const REG_MINUTES: usize = 0x01;
const REG_HOURS: usize = 0x02;

// Helper functions to encode and decode binary-coded decimal (BCD) values.
fn bcd2dec(bcd: u8) -> u8 {
    (((bcd & 0xF0) >> 4) * 10) + (bcd & 0x0F)
}

fn dec2bcd(dec: u8) -> u8 {
    ((dec / 10) << 4) | (dec % 10)
}

fn main() -> Result<(), Box<dyn Error>> {
    let mut i2c = I2c::new()?;

    // Set the I2C slave address to the device we're communicating with.
    i2c.set_slave_address(ADDR_DS3231)?;

    // Set the time to 11:59:50 AM. Start at register address 0x00 (Seconds) and
    // write 3 bytes, overwriting the Seconds, Minutes and Hours registers.
    // Setting bit 6 of the Hours register indicates we're using a 12-hour
    // format. Leaving bit 5 unset indicates AM.
    i2c.block_write(
        REG_SECONDS as u8,
        &[dec2bcd(50), dec2bcd(59), dec2bcd(11) | (1 << 6)],
    )?;

    let mut reg: [u8; 3] = [0; 3];
    loop {
        // Start at register address 0x00 (Seconds) and read the values of the
        // next 3 registers (Seconds, Minutes, Hours) into the reg variable.
        i2c.block_read(REG_SECONDS as u8, &mut reg)?;

        // Display the retrieved time in the appropriate format based on bit 6 of
        // the Hours register.
        if reg[REG_HOURS] & (1 << 6) > 0 {
            // 12-hour format.
            println!(
                "{:0>2}:{:0>2}:{:0>2} {}",
                bcd2dec(reg[REG_HOURS] & 0x1F),
                bcd2dec(reg[REG_MINUTES]),
                bcd2dec(reg[REG_SECONDS]),
                if reg[REG_HOURS] & (1 << 5) > 0 {
                    "PM"
                } else {
                    "AM"
                }
            );
        } else {
            // 24-hour format.
            println!(
                "{:0>2}:{:0>2}:{:0>2}",
                bcd2dec(reg[REG_HOURS] & 0x3F),
                bcd2dec(reg[REG_MINUTES]),
                bcd2dec(reg[REG_SECONDS])
            );
        }

        sleep(Duration::from_secs(1));
    }
}
<commit_msg>Update documentation<commit_after>// Copyright (c) 2017-2019 Rene van der Meer
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

// i2c_ds3231.rs - Sets and retrieves the time on a Maxim Integrated DS3231
// RTC using I2C.

use std::error::Error;
use std::thread::sleep;
use std::time::Duration;

use rppal::i2c::I2c;

// DS3231 I2C default slave address.
const ADDR_DS3231: u16 = 0x68;

// DS3231 register addresses.
const REG_SECONDS: usize = 0x00;
const REG_MINUTES: usize = 0x01;
const REG_HOURS: usize = 0x02;

// Helper functions to encode and decode binary-coded decimal (BCD) values.
fn bcd2dec(bcd: u8) -> u8 {
    (((bcd & 0xF0) >> 4) * 10) + (bcd & 0x0F)
}

fn dec2bcd(dec: u8) -> u8 {
    ((dec / 10) << 4) | (dec % 10)
}

fn main() -> Result<(), Box<dyn Error>> {
    let mut i2c = I2c::new()?;

    // Set the I2C slave address to the device we're communicating with.
    i2c.set_slave_address(ADDR_DS3231)?;

    // Set the time to 11:59:50 AM. Start at register address 0x00 (Seconds) and
    // write 3 bytes, overwriting the Seconds, Minutes and Hours registers.
    // Setting bit 6 of the Hours register indicates we're using a 12-hour
    // format. Leaving bit 5 unset indicates AM.
    i2c.block_write(
        REG_SECONDS as u8,
        &[dec2bcd(50), dec2bcd(59), dec2bcd(11) | (1 << 6)],
    )?;

    let mut reg: [u8; 3] = [0; 3];
    loop {
        // Start at register address 0x00 (Seconds) and read the values of the
        // next 3 registers (Seconds, Minutes, Hours) into the reg variable.
        i2c.block_read(REG_SECONDS as u8, &mut reg)?;

        // Display the retrieved time in the appropriate format based on bit 6 of
        // the Hours register.
        if reg[REG_HOURS] & (1 << 6) > 0 {
            // 12-hour format.
            println!(
                "{:0>2}:{:0>2}:{:0>2} {}",
                bcd2dec(reg[REG_HOURS] & 0x1F),
                bcd2dec(reg[REG_MINUTES]),
                bcd2dec(reg[REG_SECONDS]),
                if reg[REG_HOURS] & (1 << 5) > 0 {
                    "PM"
                } else {
                    "AM"
                }
            );
        } else {
            // 24-hour format.
            println!(
                "{:0>2}:{:0>2}:{:0>2}",
                bcd2dec(reg[REG_HOURS] & 0x3F),
                bcd2dec(reg[REG_MINUTES]),
                bcd2dec(reg[REG_SECONDS])
            );
        }

        sleep(Duration::from_secs(1));
    }
}
<|endoftext|>


<commit_before>//! Example that just prints out all the input events.

extern crate cgmath;
extern crate ggez;

use ggez::event::{self, Axis, Button, GamepadId, KeyCode, KeyMods, MouseButton};
use ggez::graphics::{self, DrawMode};
use ggez::input;
use ggez::{Context, GameResult};

struct MainState {
    pos_x: f32,
    pos_y: f32,
    mouse_down: bool,
}

impl MainState {
    fn new() -> MainState {
        MainState {
            pos_x: 100.0,
            pos_y: 100.0,
            mouse_down: false,
        }
    }
}

impl event::EventHandler for MainState {
    fn update(&mut self, ctx: &mut Context) -> GameResult {
        if input::keyboard::is_key_pressed(ctx, KeyCode::A) {
            println!("The A key is pressed");
            if input::keyboard::is_mod_active(ctx, input::keyboard::KeyMods::SHIFT) {
                println!("The shift key is held too.");
            }
            println!(
                "Full list of pressed keys: {:?}",
                input::keyboard::pressed_keys(ctx)
            );
        }
        Ok(())
    }

    fn draw(&mut self, ctx: &mut Context) -> GameResult {
        graphics::clear(ctx, [0.1, 0.2, 0.3, 1.0].into());
        let rectangle = graphics::Mesh::new_rectangle(
            ctx,
            DrawMode::fill(),
            graphics::Rect {
                x: self.pos_x,
                y: self.pos_y,
                w: 400.0,
                h: 300.0,
            },
            graphics::WHITE,
        )?;
        graphics::draw(ctx, &rectangle, (ggez::nalgebra::Point2::new(0.0, 0.0),))?;
        graphics::present(ctx)?;
        Ok(())
    }

    fn mouse_button_down_event(&mut self, _ctx: &mut Context, button: MouseButton, x: f32, y: f32) {
        self.mouse_down = true;
        println!("Mouse button pressed: {:?}, x: {}, y: {}", button, x, y);
    }

    fn mouse_button_up_event(&mut self, _ctx: &mut Context, button: MouseButton, x: f32, y: f32) {
        self.mouse_down = false;
        println!("Mouse button released: {:?}, x: {}, y: {}", button, x, y);
    }

    fn mouse_motion_event(&mut self, _ctx: &mut Context, x: f32, y: f32, xrel: f32, yrel: f32) {
        if self.mouse_down {
            self.pos_x = x;
            self.pos_y = y;
        }
        println!(
            "Mouse motion, x: {}, y: {}, relative x: {}, relative y: {}",
            x, y, xrel, yrel
        );
    }

    fn mouse_wheel_event(&mut self, _ctx: &mut Context, x: f32, y: f32) {
        println!("Mousewheel event, x: {}, y: {}", x, y);
    }

    fn key_down_event(
        &mut self,
        _ctx: &mut Context,
        keycode: KeyCode,
        keymod: KeyMods,
        repeat: bool,
    ) {
        println!(
            "Key pressed: {:?}, modifier {:?}, repeat: {}",
            keycode, keymod, repeat
        );
    }

    fn key_up_event(&mut self, _ctx: &mut Context, keycode: KeyCode, keymod: KeyMods) {
        println!("Key released: {:?}, modifier {:?}", keycode, keymod);
    }

    fn text_input_event(&mut self, _ctx: &mut Context, ch: char) {
        println!("Text input: {}", ch);
    }

    fn controller_button_down_event(&mut self, _ctx: &mut Context, btn: Button, id: GamepadId) {
        println!(
            "Gamepad button pressed: {:?} Gamepad_Id: {:?}",
            btn, id
        );
    }

    fn controller_button_up_event(&mut self, _ctx: &mut Context, btn: Button, id: GamepadId) {
        println!(
            "Gamepad button released: {:?} Gamepad_Id: {:?}",
            btn, id
        );
    }

    fn controller_axis_event(&mut self, _ctx: &mut Context, axis: Axis, value: f32, id: GamepadId) {
        println!(
            "Axis Event: {:?} Value: {} Gamepad_Id: {:?}",
            axis, value, id
        );
    }

    fn focus_event(&mut self, _ctx: &mut Context, gained: bool) {
        if gained {
            println!("Focus gained");
        } else {
            println!("Focus lost");
        }
    }
}

pub fn main() -> GameResult {
    let cb = ggez::ContextBuilder::new("input_test", "ggez");
    let (ctx, event_loop) = &mut cb.build()?;

    let state = &mut MainState::new();
    event::run(ctx, event_loop, state)
}
<commit_msg>Fix input example.<commit_after>//! Example that just prints out all the input events.

extern crate cgmath;
extern crate ggez;

use ggez::event::{self, Axis, Button, GamepadId, KeyCode, KeyMods, MouseButton};
use ggez::graphics::{self, DrawMode};
use ggez::input;
use ggez::{Context, GameResult};

struct MainState {
    pos_x: f32,
    pos_y: f32,
    mouse_down: bool,
}

impl MainState {
    fn new() -> MainState {
        MainState {
            pos_x: 100.0,
            pos_y: 100.0,
            mouse_down: false,
        }
    }
}

impl event::EventHandler for MainState {
    fn update(&mut self, ctx: &mut Context) -> GameResult {
        if input::keyboard::is_key_pressed(ctx, KeyCode::A) {
            println!("The A key is pressed");
            if input::keyboard::is_mod_active(ctx, input::keyboard::KeyMods::SHIFT) {
                println!("The shift key is held too.");
            }
            println!(
                "Full list of pressed keys: {:?}",
                input::keyboard::pressed_keys(ctx)
            );
        }
        Ok(())
    }

    fn draw(&mut self, ctx: &mut Context) -> GameResult {
        graphics::clear(ctx, [0.1, 0.2, 0.3, 1.0].into());
        let rectangle = graphics::Mesh::new_rectangle(
            ctx,
            DrawMode::fill(),
            graphics::Rect {
                x: self.pos_x,
                y: self.pos_y,
                w: 400.0,
                h: 300.0,
            },
            graphics::WHITE,
        )?;
        graphics::draw(ctx, &rectangle, (ggez::nalgebra::Point2::new(0.0, 0.0),))?;
        graphics::present(ctx)?;
        Ok(())
    }

    fn mouse_button_down_event(&mut self, _ctx: &mut Context, button: MouseButton, x: f32, y: f32) {
        self.mouse_down = true;
        println!("Mouse button pressed: {:?}, x: {}, y: {}", button, x, y);
    }

    fn mouse_button_up_event(&mut self, _ctx: &mut Context, button: MouseButton, x: f32, y: f32) {
        self.mouse_down = false;
        println!("Mouse button released: {:?}, x: {}, y: {}", button, x, y);
    }

    fn mouse_motion_event(&mut self, _ctx: &mut Context, x: f32, y: f32, xrel: f32, yrel: f32) {
        if self.mouse_down {
            self.pos_x = x;
            self.pos_y = y;
        }
        println!(
            "Mouse motion, x: {}, y: {}, relative x: {}, relative y: {}",
            x, y, xrel, yrel
        );
    }

    fn mouse_wheel_event(&mut self, _ctx: &mut Context, x: f32, y: f32) {
        println!("Mousewheel event, x: {}, y: {}", x, y);
    }

    fn key_down_event(
        &mut self,
        _ctx: &mut Context,
        keycode: KeyCode,
        keymod: KeyMods,
        repeat: bool,
    ) {
        println!(
            "Key pressed: {:?}, modifier {:?}, repeat: {}",
            keycode, keymod, repeat
        );
    }

    fn key_up_event(&mut self, _ctx: &mut Context, keycode: KeyCode, keymod: KeyMods) {
        println!("Key released: {:?}, modifier {:?}", keycode, keymod);
    }

    fn text_input_event(&mut self, _ctx: &mut Context, ch: char) {
        println!("Text input: {}", ch);
    }

    fn gamepad_button_down_event(&mut self, _ctx: &mut Context, btn: Button, id: GamepadId) {
        println!(
            "Gamepad button pressed: {:?} Gamepad_Id: {:?}",
            btn, id
        );
    }

    fn gamepad_button_up_event(&mut self, _ctx: &mut Context, btn: Button, id: GamepadId) {
        println!(
            "Gamepad button released: {:?} Gamepad_Id: {:?}",
            btn, id
        );
    }

    fn gamepad_axis_event(&mut self, _ctx: &mut Context, axis: Axis, value: f32, id: GamepadId) {
        println!(
            "Axis Event: {:?} Value: {} Gamepad_Id: {:?}",
            axis, value, id
        );
    }

    fn focus_event(&mut self, _ctx: &mut Context, gained: bool) {
        if gained {
            println!("Focus gained");
        } else {
            println!("Focus lost");
        }
    }
}

pub fn main() -> GameResult {
    let cb = ggez::ContextBuilder::new("input_test", "ggez");
    let (ctx, event_loop) = &mut cb.build()?;

    let state = &mut MainState::new();
    event::run(ctx, event_loop, state)
}
<|endoftext|>


<commit_before>pub const POMBASE_ANN_EXT_TERM_CV_NAME: &'static str = "PomBase annotation extension terms";
pub const ANNOTATION_EXT_REL_PREFIX: &'static str = "annotation_extension_relation-";

pub const DB_NAME: &'static str = "PomBase";

pub enum FeatureRelAnnotationType {
    Interaction,
    Ortholog,
    Paralog,
}
pub struct FeatureRelConfig {
    pub rel_type_name: &'static str,
    pub annotation_type: FeatureRelAnnotationType,
}
pub const FEATURE_REL_CONFIGS: [FeatureRelConfig; 4] =
    [
        FeatureRelConfig {
            rel_type_name: "interacts_physically",
            annotation_type: FeatureRelAnnotationType::Interaction,
        },
        FeatureRelConfig {
            rel_type_name: "interacts_genetically",
            annotation_type: FeatureRelAnnotationType::Interaction,
        },
        FeatureRelConfig {
            rel_type_name: "orthologous_to",
            annotation_type: FeatureRelAnnotationType::Ortholog,
        },
        FeatureRelConfig {
            rel_type_name: "paralogous_to",
            annotation_type: FeatureRelAnnotationType::Paralog,
        },
    ];

// relations to use when copy annotation to parents (ie. adding the
// annotation of child terms to parents)
pub const DESCENDANT_REL_NAMES: [&'static str; 3] = ["is_a", "part_of", "regulates"];
// relationships where the more specific term is the object, used when reading cvtermpath
pub const INVERSE_REL_NAMES: [&'static str; 1] = ["has_part"];
// only consider inverse relations for these ontologies:
pub const INVERSE_REL_CV_NAMES: [&'static str; 1] = ["fission_yeast_phenotype"];

// number of genes before (and after) to add to the gene_neighbourhood field
pub const GENE_NEIGHBOURHOOD_DISTANCE: usize = 5;

pub const TRANSCRIPT_FEATURE_TYPES: [&'static str; 6] =
    ["snRNA", "rRNA", "mRNA", "snoRNA", "ncRNA", "tRNA"];

// "interesting parents" are those stored in the JSON in the TermShort structs
#[derive(Clone)]
pub struct InterestingParent {
    pub termid: &'static str,
    pub rel_name: &'static str,
}

// when creating a TermShort struct, for each of these termids if the term has
// an "interesting parent" using the given rel_name, we store it in the
// interesting_parents field of the TermShort
pub const INTERESTING_PARENTS: [InterestingParent; 3] = [
    InterestingParent {
        termid: "FYPO:0000002",
        rel_name: "is_a",
    },
    InterestingParent {
        termid: "FYPO:0000003",
        rel_name: "is_a",
    },

    // a with property on a protein binding (GO:0005515) is displayed
    // as a binds extension - configure this to allow easy checking for that in
    // process_feature_cvterms()
    // see: https://github.com/pombase/website/issues/108
    InterestingParent {
        termid: "GO:0005515",
        rel_name: "is_a",
    },
];
<commit_msg>Add FYPO:0000652 as an interesting parent<commit_after>pub const POMBASE_ANN_EXT_TERM_CV_NAME: &'static str = "PomBase annotation extension terms";
pub const ANNOTATION_EXT_REL_PREFIX: &'static str = "annotation_extension_relation-";

pub const DB_NAME: &'static str = "PomBase";

pub enum FeatureRelAnnotationType {
    Interaction,
    Ortholog,
    Paralog,
}
pub struct FeatureRelConfig {
    pub rel_type_name: &'static str,
    pub annotation_type: FeatureRelAnnotationType,
}
pub const FEATURE_REL_CONFIGS: [FeatureRelConfig; 4] =
    [
        FeatureRelConfig {
            rel_type_name: "interacts_physically",
            annotation_type: FeatureRelAnnotationType::Interaction,
        },
        FeatureRelConfig {
            rel_type_name: "interacts_genetically",
            annotation_type: FeatureRelAnnotationType::Interaction,
        },
        FeatureRelConfig {
            rel_type_name: "orthologous_to",
            annotation_type: FeatureRelAnnotationType::Ortholog,
        },
        FeatureRelConfig {
            rel_type_name: "paralogous_to",
            annotation_type: FeatureRelAnnotationType::Paralog,
        },
    ];

// relations to use when copy annotation to parents (ie. adding the
// annotation of child terms to parents)
pub const DESCENDANT_REL_NAMES: [&'static str; 3] = ["is_a", "part_of", "regulates"];
// relationships where the more specific term is the object, used when reading cvtermpath
pub const INVERSE_REL_NAMES: [&'static str; 1] = ["has_part"];
// only consider inverse relations for these ontologies:
pub const INVERSE_REL_CV_NAMES: [&'static str; 1] = ["fission_yeast_phenotype"];

// number of genes before (and after) to add to the gene_neighbourhood field
pub const GENE_NEIGHBOURHOOD_DISTANCE: usize = 5;

pub const TRANSCRIPT_FEATURE_TYPES: [&'static str; 6] =
    ["snRNA", "rRNA", "mRNA", "snoRNA", "ncRNA", "tRNA"];

// "interesting parents" are those stored in the JSON in the TermShort structs
#[derive(Clone)]
pub struct InterestingParent {
    pub termid: &'static str,
    pub rel_name: &'static str,
}

// when creating a TermShort struct, for each of these termids if the term has
// an "interesting parent" using the given rel_name, we store it in the
// interesting_parents field of the TermShort
pub const INTERESTING_PARENTS: [InterestingParent; 4] = [
    InterestingParent {
        termid: "FYPO:0000002",
        rel_name: "is_a",
    },
    InterestingParent {
        termid: "FYPO:0000003",
        rel_name: "is_a",
    },
    InterestingParent {
        termid: "FYPO:0000652",
        rel_name: "is_a",
    },

    // a with property on a protein binding (GO:0005515) is displayed
    // as a binds extension - configure this to allow easy checking for that in
    // process_feature_cvterms()
    // see: https://github.com/pombase/website/issues/108
    InterestingParent {
        termid: "GO:0005515",
        rel_name: "is_a",
    },
];
<|endoftext|>


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

use string_cache::Atom;
use webrender_traits::NativeFontHandle;

#[derive(Deserialize, Serialize, Debug)]
pub struct FontTemplateData {
    pub bytes: Vec<u8>,
    pub identifier: Atom,
}

impl FontTemplateData {
    pub fn new(identifier: Atom, font_data: Option<Vec<u8>>) -> FontTemplateData {
        let bytes = match font_data {
            Some(bytes) => {
                bytes
            },
            None => {
                unimplemented!()
            }
        };

        FontTemplateData {
            bytes: bytes,
            identifier: identifier,
        }
    }
    pub fn bytes(&self) -> Vec<u8> {
        self.bytes.clone()
    }
    pub fn bytes_if_in_memory(&self) -> Option<Vec<u8>> {
        Some(self.bytes())
    }
    pub fn native_font(&self) -> Option<NativeFontHandle> {
        None
    }
}
<commit_msg>Make dummy font implementation conform to API changes.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use std::io::Error;
use string_cache::Atom;
use webrender_traits::NativeFontHandle;

#[derive(Deserialize, Serialize, Debug)]
pub struct FontTemplateData {
    pub bytes: Vec<u8>,
    pub identifier: Atom,
}

impl FontTemplateData {
    pub fn new(identifier: Atom, font_data: Option<Vec<u8>>) -> Result<FontTemplateData, Error> {
        let bytes = match font_data {
            Some(bytes) => {
                bytes
            },
            None => {
                unimplemented!()
            }
        };

        Ok(FontTemplateData {
            bytes: bytes,
            identifier: identifier,
        })
    }
    pub fn bytes(&self) -> Vec<u8> {
        self.bytes.clone()
    }
    pub fn bytes_if_in_memory(&self) -> Option<Vec<u8>> {
        Some(self.bytes())
    }
    pub fn native_font(&self) -> Option<NativeFontHandle> {
        None
    }
}
<|endoftext|>


<commit_before>extern crate libc;

use std::ffi::CString;
use std::fs;
use std::io;
use std::os::unix::prelude::*;
use std::path::Path;

use self::libc::{c_int, c_char, timeval, time_t, suseconds_t};
use self::libc::{timespec};

use FileTime;

cfg_if! {
    if #[cfg(target_os = "linux")] {
        mod linux;
        pub use self::linux::*;
    } else if #[cfg(any(target_os = "android",
                        target_os = "solaris",
                        target_os = "netbsd",
                        target_os = "openbsd"))] {
        mod utimensat;
        pub use self::utimensat::*;
    } else {
        mod utimes;
        pub use self::utimes::*;
    }
}

#[allow(dead_code)]
fn utimes(p: &Path,
          atime: FileTime,
          mtime: FileTime,
          utimes: unsafe extern fn(*const c_char, *const timeval) -> c_int)
    -> io::Result<()>
{
    let times = [to_timeval(&atime), to_timeval(&mtime)];
    let p = try!(CString::new(p.as_os_str().as_bytes()));
    return if unsafe { utimes(p.as_ptr() as *const _, times.as_ptr()) == 0 } {
        Ok(())
    } else {
        Err(io::Error::last_os_error())
    };

    fn to_timeval(ft: &FileTime) -> timeval {
        timeval {
            tv_sec: ft.seconds() as time_t,
            tv_usec: (ft.nanoseconds() / 1000) as suseconds_t,
        }
    }
}

#[allow(dead_code)]
fn utimensat(p: &Path,
             atime: FileTime,
             mtime: FileTime,
             f: unsafe extern fn(c_int, *const c_char, *const timespec, c_int) -> c_int,
             flags: c_int)
    -> io::Result<()>
{
    let times = [to_timespec(&atime), to_timespec(&mtime)];
    let p = try!(CString::new(p.as_os_str().as_bytes()));
    let rc = unsafe {
        f(libc::AT_FDCWD, p.as_ptr() as *const _, times.as_ptr(), flags)
    };
    return if rc == 0 {
        Ok(())
    } else {
        Err(io::Error::last_os_error())
    };

    fn to_timespec(ft: &FileTime) -> timespec {
        timespec {
            tv_sec: ft.seconds() as time_t,
            tv_nsec: ft.nanoseconds() as _,
        }
    }
}

pub fn from_last_modification_time(meta: &fs::Metadata) -> FileTime {
    FileTime {
        seconds: meta.mtime(),
        nanos: meta.mtime_nsec() as u32,
    }
}

pub fn from_last_access_time(meta: &fs::Metadata) -> FileTime {
    FileTime {
        seconds: meta.atime(),
        nanos: meta.atime_nsec() as u32,
    }
}

pub fn from_creation_time(meta: &fs::Metadata) -> Option<FileTime> {
    macro_rules! birthtim {
        ($(($e:expr, $i:ident)),*) => {
            #[cfg(any($(target_os = $e),*))]
            fn imp(meta: &fs::Metadata) -> Option<FileTime> {
                $(
                    #[cfg(target_os = $e)]
                    use std::os::$i::fs::MetadataExt;
                )*
                Some(FileTime {
                    seconds: meta.st_birthtime(),
                    nanos: meta.st_birthtime_nsec() as u32,
                })
            }

            #[cfg(all($(not(target_os = $e)),*))]
            fn imp(_meta: &fs::Metadata) -> Option<FileTime> {
                None
            }
        }
    }

    birthtim! {
        ("bitrig", bitrig),
        ("freebsd", freebsd),
        ("ios", ios),
        ("macos", macos),
        ("openbsd", openbsd)
    }

    imp(meta)
}
<commit_msg>Fix Emscripten and FreeBSD<commit_after>extern crate libc;

use std::ffi::CString;
use std::fs;
use std::io;
use std::os::unix::prelude::*;
use std::path::Path;

use self::libc::{c_int, c_char, timeval, time_t, suseconds_t};
use self::libc::{timespec};

use FileTime;

cfg_if! {
    if #[cfg(target_os = "linux")] {
        mod linux;
        pub use self::linux::*;
    } else if #[cfg(any(target_os = "android",
                        target_os = "solaris",
                        target_os = "netbsd",
                        target_os = "openbsd",
                        target_os = "freebsd",
                        target_os = "emscripten"))] {
        mod utimensat;
        pub use self::utimensat::*;
    } else {
        mod utimes;
        pub use self::utimes::*;
    }
}

#[allow(dead_code)]
fn utimes(p: &Path,
          atime: FileTime,
          mtime: FileTime,
          utimes: unsafe extern fn(*const c_char, *const timeval) -> c_int)
    -> io::Result<()>
{
    let times = [to_timeval(&atime), to_timeval(&mtime)];
    let p = try!(CString::new(p.as_os_str().as_bytes()));
    return if unsafe { utimes(p.as_ptr() as *const _, times.as_ptr()) == 0 } {
        Ok(())
    } else {
        Err(io::Error::last_os_error())
    };

    fn to_timeval(ft: &FileTime) -> timeval {
        timeval {
            tv_sec: ft.seconds() as time_t,
            tv_usec: (ft.nanoseconds() / 1000) as suseconds_t,
        }
    }
}

#[allow(dead_code)]
fn utimensat(p: &Path,
             atime: FileTime,
             mtime: FileTime,
             f: unsafe extern fn(c_int, *const c_char, *const timespec, c_int) -> c_int,
             flags: c_int)
    -> io::Result<()>
{
    let times = [to_timespec(&atime), to_timespec(&mtime)];
    let p = try!(CString::new(p.as_os_str().as_bytes()));
    let rc = unsafe {
        f(libc::AT_FDCWD, p.as_ptr() as *const _, times.as_ptr(), flags)
    };
    return if rc == 0 {
        Ok(())
    } else {
        Err(io::Error::last_os_error())
    };

    fn to_timespec(ft: &FileTime) -> timespec {
        timespec {
            tv_sec: ft.seconds() as time_t,
            tv_nsec: ft.nanoseconds() as _,
        }
    }
}

pub fn from_last_modification_time(meta: &fs::Metadata) -> FileTime {
    FileTime {
        seconds: meta.mtime(),
        nanos: meta.mtime_nsec() as u32,
    }
}

pub fn from_last_access_time(meta: &fs::Metadata) -> FileTime {
    FileTime {
        seconds: meta.atime(),
        nanos: meta.atime_nsec() as u32,
    }
}

pub fn from_creation_time(meta: &fs::Metadata) -> Option<FileTime> {
    macro_rules! birthtim {
        ($(($e:expr, $i:ident)),*) => {
            #[cfg(any($(target_os = $e),*))]
            fn imp(meta: &fs::Metadata) -> Option<FileTime> {
                $(
                    #[cfg(target_os = $e)]
                    use std::os::$i::fs::MetadataExt;
                )*
                Some(FileTime {
                    seconds: meta.st_birthtime(),
                    nanos: meta.st_birthtime_nsec() as u32,
                })
            }

            #[cfg(all($(not(target_os = $e)),*))]
            fn imp(_meta: &fs::Metadata) -> Option<FileTime> {
                None
            }
        }
    }

    birthtim! {
        ("bitrig", bitrig),
        ("freebsd", freebsd),
        ("ios", ios),
        ("macos", macos),
        ("openbsd", openbsd)
    }

    imp(meta)
}
<|endoftext|>


<commit_before>#[derive(Clone, Debug)]
pub struct URIBase {
    base_uri: String,
    port: u16
}

impl Default for URIBase {
    fn default() -> URIBase {
        URIBase {
            base_uri: "localhost".to_string(),
            port: 10041
        }
    }
}

impl URIBase {
    ///
    /// Create URIBase struct
    ///
    /// Default values are:
    ///
    ///   base_uri: "localhost"
    ///
    ///   port: 10041
    ///
    pub fn new() -> URIBase {
        let default: URIBase = Default::default();
        default
    }

    /// Set base to replace default value with specified value
    pub fn base_uri(mut self, base_uri: String) -> URIBase {
        self.base_uri = base_uri;
        self
    }

    /// Set port number to replace default value with specified value
    pub fn port(mut self, port: u16) -> URIBase {
        self.port = port;
        self
    }

    /// make base uri
    /// Default value is: "localhost:10041"
    pub fn build(self) -> String {
        format!("http://{}:{}", self.base_uri, self.port)
    }
}

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

    #[test]
    fn construct_uri_default() {
        let uri_base = URIBase::new().build();
        assert_eq!("http://localhost:10041", uri_base)
    }

    #[test]
    fn buikld_only_uri_base() {
        let uri_base = URIBase::new();
        let specified_base = uri_base.base_uri("127.0.0.1".to_string()).build();
        assert_eq!("http://127.0.0.1:10041", specified_base);
    }

    #[test]
    fn build_only_port() {
        let uri_base = URIBase::new();
        let specified_port = uri_base.port(10042).build();
        assert_eq!("http://localhost:10042", specified_port);
    }

    #[test]
    fn uri_with_builder() {
        let uri_base = URIBase::new()
            .base_uri("127.0.1.1".to_string())
            .port(10043);
        let uri_default = uri_base.build();
        assert_eq!("http://127.0.1.1:10043", uri_default)
    }

}
<commit_msg>Simplify<commit_after>#[derive(Clone, Debug)]
pub struct URIBase {
    base_uri: String,
    port: u16
}

impl Default for URIBase {
    fn default() -> URIBase {
        URIBase {
            base_uri: "localhost".to_string(),
            port: 10041
        }
    }
}

impl URIBase {
    ///
    /// Create URIBase struct
    ///
    /// Default values are:
    ///
    ///   base_uri: "localhost"
    ///
    ///   port: 10041
    ///
    pub fn new() -> URIBase {
        let default: URIBase = Default::default();
        default
    }

    /// Set base to replace default value with specified value
    pub fn base_uri(mut self, base_uri: String) -> URIBase {
        self.base_uri = base_uri;
        self
    }

    /// Set port number to replace default value with specified value
    pub fn port(mut self, port: u16) -> URIBase {
        self.port = port;
        self
    }

    /// make base uri
    /// Default value is: "localhost:10041"
    pub fn build(self) -> String {
        format!("http://{}:{}", self.base_uri, self.port)
    }
}

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

    #[test]
    fn construct_uri_default() {
        let uri_base = URIBase::new().build();
        assert_eq!("http://localhost:10041", uri_base)
    }

    #[test]
    fn buikld_only_uri_base() {
        let uri_base = URIBase::new()
            .base_uri("127.0.0.1".to_string()).build();
        assert_eq!("http://127.0.0.1:10041", uri_base);
    }

    #[test]
    fn build_only_port() {
        let uri_base = URIBase::new().port(10042).build();
        assert_eq!("http://localhost:10042", uri_base);
    }

    #[test]
    fn uri_with_builder() {
        let uri_base = URIBase::new()
            .base_uri("127.0.1.1".to_string())
            .port(10043)
            .build();
        assert_eq!("http://127.0.1.1:10043", uri_base)
    }

}
<|endoftext|>


<commit_before>use gfx;
use gfx_core;
use memmap::MmapViewSync;
use vec_map::VecMap;

use terrain::quadtree::{Node, NodeId};
use runtime_texture::{TextureArray, TextureFormat};

#[derive(Clone, Copy, PartialEq, PartialOrd, Serialize, Deserialize)]
pub struct Priority(f32);
impl Priority {
    pub fn cutoff() -> Self {
        Priority(1.0)
    }
    pub fn none() -> Self {
        Priority(-1.0)
    }
    pub fn from_f32(value: f32) -> Self {
        assert!(value.is_finite());
        Priority(value)
    }
}
impl Eq for Priority {}
impl Ord for Priority {
    fn cmp(&self, other: &Self) -> ::std::cmp::Ordering {
        self.partial_cmp(other).unwrap()
    }
}

pub const NUM_LAYERS: usize = 4;

#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub(crate) enum LayerType {
    Heights = 0,
    Colors = 1,
    Normals = 2,
    Water = 3,
}
impl LayerType {
    pub fn cache_size(&self) -> u16 {
        match *self {
            LayerType::Heights => 256,
            LayerType::Colors => 256,
            LayerType::Normals => 32,
            LayerType::Water => 256,
        }
    }
    pub fn index(&self) -> usize {
        *self as usize
    }
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub(crate) struct LayerParams {
    /// What kind of layer this is. There can be at most one of each layer type in a file.
    pub layer_type: LayerType,
    /// Byte offset from start of file.
    pub offset: usize,
    /// Number of tiles in layer.
    pub tile_count: usize,
    /// Number of samples in each dimension, per tile.
    pub tile_resolution: u32,
    /// Number of samples outside the tile on each side.
    pub border_size: u32,
    /// Format used by this layer.
    pub format: TextureFormat,
    /// Number of bytes per tile.
    pub tile_bytes: usize,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub(crate) struct NoiseParams {
    pub offset: usize,
    pub resolution: u32,
    pub format: TextureFormat,
    pub bytes: usize,
    pub wavelength: f32,
}

#[derive(Serialize, Deserialize)]
pub(crate) struct TileHeader {
    pub layers: Vec<LayerParams>,
    pub noise: NoiseParams,
    pub nodes: Vec<Node>,
}

pub(crate) struct TileCache<R: gfx::Resources> {
    /// Maximum number of slots in this `TileCache`.
    size: usize,
    /// Actually contents of the cache.
    slots: Vec<(Priority, NodeId)>,
    /// Which index each node is at in the cache (if any).
    reverse: VecMap<usize>,
    /// Nodes that should be added to the cache.
    missing: Vec<(Priority, NodeId)>,
    /// Smallest priority among all nodes in the cache.
    min_priority: Priority,

    /// Resolution of each tile in this cache.
    layer_params: LayerParams,

    texture: TextureArray<R>,

    /// Section of memory map that holds the data for this layer.
    data_file: MmapViewSync,
}
impl<R: gfx::Resources> TileCache<R> {
    pub fn new<F: gfx::Factory<R>>(
        params: LayerParams,
        data_file: MmapViewSync,
        factory: &mut F,
    ) -> Self {
        let cache_size = params.layer_type.cache_size();
        let texture = TextureArray::new(
            params.format,
            params.tile_resolution as u16,
            cache_size,
            factory,
        );

        Self {
            size: cache_size as usize,
            slots: Vec::new(),
            reverse: VecMap::new(),
            missing: Vec::new(),
            min_priority: Priority::none(),
            layer_params: params,
            data_file,
            texture,
        }
    }

    pub fn update_priorities(&mut self, nodes: &mut Vec<Node>) {
        for &mut (ref mut priority, id) in self.slots.iter_mut() {
            *priority = nodes[id].priority();
        }

        self.min_priority = self.slots.iter().map(|s| s.0).min().unwrap_or(
            Priority::none(),
        );
    }

    pub fn add_missing(&mut self, element: (Priority, NodeId)) {
        if element.0 > self.min_priority || self.slots.len() < self.size {
            self.missing.push(element);
        }
    }

    pub fn load_missing<C: gfx_core::command::Buffer<R>>(
        &mut self,
        nodes: &mut Vec<Node>,
        encoder: &mut gfx::Encoder<R, C>,
    ) {
        while !self.missing.is_empty() && self.slots.len() < self.size {
            let m = self.missing.pop().unwrap();
            let index = self.slots.len();
            self.slots.push(m.clone());
            self.load(m.1, &mut nodes[m.1], index, encoder);
        }

        if !self.missing.is_empty() {
            let mut possible: Vec<_> = self.slots
                .iter()
                .cloned()
                .chain(self.missing.iter().cloned())
                .collect();
            possible.sort();

            // Anything >= to cutoff should be included.
            let cutoff = possible[possible.len() - self.size];

            let mut index = 0;
            while let Some(m) = self.missing.pop() {
                if cutoff >= m {
                    continue;
                }

                // Find the next element to evict.
                while self.slots[index] >= cutoff {
                    index += 1;
                }

                self.slots[index] = m.clone();
                self.load(m.1, &mut nodes[m.1], index, encoder);
                index += 1;
            }
        }
    }

    fn load<C: gfx_core::command::Buffer<R>>(
        &mut self,
        id: NodeId,
        node: &mut Node,
        slot: usize,
        encoder: &mut gfx::Encoder<R, C>,
    ) {
        if slot < self.slots.len() {
            self.reverse.remove(self.slots[slot].1.index());
        }
        self.reverse.insert(id.index(), slot);

        let tile = node.tile_indices[self.layer_params.layer_type.index()].unwrap() as usize;
        let len = self.layer_params.tile_bytes;
        let offset = self.layer_params.offset + tile * len;
        let data = unsafe { &self.data_file.as_slice()[offset..(offset + len)] };

        self.texture.update_layer(
            slot as u16,
            self.layer_params.tile_resolution as u16,
            gfx::memory::cast_slice(data),
            encoder,
        )
    }

    pub fn contains(&self, id: NodeId) -> bool {
        self.reverse.contains_key(id.index())
    }

    pub fn get_slot(&self, id: NodeId) -> Option<usize> {
        self.reverse.get(id.index()).cloned()
    }

    pub fn get_texture_view_f32(&self) -> Option<&gfx_core::handle::ShaderResourceView<R, f32>> {
        match self.texture {
            TextureArray::F32 { ref view, .. } => Some(view),
            _ => None,
        }
    }

    pub fn get_texture_view_rgba8(
        &self,
    ) -> Option<&gfx_core::handle::ShaderResourceView<R, [f32; 4]>> {
        match self.texture {
            TextureArray::RGBA8 { ref view, .. } => Some(view),
            _ => None,
        }
    }

    pub fn get_texture_view_srgba(
        &self,
    ) -> Option<&gfx_core::handle::ShaderResourceView<R, [f32; 4]>> {
        match self.texture {
            TextureArray::SRGBA { ref view, .. } => Some(view),
            _ => None,
        }
    }

    pub fn resolution(&self) -> u32 {
        self.layer_params.tile_resolution
    }

    pub fn border(&self) -> u32 {
        self.layer_params.border_size
    }
}
<commit_msg>Fix bug in tile cache<commit_after>use gfx;
use gfx_core;
use memmap::MmapViewSync;
use vec_map::VecMap;

use terrain::quadtree::{Node, NodeId};
use runtime_texture::{TextureArray, TextureFormat};

#[derive(Clone, Copy, PartialEq, PartialOrd, Serialize, Deserialize)]
pub struct Priority(f32);
impl Priority {
    pub fn cutoff() -> Self {
        Priority(1.0)
    }
    pub fn none() -> Self {
        Priority(-1.0)
    }
    pub fn from_f32(value: f32) -> Self {
        assert!(value.is_finite());
        Priority(value)
    }
}
impl Eq for Priority {}
impl Ord for Priority {
    fn cmp(&self, other: &Self) -> ::std::cmp::Ordering {
        self.partial_cmp(other).unwrap()
    }
}

pub const NUM_LAYERS: usize = 4;

#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub(crate) enum LayerType {
    Heights = 0,
    Colors = 1,
    Normals = 2,
    Water = 3,
}
impl LayerType {
    pub fn cache_size(&self) -> u16 {
        match *self {
            LayerType::Heights => 256,
            LayerType::Colors => 256,
            LayerType::Normals => 32,
            LayerType::Water => 256,
        }
    }
    pub fn index(&self) -> usize {
        *self as usize
    }
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub(crate) struct LayerParams {
    /// What kind of layer this is. There can be at most one of each layer type in a file.
    pub layer_type: LayerType,
    /// Byte offset from start of file.
    pub offset: usize,
    /// Number of tiles in layer.
    pub tile_count: usize,
    /// Number of samples in each dimension, per tile.
    pub tile_resolution: u32,
    /// Number of samples outside the tile on each side.
    pub border_size: u32,
    /// Format used by this layer.
    pub format: TextureFormat,
    /// Number of bytes per tile.
    pub tile_bytes: usize,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub(crate) struct NoiseParams {
    pub offset: usize,
    pub resolution: u32,
    pub format: TextureFormat,
    pub bytes: usize,
    pub wavelength: f32,
}

#[derive(Serialize, Deserialize)]
pub(crate) struct TileHeader {
    pub layers: Vec<LayerParams>,
    pub noise: NoiseParams,
    pub nodes: Vec<Node>,
}

pub(crate) struct TileCache<R: gfx::Resources> {
    /// Maximum number of slots in this `TileCache`.
    size: usize,
    /// Actually contents of the cache.
    slots: Vec<(Priority, NodeId)>,
    /// Which index each node is at in the cache (if any).
    reverse: VecMap<usize>,
    /// Nodes that should be added to the cache.
    missing: Vec<(Priority, NodeId)>,
    /// Smallest priority among all nodes in the cache.
    min_priority: Priority,

    /// Resolution of each tile in this cache.
    layer_params: LayerParams,

    texture: TextureArray<R>,

    /// Section of memory map that holds the data for this layer.
    data_file: MmapViewSync,
}
impl<R: gfx::Resources> TileCache<R> {
    pub fn new<F: gfx::Factory<R>>(
        params: LayerParams,
        data_file: MmapViewSync,
        factory: &mut F,
    ) -> Self {
        let cache_size = params.layer_type.cache_size();
        let texture = TextureArray::new(
            params.format,
            params.tile_resolution as u16,
            cache_size,
            factory,
        );

        Self {
            size: cache_size as usize,
            slots: Vec::new(),
            reverse: VecMap::new(),
            missing: Vec::new(),
            min_priority: Priority::none(),
            layer_params: params,
            data_file,
            texture,
        }
    }

    pub fn update_priorities(&mut self, nodes: &mut Vec<Node>) {
        for &mut (ref mut priority, id) in self.slots.iter_mut() {
            *priority = nodes[id].priority();
        }

        self.min_priority = self.slots.iter().map(|s| s.0).min().unwrap_or(
            Priority::none(),
        );
    }

    pub fn add_missing(&mut self, element: (Priority, NodeId)) {
        if element.0 > self.min_priority || self.slots.len() < self.size {
            self.missing.push(element);
        }
    }

    pub fn load_missing<C: gfx_core::command::Buffer<R>>(
        &mut self,
        nodes: &mut Vec<Node>,
        encoder: &mut gfx::Encoder<R, C>,
    ) {
        while !self.missing.is_empty() && self.slots.len() < self.size {
            let m = self.missing.pop().unwrap();
            let index = self.slots.len();
            self.slots.push(m.clone());
            self.reverse.insert(m.1.index(), index);
            self.load(&mut nodes[m.1], index, encoder);
        }

        if !self.missing.is_empty() {
            let mut possible: Vec<_> = self.slots
                .iter()
                .cloned()
                .chain(self.missing.iter().cloned())
                .collect();
            possible.sort();

            // Anything >= to cutoff should be included.
            let cutoff = possible[possible.len() - self.size];

            let mut index = 0;
            while let Some(m) = self.missing.pop() {
                if cutoff >= m {
                    continue;
                }

                // Find the next element to evict.
                while self.slots[index] >= cutoff {
                    index += 1;
                }

                self.reverse.remove(self.slots[index].1.index());
                self.reverse.insert(m.1.index(), index);
                self.slots[index] = m.clone();
                self.load(&mut nodes[m.1], index, encoder);
                index += 1;
            }
        }
    }

    fn load<C: gfx_core::command::Buffer<R>>(
        &mut self,
        node: &mut Node,
        slot: usize,
        encoder: &mut gfx::Encoder<R, C>,
    ) {
        let tile = node.tile_indices[self.layer_params.layer_type.index()].unwrap() as usize;
        let len = self.layer_params.tile_bytes;
        let offset = self.layer_params.offset + tile * len;
        let data = unsafe { &self.data_file.as_slice()[offset..(offset + len)] };

        self.texture.update_layer(
            slot as u16,
            self.layer_params.tile_resolution as u16,
            gfx::memory::cast_slice(data),
            encoder,
        )
    }

    pub fn contains(&self, id: NodeId) -> bool {
        self.reverse.contains_key(id.index())
    }

    pub fn get_slot(&self, id: NodeId) -> Option<usize> {
        self.reverse.get(id.index()).cloned()
    }

    pub fn get_texture_view_f32(&self) -> Option<&gfx_core::handle::ShaderResourceView<R, f32>> {
        match self.texture {
            TextureArray::F32 { ref view, .. } => Some(view),
            _ => None,
        }
    }

    pub fn get_texture_view_rgba8(
        &self,
    ) -> Option<&gfx_core::handle::ShaderResourceView<R, [f32; 4]>> {
        match self.texture {
            TextureArray::RGBA8 { ref view, .. } => Some(view),
            _ => None,
        }
    }

    pub fn get_texture_view_srgba(
        &self,
    ) -> Option<&gfx_core::handle::ShaderResourceView<R, [f32; 4]>> {
        match self.texture {
            TextureArray::SRGBA { ref view, .. } => Some(view),
            _ => None,
        }
    }

    pub fn resolution(&self) -> u32 {
        self.layer_params.tile_resolution
    }

    pub fn border(&self) -> u32 {
        self.layer_params.border_size
    }
}
<|endoftext|>


<commit_before>#![allow(dead_code)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(non_upper_case_globals)]

include!(concat!(env!("OUT_DIR"), "/aom.rs"));

use super::*;

use rand::{ChaChaRng, Rng, SeedableRng};
use std::collections::VecDeque;
use std::mem;
use std::sync::Arc;

    fn fill_frame(ra: &mut ChaChaRng, frame: &mut Frame) {
        for plane in frame.planes.iter_mut() {
            let stride = plane.cfg.stride;
            for row in plane.data.chunks_mut(stride) {
                for mut pixel in row {
                    let v: u8 = ra.gen();
                    *pixel = v as u16;
                }
            }
        }
    }

    struct AomDecoder {
        dec: aom_codec_ctx,
    }

    fn setup_decoder(w: usize, h: usize) -> AomDecoder {
        unsafe {
            let interface = aom_codec_av1_dx();
            let mut dec: AomDecoder = mem::uninitialized();
            let cfg = aom_codec_dec_cfg_t  {
                threads: 1,
                w: w as u32,
                h: h as u32,
                allow_lowbitdepth: 1,
                cfg: cfg_options { ext_partition: 1 }
            };

            let ret = aom_codec_dec_init_ver(&mut dec.dec, interface, &cfg, 0, AOM_DECODER_ABI_VERSION as i32);
            if ret != 0 {
                panic!("Cannot instantiate the decoder {}", ret);
            }

            dec
        }
    }

    impl Drop for AomDecoder {
        fn drop(&mut self) {
            unsafe { aom_codec_destroy(&mut self.dec) };
        }

    }

    fn setup_encoder(w: usize, h: usize, speed: usize, quantizer: usize,
        bit_depth: usize, chroma_sampling: ChromaSampling) -> Context {
        unsafe {
            av1_rtcd();
            aom_dsp_rtcd();
        }

        let enc = EncoderConfig {
            quantizer: quantizer,
            speed: speed,
            ..Default::default()
        };

        let cfg = Config {
            width: w,
            height: h,
            bit_depth,
            chroma_sampling,
            timebase: Ratio::new(1, 1000),
            enc,
        };

        cfg.new_context()
    }

    // TODO: support non-multiple-of-16 dimensions
    static DIMENSION_OFFSETS: &[(usize, usize)] = &[(0, 0), (4, 4), (8, 8), (16, 16)];

    #[test]
    #[ignore]
    fn speed() {
        let quantizer = 100;
        let limit = 5;
        let w = 64;
        let h = 80;

        for b in DIMENSION_OFFSETS.iter() {
            for s in 0 .. 10 {
                encode_decode(w + b.0, h + b.1, s, quantizer, limit, 8);
            }
        }
    }

    static DIMENSIONS: &[(usize, usize)] = &[(8, 8), (16, 16), (32, 32), (64, 64),
        (128, 128), (256, 256), (512, 512), (1024, 1024), (2048, 2048),
        (258, 258), (260, 260), (262, 262), (264, 264), (265, 265)];

    #[test]
    #[ignore]
    fn dimensions() {
        let quantizer = 100;
        let limit = 1;
        let speed = 4;

        for (w, h) in DIMENSIONS.iter() {
            encode_decode(*w, *h, speed, quantizer, limit, 8);
        }
    }

    #[test]
    #[ignore]
    fn quantizer() {
        let limit = 5;
        let w = 64;
        let h = 80;
        let speed = 4;

        for b in DIMENSION_OFFSETS.iter() {
            for &q in [80, 100, 120].iter() {
                encode_decode(w + b.0, h + b.1, speed, q, limit, 8);
            }
        }
    }

    #[test]
    #[ignore]
    fn odd_size_frame_with_full_rdo() {
        let limit = 3;
        let w = 512 + 32 + 16 + 5;
        let h = 512 + 16 + 5;
        let speed = 0;
        let qindex = 100;

        encode_decode(w, h, speed, qindex, limit, 8);
    }

    #[test]
    #[ignore]
    fn high_bd() {
        let quantizer = 100;
        let limit = 3; // Include inter frames
        let speed = 0; // Test as many tools as possible
        let w = 64;
        let h = 80;

        // 10-bit
        encode_decode(w, h, speed, quantizer, limit, 10);

        // 12-bit
        encode_decode(w, h, speed, quantizer, limit, 12);
    }

    fn compare_plane<T: Ord + std::fmt::Debug>(rec: &[T], rec_stride: usize,
                     dec: &[T], dec_stride: usize,
                     width: usize, height: usize) {
        for line in rec.chunks(rec_stride)
            .zip(dec.chunks(dec_stride)).take(height) {
            assert_eq!(&line.0[..width], &line.1[..width]);
        }
    }

    fn compare_img(img: *const aom_image_t, frame: &Frame, bit_depth: usize) {
        use std::slice;
        let img = unsafe { *img };
        let img_iter = img.planes.iter().zip(img.stride.iter());

        for (img_plane, frame_plane) in img_iter.zip(frame.planes.iter()) {
            let w = frame_plane.cfg.width;
            let h = frame_plane.cfg.height;
            let rec_stride = frame_plane.cfg.stride;

            if bit_depth > 8 {
                let dec_stride = *img_plane.1 as usize / 2;

                let dec = unsafe {
                    let data = *img_plane.0 as *const u16;
                    let size = dec_stride * h;

                    slice::from_raw_parts(data, size)
                };

                let rec: Vec<u16> = frame_plane.data_origin().iter().map(|&v| v).collect();

                compare_plane::<u16>(&rec[..], rec_stride, dec, dec_stride, w, h);
            } else {
                let dec_stride = *img_plane.1 as usize;

                let dec = unsafe {
                    let data = *img_plane.0 as *const u8;
                    let size = dec_stride * h;

                    slice::from_raw_parts(data, size)
                };

                let rec: Vec<u8> = frame_plane.data_origin().iter().map(|&v| v as u8).collect();

                compare_plane::<u8>(&rec[..], rec_stride, dec, dec_stride, w, h);
            }
        }
    }

    fn encode_decode(w: usize, h: usize, speed: usize, quantizer: usize, limit: usize, bit_depth: usize) {
        use std::ptr;
        let mut ra = ChaChaRng::from_seed([0; 32]);

        let mut dec = setup_decoder(w, h);
        let mut ctx = setup_encoder(w, h, speed, quantizer, bit_depth, ChromaSampling::Cs420);

        println!("Encoding {}x{} speed {} quantizer {}", w, h, speed, quantizer);

        let mut iter: aom_codec_iter_t = ptr::null_mut();

        let mut rec_fifo = VecDeque::new();

        for _ in 0 .. limit {
            let mut input = ctx.new_frame();
            fill_frame(&mut ra, Arc::get_mut(&mut input).unwrap());

            let _ = ctx.send_frame(input);
            let pkt = ctx.receive_packet().unwrap();
            println!("Encoded packet {}", pkt.number);

            rec_fifo.push_back(pkt.rec.clone());

            let packet = pkt.data;

            let mut corrupted_count = 0;
            unsafe {
                println!("Decoding frame {}", pkt.number);
                let ret = aom_codec_decode(&mut dec.dec, packet.as_ptr(), packet.len(), ptr::null_mut());
                println!("Decoded. -> {}", ret);
                if ret != 0 {
                    use std::ffi::CStr;
                    let error_msg = aom_codec_error(&mut dec.dec);
                    println!("  Decode codec_decode failed: {}", CStr::from_ptr(error_msg).to_string_lossy());
                    let detail = aom_codec_error_detail(&mut dec.dec);
                    if !detail.is_null() {
                        println!("  Decode codec_decode failed {}", CStr::from_ptr(detail).to_string_lossy());
                    }

                    corrupted_count += 1;
                }

                if ret == 0 {
                    loop {
                        println!("Retrieving frame");
                        let img = aom_codec_get_frame(&mut dec.dec, &mut iter);
                        println!("Retrieved.");
                        if img.is_null() {
                            break;
                        }
                        let mut corrupted = 0;
                        let ret = aom_codec_control_(&mut dec.dec, aom_dec_control_id_AOMD_GET_FRAME_CORRUPTED as i32, &mut corrupted);
                        if ret != 0 {
                            use std::ffi::CStr;
                            let detail = aom_codec_error_detail(&mut dec.dec);
                            panic!("Decode codec_control failed {}", CStr::from_ptr(detail).to_string_lossy());
                        }
                        corrupted_count += corrupted;

                        let rec = rec_fifo.pop_front().unwrap();
                        compare_img(img, &rec, bit_depth);
                    }
                }
            }

            assert_eq!(corrupted_count, 0);
        }
    }
<commit_msg>Format src/test_encode_decode.rs<commit_after>#![allow(dead_code)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(non_upper_case_globals)]

include!(concat!(env!("OUT_DIR"), "/aom.rs"));

use super::*;

use rand::{ChaChaRng, Rng, SeedableRng};
use std::collections::VecDeque;
use std::mem;
use std::sync::Arc;

fn fill_frame(ra: &mut ChaChaRng, frame: &mut Frame) {
  for plane in frame.planes.iter_mut() {
    let stride = plane.cfg.stride;
    for row in plane.data.chunks_mut(stride) {
      for mut pixel in row {
        let v: u8 = ra.gen();
        *pixel = v as u16;
      }
    }
  }
}

struct AomDecoder {
  dec: aom_codec_ctx
}

fn setup_decoder(w: usize, h: usize) -> AomDecoder {
  unsafe {
    let interface = aom_codec_av1_dx();
    let mut dec: AomDecoder = mem::uninitialized();
    let cfg = aom_codec_dec_cfg_t {
      threads: 1,
      w: w as u32,
      h: h as u32,
      allow_lowbitdepth: 1,
      cfg: cfg_options { ext_partition: 1 }
    };

    let ret = aom_codec_dec_init_ver(
      &mut dec.dec,
      interface,
      &cfg,
      0,
      AOM_DECODER_ABI_VERSION as i32
    );
    if ret != 0 {
      panic!("Cannot instantiate the decoder {}", ret);
    }

    dec
  }
}

impl Drop for AomDecoder {
  fn drop(&mut self) {
    unsafe { aom_codec_destroy(&mut self.dec) };
  }
}

fn setup_encoder(
  w: usize, h: usize, speed: usize, quantizer: usize, bit_depth: usize,
  chroma_sampling: ChromaSampling
) -> Context {
  unsafe {
    av1_rtcd();
    aom_dsp_rtcd();
  }

  let enc = EncoderConfig { quantizer, speed, ..Default::default() };

  let cfg = Config {
    width: w,
    height: h,
    bit_depth,
    chroma_sampling,
    timebase: Ratio::new(1, 1000),
    enc
  };

  cfg.new_context()
}

// TODO: support non-multiple-of-16 dimensions
static DIMENSION_OFFSETS: &[(usize, usize)] =
  &[(0, 0), (4, 4), (8, 8), (16, 16)];

#[test]
#[ignore]
fn speed() {
  let quantizer = 100;
  let limit = 5;
  let w = 64;
  let h = 80;

  for b in DIMENSION_OFFSETS.iter() {
    for s in 0..10 {
      encode_decode(w + b.0, h + b.1, s, quantizer, limit, 8);
    }
  }
}

static DIMENSIONS: &[(usize, usize)] = &[
  (8, 8),
  (16, 16),
  (32, 32),
  (64, 64),
  (128, 128),
  (256, 256),
  (512, 512),
  (1024, 1024),
  (2048, 2048),
  (258, 258),
  (260, 260),
  (262, 262),
  (264, 264),
  (265, 265)
];

#[test]
#[ignore]
fn dimensions() {
  let quantizer = 100;
  let limit = 1;
  let speed = 4;

  for (w, h) in DIMENSIONS.iter() {
    encode_decode(*w, *h, speed, quantizer, limit, 8);
  }
}

#[test]
#[ignore]
fn quantizer() {
  let limit = 5;
  let w = 64;
  let h = 80;
  let speed = 4;

  for b in DIMENSION_OFFSETS.iter() {
    for &q in [80, 100, 120].iter() {
      encode_decode(w + b.0, h + b.1, speed, q, limit, 8);
    }
  }
}

#[test]
#[ignore]
fn odd_size_frame_with_full_rdo() {
  let limit = 3;
  let w = 512 + 32 + 16 + 5;
  let h = 512 + 16 + 5;
  let speed = 0;
  let qindex = 100;

  encode_decode(w, h, speed, qindex, limit, 8);
}

#[test]
#[ignore]
fn high_bd() {
  let quantizer = 100;
  let limit = 3; // Include inter frames
  let speed = 0; // Test as many tools as possible
  let w = 64;
  let h = 80;

  // 10-bit
  encode_decode(w, h, speed, quantizer, limit, 10);

  // 12-bit
  encode_decode(w, h, speed, quantizer, limit, 12);
}

fn compare_plane<T: Ord + std::fmt::Debug>(
  rec: &[T], rec_stride: usize, dec: &[T], dec_stride: usize, width: usize,
  height: usize
) {
  for line in rec.chunks(rec_stride).zip(dec.chunks(dec_stride)).take(height) {
    assert_eq!(&line.0[..width], &line.1[..width]);
  }
}

fn compare_img(img: *const aom_image_t, frame: &Frame, bit_depth: usize) {
  use std::slice;
  let img = unsafe { *img };
  let img_iter = img.planes.iter().zip(img.stride.iter());

  for (img_plane, frame_plane) in img_iter.zip(frame.planes.iter()) {
    let w = frame_plane.cfg.width;
    let h = frame_plane.cfg.height;
    let rec_stride = frame_plane.cfg.stride;

    if bit_depth > 8 {
      let dec_stride = *img_plane.1 as usize / 2;

      let dec = unsafe {
        let data = *img_plane.0 as *const u16;
        let size = dec_stride * h;

        slice::from_raw_parts(data, size)
      };

      let rec: Vec<u16> =
        frame_plane.data_origin().iter().map(|&v| v).collect();

      compare_plane::<u16>(&rec[..], rec_stride, dec, dec_stride, w, h);
    } else {
      let dec_stride = *img_plane.1 as usize;

      let dec = unsafe {
        let data = *img_plane.0 as *const u8;
        let size = dec_stride * h;

        slice::from_raw_parts(data, size)
      };

      let rec: Vec<u8> =
        frame_plane.data_origin().iter().map(|&v| v as u8).collect();

      compare_plane::<u8>(&rec[..], rec_stride, dec, dec_stride, w, h);
    }
  }
}

fn encode_decode(
  w: usize, h: usize, speed: usize, quantizer: usize, limit: usize,
  bit_depth: usize
) {
  use std::ptr;
  let mut ra = ChaChaRng::from_seed([0; 32]);

  let mut dec = setup_decoder(w, h);
  let mut ctx =
    setup_encoder(w, h, speed, quantizer, bit_depth, ChromaSampling::Cs420);

  println!("Encoding {}x{} speed {} quantizer {}", w, h, speed, quantizer);

  let mut iter: aom_codec_iter_t = ptr::null_mut();

  let mut rec_fifo = VecDeque::new();

  for _ in 0..limit {
    let mut input = ctx.new_frame();
    fill_frame(&mut ra, Arc::get_mut(&mut input).unwrap());

    let _ = ctx.send_frame(input);
    let pkt = ctx.receive_packet().unwrap();
    println!("Encoded packet {}", pkt.number);

    rec_fifo.push_back(pkt.rec.clone());

    let packet = pkt.data;

    let mut corrupted_count = 0;
    unsafe {
      println!("Decoding frame {}", pkt.number);
      let ret = aom_codec_decode(
        &mut dec.dec,
        packet.as_ptr(),
        packet.len(),
        ptr::null_mut()
      );
      println!("Decoded. -> {}", ret);
      if ret != 0 {
        use std::ffi::CStr;
        let error_msg = aom_codec_error(&mut dec.dec);
        println!(
          "  Decode codec_decode failed: {}",
          CStr::from_ptr(error_msg).to_string_lossy()
        );
        let detail = aom_codec_error_detail(&mut dec.dec);
        if !detail.is_null() {
          println!(
            "  Decode codec_decode failed {}",
            CStr::from_ptr(detail).to_string_lossy()
          );
        }

        corrupted_count += 1;
      }

      if ret == 0 {
        loop {
          println!("Retrieving frame");
          let img = aom_codec_get_frame(&mut dec.dec, &mut iter);
          println!("Retrieved.");
          if img.is_null() {
            break;
          }
          let mut corrupted = 0;
          let ret = aom_codec_control_(
            &mut dec.dec,
            aom_dec_control_id_AOMD_GET_FRAME_CORRUPTED as i32,
            &mut corrupted
          );
          if ret != 0 {
            use std::ffi::CStr;
            let detail = aom_codec_error_detail(&mut dec.dec);
            panic!(
              "Decode codec_control failed {}",
              CStr::from_ptr(detail).to_string_lossy()
            );
          }
          corrupted_count += corrupted;

          let rec = rec_fifo.pop_front().unwrap();
          compare_img(img, &rec, bit_depth);
        }
      }
    }

    assert_eq!(corrupted_count, 0);
  }
}
<|endoftext|>