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

use rustc::hir;
use rustc::hir::def_id::DefId;
use rustc::hir::itemlikevisit::ItemLikeVisitor;
use rustc::ty::subst::{Kind, Subst, UnpackedKind};
use rustc::ty::{self, Ty, TyCtxt};
use rustc::util::nodemap::FxHashMap;

use super::explicit::ExplicitPredicatesMap;
use super::utils::*;

/// Infer predicates for the items in the crate.
///
/// global_inferred_outlives: this is initially the empty map that
///     was generated by walking the items in the crate. This will
///     now be filled with inferred predicates.
pub fn infer_predicates<'tcx>(
    tcx: TyCtxt<'_, 'tcx, 'tcx>,
    explicit_map: &mut ExplicitPredicatesMap<'tcx>,
) -> FxHashMap<DefId, RequiredPredicates<'tcx>> {
    debug!("infer_predicates");

    let mut predicates_added = true;

    let mut global_inferred_outlives = FxHashMap::default();

    // If new predicates were added then we need to re-calculate
    // all crates since there could be new implied predicates.
    while predicates_added {
        predicates_added = false;

        let mut visitor = InferVisitor {
            tcx: tcx,
            global_inferred_outlives: &mut global_inferred_outlives,
            predicates_added: &mut predicates_added,
            explicit_map: explicit_map,
        };

        // Visit all the crates and infer predicates
        tcx.hir.krate().visit_all_item_likes(&mut visitor);
    }

    global_inferred_outlives
}

pub struct InferVisitor<'cx, 'tcx: 'cx> {
    tcx: TyCtxt<'cx, 'tcx, 'tcx>,
    global_inferred_outlives: &'cx mut FxHashMap<DefId, RequiredPredicates<'tcx>>,
    predicates_added: &'cx mut bool,
    explicit_map: &'cx mut ExplicitPredicatesMap<'tcx>,
}

impl<'cx, 'tcx> ItemLikeVisitor<'tcx> for InferVisitor<'cx, 'tcx> {
    fn visit_item(&mut self, item: &hir::Item) {
        let item_did = self.tcx.hir.local_def_id(item.id);

        debug!("InferVisitor::visit_item(item={:?})", item_did);

        let node_id = self
            .tcx
            .hir
            .as_local_node_id(item_did)
            .expect("expected local def-id");
        let item = match self.tcx.hir.get(node_id) {
            hir::map::NodeItem(item) => item,
            _ => bug!(),
        };

        let mut item_required_predicates = RequiredPredicates::default();
        match item.node {
            hir::ItemKind::Union(..) | hir::ItemKind::Enum(..) | hir::ItemKind::Struct(..) => {
                let adt_def = self.tcx.adt_def(item_did);

                // Iterate over all fields in item_did
                for field_def in adt_def.all_fields() {
                    // Calculating the predicate requirements necessary
                    // for item_did.
                    //
                    // For field of type &'a T (reference) or Adt
                    // (struct/enum/union) there will be outlive
                    // requirements for adt_def.
                    let field_ty = self.tcx.type_of(field_def.did);
                    insert_required_predicates_to_be_wf(
                        self.tcx,
                        field_ty,
                        self.global_inferred_outlives,
                        &mut item_required_predicates,
                        &mut self.explicit_map,
                    );
                }
            }

            _ => {}
        };

        // If new predicates were added (`local_predicate_map` has more
        // predicates than the `global_inferred_outlives`), the new predicates
        // might result in implied predicates for their parent types.
        // Therefore mark `predicates_added` as true and which will ensure
        // we walk the crates again and re-calculate predicates for all
        // items.
        let item_predicates_len: usize = self
            .global_inferred_outlives
            .get(&item_did)
            .map(|p| p.len())
            .unwrap_or(0);
        if item_required_predicates.len() > item_predicates_len {
            *self.predicates_added = true;
            self.global_inferred_outlives
                .insert(item_did, item_required_predicates);
        }
    }

    fn visit_trait_item(&mut self, _trait_item: &'tcx hir::TraitItem) {}

    fn visit_impl_item(&mut self, _impl_item: &'tcx hir::ImplItem) {}
}

fn insert_required_predicates_to_be_wf<'tcx>(
    tcx: TyCtxt<'_, 'tcx, 'tcx>,
    field_ty: Ty<'tcx>,
    global_inferred_outlives: &FxHashMap<DefId, RequiredPredicates<'tcx>>,
    required_predicates: &mut RequiredPredicates<'tcx>,
    explicit_map: &mut ExplicitPredicatesMap<'tcx>,
) {
    for ty in field_ty.walk() {
        match ty.sty {
            // The field is of type &'a T which means that we will have
            // a predicate requirement of T: 'a (T outlives 'a).
            //
            // We also want to calculate potential predicates for the T
            ty::Ref(region, rty, _) => {
                debug!("Ref");
                insert_outlives_predicate(tcx, rty.into(), region, required_predicates);
            }

            // For each Adt (struct/enum/union) type `Foo<'a, T>`, we
            // can load the current set of inferred and explicit
            // predicates from `global_inferred_outlives` and filter the
            // ones that are TypeOutlives.
            ty::Adt(def, substs) => {
                // First check the inferred predicates
                //
                // Example 1:
                //
                //     struct Foo<'a, T> {
                //         field1: Bar<'a, T>
                //     }
                //
                //     struct Bar<'b, U> {
                //         field2: &'b U
                //     }
                //
                // Here, when processing the type of `field1`, we would
                // request the set of implicit predicates computed for `Bar`
                // thus far. This will initially come back empty, but in next
                // round we will get `U: 'b`. We then apply the substitution
                // `['b => 'a, U => T]` and thus get the requirement that `T:
                // 'a` holds for `Foo`.
                debug!("Adt");
                if let Some(unsubstituted_predicates) = global_inferred_outlives.get(&def.did) {
                    for unsubstituted_predicate in unsubstituted_predicates {
                        // `unsubstituted_predicate` is `U: 'b` in the
                        // example above.  So apply the substitution to
                        // get `T: 'a` (or `predicate`):
                        let predicate = unsubstituted_predicate.subst(tcx, substs);
                        insert_outlives_predicate(
                            tcx,
                            predicate.0,
                            predicate.1,
                            required_predicates,
                        );
                    }
                }

                // Check if the type has any explicit predicates that need
                // to be added to `required_predicates`
                // let _: () = substs.region_at(0);
                check_explicit_predicates(
                    tcx,
                    &def.did,
                    substs,
                    required_predicates,
                    explicit_map,
                    IgnoreSelfTy(false),
                );
            }

            ty::Dynamic(obj, ..) => {
                // This corresponds to `dyn Trait<..>`. In this case, we should
                // use the explicit predicates as well.

                debug!("Dynamic");
                debug!("field_ty = {}", &field_ty);
                debug!("ty in field = {}", &ty);
                if let Some(ex_trait_ref) = obj.principal() {
                    // Here, we are passing the type `usize` as a
                    // placeholder value with the function
                    // `with_self_ty`, since there is no concrete type
                    // `Self` for a `dyn Trait` at this
                    // stage. Therefore when checking explicit
                    // predicates in `check_explicit_predicates` we
                    // need to ignore checking the explicit_map for
                    // Self type.
                    let substs = ex_trait_ref.with_self_ty(tcx, tcx.types.usize).skip_binder().substs;
                    check_explicit_predicates(
                        tcx,
                        &ex_trait_ref.skip_binder().def_id,
                        substs,
                        required_predicates,
                        explicit_map,
                        IgnoreSelfTy(true),
                    );
                }
            }

            ty::Projection(obj) => {
                // This corresponds to `<T as Foo<'a>>::Bar`. In this case, we should use the
                // explicit predicates as well.
                debug!("Projection");
                check_explicit_predicates(
                    tcx,
                    &tcx.associated_item(obj.item_def_id).container.id(),
                    obj.substs,
                    required_predicates,
                    explicit_map,
                    IgnoreSelfTy(false),
                );
            }

            _ => {}
        }
    }
}

pub struct IgnoreSelfTy(bool);

/// We also have to check the explicit predicates
/// declared on the type.
///
///     struct Foo<'a, T> {
///         field1: Bar<T>
///     }
///
///     struct Bar<U> where U: 'static, U: Foo {
///         ...
///     }
///
/// Here, we should fetch the explicit predicates, which
/// will give us `U: 'static` and `U: Foo`. The latter we
/// can ignore, but we will want to process `U: 'static`,
/// applying the substitution as above.
pub fn check_explicit_predicates<'tcx>(
    tcx: TyCtxt<'_, 'tcx, 'tcx>,
    def_id: &DefId,
    substs: &[Kind<'tcx>],
    required_predicates: &mut RequiredPredicates<'tcx>,
    explicit_map: &mut ExplicitPredicatesMap<'tcx>,
    ignore_self_ty: IgnoreSelfTy,
) {
    debug!("def_id = {:?}", &def_id);
    debug!("substs = {:?}", &substs);
    debug!("explicit_map =  {:?}", explicit_map);
    debug!("required_predicates = {:?}", required_predicates);
    let explicit_predicates = explicit_map.explicit_predicates_of(tcx, *def_id);

    for outlives_predicate in explicit_predicates.iter() {
        debug!("outlives_predicate = {:?}", &outlives_predicate);

        // Careful: If we are inferring the effects of a `dyn Trait<..>`
        // type, then when we look up the predicates for `Trait`,
        // we may find some that reference `Self`. e.g., perhaps the
        // definition of `Trait` was:
        //
        // ```
        // trait Trait<'a, T> where Self: 'a  { .. }
        // ```
        //
        // we want to ignore such predicates here, because
        // there is no type parameter for them to affect. Consider
        // a struct containing `dyn Trait`:
        //
        // ```
        // struct MyStruct<'x, X> { field: Box<dyn Trait<'x, X>> }
        // ```
        //
        // The `where Self: 'a` predicate refers to the *existential, hidden type*
        // that is represented by the `dyn Trait`, not to the `X` type parameter
        // (or any other generic parameter) declared on `MyStruct`.
        //
        // Note that we do this check for self **before** applying `substs`. In the
        // case that `substs` come from a `dyn Trait` type, our caller will have
        // included `Self = dyn Trait<'x, X>` as the value for `Self`. If we were
        // to apply the substs, and not filter this predicate, we might then falsely
        // conclude that e.g. `X: 'x` was a reasonable inferred requirement.
        if let UnpackedKind::Type(ty) = outlives_predicate.0.unpack() {
            if ty.is_self() && ignore_self_ty.0 {
                debug!("skipping self ty = {:?}", &ty);
                continue;
            }
        }

        let predicate = outlives_predicate.subst(tcx, substs);
        debug!("predicate = {:?}", &predicate);
        insert_outlives_predicate(tcx, predicate.0.into(), predicate.1, required_predicates);
    }
}
<commit_msg>implicit_infer: apply rustfmt<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use rustc::hir;
use rustc::hir::def_id::DefId;
use rustc::hir::itemlikevisit::ItemLikeVisitor;
use rustc::ty::subst::{Kind, Subst, UnpackedKind};
use rustc::ty::{self, Ty, TyCtxt};
use rustc::util::nodemap::FxHashMap;

use super::explicit::ExplicitPredicatesMap;
use super::utils::*;

/// Infer predicates for the items in the crate.
///
/// global_inferred_outlives: this is initially the empty map that
///     was generated by walking the items in the crate. This will
///     now be filled with inferred predicates.
pub fn infer_predicates<'tcx>(
    tcx: TyCtxt<'_, 'tcx, 'tcx>,
    explicit_map: &mut ExplicitPredicatesMap<'tcx>,
) -> FxHashMap<DefId, RequiredPredicates<'tcx>> {
    debug!("infer_predicates");

    let mut predicates_added = true;

    let mut global_inferred_outlives = FxHashMap::default();

    // If new predicates were added then we need to re-calculate
    // all crates since there could be new implied predicates.
    while predicates_added {
        predicates_added = false;

        let mut visitor = InferVisitor {
            tcx: tcx,
            global_inferred_outlives: &mut global_inferred_outlives,
            predicates_added: &mut predicates_added,
            explicit_map: explicit_map,
        };

        // Visit all the crates and infer predicates
        tcx.hir.krate().visit_all_item_likes(&mut visitor);
    }

    global_inferred_outlives
}

pub struct InferVisitor<'cx, 'tcx: 'cx> {
    tcx: TyCtxt<'cx, 'tcx, 'tcx>,
    global_inferred_outlives: &'cx mut FxHashMap<DefId, RequiredPredicates<'tcx>>,
    predicates_added: &'cx mut bool,
    explicit_map: &'cx mut ExplicitPredicatesMap<'tcx>,
}

impl<'cx, 'tcx> ItemLikeVisitor<'tcx> for InferVisitor<'cx, 'tcx> {
    fn visit_item(&mut self, item: &hir::Item) {
        let item_did = self.tcx.hir.local_def_id(item.id);

        debug!("InferVisitor::visit_item(item={:?})", item_did);

        let node_id = self.tcx
            .hir
            .as_local_node_id(item_did)
            .expect("expected local def-id");
        let item = match self.tcx.hir.get(node_id) {
            hir::map::NodeItem(item) => item,
            _ => bug!(),
        };

        let mut item_required_predicates = RequiredPredicates::default();
        match item.node {
            hir::ItemKind::Union(..) | hir::ItemKind::Enum(..) | hir::ItemKind::Struct(..) => {
                let adt_def = self.tcx.adt_def(item_did);

                // Iterate over all fields in item_did
                for field_def in adt_def.all_fields() {
                    // Calculating the predicate requirements necessary
                    // for item_did.
                    //
                    // For field of type &'a T (reference) or Adt
                    // (struct/enum/union) there will be outlive
                    // requirements for adt_def.
                    let field_ty = self.tcx.type_of(field_def.did);
                    insert_required_predicates_to_be_wf(
                        self.tcx,
                        field_ty,
                        self.global_inferred_outlives,
                        &mut item_required_predicates,
                        &mut self.explicit_map,
                    );
                }
            }

            _ => {}
        };

        // If new predicates were added (`local_predicate_map` has more
        // predicates than the `global_inferred_outlives`), the new predicates
        // might result in implied predicates for their parent types.
        // Therefore mark `predicates_added` as true and which will ensure
        // we walk the crates again and re-calculate predicates for all
        // items.
        let item_predicates_len: usize = self.global_inferred_outlives
            .get(&item_did)
            .map(|p| p.len())
            .unwrap_or(0);
        if item_required_predicates.len() > item_predicates_len {
            *self.predicates_added = true;
            self.global_inferred_outlives
                .insert(item_did, item_required_predicates);
        }
    }

    fn visit_trait_item(&mut self, _trait_item: &'tcx hir::TraitItem) {}

    fn visit_impl_item(&mut self, _impl_item: &'tcx hir::ImplItem) {}
}

fn insert_required_predicates_to_be_wf<'tcx>(
    tcx: TyCtxt<'_, 'tcx, 'tcx>,
    field_ty: Ty<'tcx>,
    global_inferred_outlives: &FxHashMap<DefId, RequiredPredicates<'tcx>>,
    required_predicates: &mut RequiredPredicates<'tcx>,
    explicit_map: &mut ExplicitPredicatesMap<'tcx>,
) {
    for ty in field_ty.walk() {
        match ty.sty {
            // The field is of type &'a T which means that we will have
            // a predicate requirement of T: 'a (T outlives 'a).
            //
            // We also want to calculate potential predicates for the T
            ty::Ref(region, rty, _) => {
                debug!("Ref");
                insert_outlives_predicate(tcx, rty.into(), region, required_predicates);
            }

            // For each Adt (struct/enum/union) type `Foo<'a, T>`, we
            // can load the current set of inferred and explicit
            // predicates from `global_inferred_outlives` and filter the
            // ones that are TypeOutlives.
            ty::Adt(def, substs) => {
                // First check the inferred predicates
                //
                // Example 1:
                //
                //     struct Foo<'a, T> {
                //         field1: Bar<'a, T>
                //     }
                //
                //     struct Bar<'b, U> {
                //         field2: &'b U
                //     }
                //
                // Here, when processing the type of `field1`, we would
                // request the set of implicit predicates computed for `Bar`
                // thus far. This will initially come back empty, but in next
                // round we will get `U: 'b`. We then apply the substitution
                // `['b => 'a, U => T]` and thus get the requirement that `T:
                // 'a` holds for `Foo`.
                debug!("Adt");
                if let Some(unsubstituted_predicates) = global_inferred_outlives.get(&def.did) {
                    for unsubstituted_predicate in unsubstituted_predicates {
                        // `unsubstituted_predicate` is `U: 'b` in the
                        // example above.  So apply the substitution to
                        // get `T: 'a` (or `predicate`):
                        let predicate = unsubstituted_predicate.subst(tcx, substs);
                        insert_outlives_predicate(
                            tcx,
                            predicate.0,
                            predicate.1,
                            required_predicates,
                        );
                    }
                }

                // Check if the type has any explicit predicates that need
                // to be added to `required_predicates`
                // let _: () = substs.region_at(0);
                check_explicit_predicates(
                    tcx,
                    &def.did,
                    substs,
                    required_predicates,
                    explicit_map,
                    IgnoreSelfTy(false),
                );
            }

            ty::Dynamic(obj, ..) => {
                // This corresponds to `dyn Trait<..>`. In this case, we should
                // use the explicit predicates as well.

                debug!("Dynamic");
                debug!("field_ty = {}", &field_ty);
                debug!("ty in field = {}", &ty);
                if let Some(ex_trait_ref) = obj.principal() {
                    // Here, we are passing the type `usize` as a
                    // placeholder value with the function
                    // `with_self_ty`, since there is no concrete type
                    // `Self` for a `dyn Trait` at this
                    // stage. Therefore when checking explicit
                    // predicates in `check_explicit_predicates` we
                    // need to ignore checking the explicit_map for
                    // Self type.
                    let substs = ex_trait_ref
                        .with_self_ty(tcx, tcx.types.usize)
                        .skip_binder()
                        .substs;
                    check_explicit_predicates(
                        tcx,
                        &ex_trait_ref.skip_binder().def_id,
                        substs,
                        required_predicates,
                        explicit_map,
                        IgnoreSelfTy(true),
                    );
                }
            }

            ty::Projection(obj) => {
                // This corresponds to `<T as Foo<'a>>::Bar`. In this case, we should use the
                // explicit predicates as well.
                debug!("Projection");
                check_explicit_predicates(
                    tcx,
                    &tcx.associated_item(obj.item_def_id).container.id(),
                    obj.substs,
                    required_predicates,
                    explicit_map,
                    IgnoreSelfTy(false),
                );
            }

            _ => {}
        }
    }
}

pub struct IgnoreSelfTy(bool);

/// We also have to check the explicit predicates
/// declared on the type.
///
///     struct Foo<'a, T> {
///         field1: Bar<T>
///     }
///
///     struct Bar<U> where U: 'static, U: Foo {
///         ...
///     }
///
/// Here, we should fetch the explicit predicates, which
/// will give us `U: 'static` and `U: Foo`. The latter we
/// can ignore, but we will want to process `U: 'static`,
/// applying the substitution as above.
pub fn check_explicit_predicates<'tcx>(
    tcx: TyCtxt<'_, 'tcx, 'tcx>,
    def_id: &DefId,
    substs: &[Kind<'tcx>],
    required_predicates: &mut RequiredPredicates<'tcx>,
    explicit_map: &mut ExplicitPredicatesMap<'tcx>,
    ignore_self_ty: IgnoreSelfTy,
) {
    debug!("def_id = {:?}", &def_id);
    debug!("substs = {:?}", &substs);
    debug!("explicit_map =  {:?}", explicit_map);
    debug!("required_predicates = {:?}", required_predicates);
    let explicit_predicates = explicit_map.explicit_predicates_of(tcx, *def_id);

    for outlives_predicate in explicit_predicates.iter() {
        debug!("outlives_predicate = {:?}", &outlives_predicate);

        // Careful: If we are inferring the effects of a `dyn Trait<..>`
        // type, then when we look up the predicates for `Trait`,
        // we may find some that reference `Self`. e.g., perhaps the
        // definition of `Trait` was:
        //
        // ```
        // trait Trait<'a, T> where Self: 'a  { .. }
        // ```
        //
        // we want to ignore such predicates here, because
        // there is no type parameter for them to affect. Consider
        // a struct containing `dyn Trait`:
        //
        // ```
        // struct MyStruct<'x, X> { field: Box<dyn Trait<'x, X>> }
        // ```
        //
        // The `where Self: 'a` predicate refers to the *existential, hidden type*
        // that is represented by the `dyn Trait`, not to the `X` type parameter
        // (or any other generic parameter) declared on `MyStruct`.
        //
        // Note that we do this check for self **before** applying `substs`. In the
        // case that `substs` come from a `dyn Trait` type, our caller will have
        // included `Self = dyn Trait<'x, X>` as the value for `Self`. If we were
        // to apply the substs, and not filter this predicate, we might then falsely
        // conclude that e.g. `X: 'x` was a reasonable inferred requirement.
        if let UnpackedKind::Type(ty) = outlives_predicate.0.unpack() {
            if ty.is_self() && ignore_self_ty.0 {
                debug!("skipping self ty = {:?}", &ty);
                continue;
            }
        }

        let predicate = outlives_predicate.subst(tcx, substs);
        debug!("predicate = {:?}", &predicate);
        insert_outlives_predicate(tcx, predicate.0.into(), predicate.1, required_predicates);
    }
}
<|endoftext|>


<commit_before>//! IGD async API example.
//!
//! It demonstrates how to:
//! * get external IP
//! * add port mappings
//! * remove port mappings
//!
//! If everything works fine, 2 port mappings are added, 1 removed and we're left with single
//! port mapping: External 1234 ---> 4321 Internal

extern crate igd;
extern crate futures;
extern crate tokio_core;

use igd::async::search_gateway;
use igd::PortMappingProtocol;
use futures::future::Future;

fn main() {
    let mut evloop = tokio_core::reactor::Core::new().unwrap();
    let handle = evloop.handle();

    let task = search_gateway(&handle)
        .map_err(|e| panic!("Failed to find IGD: {}", e))
        .and_then(|gateway| gateway.get_external_ip()
            .map_err(|e| panic!("Failed to get external IP: {}", e))
            .and_then(|ip| Ok((gateway, ip)))
        )
        .and_then(|(gateway, pub_ip)| {
            println!("Our public IP: {}", pub_ip);
            Ok(gateway)
        })
        .and_then(|gateway| {
            gateway.add_port(
                PortMappingProtocol::TCP,
                1234,
                "192.168.1.210:4321".parse().unwrap(),
                0,
                "rust-igd-async-example",
            )
            .map_err(|e| panic!("Failed to add port mapping: {}", e))
            .and_then(|_| {
                println!("New port mapping was successfully added.");
                Ok(gateway)
            })
        })
        .and_then(|gateway| {
            gateway.add_port(
                PortMappingProtocol::TCP,
                2345,
                "192.168.1.210:5432".parse().unwrap(),
                0,
                "rust-igd-async-example",
            )
            .map_err(|e| panic!("Failed to add port mapping: {}", e))
            .and_then(|_| {
                println!("New port mapping was successfully added.");
                Ok(gateway)
            })
        })
        .and_then(|gateway| gateway.remove_port(PortMappingProtocol::TCP, 2345))
        .and_then(|_| {
            println!("Port was removed.");
            Ok(())
        });

    let _ = evloop.run(task).unwrap();
}
<commit_msg>fix async example<commit_after>//! IGD async API example.
//!
//! It demonstrates how to:
//! * get external IP
//! * add port mappings
//! * remove port mappings
//!
//! If everything works fine, 2 port mappings are added, 1 removed and we're left with single
//! port mapping: External 1234 ---> 4321 Internal

extern crate igd;
extern crate futures;
extern crate tokio_core;

use std::env;
use std::net::SocketAddrV4;

use igd::async::search_gateway;
use igd::PortMappingProtocol;
use futures::future::Future;

fn main() {
    let ip = match env::args().nth(1) {
        Some(ip) => ip,
        None => {
            println!("Local socket address is missing!");
            println!("This example requires a socket address representing the local machine and the port to bind to as an argument");
            println!("Example: target/debug/examples/async 192.168.0.198:4321");
            println!("Example: cargo run --features async --example async -- 192.168.0.198:4321");
            return;
        }
    };
    let ip: SocketAddrV4 = ip.parse().expect("Invalid socket address");

    let mut evloop = tokio_core::reactor::Core::new().unwrap();
    let handle = evloop.handle();

    let task = search_gateway(&handle)
        .map_err(|e| panic!("Failed to find IGD: {}", e))
        .and_then(|gateway| gateway.get_external_ip()
            .map_err(|e| panic!("Failed to get external IP: {}", e))
            .and_then(|ip| Ok((gateway, ip)))
        )
        .and_then(|(gateway, pub_ip)| {
            println!("Our public IP: {}", pub_ip);
            Ok(gateway)
        })
        .and_then(|gateway| {
            gateway.add_port(
                PortMappingProtocol::TCP,
                1234,
                ip,
                0,
                "rust-igd-async-example",
            )
            .map_err(|e| panic!("Failed to add port mapping: {}", e))
            .and_then(|_| {
                println!("New port mapping was successfully added.");
                Ok(gateway)
            })
        })
        .and_then(|gateway| {
            gateway.add_port(
                PortMappingProtocol::TCP,
                2345,
                ip,
                0,
                "rust-igd-async-example",
            )
            .map_err(|e| panic!("Failed to add port mapping: {}", e))
            .and_then(|_| {
                println!("New port mapping was successfully added.");
                Ok(gateway)
            })
        })
        .and_then(|gateway| gateway.remove_port(PortMappingProtocol::TCP, 2345))
        .and_then(|_| {
            println!("Port was removed.");
            Ok(())
        });

    let _ = evloop.run(task).unwrap();
}
<|endoftext|>


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

#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "alloc_system"]
#![crate_type = "rlib"]
#![cfg_attr(stage0, staged_api)]
#![no_std]
#![cfg_attr(not(stage0), allocator)]
#![cfg_attr(stage0, allow(improper_ctypes))]
#![unstable(feature = "alloc_system",
            reason = "this library is unlikely to be stabilized in its current \
                      form or name",
            issue = "27783")]
#![feature(allocator)]
#![feature(libc)]
#![feature(no_std)]
#![feature(staged_api)]

extern crate libc;

// The minimum alignment guaranteed by the architecture. This value is used to
// add fast paths for low alignment values. In practice, the alignment is a
// constant at the call site and the branch will be optimized out.
#[cfg(all(any(target_arch = "arm",
              target_arch = "mips",
              target_arch = "mipsel",
              target_arch = "powerpc")))]
const MIN_ALIGN: usize = 8;
#[cfg(all(any(target_arch = "x86",
              target_arch = "x86_64",
              target_arch = "aarch64")))]
const MIN_ALIGN: usize = 16;

#[no_mangle]
pub extern "C" fn __rust_allocate(size: usize, align: usize) -> *mut u8 {
    unsafe { imp::allocate(size, align) }
}

#[no_mangle]
pub extern "C" fn __rust_deallocate(ptr: *mut u8, old_size: usize, align: usize) {
    unsafe { imp::deallocate(ptr, old_size, align) }
}

#[no_mangle]
pub extern "C" fn __rust_reallocate(ptr: *mut u8,
                                    old_size: usize,
                                    size: usize,
                                    align: usize)
                                    -> *mut u8 {
    unsafe { imp::reallocate(ptr, old_size, size, align) }
}

#[no_mangle]
pub extern "C" fn __rust_reallocate_inplace(ptr: *mut u8,
                                            old_size: usize,
                                            size: usize,
                                            align: usize)
                                            -> usize {
    unsafe { imp::reallocate_inplace(ptr, old_size, size, align) }
}

#[no_mangle]
pub extern "C" fn __rust_usable_size(size: usize, align: usize) -> usize {
    imp::usable_size(size, align)
}

#[cfg(unix)]
mod imp {
    use core::cmp;
    use core::ptr;
    use libc;
    use MIN_ALIGN;

    extern "C" {
        // Apparently android doesn't have posix_memalign
        #[cfg(target_os = "android")]
        fn memalign(align: libc::size_t, size: libc::size_t) -> *mut libc::c_void;

        #[cfg(not(target_os = "android"))]
        fn posix_memalign(memptr: *mut *mut libc::c_void,
                          align: libc::size_t,
                          size: libc::size_t)
                          -> libc::c_int;
    }

    pub unsafe fn allocate(size: usize, align: usize) -> *mut u8 {
        if align <= MIN_ALIGN {
            libc::malloc(size as libc::size_t) as *mut u8
        } else {
            #[cfg(target_os = "android")]
            unsafe fn more_aligned_malloc(size: usize, align: usize) -> *mut u8 {
                memalign(align as libc::size_t, size as libc::size_t) as *mut u8
            }
            #[cfg(not(target_os = "android"))]
            unsafe fn more_aligned_malloc(size: usize, align: usize) -> *mut u8 {
                let mut out = ptr::null_mut();
                let ret = posix_memalign(&mut out, align as libc::size_t, size as libc::size_t);
                if ret != 0 {
                    ptr::null_mut()
                } else {
                    out as *mut u8
                }
            }
            more_aligned_malloc(size, align)
        }
    }

    pub unsafe fn reallocate(ptr: *mut u8, old_size: usize, size: usize, align: usize) -> *mut u8 {
        if align <= MIN_ALIGN {
            libc::realloc(ptr as *mut libc::c_void, size as libc::size_t) as *mut u8
        } else {
            let new_ptr = allocate(size, align);
            ptr::copy(ptr, new_ptr, cmp::min(size, old_size));
            deallocate(ptr, old_size, align);
            new_ptr
        }
    }

    pub unsafe fn reallocate_inplace(_ptr: *mut u8,
                                     old_size: usize,
                                     _size: usize,
                                     _align: usize)
                                     -> usize {
        old_size
    }

    pub unsafe fn deallocate(ptr: *mut u8, _old_size: usize, _align: usize) {
        libc::free(ptr as *mut libc::c_void)
    }

    pub fn usable_size(size: usize, _align: usize) -> usize {
        size
    }
}

#[cfg(windows)]
#[allow(bad_style)]
mod imp {
    use MIN_ALIGN;

    type LPVOID = *mut u8;
    type HANDLE = LPVOID;
    type SIZE_T = usize;
    type DWORD = u32;
    type BOOL = i32;

    extern "system" {
        fn GetProcessHeap() -> HANDLE;
        fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) -> LPVOID;
        fn HeapReAlloc(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID, dwBytes: SIZE_T) -> LPVOID;
        fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID) -> BOOL;
    }

    #[repr(C)]
    struct Header(*mut u8);

    const HEAP_REALLOC_IN_PLACE_ONLY: DWORD = 0x00000010;

    unsafe fn get_header<'a>(ptr: *mut u8) -> &'a mut Header {
        &mut *(ptr as *mut Header).offset(-1)
    }

    unsafe fn align_ptr(ptr: *mut u8, align: usize) -> *mut u8 {
        let aligned = ptr.offset((align - (ptr as usize & (align - 1))) as isize);
        *get_header(aligned) = Header(ptr);
        aligned
    }

    pub unsafe fn allocate(size: usize, align: usize) -> *mut u8 {
        if align <= MIN_ALIGN {
            HeapAlloc(GetProcessHeap(), 0, size as SIZE_T) as *mut u8
        } else {
            let ptr = HeapAlloc(GetProcessHeap(), 0, (size + align) as SIZE_T) as *mut u8;
            if ptr.is_null() {
                return ptr;
            }
            align_ptr(ptr, align)
        }
    }

    pub unsafe fn reallocate(ptr: *mut u8, _old_size: usize, size: usize, align: usize) -> *mut u8 {
        if align <= MIN_ALIGN {
            HeapReAlloc(GetProcessHeap(), 0, ptr as LPVOID, size as SIZE_T) as *mut u8
        } else {
            let header = get_header(ptr);
            let new = HeapReAlloc(GetProcessHeap(),
                                  0,
                                  header.0 as LPVOID,
                                  (size + align) as SIZE_T) as *mut u8;
            if new.is_null() {
                return new;
            }
            align_ptr(new, align)
        }
    }

    pub unsafe fn reallocate_inplace(ptr: *mut u8,
                                     old_size: usize,
                                     size: usize,
                                     align: usize)
                                     -> usize {
        if align <= MIN_ALIGN {
            let new = HeapReAlloc(GetProcessHeap(),
                                  HEAP_REALLOC_IN_PLACE_ONLY,
                                  ptr as LPVOID,
                                  size as SIZE_T) as *mut u8;
            if new.is_null() {
                old_size
            } else {
                size
            }
        } else {
            old_size
        }
    }

    pub unsafe fn deallocate(ptr: *mut u8, _old_size: usize, align: usize) {
        if align <= MIN_ALIGN {
            let err = HeapFree(GetProcessHeap(), 0, ptr as LPVOID);
            debug_assert!(err != 0);
        } else {
            let header = get_header(ptr);
            let err = HeapFree(GetProcessHeap(), 0, header.0 as LPVOID);
            debug_assert!(err != 0);
        }
    }

    pub fn usable_size(size: usize, _align: usize) -> usize {
        size
    }
}
<commit_msg>MIN_ALIGN is definitely 8 on 32-bit x86, at least on Windows.<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "alloc_system"]
#![crate_type = "rlib"]
#![cfg_attr(stage0, staged_api)]
#![no_std]
#![cfg_attr(not(stage0), allocator)]
#![cfg_attr(stage0, allow(improper_ctypes))]
#![unstable(feature = "alloc_system",
            reason = "this library is unlikely to be stabilized in its current \
                      form or name",
            issue = "27783")]
#![feature(allocator)]
#![feature(libc)]
#![feature(no_std)]
#![feature(staged_api)]

extern crate libc;

// The minimum alignment guaranteed by the architecture. This value is used to
// add fast paths for low alignment values. In practice, the alignment is a
// constant at the call site and the branch will be optimized out.
#[cfg(all(any(target_arch = "x86",
              target_arch = "arm",
              target_arch = "mips",
              target_arch = "mipsel",
              target_arch = "powerpc")))]
const MIN_ALIGN: usize = 8;
#[cfg(all(any(target_arch = "x86_64",
              target_arch = "aarch64")))]
const MIN_ALIGN: usize = 16;

#[no_mangle]
pub extern "C" fn __rust_allocate(size: usize, align: usize) -> *mut u8 {
    unsafe { imp::allocate(size, align) }
}

#[no_mangle]
pub extern "C" fn __rust_deallocate(ptr: *mut u8, old_size: usize, align: usize) {
    unsafe { imp::deallocate(ptr, old_size, align) }
}

#[no_mangle]
pub extern "C" fn __rust_reallocate(ptr: *mut u8,
                                    old_size: usize,
                                    size: usize,
                                    align: usize)
                                    -> *mut u8 {
    unsafe { imp::reallocate(ptr, old_size, size, align) }
}

#[no_mangle]
pub extern "C" fn __rust_reallocate_inplace(ptr: *mut u8,
                                            old_size: usize,
                                            size: usize,
                                            align: usize)
                                            -> usize {
    unsafe { imp::reallocate_inplace(ptr, old_size, size, align) }
}

#[no_mangle]
pub extern "C" fn __rust_usable_size(size: usize, align: usize) -> usize {
    imp::usable_size(size, align)
}

#[cfg(unix)]
mod imp {
    use core::cmp;
    use core::ptr;
    use libc;
    use MIN_ALIGN;

    extern "C" {
        // Apparently android doesn't have posix_memalign
        #[cfg(target_os = "android")]
        fn memalign(align: libc::size_t, size: libc::size_t) -> *mut libc::c_void;

        #[cfg(not(target_os = "android"))]
        fn posix_memalign(memptr: *mut *mut libc::c_void,
                          align: libc::size_t,
                          size: libc::size_t)
                          -> libc::c_int;
    }

    pub unsafe fn allocate(size: usize, align: usize) -> *mut u8 {
        if align <= MIN_ALIGN {
            libc::malloc(size as libc::size_t) as *mut u8
        } else {
            #[cfg(target_os = "android")]
            unsafe fn more_aligned_malloc(size: usize, align: usize) -> *mut u8 {
                memalign(align as libc::size_t, size as libc::size_t) as *mut u8
            }
            #[cfg(not(target_os = "android"))]
            unsafe fn more_aligned_malloc(size: usize, align: usize) -> *mut u8 {
                let mut out = ptr::null_mut();
                let ret = posix_memalign(&mut out, align as libc::size_t, size as libc::size_t);
                if ret != 0 {
                    ptr::null_mut()
                } else {
                    out as *mut u8
                }
            }
            more_aligned_malloc(size, align)
        }
    }

    pub unsafe fn reallocate(ptr: *mut u8, old_size: usize, size: usize, align: usize) -> *mut u8 {
        if align <= MIN_ALIGN {
            libc::realloc(ptr as *mut libc::c_void, size as libc::size_t) as *mut u8
        } else {
            let new_ptr = allocate(size, align);
            ptr::copy(ptr, new_ptr, cmp::min(size, old_size));
            deallocate(ptr, old_size, align);
            new_ptr
        }
    }

    pub unsafe fn reallocate_inplace(_ptr: *mut u8,
                                     old_size: usize,
                                     _size: usize,
                                     _align: usize)
                                     -> usize {
        old_size
    }

    pub unsafe fn deallocate(ptr: *mut u8, _old_size: usize, _align: usize) {
        libc::free(ptr as *mut libc::c_void)
    }

    pub fn usable_size(size: usize, _align: usize) -> usize {
        size
    }
}

#[cfg(windows)]
#[allow(bad_style)]
mod imp {
    use MIN_ALIGN;

    type LPVOID = *mut u8;
    type HANDLE = LPVOID;
    type SIZE_T = usize;
    type DWORD = u32;
    type BOOL = i32;

    extern "system" {
        fn GetProcessHeap() -> HANDLE;
        fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) -> LPVOID;
        fn HeapReAlloc(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID, dwBytes: SIZE_T) -> LPVOID;
        fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID) -> BOOL;
    }

    #[repr(C)]
    struct Header(*mut u8);

    const HEAP_REALLOC_IN_PLACE_ONLY: DWORD = 0x00000010;

    unsafe fn get_header<'a>(ptr: *mut u8) -> &'a mut Header {
        &mut *(ptr as *mut Header).offset(-1)
    }

    unsafe fn align_ptr(ptr: *mut u8, align: usize) -> *mut u8 {
        let aligned = ptr.offset((align - (ptr as usize & (align - 1))) as isize);
        *get_header(aligned) = Header(ptr);
        aligned
    }

    pub unsafe fn allocate(size: usize, align: usize) -> *mut u8 {
        if align <= MIN_ALIGN {
            HeapAlloc(GetProcessHeap(), 0, size as SIZE_T) as *mut u8
        } else {
            let ptr = HeapAlloc(GetProcessHeap(), 0, (size + align) as SIZE_T) as *mut u8;
            if ptr.is_null() {
                return ptr;
            }
            align_ptr(ptr, align)
        }
    }

    pub unsafe fn reallocate(ptr: *mut u8, _old_size: usize, size: usize, align: usize) -> *mut u8 {
        if align <= MIN_ALIGN {
            HeapReAlloc(GetProcessHeap(), 0, ptr as LPVOID, size as SIZE_T) as *mut u8
        } else {
            let header = get_header(ptr);
            let new = HeapReAlloc(GetProcessHeap(),
                                  0,
                                  header.0 as LPVOID,
                                  (size + align) as SIZE_T) as *mut u8;
            if new.is_null() {
                return new;
            }
            align_ptr(new, align)
        }
    }

    pub unsafe fn reallocate_inplace(ptr: *mut u8,
                                     old_size: usize,
                                     size: usize,
                                     align: usize)
                                     -> usize {
        if align <= MIN_ALIGN {
            let new = HeapReAlloc(GetProcessHeap(),
                                  HEAP_REALLOC_IN_PLACE_ONLY,
                                  ptr as LPVOID,
                                  size as SIZE_T) as *mut u8;
            if new.is_null() {
                old_size
            } else {
                size
            }
        } else {
            old_size
        }
    }

    pub unsafe fn deallocate(ptr: *mut u8, _old_size: usize, align: usize) {
        if align <= MIN_ALIGN {
            let err = HeapFree(GetProcessHeap(), 0, ptr as LPVOID);
            debug_assert!(err != 0);
        } else {
            let header = get_header(ptr);
            let err = HeapFree(GetProcessHeap(), 0, header.0 as LPVOID);
            debug_assert!(err != 0);
        }
    }

    pub fn usable_size(size: usize, _align: usize) -> usize {
        size
    }
}
<|endoftext|>


<commit_before>extern crate pretty;

use pretty::doc::{
    Doc
};

#[deriving(Clone)]
#[deriving(Show)]
struct Tree<'a> {
    node:String,
    subtrees:&'a[Tree<'a>]
}

impl<'a> Tree<'a> {
    pub fn tree(node:&str, subtrees:&'a[Tree<'a>]) -> Tree<'a> {
        Tree {
            node: String::from_str(node),
            subtrees: subtrees
        }
    }

    fn pretty_trees(trees:&'a[Tree<'a>]) -> Doc {
        match trees {
            [] => fail!(),
            [ref t] => t.pretty(),
            [ref t, ref ts..] => {
                t.pretty().append(
                    Doc::text(",")
                ).append(
                    Doc::newline()
                ).append(
                    Tree::pretty_trees(*ts)
                )
            }
        }
    }

    fn pretty_bracket(ts:&'a[Tree<'a>]) -> Doc {
        match ts {
            [] => Doc::nil(),
            ts => {
                Doc::text("[").append(
                    Doc::newline().append(
                        Tree::pretty_trees(ts)
                    ).nest(2)
                ).append(
                    Doc::newline()
                ).append(
                    Doc::text("]")
                )
            }
        }
    }

    pub fn pretty(&self) -> Doc {
        Doc::text(self.node.clone()).append(Tree::pretty_bracket(self.subtrees))
    }
}

pub fn main() {
    let bbbbbbs =
        [ Tree::tree("ccc", [])
        , Tree::tree("dd", [])
        ];
    let ffffs =
        [ Tree::tree("gg", [])
        , Tree::tree("hhh", [])
        , Tree::tree("ii", [])
        ];

    let aaas =
        [ Tree::tree("bbbbbb", bbbbbbs)
        , Tree::tree("eee", [])
        , Tree::tree("ffff", ffffs)
        ];

    let example = Tree::tree("aaa", aaas);

    print!("{}", example.pretty().to_string(70));
}
<commit_msg>Use ::new instead of ::tree<commit_after>extern crate pretty;

use pretty::doc::{
    Doc
};

#[deriving(Clone)]
#[deriving(Show)]
struct Tree<'a> {
    node:String,
    subtrees:&'a[Tree<'a>]
}

impl<'a> Tree<'a> {
    pub fn new(node:&str, subtrees:&'a[Tree<'a>]) -> Tree<'a> {
        Tree {
            node: String::from_str(node),
            subtrees: subtrees
        }
    }

    fn pretty_trees(trees:&'a[Tree<'a>]) -> Doc {
        match trees {
            [] => fail!(),
            [ref t] => t.pretty(),
            [ref t, ref ts..] => {
                t.pretty().append(
                    Doc::text(",")
                ).append(
                    Doc::newline()
                ).append(
                    Tree::pretty_trees(*ts)
                )
            }
        }
    }

    fn pretty_bracket(ts:&'a[Tree<'a>]) -> Doc {
        match ts {
            [] => Doc::nil(),
            ts => {
                Doc::text("[").append(
                    Doc::newline().append(
                        Tree::pretty_trees(ts)
                    ).nest(2)
                ).append(
                    Doc::newline()
                ).append(
                    Doc::text("]")
                )
            }
        }
    }

    pub fn pretty(&self) -> Doc {
        Doc::text(self.node.clone()).append(Tree::pretty_bracket(self.subtrees))
    }
}

pub fn main() {
    let bbbbbbs =
        [ Tree::new("ccc", [])
        , Tree::new("dd", [])
        ];
    let ffffs =
        [ Tree::new("gg", [])
        , Tree::new("hhh", [])
        , Tree::new("ii", [])
        ];

    let aaas =
        [ Tree::new("bbbbbb", bbbbbbs)
        , Tree::new("eee", [])
        , Tree::new("ffff", ffffs)
        ];

    let example = Tree::new("aaa", aaas);

    print!("{}", example.pretty().to_string(70));
}
<|endoftext|>


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

//! A standard, garbage-collected linked list.

#[deriving(Clone, Eq)]
#[allow(missing_doc)]
pub enum List<T> {
    Cons(T, @List<T>),
    Nil,
}

pub struct Items<'a, T> {
    priv head: &'a List<T>,
    priv next: Option<&'a @List<T>>
}

impl<'a, T> Iterator<&'a T> for Items<'a, T> {
    fn next(&mut self) -> Option<&'a T> {
        match self.next {
            None => match *self.head {
                Nil => None,
                Cons(ref value, ref tail) => {
                    self.next = Some(tail);
                    Some(value)
                }
            },
            Some(next) => match **next {
                Nil => None,
                Cons(ref value, ref tail) => {
                    self.next = Some(tail);
                    Some(value)
                }
            }
        }
    }
}

impl<T> List<T> {
    /// Returns a forward iterator
    pub fn iter<'a>(&'a self) -> Items<'a, T> {
        Items {
            head: self,
            next: None
        }
    }
}

/// Returns true if a list contains an element with the given value
pub fn has<T:Eq>(list: @List<T>, element: T) -> bool {
    let mut found = false;
    each(list, |e| {
        if *e == element { found = true; false } else { true }
    });
    return found;
}

/// Returns true if the list is empty
pub fn is_empty<T>(list: @List<T>) -> bool {
    match *list {
        Nil => true,
        _ => false
    }
}

/// Returns the length of a list
pub fn len<T>(list: @List<T>) -> uint {
    let mut count = 0u;
    iter(list, |_e| count += 1u);
    count
}

/// Returns all but the first element of a list
pub fn tail<T>(list: @List<T>) -> @List<T> {
    match *list {
        Cons(_, tail) => return tail,
        Nil => fail!("list empty")
    }
}

/// Returns the first element of a list
pub fn head<T:Clone>(list: @List<T>) -> T {
    match *list {
      Cons(ref head, _) => (*head).clone(),
      // makes me sad
      _ => fail!("head invoked on empty list")
    }
}

/// Appends one list to another
pub fn append<T:Clone + 'static>(list: @List<T>, other: @List<T>) -> @List<T> {
    match *list {
      Nil => return other,
      Cons(ref head, tail) => {
        let rest = append(tail, other);
        return @Cons((*head).clone(), rest);
      }
    }
}

impl<T:'static + Clone> List<T> {
    /// Create a list from a vector
    pub fn from_vec(v: &[T]) -> List<T> {
        match v.len() {
            0 => Nil,
            _ => v.rev_iter().fold(Nil, |tail, value: &T| Cons(value.clone(), @tail))
        }
    }
}

/*
/// Push one element into the front of a list, returning a new list
/// THIS VERSION DOESN'T ACTUALLY WORK
fn push<T:Clone>(ll: &mut @list<T>, vv: T) {
    ll = &mut @cons(vv, *ll)
}
*/

/// Iterate over a list
pub fn iter<T>(list: @List<T>, f: |&T|) {
    let mut cur = list;
    loop {
        cur = match *cur {
          Cons(ref head, tail) => {
            f(head);
            tail
          }
          Nil => break
        }
    }
}

/// Iterate over a list
pub fn each<T>(list: @List<T>, f: |&T| -> bool) -> bool {
    let mut cur = list;
    loop {
        cur = match *cur {
          Cons(ref head, tail) => {
            if !f(head) { return false; }
            tail
          }
          Nil => { return true; }
        }
    }
}

#[cfg(test)]
mod tests {
    use list::{List, Nil, head, is_empty, tail};
    use list;

    #[test]
    fn test_iter() {
        let list = List::from_vec([0, 1, 2]);
        let mut iter = list.iter();
        assert_eq!(&0, iter.next().unwrap());
        assert_eq!(&1, iter.next().unwrap());
        assert_eq!(&2, iter.next().unwrap());
        assert_eq!(None, iter.next());
    }

    #[test]
    fn test_is_empty() {
        let empty : @list::List<int> = @List::from_vec([]);
        let full1 = @List::from_vec([1]);
        let full2 = @List::from_vec(['r', 'u']);

        assert!(is_empty(empty));
        assert!(!is_empty(full1));
        assert!(!is_empty(full2));
    }

    #[test]
    fn test_from_vec() {
        let list = @List::from_vec([0, 1, 2]);

        assert_eq!(head(list), 0);

        let tail_l = tail(list);
        assert_eq!(head(tail_l), 1);

        let tail_tail_l = tail(tail_l);
        assert_eq!(head(tail_tail_l), 2);
    }

    #[test]
    fn test_from_vec_empty() {
        let empty : list::List<int> = List::from_vec([]);
        assert_eq!(empty, Nil::<int>);
    }

    #[test]
    fn test_fold() {
        fn add_(a: uint, b: &uint) -> uint { a + *b }
        fn subtract_(a: uint, b: &uint) -> uint { a - *b }

        let empty = Nil::<uint>;
        assert_eq!(empty.iter().fold(0u, add_), 0u);
        assert_eq!(empty.iter().fold(10u, subtract_), 10u);

        let list = List::from_vec([0u, 1u, 2u, 3u, 4u]);
        assert_eq!(list.iter().fold(0u, add_), 10u);
        assert_eq!(list.iter().fold(10u, subtract_), 0u);
    }

    #[test]
    fn test_find_success() {
        fn match_(i: & &int) -> bool { **i == 2 }

        let list = List::from_vec([0, 1, 2]);
        assert_eq!(list.iter().find(match_).unwrap(), &2);
    }

    #[test]
    fn test_find_fail() {
        fn match_(_i: & &int) -> bool { false }

        let empty = Nil::<int>;
        assert_eq!(empty.iter().find(match_), None);

        let list = List::from_vec([0, 1, 2]);
        assert_eq!(list.iter().find(match_), None);
    }

    #[test]
    fn test_any() {
        fn match_(i: &int) -> bool { *i == 2 }

        let empty = Nil::<int>;
        assert_eq!(empty.iter().any(match_), false);

        let list = List::from_vec([0, 1, 2]);
        assert_eq!(list.iter().any(match_), true);
    }

    #[test]
    fn test_has() {
        let list = @List::from_vec([5, 8, 6]);
        let empty = @list::Nil::<int>;
        assert!((list::has(list, 5)));
        assert!((!list::has(list, 7)));
        assert!((list::has(list, 8)));
        assert!((!list::has(empty, 5)));
    }

    #[test]
    fn test_len() {
        let list = @List::from_vec([0, 1, 2]);
        let empty = @list::Nil::<int>;
        assert_eq!(list::len(list), 3u);
        assert_eq!(list::len(empty), 0u);
    }

    #[test]
    fn test_append() {
        assert!(@List::from_vec([1,2,3,4])
            == list::append(@List::from_vec([1,2]), @List::from_vec([3,4])));
    }
}
<commit_msg>Implemented list::len() based on Container trait<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! A standard, garbage-collected linked list.

use std::container::Container;

#[deriving(Clone, Eq)]
#[allow(missing_doc)]
pub enum List<T> {
    Cons(T, @List<T>),
    Nil,
}

pub struct Items<'a, T> {
    priv head: &'a List<T>,
    priv next: Option<&'a @List<T>>
}

impl<'a, T> Iterator<&'a T> for Items<'a, T> {
    fn next(&mut self) -> Option<&'a T> {
        match self.next {
            None => match *self.head {
                Nil => None,
                Cons(ref value, ref tail) => {
                    self.next = Some(tail);
                    Some(value)
                }
            },
            Some(next) => match **next {
                Nil => None,
                Cons(ref value, ref tail) => {
                    self.next = Some(tail);
                    Some(value)
                }
            }
        }
    }
}

impl<T> List<T> {
    /// Returns a forward iterator
    pub fn iter<'a>(&'a self) -> Items<'a, T> {
        Items {
            head: self,
            next: None
        }
    }
}

impl<T> Container for List<T> {
    /// Returns the length of a list
    fn len(&self) -> uint { self.iter().len() }
}

/// Returns true if a list contains an element with the given value
pub fn has<T:Eq>(list: @List<T>, element: T) -> bool {
    let mut found = false;
    each(list, |e| {
        if *e == element { found = true; false } else { true }
    });
    return found;
}

/// Returns true if the list is empty
pub fn is_empty<T>(list: @List<T>) -> bool {
    match *list {
        Nil => true,
        _ => false
    }
}

/// Returns all but the first element of a list
pub fn tail<T>(list: @List<T>) -> @List<T> {
    match *list {
        Cons(_, tail) => return tail,
        Nil => fail!("list empty")
    }
}

/// Returns the first element of a list
pub fn head<T:Clone>(list: @List<T>) -> T {
    match *list {
      Cons(ref head, _) => (*head).clone(),
      // makes me sad
      _ => fail!("head invoked on empty list")
    }
}

/// Appends one list to another
pub fn append<T:Clone + 'static>(list: @List<T>, other: @List<T>) -> @List<T> {
    match *list {
      Nil => return other,
      Cons(ref head, tail) => {
        let rest = append(tail, other);
        return @Cons((*head).clone(), rest);
      }
    }
}

impl<T:'static + Clone> List<T> {
    /// Create a list from a vector
    pub fn from_vec(v: &[T]) -> List<T> {
        match v.len() {
            0 => Nil,
            _ => v.rev_iter().fold(Nil, |tail, value: &T| Cons(value.clone(), @tail))
        }
    }
}

/*
/// Push one element into the front of a list, returning a new list
/// THIS VERSION DOESN'T ACTUALLY WORK
fn push<T:Clone>(ll: &mut @list<T>, vv: T) {
    ll = &mut @cons(vv, *ll)
}
*/

/// Iterate over a list
pub fn iter<T>(list: @List<T>, f: |&T|) {
    let mut cur = list;
    loop {
        cur = match *cur {
          Cons(ref head, tail) => {
            f(head);
            tail
          }
          Nil => break
        }
    }
}

/// Iterate over a list
pub fn each<T>(list: @List<T>, f: |&T| -> bool) -> bool {
    let mut cur = list;
    loop {
        cur = match *cur {
          Cons(ref head, tail) => {
            if !f(head) { return false; }
            tail
          }
          Nil => { return true; }
        }
    }
}

#[cfg(test)]
mod tests {
    use list::{List, Nil, head, is_empty, tail};
    use list;

    #[test]
    fn test_iter() {
        let list = List::from_vec([0, 1, 2]);
        let mut iter = list.iter();
        assert_eq!(&0, iter.next().unwrap());
        assert_eq!(&1, iter.next().unwrap());
        assert_eq!(&2, iter.next().unwrap());
        assert_eq!(None, iter.next());
    }

    #[test]
    fn test_is_empty() {
        let empty : @list::List<int> = @List::from_vec([]);
        let full1 = @List::from_vec([1]);
        let full2 = @List::from_vec(['r', 'u']);

        assert!(is_empty(empty));
        assert!(!is_empty(full1));
        assert!(!is_empty(full2));
    }

    #[test]
    fn test_from_vec() {
        let list = @List::from_vec([0, 1, 2]);

        assert_eq!(head(list), 0);

        let tail_l = tail(list);
        assert_eq!(head(tail_l), 1);

        let tail_tail_l = tail(tail_l);
        assert_eq!(head(tail_tail_l), 2);
    }

    #[test]
    fn test_from_vec_empty() {
        let empty : list::List<int> = List::from_vec([]);
        assert_eq!(empty, Nil::<int>);
    }

    #[test]
    fn test_fold() {
        fn add_(a: uint, b: &uint) -> uint { a + *b }
        fn subtract_(a: uint, b: &uint) -> uint { a - *b }

        let empty = Nil::<uint>;
        assert_eq!(empty.iter().fold(0u, add_), 0u);
        assert_eq!(empty.iter().fold(10u, subtract_), 10u);

        let list = List::from_vec([0u, 1u, 2u, 3u, 4u]);
        assert_eq!(list.iter().fold(0u, add_), 10u);
        assert_eq!(list.iter().fold(10u, subtract_), 0u);
    }

    #[test]
    fn test_find_success() {
        fn match_(i: & &int) -> bool { **i == 2 }

        let list = List::from_vec([0, 1, 2]);
        assert_eq!(list.iter().find(match_).unwrap(), &2);
    }

    #[test]
    fn test_find_fail() {
        fn match_(_i: & &int) -> bool { false }

        let empty = Nil::<int>;
        assert_eq!(empty.iter().find(match_), None);

        let list = List::from_vec([0, 1, 2]);
        assert_eq!(list.iter().find(match_), None);
    }

    #[test]
    fn test_any() {
        fn match_(i: &int) -> bool { *i == 2 }

        let empty = Nil::<int>;
        assert_eq!(empty.iter().any(match_), false);

        let list = List::from_vec([0, 1, 2]);
        assert_eq!(list.iter().any(match_), true);
    }

    #[test]
    fn test_has() {
        let list = @List::from_vec([5, 8, 6]);
        let empty = @list::Nil::<int>;
        assert!((list::has(list, 5)));
        assert!((!list::has(list, 7)));
        assert!((list::has(list, 8)));
        assert!((!list::has(empty, 5)));
    }

    #[test]
    fn test_len() {
        let empty = Nil::<int>;
        assert_eq!(empty.len(), 0u);

        let list = List::from_vec([0, 1, 2]);
        assert_eq!(list.len(), 3u);
    }

    #[test]
    fn test_append() {
        assert!(@List::from_vec([1,2,3,4])
            == list::append(@List::from_vec([1,2]), @List::from_vec([3,4])));
    }
}
<|endoftext|>


<commit_before>use std::collections::VecDeque;
use std::marker::PhantomData;

pub trait Primitive<T>: Sized {
    fn into_points<F>(self, f: F) where F: FnMut(T);
    fn into_lines<F>(self, f: F) where F: FnMut(Line<T>);
}

pub trait Polygonal<T>: Primitive<T> {
    fn into_triangles<F>(self, f: F) where F: FnMut(Triangle<T>);
}

pub trait MapPrimitiveInto<T, U> {
    type Output;

    fn map_points_into<F>(self, f: F) -> Self::Output where F: FnMut(T) -> U;
}

pub trait MapPrimitive<T, U>: Sized {
    type Output;

    fn map_points<F>(self, f: F) -> Map<Self, T, U, F> where F: FnMut(T) -> U;
}

pub trait DecomposePrimitive<T>: Sized {
    fn points(self) -> PointIter<Self, T>;
}

pub trait DecomposePolygon<T>: Sized {
    fn triangulate(self) -> TriangleIter<Self, T>;
}

impl<I, T, U, P, Q> MapPrimitive<T, U> for I
    where I: Iterator<Item = P>,
          P: MapPrimitiveInto<T, U, Output = Q>
{
    type Output = Q;

    fn map_points<F>(self, f: F) -> Map<Self, T, U, F>
        where F: FnMut(T) -> U
    {
        Map::new(self, f)
    }
}

pub struct Map<I, T, U, F> {
    primitives: I,
    f: F,
    phantom_t: PhantomData<T>,
    phantom_u: PhantomData<U>,
}

impl<I, T, U, F> Map<I, T, U, F> {
    fn new(primitives: I, f: F) -> Self {
        Map {
            primitives: primitives,
            f: f,
            phantom_t: PhantomData,
            phantom_u: PhantomData,
        }
    }
}

impl<I, T, U, F, P, Q> Iterator for Map<I, T, U, F>
    where I: Iterator<Item = P>,
          F: FnMut(T) -> U,
          P: MapPrimitiveInto<T, U, Output = Q>
{
    type Item = Q;

    fn next(&mut self) -> Option<Self::Item> {
        self.primitives.next().map(|primitive| primitive.map_points_into(|point| (self.f)(point)))
    }
}

impl<I, T, P> DecomposePrimitive<T> for I
    where I: Iterator<Item = P>,
          P: Primitive<T>
{
    fn points(self) -> PointIter<Self, T> {
        PointIter::new(self)
    }
}

pub struct PointIter<I, T> {
    primitives: I,
    points: VecDeque<T>,
}

impl<I, T> PointIter<I, T> {
    fn new(primitives: I) -> Self {
        PointIter {
            primitives: primitives,
            points: VecDeque::new(),
        }
    }
}

impl<I, T, P> Iterator for PointIter<I, T>
    where I: Iterator<Item = P>,
          P: Primitive<T>
{
    type Item = T;

    fn next(&mut self) -> Option<Self::Item> {
        loop {
            if let Some(point) = self.points.pop_front() {
                return Some(point);
            }
            if let Some(primitive) = self.primitives.next() {
                primitive.into_points(|point| self.points.push_back(point))
            }
            else {
                return None;
            }
        }
    }
}

impl<I, T, P> DecomposePolygon<T> for I
    where I: Iterator<Item = P>,
          P: Polygonal<T>
{
    fn triangulate(self) -> TriangleIter<Self, T> {
        TriangleIter::new(self)
    }
}

pub struct TriangleIter<I, T> {
    polygons: I,
    triangles: VecDeque<Triangle<T>>,
}

impl<I, T> TriangleIter<I, T> {
    fn new(polygons: I) -> Self {
        TriangleIter {
            polygons: polygons,
            triangles: VecDeque::new(),
        }
    }
}

impl<I, T, P> Iterator for TriangleIter<I, T>
    where I: Iterator<Item = P>,
          P: Polygonal<T>
{
    type Item = Triangle<T>;

    fn next(&mut self) -> Option<Self::Item> {
        loop {
            if let Some(triangle) = self.triangles.pop_front() {
                return Some(triangle);
            }
            if let Some(polygon) = self.polygons.next() {
                polygon.into_triangles(|triangle| self.triangles.push_back(triangle))
            }
            else {
                return None;
            }
        }
    }
}

pub struct Line<T> {
    a: T,
    b: T,
}

impl<T> Line<T> {
    pub fn new(a: T, b: T) -> Self {
        Line { a: a, b: b }
    }
}

impl<T, U> MapPrimitiveInto<T, U> for Line<T> {
    type Output = Line<U>;

    fn map_points_into<F>(self, mut f: F) -> Self::Output
        where F: FnMut(T) -> U
    {
        let Line { a, b } = self;
        Line::new(f(a), f(b))
    }
}

impl<T> Primitive<T> for Line<T> {
    fn into_points<F>(self, mut f: F)
        where F: FnMut(T)
    {
        let Line { a, b } = self;
        f(a);
        f(b);
    }

    fn into_lines<F>(self, mut f: F)
        where F: FnMut(Line<T>)
    {
        f(self);
    }
}

pub struct Triangle<T> {
    a: T,
    b: T,
    c: T,
}

impl<T> Triangle<T> {
    pub fn new(a: T, b: T, c: T) -> Self {
        Triangle { a: a, b: b, c: c }
    }
}

impl<T, U> MapPrimitiveInto<T, U> for Triangle<T> {
    type Output = Triangle<U>;

    fn map_points_into<F>(self, mut f: F) -> Self::Output
        where F: FnMut(T) -> U
    {
        let Triangle { a, b, c } = self;
        Triangle::new(f(a), f(b), f(c))
    }
}

impl<T> Primitive<T> for Triangle<T>
    where T: Clone
{
    fn into_points<F>(self, mut f: F)
        where F: FnMut(T)
    {
        let Triangle { a, b, c } = self;
        f(a);
        f(b);
        f(c);
    }

    fn into_lines<F>(self, mut f: F)
        where F: FnMut(Line<T>)
    {
        let Triangle { a, b, c } = self;
        f(Line::new(a.clone(), b.clone()));
        f(Line::new(b, c.clone()));
        f(Line::new(c, a));
    }
}

impl<T> Polygonal<T> for Triangle<T>
    where T: Clone
{
    fn into_triangles<F>(self, mut f: F)
        where F: FnMut(Triangle<T>)
    {
        f(self);
    }
}

pub struct Quad<T> {
    a: T,
    b: T,
    c: T,
    d: T,
}

impl<T> Quad<T> {
    pub fn new(a: T, b: T, c: T, d: T) -> Self {
        Quad {
            a: a,
            b: b,
            c: c,
            d: d,
        }
    }
}

impl<T, U> MapPrimitiveInto<T, U> for Quad<T> {
    type Output = Quad<U>;

    fn map_points_into<F>(self, mut f: F) -> Self::Output
        where F: FnMut(T) -> U
    {
        let Quad { a, b, c, d } = self;
        Quad::new(f(a), f(b), f(c), f(d))
    }
}

impl<T> Primitive<T> for Quad<T>
    where T: Clone
{
    fn into_points<F>(self, mut f: F)
        where F: FnMut(T)
    {
        let Quad { a, b, c, d } = self;
        f(a);
        f(b);
        f(c);
        f(d);
    }

    fn into_lines<F>(self, mut f: F)
        where F: FnMut(Line<T>)
    {
        let Quad { a, b, c, d } = self;
        f(Line::new(a.clone(), b.clone()));
        f(Line::new(b, c.clone()));
        f(Line::new(c, d.clone()));
        f(Line::new(d, a));
    }
}

impl<T> Polygonal<T> for Quad<T>
    where T: Clone
{
    fn into_triangles<F>(self, mut f: F)
        where F: FnMut(Triangle<T>)
    {
        let Quad { a, b, c, d } = self;
        f(Triangle::new(a.clone(), b, c.clone()));
        f(Triangle::new(c, d, a));
    }
}

pub enum Polygon<T> {
    Triangle(Triangle<T>),
    Quad(Quad<T>),
}

impl<T> Primitive<T> for Polygon<T>
    where T: Clone
{
    fn into_points<F>(self, f: F)
        where F: FnMut(T)
    {
        match self {
            Polygon::Triangle(triangle) => triangle.into_points(f),
            Polygon::Quad(quad) => quad.into_points(f),
        }
    }

    fn into_lines<F>(self, f: F)
        where F: FnMut(Line<T>)
    {
        match self {
            Polygon::Triangle(triangle) => triangle.into_lines(f),
            Polygon::Quad(quad) => quad.into_lines(f),
        }
    }
}

impl<T> Polygonal<T> for Polygon<T>
    where T: Clone
{
    fn into_triangles<F>(self, f: F)
        where F: FnMut(Triangle<T>)
    {
        match self {
            Polygon::Triangle(triangle) => triangle.into_triangles(f),
            Polygon::Quad(quad) => quad.into_triangles(f),
        }
    }
}
<commit_msg>Expose points in primitives and polygons.<commit_after>use std::collections::VecDeque;
use std::marker::PhantomData;

pub trait Primitive<T>: Sized {
    fn into_points<F>(self, f: F) where F: FnMut(T);
    fn into_lines<F>(self, f: F) where F: FnMut(Line<T>);
}

pub trait Polygonal<T>: Primitive<T> {
    fn into_triangles<F>(self, f: F) where F: FnMut(Triangle<T>);
}

pub trait MapPrimitiveInto<T, U> {
    type Output;

    fn map_points_into<F>(self, f: F) -> Self::Output where F: FnMut(T) -> U;
}

pub trait MapPrimitive<T, U>: Sized {
    type Output;

    fn map_points<F>(self, f: F) -> Map<Self, T, U, F> where F: FnMut(T) -> U;
}

pub trait DecomposePrimitive<T>: Sized {
    fn points(self) -> PointIter<Self, T>;
}

pub trait DecomposePolygon<T>: Sized {
    fn triangulate(self) -> TriangleIter<Self, T>;
}

impl<I, T, U, P, Q> MapPrimitive<T, U> for I
    where I: Iterator<Item = P>,
          P: MapPrimitiveInto<T, U, Output = Q>
{
    type Output = Q;

    fn map_points<F>(self, f: F) -> Map<Self, T, U, F>
        where F: FnMut(T) -> U
    {
        Map::new(self, f)
    }
}

pub struct Map<I, T, U, F> {
    primitives: I,
    f: F,
    phantom_t: PhantomData<T>,
    phantom_u: PhantomData<U>,
}

impl<I, T, U, F> Map<I, T, U, F> {
    fn new(primitives: I, f: F) -> Self {
        Map {
            primitives: primitives,
            f: f,
            phantom_t: PhantomData,
            phantom_u: PhantomData,
        }
    }
}

impl<I, T, U, F, P, Q> Iterator for Map<I, T, U, F>
    where I: Iterator<Item = P>,
          F: FnMut(T) -> U,
          P: MapPrimitiveInto<T, U, Output = Q>
{
    type Item = Q;

    fn next(&mut self) -> Option<Self::Item> {
        self.primitives.next().map(|primitive| primitive.map_points_into(|point| (self.f)(point)))
    }
}

impl<I, T, P> DecomposePrimitive<T> for I
    where I: Iterator<Item = P>,
          P: Primitive<T>
{
    fn points(self) -> PointIter<Self, T> {
        PointIter::new(self)
    }
}

pub struct PointIter<I, T> {
    primitives: I,
    points: VecDeque<T>,
}

impl<I, T> PointIter<I, T> {
    fn new(primitives: I) -> Self {
        PointIter {
            primitives: primitives,
            points: VecDeque::new(),
        }
    }
}

impl<I, T, P> Iterator for PointIter<I, T>
    where I: Iterator<Item = P>,
          P: Primitive<T>
{
    type Item = T;

    fn next(&mut self) -> Option<Self::Item> {
        loop {
            if let Some(point) = self.points.pop_front() {
                return Some(point);
            }
            if let Some(primitive) = self.primitives.next() {
                primitive.into_points(|point| self.points.push_back(point))
            }
            else {
                return None;
            }
        }
    }
}

impl<I, T, P> DecomposePolygon<T> for I
    where I: Iterator<Item = P>,
          P: Polygonal<T>
{
    fn triangulate(self) -> TriangleIter<Self, T> {
        TriangleIter::new(self)
    }
}

pub struct TriangleIter<I, T> {
    polygons: I,
    triangles: VecDeque<Triangle<T>>,
}

impl<I, T> TriangleIter<I, T> {
    fn new(polygons: I) -> Self {
        TriangleIter {
            polygons: polygons,
            triangles: VecDeque::new(),
        }
    }
}

impl<I, T, P> Iterator for TriangleIter<I, T>
    where I: Iterator<Item = P>,
          P: Polygonal<T>
{
    type Item = Triangle<T>;

    fn next(&mut self) -> Option<Self::Item> {
        loop {
            if let Some(triangle) = self.triangles.pop_front() {
                return Some(triangle);
            }
            if let Some(polygon) = self.polygons.next() {
                polygon.into_triangles(|triangle| self.triangles.push_back(triangle))
            }
            else {
                return None;
            }
        }
    }
}

pub struct Line<T> {
    pub a: T,
    pub b: T,
}

impl<T> Line<T> {
    pub fn new(a: T, b: T) -> Self {
        Line { a: a, b: b }
    }
}

impl<T, U> MapPrimitiveInto<T, U> for Line<T> {
    type Output = Line<U>;

    fn map_points_into<F>(self, mut f: F) -> Self::Output
        where F: FnMut(T) -> U
    {
        let Line { a, b } = self;
        Line::new(f(a), f(b))
    }
}

impl<T> Primitive<T> for Line<T> {
    fn into_points<F>(self, mut f: F)
        where F: FnMut(T)
    {
        let Line { a, b } = self;
        f(a);
        f(b);
    }

    fn into_lines<F>(self, mut f: F)
        where F: FnMut(Line<T>)
    {
        f(self);
    }
}

pub struct Triangle<T> {
    pub a: T,
    pub b: T,
    pub c: T,
}

impl<T> Triangle<T> {
    pub fn new(a: T, b: T, c: T) -> Self {
        Triangle { a: a, b: b, c: c }
    }
}

impl<T, U> MapPrimitiveInto<T, U> for Triangle<T> {
    type Output = Triangle<U>;

    fn map_points_into<F>(self, mut f: F) -> Self::Output
        where F: FnMut(T) -> U
    {
        let Triangle { a, b, c } = self;
        Triangle::new(f(a), f(b), f(c))
    }
}

impl<T> Primitive<T> for Triangle<T>
    where T: Clone
{
    fn into_points<F>(self, mut f: F)
        where F: FnMut(T)
    {
        let Triangle { a, b, c } = self;
        f(a);
        f(b);
        f(c);
    }

    fn into_lines<F>(self, mut f: F)
        where F: FnMut(Line<T>)
    {
        let Triangle { a, b, c } = self;
        f(Line::new(a.clone(), b.clone()));
        f(Line::new(b, c.clone()));
        f(Line::new(c, a));
    }
}

impl<T> Polygonal<T> for Triangle<T>
    where T: Clone
{
    fn into_triangles<F>(self, mut f: F)
        where F: FnMut(Triangle<T>)
    {
        f(self);
    }
}

pub struct Quad<T> {
    pub a: T,
    pub b: T,
    pub c: T,
    pub d: T,
}

impl<T> Quad<T> {
    pub fn new(a: T, b: T, c: T, d: T) -> Self {
        Quad {
            a: a,
            b: b,
            c: c,
            d: d,
        }
    }
}

impl<T, U> MapPrimitiveInto<T, U> for Quad<T> {
    type Output = Quad<U>;

    fn map_points_into<F>(self, mut f: F) -> Self::Output
        where F: FnMut(T) -> U
    {
        let Quad { a, b, c, d } = self;
        Quad::new(f(a), f(b), f(c), f(d))
    }
}

impl<T> Primitive<T> for Quad<T>
    where T: Clone
{
    fn into_points<F>(self, mut f: F)
        where F: FnMut(T)
    {
        let Quad { a, b, c, d } = self;
        f(a);
        f(b);
        f(c);
        f(d);
    }

    fn into_lines<F>(self, mut f: F)
        where F: FnMut(Line<T>)
    {
        let Quad { a, b, c, d } = self;
        f(Line::new(a.clone(), b.clone()));
        f(Line::new(b, c.clone()));
        f(Line::new(c, d.clone()));
        f(Line::new(d, a));
    }
}

impl<T> Polygonal<T> for Quad<T>
    where T: Clone
{
    fn into_triangles<F>(self, mut f: F)
        where F: FnMut(Triangle<T>)
    {
        let Quad { a, b, c, d } = self;
        f(Triangle::new(a.clone(), b, c.clone()));
        f(Triangle::new(c, d, a));
    }
}

pub enum Polygon<T> {
    Triangle(Triangle<T>),
    Quad(Quad<T>),
}

impl<T> Primitive<T> for Polygon<T>
    where T: Clone
{
    fn into_points<F>(self, f: F)
        where F: FnMut(T)
    {
        match self {
            Polygon::Triangle(triangle) => triangle.into_points(f),
            Polygon::Quad(quad) => quad.into_points(f),
        }
    }

    fn into_lines<F>(self, f: F)
        where F: FnMut(Line<T>)
    {
        match self {
            Polygon::Triangle(triangle) => triangle.into_lines(f),
            Polygon::Quad(quad) => quad.into_lines(f),
        }
    }
}

impl<T> Polygonal<T> for Polygon<T>
    where T: Clone
{
    fn into_triangles<F>(self, f: F)
        where F: FnMut(Triangle<T>)
    {
        match self {
            Polygon::Triangle(triangle) => triangle.into_triangles(f),
            Polygon::Quad(quad) => quad.into_triangles(f),
        }
    }
}
<|endoftext|>


<commit_before>use std::borrow::Cow;
use std::fmt::Debug;
use std::str::FromStr;
use std::net::SocketAddr;

use hyper::header::{Header, HeaderFormat};

use error::{SSDPResult, MsgError};
use header::{HeaderRef, HeaderMut};
use message::{self, MessageType};
use message::ssdp::SSDPMessage;
use receiver::{SSDPReceiver, FromRawSSDP};
use net;

/// Notify message that can be sent via multicast to devices on the network.
#[derive(Debug, Clone)]
pub struct NotifyMessage {
    message: SSDPMessage,
}

impl NotifyMessage {
    /// Construct a new NotifyMessage.
    pub fn new() -> Self {
        NotifyMessage { message: SSDPMessage::new(MessageType::Notify) }
    }

    /// Send this notify message to the standard multicast address:port.
    pub fn multicast(&mut self) -> SSDPResult<()> {
        self.multicast_with_port(message::UPNP_MULTICAST_PORT)
    }

    /// Send this notify message to the standard multicast address but a custom port.
    pub fn multicast_with_port(&mut self, port: u16) -> SSDPResult<()> {
        let mcast_ttl = Some(message::UPNP_MULTICAST_TTL);

        let mut connectors = try!(message::all_local_connectors(mcast_ttl, net::IpVersionMode::Any));

        // Send On All Connectors
        for conn in &mut connectors {
            match try!(conn.local_addr()) {
                SocketAddr::V4(n) => {
                    let mcast_addr = (message::UPNP_MULTICAST_IPV4_ADDR, port);
                    debug!("Sending ipv4 multicast through {} to {:?}", n, mcast_addr);
                    try!(self.message.send(conn, &mcast_addr));
                }
                SocketAddr::V6(n) => {
                    let mcast_addr = (message::UPNP_MULTICAST_IPV6_LINK_LOCAL_ADDR, port);
                    debug!("Sending Ipv6 multicast through {} to {:?}", n, mcast_addr);
                    try!(self.message.send(conn, &mcast_addr));
                }
            }
        }

        Ok(())
    }
}

impl Default for NotifyMessage {
    fn default() -> Self {
        NotifyMessage::new()
    }
}

impl FromRawSSDP for NotifyMessage {
    fn raw_ssdp(bytes: &[u8]) -> SSDPResult<NotifyMessage> {
        let message = try!(SSDPMessage::raw_ssdp(bytes));

        if message.message_type() != MessageType::Notify {
            try!(Err(MsgError::new("SSDP Message Received Is Not A NotifyMessage")))
        } else {
            Ok(NotifyMessage { message: message })
        }
    }
}

impl HeaderRef for NotifyMessage {
    fn get<H>(&self) -> Option<&H>
        where H: Header + HeaderFormat
    {
        self.message.get::<H>()
    }

    fn get_raw(&self, name: &str) -> Option<&[Vec<u8>]> {
        self.message.get_raw(name)
    }
}

impl HeaderMut for NotifyMessage {
    fn set<H>(&mut self, value: H)
        where H: Header + HeaderFormat
    {
        self.message.set(value)
    }

    fn set_raw<K>(&mut self, name: K, value: Vec<Vec<u8>>)
        where K: Into<Cow<'static, str>> + Debug
    {
        self.message.set_raw(name, value)
    }
}

/// Notify listener that can listen to notify messages sent within the network.
pub struct NotifyListener;

impl NotifyListener {
    /// Listen for notify messages on all local network interfaces.
    pub fn listen() -> SSDPResult<SSDPReceiver<NotifyMessage>> {
        NotifyListener::listen_on_port(message::UPNP_MULTICAST_PORT)
    }

    /// Listen for notify messages on a custom port on all local network interfaces.
    pub fn listen_on_port(port: u16) -> SSDPResult<SSDPReceiver<NotifyMessage>> {
        // Generate a list of reused sockets on the standard multicast address.
        let reuse_sockets = try!(message::map_local(|&addr| match addr {
            SocketAddr::V4(v4_addr) => {
                let sock = try!(net::bind_reuse((*v4_addr.ip(), port)));

                let mcast_ip = FromStr::from_str(message::UPNP_MULTICAST_IPV4_ADDR).unwrap();

                debug!("Joining ipv4 multicast {} at iface: {}", mcast_ip, addr);
                try!(net::join_multicast(&sock, &addr, &mcast_ip));

                Ok(Some(sock))
            }
            SocketAddr::V6(v6_addr) => {
                let sock = try!(net::bind_reuse((*v6_addr.ip(), port)));

                let mcast_ip = FromStr::from_str(message::UPNP_MULTICAST_IPV6_LINK_LOCAL_ADDR).unwrap();

                debug!("Joining ipv6 multicast {} at iface: {}", mcast_ip, addr);
                try!(net::join_multicast(&sock, &addr, &mcast_ip));

                Ok(Some(sock))
            }
        }));

        Ok(try!(SSDPReceiver::new(reuse_sockets, None)))
    }
}

#[cfg(test)]
mod tests {
    use super::NotifyMessage;
    use receiver::FromRawSSDP;

    #[test]
    fn positive_notify_message_type() {
        let raw_message = "NOTIFY * HTTP/1.1\r\nHOST: 192.168.1.1\r\n\r\n";

        NotifyMessage::raw_ssdp(raw_message.as_bytes()).unwrap();
    }

    #[test]
    #[should_panic]
    fn negative_search_message_type() {
        let raw_message = "M-SEARCH * HTTP/1.1\r\nHOST: 192.168.1.1\r\n\r\n";

        NotifyMessage::raw_ssdp(raw_message.as_bytes()).unwrap();
    }

    #[test]
    #[should_panic]
    fn negative_response_message_type() {
        let raw_message = "HTTP/1.1 200 OK\r\n\r\n";

        NotifyMessage::raw_ssdp(raw_message.as_bytes()).unwrap();
    }
}
<commit_msg>fix(notify): ipv6 broke in commit 3f3c27e<commit_after>use std::borrow::Cow;
use std::fmt::Debug;
use std::str::FromStr;
use std::net::{SocketAddr, IpAddr, Ipv6Addr};

use hyper::header::{Header, HeaderFormat};

use error::{SSDPResult, MsgError};
use header::{HeaderRef, HeaderMut};
use message::{self, MessageType};
use message::ssdp::SSDPMessage;
use receiver::{SSDPReceiver, FromRawSSDP};
use net;

/// Notify message that can be sent via multicast to devices on the network.
#[derive(Debug, Clone)]
pub struct NotifyMessage {
    message: SSDPMessage,
}

impl NotifyMessage {
    /// Construct a new NotifyMessage.
    pub fn new() -> Self {
        NotifyMessage { message: SSDPMessage::new(MessageType::Notify) }
    }

    /// Send this notify message to the standard multicast address:port.
    pub fn multicast(&mut self) -> SSDPResult<()> {
        self.multicast_with_port(message::UPNP_MULTICAST_PORT)
    }

    /// Send this notify message to the standard multicast address but a custom port.
    pub fn multicast_with_port(&mut self, port: u16) -> SSDPResult<()> {
        let mcast_ttl = Some(message::UPNP_MULTICAST_TTL);

        let mut connectors = try!(message::all_local_connectors(mcast_ttl, net::IpVersionMode::Any));

        // Send On All Connectors
        for conn in &mut connectors {
            match try!(conn.local_addr()) {
                SocketAddr::V4(n) => {
                    let mcast_addr = (message::UPNP_MULTICAST_IPV4_ADDR, port);
                    debug!("Sending ipv4 multicast through {} to {:?}", n, mcast_addr);
                    try!(self.message.send(conn, &mcast_addr));
                }
                SocketAddr::V6(n) => {
                    let mcast_addr = (message::UPNP_MULTICAST_IPV6_LINK_LOCAL_ADDR, port);
                    debug!("Sending Ipv6 multicast through {} to {:?}", n, mcast_addr);
                    try!(self.message.send(conn, &mcast_addr));
                }
            }
        }

        Ok(())
    }
}

impl Default for NotifyMessage {
    fn default() -> Self {
        NotifyMessage::new()
    }
}

impl FromRawSSDP for NotifyMessage {
    fn raw_ssdp(bytes: &[u8]) -> SSDPResult<NotifyMessage> {
        let message = try!(SSDPMessage::raw_ssdp(bytes));

        if message.message_type() != MessageType::Notify {
            try!(Err(MsgError::new("SSDP Message Received Is Not A NotifyMessage")))
        } else {
            Ok(NotifyMessage { message: message })
        }
    }
}

impl HeaderRef for NotifyMessage {
    fn get<H>(&self) -> Option<&H>
        where H: Header + HeaderFormat
    {
        self.message.get::<H>()
    }

    fn get_raw(&self, name: &str) -> Option<&[Vec<u8>]> {
        self.message.get_raw(name)
    }
}

impl HeaderMut for NotifyMessage {
    fn set<H>(&mut self, value: H)
        where H: Header + HeaderFormat
    {
        self.message.set(value)
    }

    fn set_raw<K>(&mut self, name: K, value: Vec<Vec<u8>>)
        where K: Into<Cow<'static, str>> + Debug
    {
        self.message.set_raw(name, value)
    }
}

/// Notify listener that can listen to notify messages sent within the network.
pub struct NotifyListener;

impl NotifyListener {
    /// Listen for notify messages on all local network interfaces.
    pub fn listen() -> SSDPResult<SSDPReceiver<NotifyMessage>> {
        NotifyListener::listen_on_port(message::UPNP_MULTICAST_PORT)
    }

    /// Listen for notify messages on a custom port on all local network interfaces.
    pub fn listen_on_port(port: u16) -> SSDPResult<SSDPReceiver<NotifyMessage>> {
        // Generate a list of reused sockets on the standard multicast address.
        let reuse_sockets = try!(message::map_local(|&addr| match addr {
            SocketAddr::V4(v4_addr) => {
                let sock = try!(net::bind_reuse((*v4_addr.ip(), port)));

                let mcast_ip = FromStr::from_str(message::UPNP_MULTICAST_IPV4_ADDR).unwrap();

                debug!("Joining ipv4 multicast {} at iface: {}", mcast_ip, addr);
                try!(net::join_multicast(&sock, &addr, &mcast_ip));

                Ok(Some(sock))
            }
            SocketAddr::V6(v6_addr) => {
                let mcast_ip: Ipv6Addr = FromStr::from_str(message::UPNP_MULTICAST_IPV6_LINK_LOCAL_ADDR)
                    .unwrap();

                // clone to preserve interface scope
                let mut x = v6_addr.clone();
                x.set_ip(mcast_ip);
                x.set_port(port);
                let sock = try!(net::bind_reuse(x));

                debug!("Joining ipv6 multicast {} at iface: {}", mcast_ip, addr);
                try!(net::join_multicast(&sock, &addr, &IpAddr::V6(mcast_ip)));

                Ok(Some(sock))
            }
        }));

        Ok(try!(SSDPReceiver::new(reuse_sockets, None)))
    }
}

#[cfg(test)]
mod tests {
    use super::NotifyMessage;
    use receiver::FromRawSSDP;

    #[test]
    fn positive_notify_message_type() {
        let raw_message = "NOTIFY * HTTP/1.1\r\nHOST: 192.168.1.1\r\n\r\n";

        NotifyMessage::raw_ssdp(raw_message.as_bytes()).unwrap();
    }

    #[test]
    #[should_panic]
    fn negative_search_message_type() {
        let raw_message = "M-SEARCH * HTTP/1.1\r\nHOST: 192.168.1.1\r\n\r\n";

        NotifyMessage::raw_ssdp(raw_message.as_bytes()).unwrap();
    }

    #[test]
    #[should_panic]
    fn negative_response_message_type() {
        let raw_message = "HTTP/1.1 200 OK\r\n\r\n";

        NotifyMessage::raw_ssdp(raw_message.as_bytes()).unwrap();
    }
}
<|endoftext|>