<commit_before>export OSMain;
export Msg, BeginDrawing, Draw, AddKeyHandler, Exit;

import azure::*;
import azure::bindgen::*;
import azure::cairo;
import azure::cairo::bindgen::*;
import comm::*;
import dvec::{dvec, extensions};
import azure::cairo::cairo_surface_t;
import gfx::renderer::{Sink};
import dom::event::{Event, ResizeEvent};
import layers::ImageLayer;
import geom::size::Size2D;
import std::cmp::fuzzy_eq;
import vec::push;

type OSMain = chan<Msg>;

enum Msg {
    BeginDrawing(chan<AzDrawTargetRef>),
    Draw(chan<AzDrawTargetRef>, AzDrawTargetRef),
    AddKeyHandler(chan<()>),
    AddEventListener(chan<Event>),
    Exit
}

fn OSMain() -> OSMain {
    do on_osmain::<Msg> |po| {
        do platform::runmain {
            #debug("preparing to enter main loop");
	        mainloop(po);
        }
    }
}

fn mainloop(po: port<Msg>) {
    let key_handlers: @dvec<chan<()>> = @dvec();
    let event_listeners: @dvec<chan<Event>> = @dvec();

    glut::init();
    glut::init_display_mode(glut::DOUBLE);

    let surfaces = @surface_set();

    let window = glut::create_window(~"Servo");
    glut::reshape_window(window, 800, 600);

    let context = layers::rendergl::init_render_context();

    let image = @layers::layers::Image(0, 0, layers::layers::RGB24Format, ~[]);
    let image_layer = @layers::layers::ImageLayer(image);
    image_layer.common.set_transform
        (image_layer.common.transform.scale(800.0f32, 600.0f32, 1.0f32));

    let scene = @mut layers::scene::Scene(layers::layers::ImageLayerKind(image_layer),
                                          Size2D(800.0f32, 600.0f32));

    let done = @mut false;

    let check_for_messages = fn@() {
        // Handle messages
        #debug("osmain: peeking");
        while po.peek() {
            alt po.recv() {
              AddKeyHandler(key_ch) {
                key_handlers.push(key_ch);
              }
              AddEventListener(event_listener) {
                event_listeners.push(event_listener);
              }
              BeginDrawing(sender) {
                lend_surface(*surfaces, sender);
              }
              Draw(sender, dt) {
                #debug("osmain: received new frame");
                return_surface(*surfaces, dt);
                lend_surface(*surfaces, sender);

                let mut image_data;
                unsafe {
                    let buffer = cairo_image_surface_get_data(surfaces.s1.surf.cairo_surf);
                    image_data = vec::unsafe::from_buf(buffer, 800 * 600 * 4);
                }

                let image =
                    @layers::layers::Image(800, 600, layers::layers::ARGB32Format, image_data);
                image_layer.set_image(image);
              }
              exit {
                *done = true;
              }
            }
        }
    };

    do glut::reshape_func(window) |width, height| {
        check_for_messages();

        #debug("osmain: window resized to %d,%d", width as int, height as int);
        for event_listeners.each |event_listener| {
            event_listener.send(ResizeEvent(width as int, height as int));
        }
    }

    do glut::display_func() {
        check_for_messages();

        #debug("osmain: drawing to screen");

        do util::time::time(~"compositing") {
            layers::rendergl::render_scene(context, *scene);
        }

        glut::swap_buffers();
        glut::post_redisplay();
    }

    while !*done {
        #debug("osmain: running GLUT check loop");
        glut::check_loop();
    }

    destroy_surface(surfaces.s1.surf);
    destroy_surface(surfaces.s2.surf);
}

#[doc = "
Implementation to allow the osmain channel to be used as a graphics
sink for the renderer
"]
impl OSMain of Sink for OSMain {
    fn begin_drawing(next_dt: chan<AzDrawTargetRef>) {
        self.send(BeginDrawing(next_dt))
    }
    fn draw(next_dt: chan<AzDrawTargetRef>, draw_me: AzDrawTargetRef) {
        self.send(Draw(next_dt, draw_me))
    }
    fn add_event_listener(listener: chan<Event>) {
        self.send(AddEventListener(listener));
    }
}

type surface_set = {
    mut s1: {
        surf: surface,
        have: bool
    },
    mut s2: {
        surf: surface,
        have: bool
    }
};

fn lend_surface(surfaces: surface_set, recvr: chan<AzDrawTargetRef>) {
    // We are in a position to lend out the surface?
    assert surfaces.s1.have;
    // Ok then take it
    let dt1 = surfaces.s1.surf.az_target;
    #debug("osmain: lending surface %?", dt1);
    recvr.send(dt1);
    // Now we don't have it
    surfaces.s1 = {
        have: false
        with surfaces.s1
    };
    // But we (hopefully) have another!
    surfaces.s1 <-> surfaces.s2;
    // Let's look
    assert surfaces.s1.have;
}

fn return_surface(surfaces: surface_set, dt: AzDrawTargetRef) {
    #debug("osmain: returning surface %?", dt);
    // We have room for a return
    assert surfaces.s1.have;
    assert !surfaces.s2.have;
    assert surfaces.s2.surf.az_target == dt;
    // Now we have it again
    surfaces.s2 = {
        have: true
        with surfaces.s2
    };
}

fn surface_set() -> surface_set {
    {
        mut s1: {
            surf: mk_surface(),
            have: true
        },
        mut s2: {
            surf: mk_surface(),
            have: true
        }
    }
}

type surface = {
    cairo_surf: *cairo_surface_t,
    az_target: AzDrawTargetRef
};

fn mk_surface() -> surface {
    let cairo_surf = cairo_image_surface_create(cairo::CAIRO_FORMAT_RGB24, 800, 600);

    assert !ptr::is_null(cairo_surf);

    let azure_target = AzCreateDrawTargetForCairoSurface(cairo_surf);
    assert !ptr::is_null(azure_target);

    {
        cairo_surf: cairo_surf,
        az_target: azure_target
    }
}

fn destroy_surface(+surface: surface) {
    AzReleaseDrawTarget(surface.az_target);
    cairo_surface_destroy(surface.cairo_surf);
}

#[doc = "A function for spawning into the platform's main thread"]
fn on_osmain<T: send>(+f: fn~(comm::port<T>)) -> comm::chan<T> {
    let builder = task::builder();
    let opts = {
        sched: some({
            mode: task::osmain,
            foreign_stack_size: none
        })
        with task::get_opts(builder)
    };
    task::set_opts(builder, opts);
    ret task::run_listener(builder, f);
}

// #[cfg(target_os = "linux")]
mod platform {
    fn runmain(f: fn()) {
        f()
    }
}

<commit_msg>Change osmain.rs to new task::task_builder interface<commit_after>export OSMain;
export Msg, BeginDrawing, Draw, AddKeyHandler, Exit;

import azure::*;
import azure::bindgen::*;
import azure::cairo;
import azure::cairo::bindgen::*;
import comm::*;
import dvec::{dvec, extensions};
import azure::cairo::cairo_surface_t;
import gfx::renderer::{Sink};
import dom::event::{Event, ResizeEvent};
import layers::ImageLayer;
import geom::size::Size2D;
import std::cmp::fuzzy_eq;
import task::task_builder;
import vec::push;

type OSMain = chan<Msg>;

enum Msg {
    BeginDrawing(chan<AzDrawTargetRef>),
    Draw(chan<AzDrawTargetRef>, AzDrawTargetRef),
    AddKeyHandler(chan<()>),
    AddEventListener(chan<Event>),
    Exit
}

fn OSMain() -> OSMain {
    do on_osmain::<Msg> |po| {
        do platform::runmain {
            #debug("preparing to enter main loop");
	        mainloop(po);
        }
    }
}

fn mainloop(po: port<Msg>) {
    let key_handlers: @dvec<chan<()>> = @dvec();
    let event_listeners: @dvec<chan<Event>> = @dvec();

    glut::init();
    glut::init_display_mode(glut::DOUBLE);

    let surfaces = @surface_set();

    let window = glut::create_window(~"Servo");
    glut::reshape_window(window, 800, 600);

    let context = layers::rendergl::init_render_context();

    let image = @layers::layers::Image(0, 0, layers::layers::RGB24Format, ~[]);
    let image_layer = @layers::layers::ImageLayer(image);
    image_layer.common.set_transform
        (image_layer.common.transform.scale(800.0f32, 600.0f32, 1.0f32));

    let scene = @mut layers::scene::Scene(layers::layers::ImageLayerKind(image_layer),
                                          Size2D(800.0f32, 600.0f32));

    let done = @mut false;

    let check_for_messages = fn@() {
        // Handle messages
        #debug("osmain: peeking");
        while po.peek() {
            alt po.recv() {
              AddKeyHandler(key_ch) {
                key_handlers.push(key_ch);
              }
              AddEventListener(event_listener) {
                event_listeners.push(event_listener);
              }
              BeginDrawing(sender) {
                lend_surface(*surfaces, sender);
              }
              Draw(sender, dt) {
                #debug("osmain: received new frame");
                return_surface(*surfaces, dt);
                lend_surface(*surfaces, sender);

                let mut image_data;
                unsafe {
                    let buffer = cairo_image_surface_get_data(surfaces.s1.surf.cairo_surf);
                    image_data = vec::unsafe::from_buf(buffer, 800 * 600 * 4);
                }

                let image =
                    @layers::layers::Image(800, 600, layers::layers::ARGB32Format, image_data);
                image_layer.set_image(image);
              }
              exit {
                *done = true;
              }
            }
        }
    };

    do glut::reshape_func(window) |width, height| {
        check_for_messages();

        #debug("osmain: window resized to %d,%d", width as int, height as int);
        for event_listeners.each |event_listener| {
            event_listener.send(ResizeEvent(width as int, height as int));
        }
    }

    do glut::display_func() {
        check_for_messages();

        #debug("osmain: drawing to screen");

        do util::time::time(~"compositing") {
            layers::rendergl::render_scene(context, *scene);
        }

        glut::swap_buffers();
        glut::post_redisplay();
    }

    while !*done {
        #debug("osmain: running GLUT check loop");
        glut::check_loop();
    }

    destroy_surface(surfaces.s1.surf);
    destroy_surface(surfaces.s2.surf);
}

#[doc = "
Implementation to allow the osmain channel to be used as a graphics
sink for the renderer
"]
impl OSMain of Sink for OSMain {
    fn begin_drawing(next_dt: chan<AzDrawTargetRef>) {
        self.send(BeginDrawing(next_dt))
    }
    fn draw(next_dt: chan<AzDrawTargetRef>, draw_me: AzDrawTargetRef) {
        self.send(Draw(next_dt, draw_me))
    }
    fn add_event_listener(listener: chan<Event>) {
        self.send(AddEventListener(listener));
    }
}

type surface_set = {
    mut s1: {
        surf: surface,
        have: bool
    },
    mut s2: {
        surf: surface,
        have: bool
    }
};

fn lend_surface(surfaces: surface_set, recvr: chan<AzDrawTargetRef>) {
    // We are in a position to lend out the surface?
    assert surfaces.s1.have;
    // Ok then take it
    let dt1 = surfaces.s1.surf.az_target;
    #debug("osmain: lending surface %?", dt1);
    recvr.send(dt1);
    // Now we don't have it
    surfaces.s1 = {
        have: false
        with surfaces.s1
    };
    // But we (hopefully) have another!
    surfaces.s1 <-> surfaces.s2;
    // Let's look
    assert surfaces.s1.have;
}

fn return_surface(surfaces: surface_set, dt: AzDrawTargetRef) {
    #debug("osmain: returning surface %?", dt);
    // We have room for a return
    assert surfaces.s1.have;
    assert !surfaces.s2.have;
    assert surfaces.s2.surf.az_target == dt;
    // Now we have it again
    surfaces.s2 = {
        have: true
        with surfaces.s2
    };
}

fn surface_set() -> surface_set {
    {
        mut s1: {
            surf: mk_surface(),
            have: true
        },
        mut s2: {
            surf: mk_surface(),
            have: true
        }
    }
}

type surface = {
    cairo_surf: *cairo_surface_t,
    az_target: AzDrawTargetRef
};

fn mk_surface() -> surface {
    let cairo_surf = cairo_image_surface_create(cairo::CAIRO_FORMAT_RGB24, 800, 600);

    assert !ptr::is_null(cairo_surf);

    let azure_target = AzCreateDrawTargetForCairoSurface(cairo_surf);
    assert !ptr::is_null(azure_target);

    {
        cairo_surf: cairo_surf,
        az_target: azure_target
    }
}

fn destroy_surface(+surface: surface) {
    AzReleaseDrawTarget(surface.az_target);
    cairo_surface_destroy(surface.cairo_surf);
}

#[doc = "A function for spawning into the platform's main thread"]
fn on_osmain<T: send>(+f: fn~(comm::port<T>)) -> comm::chan<T> {
    task::task().sched_mode(task::osmain).spawn_listener(f)
}

// #[cfg(target_os = "linux")]
mod platform {
    fn runmain(f: fn()) {
        f()
    }
}

<|endoftext|>


<commit_before>extern crate orbclient;
extern crate tetrahedrane;

fn main() {
    let mut window = orbclient::window::Window::new_flags(-1, -1, 640, 480, &"dziki wunsz", true).unwrap();

    'gameloop: loop {
        for event in window.events() {
            use orbclient::event::EventOption;
            let ev_opt = event.to_option();

            match ev_opt {
                EventOption::Quit(..) => break 'gameloop,
                _ => {}
            }
        }

        window.clear();

        tetrahedrane::renderers::wireframe::triangle_p(0.0, 0.0, 1.0,
                                                    1.0, 1.0, 1.0,
                                                    1.0, 0.0, 1.0,
                                                    orbclient::Color::rgb(255,0,255),
                                                    &mut window);

        window.sync();
    }
}<commit_msg>Added filled triangle example<commit_after>extern crate orbclient;
extern crate tetrahedrane;

fn main() {
    let mut window = orbclient::window::Window::new_flags(-1, -1, 640, 480, &"dziki wunsz", true).unwrap();

    let mut framecounter = 0;
    let mut timecounter = std::time::Duration::new(0,0);

    'gameloop: loop {
        let begin = std::time::Instant::now();

        for event in window.events() {
            use orbclient::event::EventOption;
            let ev_opt = event.to_option();

            match ev_opt {
                EventOption::Quit(..) => break 'gameloop,
                _ => {}
            }
        }

        window.clear();

        tetrahedrane::renderers::filled::triangle_p(0.0, 0.0, 1.0,
                                                    1.0, 1.0, 1.0,
                                                    1.0, 0.0, 1.0,
                                                    orbclient::Color::rgb(255,0,255),
                                                    &mut window);

        window.sync();

        let end = std::time::Instant::now();

        framecounter += 1;
        timecounter += end.duration_since(begin);

        if timecounter > std::time::Duration::new(1, 0) {
            timecounter = std::time::Duration::new(0, 0);
            println!("FPS: {}", framecounter);
            framecounter = 0;
        }
    }
}<|endoftext|>


<commit_before>extern crate bytes;
extern crate futures;
extern crate libp2p_peerstore;
extern crate libp2p_identify;
extern crate libp2p_core;
extern crate libp2p_mplex;
extern crate libp2p_tcp_transport;
extern crate libp2p_floodsub;
extern crate libp2p_kad;
extern crate slog;
extern crate tokio_core;
extern crate tokio_io;

use self::futures::Future;
use self::libp2p_peerstore::PeerId;
use self::libp2p_core::{ Endpoint, Multiaddr, Transport, ConnectionUpgrade };
use self::libp2p_floodsub::{ FloodSubUpgrade, FloodSubFuture };
use self::libp2p_kad::{ KademliaUpgrade, KademliaProcessingFuture};
use self::libp2p_identify::{ IdentifyInfo, IdentifyTransport, IdentifyOutput };
use self::slog::Logger;
use std::sync::{ Arc, RwLock };
use std::time::Duration;
use std::ops::Deref;
use std::io::Error as IoError;
use libp2p_peerstore::memory_peerstore::MemoryPeerstore;
use self::tokio_io::{ AsyncRead, AsyncWrite };
use self::bytes::Bytes;

pub fn listen(peer_id: PeerId,
               peer_store: Arc<MemoryPeerstore>,
               log: &Logger)
{
    let listen_multiaddr: Multiaddr = "/ip4/0.0.0.0/tcp/10101/ws"
        .parse::<Multiaddr>().expect("Failed to parse listen multiaddr.");

    let core =  tokio_core::reactor::Core::new().expect("tokio failure.");
    let listened_addrs = Arc::new(RwLock::new(vec![]));
    let transport = libp2p_tcp_transport::TcpConfig::new(core.handle())
        .with_upgrade(libp2p_core::upgrade::PlainTextConfig)
        .with_upgrade(libp2p_mplex::BufferedMultiplexConfig::<[_; 256]>::new())
        .into_connection_reuse();

    let (floodsub_upgrade, floodsub_rx) = FloodSubUpgrade::new(peer_id.clone());

    let transport_sockets = {
        let listened_addrs = Arc::new(RwLock::new(vec![]));
        let listen_multiaddr = listen_multiaddr.clone();
        IdentifyTransport::new(transport.clone(), peer_store.clone())
            .map(move |out, _, _| {
                if let(Some(ref observed), ref listen_multiaddr) = (out.observed_addr, listen_multiaddr) {
                    if let Some(viewed_from_outisde) = transport.nat_traversal(listen_multiaddr, observed) {
                        listened_addrs.write().unwrap().push(viewed_from_outisde);
                    }
                }
                out.socket
            })
    };

    let kad_config = libp2p_kad::KademliaConfig {
        parallelism: 3,
        record_store: (),
        peer_store: peer_store,
        local_peer_id: peer_id.clone(),
        timeout: Duration::from_secs(2)
    };

    let kad_ctl_proto = libp2p_kad::KademliaControllerPrototype::new(kad_config);
    let kad_upgrade = libp2p_kad::KademliaUpgrade::from_prototype(&kad_ctl_proto);

    let upgrade = ConnectionUpgrader {
        kad: kad_upgrade.clone(),
        identify: libp2p_identify::IdentifyProtocolConfig,
        floodsub: floodsub_upgrade.clone(),
    };

    let swarm_listened_addrs = listened_addrs.clone();
    let (swarm_ctrl, swarm_future) = libp2p_core::swarm(
        transport_sockets.clone().with_upgrade(upgrade),
        move |upgrade, client_addr| match upgrade {
            FinalUpgrade::Kad(kad) => Box::new(kad) as Box<_>,
            FinalUpgrade::FloodSub(future) => Box::new(future) as Box<_>,
            FinalUpgrade::Identify(IdentifyOutput::Sender { sender, .. }) => sender.send(
                IdentifyInfo {
                    public_key: peer_id.clone().into_bytes(),
                    agent_version: "lighthouse/1.0.0".to_owned(),
                    protocol_version: "rust-libp2p/1.0.0".to_owned(),
                    listen_addrs: swarm_listened_addrs.read().unwrap().to_vec(),
                    protocols: vec![
                        "/ipfs/kad/1.0.0".to_owned(),
                        "/ipfs/id/1.0.0".to_owned(),
                        "/floodsub/1.0.0".to_owned(),
                    ]
                },
                &client_addr
            ),
            FinalUpgrade::Identify(IdentifyOutput::RemoteInfo { .. }) => {
                unreachable!("Never dial with the identify protocol.")
            }
        },
    );

    let actual_addr = swarm_ctrl
        .listen_on(listen_multiaddr)
        .expect("Failed to listen on multiaddr");
}

#[derive(Clone)]
struct ConnectionUpgrader<P, R> {
    kad: KademliaUpgrade<P, R>,
    identify: libp2p_identify::IdentifyProtocolConfig,
    floodsub: FloodSubUpgrade
}

impl<C, P, R, Pc> ConnectionUpgrade<C> for ConnectionUpgrader<P, R>
where
    C: AsyncRead + AsyncWrite + 'static,
    P: Deref<Target = Pc> + Clone + 'static,
    for<'r> &'r Pc: libp2p_peerstore::Peerstore,
    R: 'static
{
    type NamesIter = ::std::vec::IntoIter<(Bytes, usize)>;
    type UpgradeIdentifier = usize;
    type Output = FinalUpgrade<C>;
    type Future = Box<Future<Item = FinalUpgrade<C>, Error = IoError>>;

    #[inline]
    fn protocol_names(&self) -> Self::NamesIter {
        vec![
            (Bytes::from("/ipfs/kad/1.0.0"), 0),
            (Bytes::from("/ipfs/id/1.0.0"), 1),
            (Bytes::from("/floodsub/1.0.0"), 2),
        ].into_iter()
    }

    fn upgrade(
        self,
        socket: C,
        id: Self::UpgradeIdentifier,
        ty: Endpoint,
        remote_addr: &Multiaddr)
        -> Self::Future
    {
        match id {
            0 => Box::new(
                self.kad
                    .upgrade(socket, (), ty, remote_addr)
                    .map(|upg| upg.into())),
            1 => Box::new(
                self.identify
                    .upgrade(socket, (), ty, remote_addr)
                    .map(|upg| upg.into())),
            2 => Box::new(
                self.floodsub
                    .upgrade(socket, (), ty, remote_addr)
                    .map(|upg| upg.into())),
            _ => unreachable!()
        }

    }
}

enum FinalUpgrade<C> {
    Kad(KademliaProcessingFuture),
    Identify(IdentifyOutput<C>),
    FloodSub(FloodSubFuture),
}

impl<C> From<libp2p_kad::KademliaProcessingFuture> for FinalUpgrade<C> {
    #[inline]
    fn from(upgrade: libp2p_kad::KademliaProcessingFuture) -> Self {
        FinalUpgrade::Kad(upgrade)
    }
}

impl<C> From<IdentifyOutput<C>> for FinalUpgrade<C> {
    #[inline]
    fn from(upgrade: IdentifyOutput<C>) -> Self {
        FinalUpgrade::Identify(upgrade)
    }
}

impl<C> From<FloodSubFuture> for FinalUpgrade<C> {
    #[inline]
    fn from(upgrade: FloodSubFuture) -> Self {
        FinalUpgrade::FloodSub(upgrade)
    }
}
<commit_msg>Fix incorrect multiaddr, add logs<commit_after>extern crate bytes;
extern crate futures;
extern crate libp2p_peerstore;
extern crate libp2p_identify;
extern crate libp2p_core;
extern crate libp2p_mplex;
extern crate libp2p_tcp_transport;
extern crate libp2p_floodsub;
extern crate libp2p_kad;
extern crate slog;
extern crate tokio_core;
extern crate tokio_io;

use self::futures::Future;
use self::libp2p_peerstore::PeerId;
use self::libp2p_core::{ Endpoint, Multiaddr, Transport, ConnectionUpgrade };
use self::libp2p_floodsub::{ FloodSubUpgrade, FloodSubFuture };
use self::libp2p_kad::{ KademliaUpgrade, KademliaProcessingFuture};
use self::libp2p_identify::{ IdentifyInfo, IdentifyTransport, IdentifyOutput };
use self::slog::Logger;
use std::sync::{ Arc, RwLock };
use std::time::Duration;
use std::ops::Deref;
use std::io::Error as IoError;
use libp2p_peerstore::memory_peerstore::MemoryPeerstore;
use self::tokio_io::{ AsyncRead, AsyncWrite };
use self::bytes::Bytes;

pub fn listen(peer_id: PeerId,
               peer_store: Arc<MemoryPeerstore>,
               log: &Logger)
{
    let listen_multiaddr: Multiaddr = "/ip4/0.0.0.0/tcp/0"
        .parse::<Multiaddr>().expect("Failed to parse listen multiaddr.");

    info!(log, "Local PeerId: {:?}", peer_id);

    let core =  tokio_core::reactor::Core::new().expect("tokio failure.");
    let listened_addrs = Arc::new(RwLock::new(vec![]));
    let transport = libp2p_tcp_transport::TcpConfig::new(core.handle())
        .with_upgrade(libp2p_core::upgrade::PlainTextConfig)
        .with_upgrade(libp2p_mplex::BufferedMultiplexConfig::<[_; 256]>::new())
        .into_connection_reuse();

    let (floodsub_upgrade, floodsub_rx) = FloodSubUpgrade::new(peer_id.clone());

    let transport_sockets = {
        let listened_addrs = Arc::new(RwLock::new(vec![]));
        let listen_multiaddr = listen_multiaddr.clone();
        IdentifyTransport::new(transport.clone(), peer_store.clone())
            .map(move |out, _, _| {
                if let(Some(ref observed), ref listen_multiaddr) = (out.observed_addr, listen_multiaddr) {
                    if let Some(viewed_from_outisde) = transport.nat_traversal(listen_multiaddr, observed) {
                        listened_addrs.write().unwrap().push(viewed_from_outisde);
                    }
                }
                out.socket
            })
    };

    let kad_config = libp2p_kad::KademliaConfig {
        parallelism: 3,
        record_store: (),
        peer_store: peer_store,
        local_peer_id: peer_id.clone(),
        timeout: Duration::from_secs(2)
    };

    let kad_ctl_proto = libp2p_kad::KademliaControllerPrototype::new(kad_config);
    let kad_upgrade = libp2p_kad::KademliaUpgrade::from_prototype(&kad_ctl_proto);

    let upgrade = ConnectionUpgrader {
        kad: kad_upgrade.clone(),
        identify: libp2p_identify::IdentifyProtocolConfig,
        floodsub: floodsub_upgrade.clone(),
    };

    let swarm_listened_addrs = listened_addrs.clone();
    let (swarm_ctrl, swarm_future) = libp2p_core::swarm(
        transport_sockets.clone().with_upgrade(upgrade),
        move |upgrade, client_addr| match upgrade {
            FinalUpgrade::Kad(kad) => Box::new(kad) as Box<_>,
            FinalUpgrade::FloodSub(future) => Box::new(future) as Box<_>,
            FinalUpgrade::Identify(IdentifyOutput::Sender { sender, .. }) => sender.send(
                IdentifyInfo {
                    public_key: peer_id.clone().into_bytes(),
                    agent_version: "lighthouse/1.0.0".to_owned(),
                    protocol_version: "rust-libp2p/1.0.0".to_owned(),
                    listen_addrs: swarm_listened_addrs.read().unwrap().to_vec(),
                    protocols: vec![
                        "/ipfs/kad/1.0.0".to_owned(),
                        "/ipfs/id/1.0.0".to_owned(),
                        "/floodsub/1.0.0".to_owned(),
                    ]
                },
                &client_addr
            ),
            FinalUpgrade::Identify(IdentifyOutput::RemoteInfo { .. }) => {
                unreachable!("Never dial with the identify protocol.")
            }
        },
    );

    let actual_addr = swarm_ctrl
        .listen_on(listen_multiaddr)
        .expect("Failed to listen on multiaddr");

    info!(log, "Listening on: {:?}", actual_addr);
}

#[derive(Clone)]
struct ConnectionUpgrader<P, R> {
    kad: KademliaUpgrade<P, R>,
    identify: libp2p_identify::IdentifyProtocolConfig,
    floodsub: FloodSubUpgrade
}

impl<C, P, R, Pc> ConnectionUpgrade<C> for ConnectionUpgrader<P, R>
where
    C: AsyncRead + AsyncWrite + 'static,
    P: Deref<Target = Pc> + Clone + 'static,
    for<'r> &'r Pc: libp2p_peerstore::Peerstore,
    R: 'static
{
    type NamesIter = ::std::vec::IntoIter<(Bytes, usize)>;
    type UpgradeIdentifier = usize;
    type Output = FinalUpgrade<C>;
    type Future = Box<Future<Item = FinalUpgrade<C>, Error = IoError>>;

    #[inline]
    fn protocol_names(&self) -> Self::NamesIter {
        vec![
            (Bytes::from("/ipfs/kad/1.0.0"), 0),
            (Bytes::from("/ipfs/id/1.0.0"), 1),
            (Bytes::from("/floodsub/1.0.0"), 2),
        ].into_iter()
    }

    fn upgrade(
        self,
        socket: C,
        id: Self::UpgradeIdentifier,
        ty: Endpoint,
        remote_addr: &Multiaddr)
        -> Self::Future
    {
        match id {
            0 => Box::new(
                self.kad
                    .upgrade(socket, (), ty, remote_addr)
                    .map(|upg| upg.into())),
            1 => Box::new(
                self.identify
                    .upgrade(socket, (), ty, remote_addr)
                    .map(|upg| upg.into())),
            2 => Box::new(
                self.floodsub
                    .upgrade(socket, (), ty, remote_addr)
                    .map(|upg| upg.into())),
            _ => unreachable!()
        }

    }
}

enum FinalUpgrade<C> {
    Kad(KademliaProcessingFuture),
    Identify(IdentifyOutput<C>),
    FloodSub(FloodSubFuture),
}

impl<C> From<libp2p_kad::KademliaProcessingFuture> for FinalUpgrade<C> {
    #[inline]
    fn from(upgrade: libp2p_kad::KademliaProcessingFuture) -> Self {
        FinalUpgrade::Kad(upgrade)
    }
}

impl<C> From<IdentifyOutput<C>> for FinalUpgrade<C> {
    #[inline]
    fn from(upgrade: IdentifyOutput<C>) -> Self {
        FinalUpgrade::Identify(upgrade)
    }
}

impl<C> From<FloodSubFuture> for FinalUpgrade<C> {
    #[inline]
    fn from(upgrade: FloodSubFuture) -> Self {
        FinalUpgrade::FloodSub(upgrade)
    }
}
<|endoftext|>


<commit_before>// Copyright 2015 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// 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(all(not(feature = "force-inprocess"), any(target_os = "linux",
                                                target_os = "openbsd",
                                                target_os = "freebsd")))]
mod unix;
#[cfg(all(not(feature = "force-inprocess"), any(target_os = "linux",
                                                target_os = "openbsd",
                                                target_os = "freebsd")))]
mod os {
    pub use super::unix::*;
}

#[cfg(all(not(feature = "force-inprocess"), target_os = "macos"))]
mod macos;
#[cfg(all(not(feature = "force-inprocess"), target_os = "macos"))]
mod os {
    pub use super::macos::*;
}

#[cfg(any(feature = "force-inprocess", target_os = "windows", target_os = "android", target_os = "ios"))]
mod inprocess;
#[cfg(any(feature = "force-inprocess", target_os = "windows", target_os = "android", target_os = "ios"))]
mod os {
    pub use super::inprocess::*;
}

pub use self::os::{OsIpcChannel, OsIpcOneShotServer, OsIpcReceiver, OsIpcReceiverSet};
pub use self::os::{OsIpcSelectionResult, OsIpcSender, OsIpcSharedMemory};
pub use self::os::{OsOpaqueIpcChannel, channel};

#[cfg(test)]
mod test;
<commit_msg>Make it compile for wasm32-unknown-unknown and wasm32-wasi<commit_after>// Copyright 2015 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// 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(all(not(feature = "force-inprocess"), any(target_os = "linux",
                                                target_os = "openbsd",
                                                target_os = "freebsd")))]
mod unix;
#[cfg(all(not(feature = "force-inprocess"), any(target_os = "linux",
                                                target_os = "openbsd",
                                                target_os = "freebsd")))]
mod os {
    pub use super::unix::*;
}

#[cfg(all(not(feature = "force-inprocess"), target_os = "macos"))]
mod macos;
#[cfg(all(not(feature = "force-inprocess"), target_os = "macos"))]
mod os {
    pub use super::macos::*;
}

#[cfg(any(
    feature = "force-inprocess",
    target_os = "windows", target_os = "android", target_os = "ios", target_os = "wasi", target_os = "unknown"
))]
mod inprocess;
#[cfg(any(
    feature = "force-inprocess",
    target_os = "windows", target_os = "android", target_os = "ios", target_os = "wasi", target_os = "unknown"
))]
mod os {
    pub use super::inprocess::*;
}

pub use self::os::{OsIpcChannel, OsIpcOneShotServer, OsIpcReceiver, OsIpcReceiverSet};
pub use self::os::{OsIpcSelectionResult, OsIpcSender, OsIpcSharedMemory};
pub use self::os::{OsOpaqueIpcChannel, channel};

#[cfg(test)]
mod test;
<|endoftext|>


<commit_before>// Copyright 2014 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.

#![allow(non_snake_case)]

// Error messages for EXXXX errors.
// Each message should start and end with a new line, and be wrapped to 80 characters.
// In vim you can `:set tw=80` and use `gq` to wrap paragraphs. Use `:set tw=0` to disable.
register_long_diagnostics! {

E0001: r##"
This error suggests that the expression arm corresponding to the noted pattern
will never be reached as for all possible values of the expression being
matched, one of the preceding patterns will match.

This means that perhaps some of the preceding patterns are too general, this one
is too specific or the ordering is incorrect.
"##,

E0002: r##"
This error indicates that an empty match expression is illegal because the type
it is matching on is non-empty (there exist values of this type). In safe code
it is impossible to create an instance of an empty type, so empty match
expressions are almost never desired.  This error is typically fixed by adding
one or more cases to the match expression.

An example of an empty type is `enum Empty { }`.
"##,

E0003: r##"
Not-a-Number (NaN) values cannot be compared for equality and hence can never
match the input to a match expression. To match against NaN values, you should
instead use the `is_nan` method in a guard, as in: x if x.is_nan() => ...
"##,

E0004: r##"
This error indicates that the compiler cannot guarantee a matching pattern for
one or more possible inputs to a match expression. Guaranteed matches are
required in order to assign values to match expressions, or alternatively,
determine the flow of execution.

If you encounter this error you must alter your patterns so that every possible
value of the input type is matched. For types with a small number of variants
(like enums) you should probably cover all cases explicitly. Alternatively, the
underscore `_` wildcard pattern can be added after all other patterns to match
"anything else".
"##,

// FIXME: Remove duplication here?
E0005: r##"
Patterns used to bind names must be irrefutable, that is, they must guarantee that a
name will be extracted in all cases. If you encounter this error you probably need
to use a `match` or `if let` to deal with the possibility of failure.
"##,

E0006: r##"
Patterns used to bind names must be irrefutable, that is, they must guarantee that a
name will be extracted in all cases. If you encounter this error you probably need
to use a `match` or `if let` to deal with the possibility of failure.
"##,

E0007: r##"
This error indicates that the bindings in a match arm would require a value to
be moved into more than one location, thus violating unique ownership. Code like
the following is invalid as it requires the entire Option<String> to be moved
into a variable called `op_string` while simultaneously requiring the inner
String to be moved into a variable called `s`.

let x = Some("s".to_string());
match x {
    op_string @ Some(s) => ...
    None => ...
}

See also Error 303.
"##,

E0008: r##"
Names bound in match arms retain their type in pattern guards. As such, if a
name is bound by move in a pattern, it should also be moved to wherever it is
referenced in the pattern guard code. Doing so however would prevent the name
from being available in the body of the match arm. Consider the following:

match Some("hi".to_string()) {
    Some(s) if s.len() == 0 => // use s.
    ...
}

The variable `s` has type String, and its use in the guard is as a variable of
type String. The guard code effectively executes in a separate scope to the body
of the arm, so the value would be moved into this anonymous scope and therefore
become unavailable in the body of the arm. Although this example seems
innocuous, the problem is most clear when considering functions that take their
argument by value.

match Some("hi".to_string()) {
    Some(s) if { drop(s); false } => (),
    Some(s) => // use s.
    ...
}

The value would be dropped in the guard then become unavailable not only in the
body of that arm but also in all subsequent arms! The solution is to bind by
reference when using guards or refactor the entire expression, perhaps by
putting the condition inside the body of the arm.
"##,

E0152: r##"
Lang items are already implemented in the standard library. Unless you are
writing a free-standing application (e.g. a kernel), you do not need to provide
them yourself.

You can build a free-standing crate by adding `#![no_std]` to the crate
attributes:

#![feature(no_std)]
#![no_std]

See also https://doc.rust-lang.org/book/no-stdlib.html
"##,

E0158: r##"
`const` and `static` mean different things. A `const` is a compile-time
constant, an alias for a literal value. This property means you can match it
directly within a pattern.

The `static` keyword, on the other hand, guarantees a fixed location in memory.
This does not always mean that the value is constant. For example, a global
mutex can be declared `static` as well.

If you want to match against a `static`, consider using a guard instead:

static FORTY_TWO: i32 = 42;
match Some(42) {
    Some(x) if x == FORTY_TWO => ...
    ...
}
"##,

E0161: r##"
In Rust, you can only move a value when its size is known at compile time.

To work around this restriction, consider "hiding" the value behind a reference:
either `&x` or `&mut x`. Since a reference has a fixed size, this lets you move
it around as usual.
"##,

E0162: r##"
An if-let pattern attempts to match the pattern, and enters the body if the
match was succesful. If the match is irrefutable (when it cannot fail to match),
use a regular `let`-binding instead. For instance:

struct Irrefutable(i32);
let irr = Irrefutable(0);

// This fails to compile because the match is irrefutable.
if let Irrefutable(x) = irr {
    // This body will always be executed.
    foo(x);
}

// Try this instead:
let Irrefutable(x) = irr;
foo(x);
"##,

E0165: r##"
A while-let pattern attempts to match the pattern, and enters the body if the
match was succesful. If the match is irrefutable (when it cannot fail to match),
use a regular `let`-binding inside a `loop` instead. For instance:

struct Irrefutable(i32);
let irr = Irrefutable(0);

// This fails to compile because the match is irrefutable.
while let Irrefutable(x) = irr {
    ...
}

// Try this instead:
loop {
    let Irrefutable(x) = irr;
    ...
}
"##,

E0170: r##"
Enum variants are qualified by default. For example, given this type:

enum Method {
    GET,
    POST
}

you would match it using:

match m {
    Method::GET => ...
    Method::POST => ...
}

If you don't qualify the names, the code will bind new variables named "GET" and
"POST" instead. This behavior is likely not what you want, so rustc warns when
that happens.

Qualified names are good practice, and most code works well with them. But if
you prefer them unqualified, you can import the variants into scope:

use Method::*;
enum Method { GET, POST }
"##,

E0297: r##"
Patterns used to bind names must be irrefutable. That is, they must guarantee
that a name will be extracted in all cases. Instead of pattern matching the
loop variable, consider using a `match` or `if let` inside the loop body. For
instance:

// This fails because `None` is not covered.
for Some(x) in xs {
    ...
}

// Match inside the loop instead:
for item in xs {
    match item {
        Some(x) => ...
        None => ...
    }
}

// Or use `if let`:
for item in xs {
    if let Some(x) = item {
        ...
    }
}
"##,

E0301: r##"
Mutable borrows are not allowed in pattern guards, because matching cannot have
side effects. Side effects could alter the matched object or the environment
on which the match depends in such a way, that the match would not be
exhaustive. For instance, the following would not match any arm if mutable
borrows were allowed:

match Some(()) {
    None => { },
    option if option.take().is_none() => { /* impossible, option is `Some` */ },
    Some(_) => { } // When the previous match failed, the option became `None`.
}
"##,

E0302: r##"
Assignments are not allowed in pattern guards, because matching cannot have
side effects. Side effects could alter the matched object or the environment
on which the match depends in such a way, that the match would not be
exhaustive. For instance, the following would not match any arm if assignments
were allowed:

match Some(()) {
    None => { },
    option if { option = None; false } { },
    Some(_) => { } // When the previous match failed, the option became `None`.
}
"##,

E0303: r##"
In certain cases it is possible for sub-bindings to violate memory safety.
Updates to the borrow checker in a future version of Rust may remove this
restriction, but for now patterns must be rewritten without sub-bindings.

// Code like this...
match Some(5) {
    ref op_num @ Some(num) => ...
    None => ...
}

// ... should be updated to code like this.
match Some(5) {
    Some(num) => {
        let op_num = &Some(num);
        ...
    }
    None => ...
}

See also https://github.com/rust-lang/rust/issues/14587
"##,

E0306: r##"
In an array literal `[x; N]`, `N` is the number of elements in the array. This
number cannot be negative.
"##,

E0307: r##"
The length of an array is part of its type. For this reason, this length must be
a compile-time constant.
"##,

E0308: r##"
This error occurs when the compiler was unable to infer the concrete type of a
variable. This error can occur for several cases, the most common of which is
that there is a mismatch in the expected type that the compiler inferred, and
the actual type that the user defined a variable as.

let a: char = 7;    // An integral type can't be contained in a character, so
                    // there is a mismatch.

let b: u32 = 7;     // Either use the right type...
let c = 7;          // ...or let the compiler infer it.

let d: char = c;    // This also causes a mismatch because c is some sort
                    // of number whereas d is definitely a character.
"##,

E0309: r##"
Types in type definitions have lifetimes associated with them that represent
how long the data stored within them is guaranteed to be live. This lifetime
must be as long as the data needs to be alive, and missing the constraint that
denotes this will cause this error.

// This won't compile because T is not constrained, meaning the data
// stored in it is not guaranteed to last as long as the reference
struct Foo<'a, T> {
    foo: &'a T
}

// This will compile, because it has the constraint on the type parameter
struct Foo<'a, T: 'a> {
    foo: &'a T
}
"##,

E0310: r##"
Types in type definitions have lifetimes associated with them that represent
how long the data stored within them is guaranteed to be live. This lifetime
must be as long as the data needs to be alive, and missing the constraint that
denotes this will cause this error.

// This won't compile because T is not constrained to the static lifetime
// the reference needs
struct Foo<T> {
    foo: &'static T
}

// This will compile, because it has the constraint on the type parameter
struct Foo<T: 'static> {
    foo: &'static T
}
"##

}

register_diagnostics! {
    E0009,
    E0010,
    E0011,
    E0012,
    E0013,
    E0014,
    E0015,
    E0016,
    E0017,
    E0018,
    E0019,
    E0020,
    E0022,
    E0079, // enum variant: expected signed integer constant
    E0080, // enum variant: constant evaluation error
    E0109,
    E0110,
    E0133,
    E0134,
    E0135,
    E0136,
    E0137,
    E0138,
    E0139,
    E0261, // use of undeclared lifetime name
    E0262, // illegal lifetime parameter name
    E0263, // lifetime name declared twice in same scope
    E0264, // unknown external lang item
    E0265, // recursive constant
    E0266, // expected item
    E0267, // thing inside of a closure
    E0268, // thing outside of a loop
    E0269, // not all control paths return a value
    E0270, // computation may converge in a function marked as diverging
    E0271, // type mismatch resolving
    E0272, // rustc_on_unimplemented attribute refers to non-existent type parameter
    E0273, // rustc_on_unimplemented must have named format arguments
    E0274, // rustc_on_unimplemented must have a value
    E0275, // overflow evaluating requirement
    E0276, // requirement appears on impl method but not on corresponding trait method
    E0277, // trait is not implemented for type
    E0278, // requirement is not satisfied
    E0279, // requirement is not satisfied
    E0280, // requirement is not satisfied
    E0281, // type implements trait but other trait is required
    E0282, // unable to infer enough type information about
    E0283, // cannot resolve type
    E0284, // cannot resolve type
    E0285, // overflow evaluation builtin bounds
    E0296, // malformed recursion limit attribute
    E0298, // mismatched types between arms
    E0299, // mismatched types between arms
    E0300, // unexpanded macro
    E0304, // expected signed integer constant
    E0305, // expected constant
    E0311, // thing may not live long enough
    E0312, // lifetime of reference outlives lifetime of borrowed content
    E0313, // lifetime of borrowed pointer outlives lifetime of captured variable
    E0314, // closure outlives stack frame
    E0315, // cannot invoke closure outside of its lifetime
    E0316, // nested quantification of lifetimes
    E0370  // discriminant overflow
}

__build_diagnostic_array! { DIAGNOSTICS }
<commit_msg>Fix trailing whitespaces<commit_after>// Copyright 2014 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.

#![allow(non_snake_case)]

// Error messages for EXXXX errors.
// Each message should start and end with a new line, and be wrapped to 80 characters.
// In vim you can `:set tw=80` and use `gq` to wrap paragraphs. Use `:set tw=0` to disable.
register_long_diagnostics! {

E0001: r##"
This error suggests that the expression arm corresponding to the noted pattern
will never be reached as for all possible values of the expression being
matched, one of the preceding patterns will match.

This means that perhaps some of the preceding patterns are too general, this one
is too specific or the ordering is incorrect.
"##,

E0002: r##"
This error indicates that an empty match expression is illegal because the type
it is matching on is non-empty (there exist values of this type). In safe code
it is impossible to create an instance of an empty type, so empty match
expressions are almost never desired.  This error is typically fixed by adding
one or more cases to the match expression.

An example of an empty type is `enum Empty { }`.
"##,

E0003: r##"
Not-a-Number (NaN) values cannot be compared for equality and hence can never
match the input to a match expression. To match against NaN values, you should
instead use the `is_nan` method in a guard, as in: x if x.is_nan() => ...
"##,

E0004: r##"
This error indicates that the compiler cannot guarantee a matching pattern for
one or more possible inputs to a match expression. Guaranteed matches are
required in order to assign values to match expressions, or alternatively,
determine the flow of execution.

If you encounter this error you must alter your patterns so that every possible
value of the input type is matched. For types with a small number of variants
(like enums) you should probably cover all cases explicitly. Alternatively, the
underscore `_` wildcard pattern can be added after all other patterns to match
"anything else".
"##,

// FIXME: Remove duplication here?
E0005: r##"
Patterns used to bind names must be irrefutable, that is, they must guarantee that a
name will be extracted in all cases. If you encounter this error you probably need
to use a `match` or `if let` to deal with the possibility of failure.
"##,

E0006: r##"
Patterns used to bind names must be irrefutable, that is, they must guarantee that a
name will be extracted in all cases. If you encounter this error you probably need
to use a `match` or `if let` to deal with the possibility of failure.
"##,

E0007: r##"
This error indicates that the bindings in a match arm would require a value to
be moved into more than one location, thus violating unique ownership. Code like
the following is invalid as it requires the entire Option<String> to be moved
into a variable called `op_string` while simultaneously requiring the inner
String to be moved into a variable called `s`.

let x = Some("s".to_string());
match x {
    op_string @ Some(s) => ...
    None => ...
}

See also Error 303.
"##,

E0008: r##"
Names bound in match arms retain their type in pattern guards. As such, if a
name is bound by move in a pattern, it should also be moved to wherever it is
referenced in the pattern guard code. Doing so however would prevent the name
from being available in the body of the match arm. Consider the following:

match Some("hi".to_string()) {
    Some(s) if s.len() == 0 => // use s.
    ...
}

The variable `s` has type String, and its use in the guard is as a variable of
type String. The guard code effectively executes in a separate scope to the body
of the arm, so the value would be moved into this anonymous scope and therefore
become unavailable in the body of the arm. Although this example seems
innocuous, the problem is most clear when considering functions that take their
argument by value.

match Some("hi".to_string()) {
    Some(s) if { drop(s); false } => (),
    Some(s) => // use s.
    ...
}

The value would be dropped in the guard then become unavailable not only in the
body of that arm but also in all subsequent arms! The solution is to bind by
reference when using guards or refactor the entire expression, perhaps by
putting the condition inside the body of the arm.
"##,

E0152: r##"
Lang items are already implemented in the standard library. Unless you are
writing a free-standing application (e.g. a kernel), you do not need to provide
them yourself.

You can build a free-standing crate by adding `#![no_std]` to the crate
attributes:

#![feature(no_std)]
#![no_std]

See also https://doc.rust-lang.org/book/no-stdlib.html
"##,

E0158: r##"
`const` and `static` mean different things. A `const` is a compile-time
constant, an alias for a literal value. This property means you can match it
directly within a pattern.

The `static` keyword, on the other hand, guarantees a fixed location in memory.
This does not always mean that the value is constant. For example, a global
mutex can be declared `static` as well.

If you want to match against a `static`, consider using a guard instead:

static FORTY_TWO: i32 = 42;
match Some(42) {
    Some(x) if x == FORTY_TWO => ...
    ...
}
"##,

E0161: r##"
In Rust, you can only move a value when its size is known at compile time.

To work around this restriction, consider "hiding" the value behind a reference:
either `&x` or `&mut x`. Since a reference has a fixed size, this lets you move
it around as usual.
"##,

E0162: r##"
An if-let pattern attempts to match the pattern, and enters the body if the
match was succesful. If the match is irrefutable (when it cannot fail to match),
use a regular `let`-binding instead. For instance:

struct Irrefutable(i32);
let irr = Irrefutable(0);

// This fails to compile because the match is irrefutable.
if let Irrefutable(x) = irr {
    // This body will always be executed.
    foo(x);
}

// Try this instead:
let Irrefutable(x) = irr;
foo(x);
"##,

E0165: r##"
A while-let pattern attempts to match the pattern, and enters the body if the
match was succesful. If the match is irrefutable (when it cannot fail to match),
use a regular `let`-binding inside a `loop` instead. For instance:

struct Irrefutable(i32);
let irr = Irrefutable(0);

// This fails to compile because the match is irrefutable.
while let Irrefutable(x) = irr {
    ...
}

// Try this instead:
loop {
    let Irrefutable(x) = irr;
    ...
}
"##,

E0170: r##"
Enum variants are qualified by default. For example, given this type:

enum Method {
    GET,
    POST
}

you would match it using:

match m {
    Method::GET => ...
    Method::POST => ...
}

If you don't qualify the names, the code will bind new variables named "GET" and
"POST" instead. This behavior is likely not what you want, so rustc warns when
that happens.

Qualified names are good practice, and most code works well with them. But if
you prefer them unqualified, you can import the variants into scope:

use Method::*;
enum Method { GET, POST }
"##,

E0297: r##"
Patterns used to bind names must be irrefutable. That is, they must guarantee
that a name will be extracted in all cases. Instead of pattern matching the
loop variable, consider using a `match` or `if let` inside the loop body. For
instance:

// This fails because `None` is not covered.
for Some(x) in xs {
    ...
}

// Match inside the loop instead:
for item in xs {
    match item {
        Some(x) => ...
        None => ...
    }
}

// Or use `if let`:
for item in xs {
    if let Some(x) = item {
        ...
    }
}
"##,

E0301: r##"
Mutable borrows are not allowed in pattern guards, because matching cannot have
side effects. Side effects could alter the matched object or the environment
on which the match depends in such a way, that the match would not be
exhaustive. For instance, the following would not match any arm if mutable
borrows were allowed:

match Some(()) {
    None => { },
    option if option.take().is_none() => { /* impossible, option is `Some` */ },
    Some(_) => { } // When the previous match failed, the option became `None`.
}
"##,

E0302: r##"
Assignments are not allowed in pattern guards, because matching cannot have
side effects. Side effects could alter the matched object or the environment
on which the match depends in such a way, that the match would not be
exhaustive. For instance, the following would not match any arm if assignments
were allowed:

match Some(()) {
    None => { },
    option if { option = None; false } { },
    Some(_) => { } // When the previous match failed, the option became `None`.
}
"##,

E0303: r##"
In certain cases it is possible for sub-bindings to violate memory safety.
Updates to the borrow checker in a future version of Rust may remove this
restriction, but for now patterns must be rewritten without sub-bindings.

// Code like this...
match Some(5) {
    ref op_num @ Some(num) => ...
    None => ...
}

// ... should be updated to code like this.
match Some(5) {
    Some(num) => {
        let op_num = &Some(num);
        ...
    }
    None => ...
}

See also https://github.com/rust-lang/rust/issues/14587
"##,

E0306: r##"
In an array literal `[x; N]`, `N` is the number of elements in the array. This
number cannot be negative.
"##,

E0307: r##"
The length of an array is part of its type. For this reason, this length must be
a compile-time constant.
"##,

E0308: r##"
This error occurs when the compiler was unable to infer the concrete type of a
variable. This error can occur for several cases, the most common of which is
that there is a mismatch in the expected type that the compiler inferred, and
the actual type that the user defined a variable as.

let a: char = 7;    // An integral type can't be contained in a character, so
                    // there is a mismatch.

let b: u32 = 7;     // Either use the right type...
let c = 7;          // ...or let the compiler infer it.

let d: char = c;    // This also causes a mismatch because c is some sort
                    // of number whereas d is definitely a character.
"##,

E0309: r##"
Types in type definitions have lifetimes associated with them that represent
how long the data stored within them is guaranteed to be live. This lifetime
must be as long as the data needs to be alive, and missing the constraint that
denotes this will cause this error.

// This won't compile because T is not constrained, meaning the data
// stored in it is not guaranteed to last as long as the reference
struct Foo<'a, T> {
    foo: &'a T
}

// This will compile, because it has the constraint on the type parameter
struct Foo<'a, T: 'a> {
    foo: &'a T
}
"##,

E0310: r##"
Types in type definitions have lifetimes associated with them that represent
how long the data stored within them is guaranteed to be live. This lifetime
must be as long as the data needs to be alive, and missing the constraint that
denotes this will cause this error.

// This won't compile because T is not constrained to the static lifetime
// the reference needs
struct Foo<T> {
    foo: &'static T
}

// This will compile, because it has the constraint on the type parameter
struct Foo<T: 'static> {
    foo: &'static T
}
"##

}

register_diagnostics! {
    E0009,
    E0010,
    E0011,
    E0012,
    E0013,
    E0014,
    E0015,
    E0016,
    E0017,
    E0018,
    E0019,
    E0020,
    E0022,
    E0079, // enum variant: expected signed integer constant
    E0080, // enum variant: constant evaluation error
    E0109,
    E0110,
    E0133,
    E0134,
    E0135,
    E0136,
    E0137,
    E0138,
    E0139,
    E0261, // use of undeclared lifetime name
    E0262, // illegal lifetime parameter name
    E0263, // lifetime name declared twice in same scope
    E0264, // unknown external lang item
    E0265, // recursive constant
    E0266, // expected item
    E0267, // thing inside of a closure
    E0268, // thing outside of a loop
    E0269, // not all control paths return a value
    E0270, // computation may converge in a function marked as diverging
    E0271, // type mismatch resolving
    E0272, // rustc_on_unimplemented attribute refers to non-existent type parameter
    E0273, // rustc_on_unimplemented must have named format arguments
    E0274, // rustc_on_unimplemented must have a value
    E0275, // overflow evaluating requirement
    E0276, // requirement appears on impl method but not on corresponding trait method
    E0277, // trait is not implemented for type
    E0278, // requirement is not satisfied
    E0279, // requirement is not satisfied
    E0280, // requirement is not satisfied
    E0281, // type implements trait but other trait is required
    E0282, // unable to infer enough type information about
    E0283, // cannot resolve type
    E0284, // cannot resolve type
    E0285, // overflow evaluation builtin bounds
    E0296, // malformed recursion limit attribute
    E0298, // mismatched types between arms
    E0299, // mismatched types between arms
    E0300, // unexpanded macro
    E0304, // expected signed integer constant
    E0305, // expected constant
    E0311, // thing may not live long enough
    E0312, // lifetime of reference outlives lifetime of borrowed content
    E0313, // lifetime of borrowed pointer outlives lifetime of captured variable
    E0314, // closure outlives stack frame
    E0315, // cannot invoke closure outside of its lifetime
    E0316, // nested quantification of lifetimes
    E0370  // discriminant overflow
}

__build_diagnostic_array! { DIAGNOSTICS }
<|endoftext|>


<commit_before>use Result;
use point::Error;
use std::fmt;

const TIME_FORMATS: &'static [u8] = &[1, 3, 4, 5, 6, 7, 8, 9, 10];
const COLOR_FORMATS: &'static [u8] = &[2, 3, 5, 7, 8, 10];
const WAVEFORM_FORMATS: &'static [u8] = &[4, 5, 9, 10];
const NIR_FORMATS: &'static [u8] = &[8, 10];
const IS_COMPRESSED_MASK: u8 = 0x80;

/// Point formats are defined by the las spec.
///
/// As of las 1.4, there are eleven point formats (0-10). A new `Format` can be created from its
/// code and converted back into it:
///
/// ```
/// use las::point::Format;
///
/// let format_1 = Format::new(1).unwrap();
/// assert!(format_1.has_gps_time);
/// assert_eq!(1, format_1.to_u8().unwrap());
///
/// assert!(Format::new(11).is_err());
/// ```
///
/// Point formats can have extra bytes, which are user-defined attributes. Extra bytes were
/// introduced in las 1.4.
///
/// ```
/// use las::point::Format;
/// let mut format = Format::new(0).unwrap();
/// format.extra_bytes = 1;
/// assert_eq!(21, format.len());
/// ```
///
/// Certain combinations of attributes in a point format are illegal, e.g. gps time is required for
/// all formats >= 6:
///
/// ```
/// use las::point::Format;
/// let mut format = Format::new(6).unwrap();
/// format.has_gps_time = false;
/// assert!(format.to_u8().is_err());
/// ```
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct Format {
    /// Does this point format include gps time?
    pub has_gps_time: bool,
    /// Does this point format include red, green, and blue colors?
    pub has_color: bool,
    /// Does this point format use two bytes for its flags and scaled scan angles?
    pub is_extended: bool,
    /// Does this point format have waveforms?
    pub has_waveform: bool,
    /// Does this point format have near infrared data?
    pub has_nir: bool,
    /// The number of extra bytes on each point.
    pub extra_bytes: u16,
    /// Is this point format compressed?
    pub is_compressed: bool,
}

#[cfg_attr(feature = "cargo-clippy", allow(len_without_is_empty))]
impl Format {
    /// Creates a new point format from a u8.
    ///
    /// # Examples
    ///
    /// ```
    /// use las::point::Format;
    /// let format = Format::new(0).unwrap();
    /// assert!(!format.has_gps_time);
    /// assert!(!format.has_color);
    ///
    /// let format = Format::new(3).unwrap();
    /// assert!(format.has_gps_time);
    /// assert!(format.has_color);
    ///
    /// assert!(Format::new(11).is_err());
    /// ```
    pub fn new(n: u8) -> Result<Format> {
        if n > 10 {
            Err(Error::FormatNumber(n).into())
        } else {
            Ok(Format {
                has_gps_time: TIME_FORMATS.contains(&n),
                has_color: COLOR_FORMATS.contains(&n),
                has_waveform: WAVEFORM_FORMATS.contains(&n),
                has_nir: NIR_FORMATS.contains(&n),
                is_extended: n >= 6,
                extra_bytes: 0,
                is_compressed: n & IS_COMPRESSED_MASK == IS_COMPRESSED_MASK,
            })
        }
    }

    /// Converts this point format into an extended format.
    ///
    /// "Extended" formats can contain more information per point, and must have gps time.
    ///
    /// # Examples
    ///
    /// ```
    /// use las::point::Format;
    /// let mut format = Format::default();
    /// assert!(!format.has_gps_time);
    /// assert!(!format.is_extended);
    /// format.extend();
    /// assert!(format.has_gps_time);
    /// assert!(format.is_extended);
    pub fn extend(&mut self) {
        self.has_gps_time = true;
        self.is_extended = true;
    }

    /// Returns this point format's length.
    ///
    /// # Examples
    ///
    /// ```
    /// use las::point::Format;
    /// let mut format = Format::new(0).unwrap();
    /// assert_eq!(20, format.len());
    /// format.has_gps_time = true;
    /// assert_eq!(28, format.len());
    /// ```
    pub fn len(&self) -> u16 {
        let mut len = if self.is_extended { 22 } else { 20 } + self.extra_bytes;
        if self.has_gps_time {
            len += 8;
        }
        if self.has_color {
            len += 6;
        }
        if self.has_nir {
            len += 2;
        }
        if self.has_waveform {
            len += 29;
        }
        len
    }

    /// Converts this point format to a u8.
    ///
    /// Can return an error if there is an invalid combination of attributes.
    ///
    /// # Examples
    ///
    /// ```
    /// use las::point::Format;
    /// let mut format = Format::default();
    /// assert_eq!(0, format.to_u8().unwrap());
    /// format.is_extended = true;
    /// assert!(format.to_u8().is_err());
    /// format.has_gps_time = true;
    /// assert_eq!(6, format.to_u8().unwrap());
    /// ```
    pub fn to_u8(&self) -> Result<u8> {
        if self.is_compressed {
            Err(Error::Format(*self).into())
        } else if self.is_extended {
            if self.has_gps_time {
                if self.has_color {
                    if self.has_nir {
                        if self.has_waveform { Ok(10) } else { Ok(8) }
                    } else if self.has_waveform {
                        Err(Error::Format(*self).into())
                    } else {
                        Ok(7)
                    }
                } else if self.has_nir {
                    Err(Error::Format(*self).into())
                } else if self.has_waveform {
                    Ok(9)
                } else {
                    Ok(6)
                }
            } else {
                Err(Error::Format(*self).into())
            }
        } else if self.has_nir {
            Err(Error::Format(*self).into())
        } else if self.has_waveform {
            if self.has_gps_time {
                if self.has_color { Ok(5) } else { Ok(4) }
            } else {
                Err(Error::Format(*self).into())
            }
        } else {
            let mut n = if self.has_gps_time { 1 } else { 0 };
            if self.has_color {
                n += 2;
            }
            Ok(n)
        }
    }
}

impl fmt::Display for Format {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if let Ok(n) = self.to_u8() {
            write!(f, "point format {}", n)
        } else {
            write!(f, "point format that does not map onto a code: {:?}", self)
        }
    }
}

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

    macro_rules! format {
        ($name:ident, $n:expr, $expected:expr, $len:expr) => {
            mod $name {
                use point::Format;

                #[test]
                fn new() {
                    assert_eq!($expected, Format::new($n).unwrap());
                }

                #[test]
                fn len() {
                    assert_eq!($len, Format::new($n).unwrap().len());
                }

                #[test]
                fn to_u8() {
                    assert_eq!($n, Format::new($n).unwrap().to_u8().unwrap());
                }
            }
        }
    }

    format!(format_0, 0, Format::default(), 20);
    format!(
        format_1,
        1,
        Format {
            has_gps_time: true,
            ..Default::default()
        },
        28
    );
    format!(
        format_2,
        2,
        Format {
            has_color: true,
            ..Default::default()
        },
        26
    );
    format!(
        format_3,
        3,
        Format {
            has_gps_time: true,
            has_color: true,
            ..Default::default()
        },
        34
    );
    format!(
        format_4,
        4,
        Format {
            has_gps_time: true,
            has_waveform: true,
            ..Default::default()
        },
        57
    );
    format!(
        format_5,
        5,
        Format {
            has_gps_time: true,
            has_color: true,
            has_waveform: true,
            ..Default::default()
        },
        63
    );
    format!(
        format_6,
        6,
        Format {
            has_gps_time: true,
            is_extended: true,
            ..Default::default()
        },
        30
    );
    format!(
        format_7,
        7,
        Format {
            has_gps_time: true,
            has_color: true,
            is_extended: true,
            ..Default::default()
        },
        36
    );
    format!(
        format_8,
        8,
        Format {
            has_gps_time: true,
            has_color: true,
            has_nir: true,
            is_extended: true,
            ..Default::default()
        },
        38
    );
    format!(
        format_9,
        9,
        Format {
            has_gps_time: true,
            has_waveform: true,
            is_extended: true,
            ..Default::default()
        },
        59
    );
    format!(
        format_10,
        10,
        Format {
            has_gps_time: true,
            has_color: true,
            has_nir: true,
            has_waveform: true,
            is_extended: true,
            ..Default::default()
        },
        67
    );

    #[test]
    fn waveform_without_gps_time() {
        let format = Format {
            has_waveform: true,
            ..Default::default()
        };
        assert!(format.to_u8().is_err());
    }

    #[test]
    fn extended_without_gps_time() {
        let format = Format {
            is_extended: true,
            ..Default::default()
        };
        assert!(format.to_u8().is_err());
    }

    #[test]
    fn nir_without_extended() {
        let format = Format {
            has_nir: true,
            ..Default::default()
        };
        assert!(format.to_u8().is_err());
    }

    #[test]
    fn nir_without_color() {
        let format = Format {
            is_extended: true,
            has_nir: true,
            ..Default::default()
        };
        assert!(format.to_u8().is_err());
    }

    #[test]
    fn extra_bytes() {
        let format = Format {
            extra_bytes: 1,
            ..Default::default()
        };
        assert_eq!(21, format.len());
    }

    #[test]
    fn is_compressed() {
        let format = Format {
            is_compressed: true,
            ..Default::default()
        };
        assert!(format.to_u8().is_err());
    }
}
<commit_msg>Fix Point::Format::new<commit_after>use std::fmt;

use point::Error;
use Result;

const TIME_FORMATS: &'static [u8] = &[1, 3, 4, 5, 6, 7, 8, 9, 10];
const COLOR_FORMATS: &'static [u8] = &[2, 3, 5, 7, 8, 10];
const WAVEFORM_FORMATS: &'static [u8] = &[4, 5, 9, 10];
const NIR_FORMATS: &'static [u8] = &[8, 10];
const IS_COMPRESSED_MASK: u8 = 0x80;

/// Point formats are defined by the las spec.
///
/// As of las 1.4, there are eleven point formats (0-10). A new `Format` can be created from its
/// code and converted back into it:
///
/// ```
/// use las::point::Format;
///
/// let format_1 = Format::new(1).unwrap();
/// assert!(format_1.has_gps_time);
/// assert_eq!(1, format_1.to_u8().unwrap());
///
/// assert!(Format::new(11).is_err());
/// ```
///
/// Point formats can have extra bytes, which are user-defined attributes. Extra bytes were
/// introduced in las 1.4.
///
/// ```
/// use las::point::Format;
/// let mut format = Format::new(0).unwrap();
/// format.extra_bytes = 1;
/// assert_eq!(21, format.len());
/// ```
///
/// Certain combinations of attributes in a point format are illegal, e.g. gps time is required for
/// all formats >= 6:
///
/// ```
/// use las::point::Format;
/// let mut format = Format::new(6).unwrap();
/// format.has_gps_time = false;
/// assert!(format.to_u8().is_err());
/// ```
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct Format {
    /// Does this point format include gps time?
    pub has_gps_time: bool,
    /// Does this point format include red, green, and blue colors?
    pub has_color: bool,
    /// Does this point format use two bytes for its flags and scaled scan angles?
    pub is_extended: bool,
    /// Does this point format have waveforms?
    pub has_waveform: bool,
    /// Does this point format have near infrared data?
    pub has_nir: bool,
    /// The number of extra bytes on each point.
    pub extra_bytes: u16,
    /// Is this point format compressed?
    pub is_compressed: bool,
}

#[cfg_attr(feature = "cargo-clippy", allow(len_without_is_empty))]
impl Format {
    /// Creates a new point format from a u8.
    ///
    /// # Examples
    ///
    /// ```
    /// use las::point::Format;
    /// let format = Format::new(0).unwrap();
    /// assert!(!format.has_gps_time);
    /// assert!(!format.has_color);
    ///
    /// let format = Format::new(3).unwrap();
    /// assert!(format.has_gps_time);
    /// assert!(format.has_color);
    ///
    /// assert!(Format::new(11).is_err());
    /// ```
    pub fn new(n: u8) -> Result<Format> {
        let is_compressed = n & IS_COMPRESSED_MASK == IS_COMPRESSED_MASK;
        if n > 10 && !is_compressed{
            Err(Error::FormatNumber(n).into())
        } else {
            Ok(Format {
                has_gps_time: TIME_FORMATS.contains(&n),
                has_color: COLOR_FORMATS.contains(&n),
                has_waveform: WAVEFORM_FORMATS.contains(&n),
                has_nir: NIR_FORMATS.contains(&n),
                is_extended: n >= 6,
                extra_bytes: 0,
                is_compressed
            })
        }
    }

    /// Converts this point format into an extended format.
    ///
    /// "Extended" formats can contain more information per point, and must have gps time.
    ///
    /// # Examples
    ///
    /// ```
    /// use las::point::Format;
    /// let mut format = Format::default();
    /// assert!(!format.has_gps_time);
    /// assert!(!format.is_extended);
    /// format.extend();
    /// assert!(format.has_gps_time);
    /// assert!(format.is_extended);
    pub fn extend(&mut self) {
        self.has_gps_time = true;
        self.is_extended = true;
    }

    /// Returns this point format's length.
    ///
    /// # Examples
    ///
    /// ```
    /// use las::point::Format;
    /// let mut format = Format::new(0).unwrap();
    /// assert_eq!(20, format.len());
    /// format.has_gps_time = true;
    /// assert_eq!(28, format.len());
    /// ```
    pub fn len(&self) -> u16 {
        let mut len = if self.is_extended { 22 } else { 20 } + self.extra_bytes;
        if self.has_gps_time {
            len += 8;
        }
        if self.has_color {
            len += 6;
        }
        if self.has_nir {
            len += 2;
        }
        if self.has_waveform {
            len += 29;
        }
        len
    }

    /// Converts this point format to a u8.
    ///
    /// Can return an error if there is an invalid combination of attributes.
    ///
    /// # Examples
    ///
    /// ```
    /// use las::point::Format;
    /// let mut format = Format::default();
    /// assert_eq!(0, format.to_u8().unwrap());
    /// format.is_extended = true;
    /// assert!(format.to_u8().is_err());
    /// format.has_gps_time = true;
    /// assert_eq!(6, format.to_u8().unwrap());
    /// ```
    pub fn to_u8(&self) -> Result<u8> {
        if self.is_compressed {
            Err(Error::Format(*self).into())
        } else if self.is_extended {
            if self.has_gps_time {
                if self.has_color {
                    if self.has_nir {
                        if self.has_waveform { Ok(10) } else { Ok(8) }
                    } else if self.has_waveform {
                        Err(Error::Format(*self).into())
                    } else {
                        Ok(7)
                    }
                } else if self.has_nir {
                    Err(Error::Format(*self).into())
                } else if self.has_waveform {
                    Ok(9)
                } else {
                    Ok(6)
                }
            } else {
                Err(Error::Format(*self).into())
            }
        } else if self.has_nir {
            Err(Error::Format(*self).into())
        } else if self.has_waveform {
            if self.has_gps_time {
                if self.has_color { Ok(5) } else { Ok(4) }
            } else {
                Err(Error::Format(*self).into())
            }
        } else {
            let mut n = if self.has_gps_time { 1 } else { 0 };
            if self.has_color {
                n += 2;
            }
            Ok(n)
        }
    }
}

impl fmt::Display for Format {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if let Ok(n) = self.to_u8() {
            write!(f, "point format {}", n)
        } else {
            write!(f, "point format that does not map onto a code: {:?}", self)
        }
    }
}

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

    macro_rules! format {
        ($name:ident, $n:expr, $expected:expr, $len:expr) => {
            mod $name {
                use point::Format;

                #[test]
                fn new() {
                    assert_eq!($expected, Format::new($n).unwrap());
                }

                #[test]
                fn len() {
                    assert_eq!($len, Format::new($n).unwrap().len());
                }

                #[test]
                fn to_u8() {
                    assert_eq!($n, Format::new($n).unwrap().to_u8().unwrap());
                }
            }
        }
    }

    format!(format_0, 0, Format::default(), 20);
    format!(
        format_1,
        1,
        Format {
            has_gps_time: true,
            ..Default::default()
        },
        28
    );
    format!(
        format_2,
        2,
        Format {
            has_color: true,
            ..Default::default()
        },
        26
    );
    format!(
        format_3,
        3,
        Format {
            has_gps_time: true,
            has_color: true,
            ..Default::default()
        },
        34
    );
    format!(
        format_4,
        4,
        Format {
            has_gps_time: true,
            has_waveform: true,
            ..Default::default()
        },
        57
    );
    format!(
        format_5,
        5,
        Format {
            has_gps_time: true,
            has_color: true,
            has_waveform: true,
            ..Default::default()
        },
        63
    );
    format!(
        format_6,
        6,
        Format {
            has_gps_time: true,
            is_extended: true,
            ..Default::default()
        },
        30
    );
    format!(
        format_7,
        7,
        Format {
            has_gps_time: true,
            has_color: true,
            is_extended: true,
            ..Default::default()
        },
        36
    );
    format!(
        format_8,
        8,
        Format {
            has_gps_time: true,
            has_color: true,
            has_nir: true,
            is_extended: true,
            ..Default::default()
        },
        38
    );
    format!(
        format_9,
        9,
        Format {
            has_gps_time: true,
            has_waveform: true,
            is_extended: true,
            ..Default::default()
        },
        59
    );
    format!(
        format_10,
        10,
        Format {
            has_gps_time: true,
            has_color: true,
            has_nir: true,
            has_waveform: true,
            is_extended: true,
            ..Default::default()
        },
        67
    );

    #[test]
    fn waveform_without_gps_time() {
        let format = Format {
            has_waveform: true,
            ..Default::default()
        };
        assert!(format.to_u8().is_err());
    }

    #[test]
    fn extended_without_gps_time() {
        let format = Format {
            is_extended: true,
            ..Default::default()
        };
        assert!(format.to_u8().is_err());
    }

    #[test]
    fn nir_without_extended() {
        let format = Format {
            has_nir: true,
            ..Default::default()
        };
        assert!(format.to_u8().is_err());
    }

    #[test]
    fn nir_without_color() {
        let format = Format {
            is_extended: true,
            has_nir: true,
            ..Default::default()
        };
        assert!(format.to_u8().is_err());
    }

    #[test]
    fn extra_bytes() {
        let format = Format {
            extra_bytes: 1,
            ..Default::default()
        };
        assert_eq!(21, format.len());
    }

    #[test]
    fn is_compressed() {
        let format = Format {
            is_compressed: true,
            ..Default::default()
        };
        assert!(format.to_u8().is_err());
    }
}
<|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 dom::bindings::utils::{Reflector, Reflectable};
use dom::window::Window;
use js::jsapi::JSContext;
use layout_interface::TrustedNodeAddress;

use std::cast;
use std::cell::RefCell;

pub struct JS<T> {
    priv ptr: RefCell<*mut T>
}

impl<T> Eq for JS<T> {
    fn eq(&self, other: &JS<T>) -> bool {
        self.ptr == other.ptr
    }
}

impl <T> Clone for JS<T> {
    fn clone(&self) -> JS<T> {
        JS {
            ptr: self.ptr.clone()
        }
    }
}

impl<T: Reflectable> JS<T> {
    pub fn new(obj: ~T,
               window:  &JS<Window>,
               wrap_fn: extern "Rust" fn(*JSContext, &JS<Window>, ~T) -> JS<T>) -> JS<T> {
        wrap_fn(window.get().get_cx(), window, obj)
    }

    pub unsafe fn from_raw(raw: *mut T) -> JS<T> {
        JS {
            ptr: RefCell::new(raw)
        }
    }

    pub unsafe fn from_trusted_node_address(inner: TrustedNodeAddress) -> JS<T> {
        JS {
            ptr: RefCell::new(inner as *mut T)
        }
    }
}

impl<T: Reflectable> Reflectable for JS<T> {
    fn reflector<'a>(&'a self) -> &'a Reflector {
        self.get().reflector()
    }

    fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
        self.get_mut().mut_reflector()
    }
}

impl<T> JS<T> {
    pub fn get<'a>(&'a self) -> &'a T {
        let borrowed = self.ptr.borrow();
        unsafe {
            &(**borrowed.get())
        }
    }

    pub fn get_mut<'a>(&'a mut self) -> &'a mut T {
        let mut borrowed = self.ptr.borrow_mut();
        unsafe {
            &mut (**borrowed.get())
        }
    }

    /// Returns an unsafe pointer to the interior of this JS object without touching the borrow
    /// flags. This is the only method that be safely accessed from layout. (The fact that this
    /// is unsafe is what necessitates the layout wrappers.)
    pub unsafe fn unsafe_get(&self) -> *mut T {
        cast::transmute_copy(&self.ptr)
    }
}

impl<From, To> JS<From> {
    //XXXjdm It would be lovely if this could be private.
    pub unsafe fn transmute(self) -> JS<To> {
        cast::transmute(self)
    }

    pub unsafe fn transmute_copy(&self) -> JS<To> {
        cast::transmute_copy(self)
    }
}
<commit_msg>auto merge of #1966 : lpy/servo/issue1955, r=jdm<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 dom::bindings::utils::{Reflector, Reflectable};
use dom::window::Window;
use js::jsapi::JSContext;
use layout_interface::TrustedNodeAddress;

use std::cast;
use std::cell::RefCell;

pub struct JS<T> {
    priv ptr: RefCell<*mut T>
}

impl<T> Eq for JS<T> {
    fn eq(&self, other: &JS<T>) -> bool {
        self.ptr == other.ptr
    }
}

impl <T> Clone for JS<T> {
    #[inline]
    fn clone(&self) -> JS<T> {
        JS {
            ptr: self.ptr.clone()
        }
    }
}

impl<T: Reflectable> JS<T> {
    pub fn new(obj: ~T,
               window:  &JS<Window>,
               wrap_fn: extern "Rust" fn(*JSContext, &JS<Window>, ~T) -> JS<T>) -> JS<T> {
        wrap_fn(window.get().get_cx(), window, obj)
    }

    pub unsafe fn from_raw(raw: *mut T) -> JS<T> {
        JS {
            ptr: RefCell::new(raw)
        }
    }

    pub unsafe fn from_trusted_node_address(inner: TrustedNodeAddress) -> JS<T> {
        JS {
            ptr: RefCell::new(inner as *mut T)
        }
    }
}

impl<T: Reflectable> Reflectable for JS<T> {
    fn reflector<'a>(&'a self) -> &'a Reflector {
        self.get().reflector()
    }

    fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
        self.get_mut().mut_reflector()
    }
}

impl<T> JS<T> {
    pub fn get<'a>(&'a self) -> &'a T {
        let borrowed = self.ptr.borrow();
        unsafe {
            &(**borrowed.get())
        }
    }

    pub fn get_mut<'a>(&'a mut self) -> &'a mut T {
        let mut borrowed = self.ptr.borrow_mut();
        unsafe {
            &mut (**borrowed.get())
        }
    }

    /// Returns an unsafe pointer to the interior of this JS object without touching the borrow
    /// flags. This is the only method that be safely accessed from layout. (The fact that this
    /// is unsafe is what necessitates the layout wrappers.)
    pub unsafe fn unsafe_get(&self) -> *mut T {
        cast::transmute_copy(&self.ptr)
    }
}

impl<From, To> JS<From> {
    //XXXjdm It would be lovely if this could be private.
    pub unsafe fn transmute(self) -> JS<To> {
        cast::transmute(self)
    }

    pub unsafe fn transmute_copy(&self) -> JS<To> {
        cast::transmute_copy(self)
    }
}
<|endoftext|>


<commit_before>#[macro_export]
macro_rules! __inst_gen_bf {
    // We don't care about the value (`{val}.n`) parts. Reduces item list. Reduces $itop to next item.
    (
        $itop:expr, [ {$fpart:expr}.$fwidth:expr $(; $part:tt.$width:expr)* ],
                    { $($spart:ident: $splow:expr => $sphi:expr),* }, $ty:ty
    ) => (
        // Move counter but otherwise pass it right through
        __inst_gen_bf!($itop - $fwidth, [ $($part.$width);* ],
                                        { $($spart: $splow => $sphi),* }, $ty);
    );

    // Skip filler (`{}.n`) parts. Reduces item list. Reduces $itop to next item.
    (
        $itop:expr, [ {}.$fwidth:expr $(; $part:tt.$width:expr)* ],
                    { $($spart:ident: $splow:expr => $sphi:expr),* }, $ty:ty
    ) => (
        // Move counter but otherwise pass it right through
        __inst_gen_bf!($itop - $fwidth, [ $($part.$width);* ],
                                        { $($spart: $splow => $sphi),* }, $ty);
    );

    // From named (`foo.n`) parts, accumulate top and bottom bits into position list.
    // Reduces item list. Reduces $itop to next item.
    (
        $itop:expr, [ $fpart:tt.$fwidth:expr $(; $part:tt.$width:expr)* ],
                    { $($spart:ident: $splow:expr => $sphi:expr),* }, $ty:ty
    ) => (
        __inst_gen_bf!($itop - $fwidth, [ $($part.$width);* ], {
                                            $($spart: $splow => $sphi,)*
                                            $fpart: ($itop - $fwidth) => ($itop - 1)
                                        }, $ty);
    );

    // Once item list is empty, finally produce our end result: the `InstrDesc` bitfield.
    (
        $itop:expr, [ ], { $($spart:ident: $splow:expr => $sphi:expr),* }, $ty:ty
    ) => (
        bitfield!(InstrDesc: $ty, {
            $($spart: $splow => $sphi),*
        });
    )
}

#[macro_export]
macro_rules! __inst_gen_decode {
    // ORs value (`{val}.n`) at position into $test, mask of value into $mask. Reduces item list.
    // Reduces $itop to next item.
    (
        $itop:expr, [ {$fpart:expr}.$fwidth:expr $(; $part:tt.$width:expr)* ], $mask:expr, $test:expr, $ty:ty
    ) => (
        __inst_gen_decode!($itop - $fwidth, [ $($part.$width);* ],
                           $mask | (bits!(!0 as $ty,     0 => ($fwidth - 1)) << ($itop - $fwidth)),
                           $test | (bits!($fpart as $ty, 0 => ($fwidth - 1)) << ($itop - $fwidth)), $ty);
    );

    // We don't care about the named (`foo.n`) parts. Reduces item list. Reduces $itop to next item.
    (
        $itop:expr, [ $fpart:tt.$fwidth:expr $(; $part:tt.$width:expr)* ], $mask:expr, $test:expr, $ty:ty
    ) => (
        // Move counter but otherwise pass it right through
        __inst_gen_decode!($itop - $fwidth, [ $($part.$width);* ], $mask, $test, $ty);
    );

    // Skip filler (`{}.n`) parts. Reduces item list. Reduces $itop to next item.
    (
        $itop:expr, [ {}.$fwidth:expr $(; $part:tt.$width:expr)* ], $mask:expr, $test:expr, $ty:ty
    ) => (
        // Move counter but otherwise pass it right through
        __inst_gen_decode!($itop - $fwidth, [ $($part.$width);* ], $mask, $test, $ty);
    );

    // Once item list is empty, finally produce our end result: the `decodable` function.
    (
        $itop:expr, [ ], $mask:expr, $test:expr, $ty:ty
    ) => (
        #[inline(always)]
        pub fn decodable(encoding: $ty) -> bool {
            assert!($itop == 0, format!("{} encoded bits do not add up!", module_path!()));
            encoding & $mask == $test
        }
    )
}

#[macro_export]
macro_rules! define_inst {
    ($name:ident: $ty:ty, $($part:tt.$width:expr);* ) => (
        pub mod $name {
            __inst_gen_bf!(::std::mem::size_of::<$ty>()*8, [ $($part.$width);* ], { }, $ty);
            __inst_gen_decode!(::std::mem::size_of::<$ty>()*8, [ $($part.$width);* ], 0, 0, $ty);
        }
    )
}

// Usage:
// define_insts!(Foo: ty {
//     with [ constraints ]
//       or [ constraints ]...
//     {
//         bar: [ constraints ],...
//     }
//     ...
// });
#[macro_export]
macro_rules! define_insts {
    ($enumname:ident: $ty:ty, {
        $(
            with $([ $($wpart:tt.$wwidth:expr);* ])or*
            {
                $( $name:ident: [ $($part:tt.$width:expr);* ] ),*
            }
        )*
    }) => (
        $($( define_inst!($name: $ty, $($part.$width);*); )*)*

        #[derive(Debug)]
        #[allow(non_camel_case_types)]
        pub enum $enumname {
            $($( $name($name::InstrDesc), )*)*
            Unknown
        }

        impl $enumname {
            pub fn decode(encoding: $ty) -> $enumname {
                $(
                    if $({ __inst_gen_decode!(::std::mem::size_of::<$ty>()*8, [ $($wpart.$wwidth);* ], 0, 0, $ty);
                         decodable(encoding) })||* {
                    $(
                        if $name::decodable(encoding) {
                            return $enumname::$name($name::InstrDesc::new(encoding))
                        }
                    )*
                    }
                )*

                $enumname::Unknown
            }
        }
    )
}

#[cfg(test)]
mod test {
    define_inst!(add_1: u16, {0b0001110}.7;immed_3.3;rn.3;rd.3);
    define_inst!(ldrh: u32, cond.4; {0b000}.3; p_bit.1; u_bit.1; i_bit.1; w_bit.1;
                            {0b1}.1; rn.4; rd.4; addr_mode.4; {0b1011}.4; addr_mode_.4);

    #[test]
    fn decode_add1() {
        assert!(add_1::try_decode(0b0001110000000000).is_some());
        assert!(add_1::try_decode(0b0011110000000000).is_none());
    }

    #[test]
    fn decode_ldrh() {
        let desc = ldrh::try_decode(0b11100000110101001001000010110100).unwrap();
        assert_eq!(bf!(desc.cond), 0b1110);
        assert_eq!(bf!(desc.rn), 4);
        assert_eq!(bf!(desc.rd), 9);
        assert!(ldrh::try_decode(0b11100000110101001001000011110100).is_none());
    }
}<commit_msg>define_inst: Update test code to reflect change in API<commit_after>#[macro_export]
macro_rules! __inst_gen_bf {
    // We don't care about the value (`{val}.n`) parts. Reduces item list. Reduces $itop to next item.
    (
        $itop:expr, [ {$fpart:expr}.$fwidth:expr $(; $part:tt.$width:expr)* ],
                    { $($spart:ident: $splow:expr => $sphi:expr),* }, $ty:ty
    ) => (
        // Move counter but otherwise pass it right through
        __inst_gen_bf!($itop - $fwidth, [ $($part.$width);* ],
                                        { $($spart: $splow => $sphi),* }, $ty);
    );

    // Skip filler (`{}.n`) parts. Reduces item list. Reduces $itop to next item.
    (
        $itop:expr, [ {}.$fwidth:expr $(; $part:tt.$width:expr)* ],
                    { $($spart:ident: $splow:expr => $sphi:expr),* }, $ty:ty
    ) => (
        // Move counter but otherwise pass it right through
        __inst_gen_bf!($itop - $fwidth, [ $($part.$width);* ],
                                        { $($spart: $splow => $sphi),* }, $ty);
    );

    // From named (`foo.n`) parts, accumulate top and bottom bits into position list.
    // Reduces item list. Reduces $itop to next item.
    (
        $itop:expr, [ $fpart:tt.$fwidth:expr $(; $part:tt.$width:expr)* ],
                    { $($spart:ident: $splow:expr => $sphi:expr),* }, $ty:ty
    ) => (
        __inst_gen_bf!($itop - $fwidth, [ $($part.$width);* ], {
                                            $($spart: $splow => $sphi,)*
                                            $fpart: ($itop - $fwidth) => ($itop - 1)
                                        }, $ty);
    );

    // Once item list is empty, finally produce our end result: the `InstrDesc` bitfield.
    (
        $itop:expr, [ ], { $($spart:ident: $splow:expr => $sphi:expr),* }, $ty:ty
    ) => (
        bitfield!(InstrDesc: $ty, {
            $($spart: $splow => $sphi),*
        });
    )
}

#[macro_export]
macro_rules! __inst_gen_decode {
    // ORs value (`{val}.n`) at position into $test, mask of value into $mask. Reduces item list.
    // Reduces $itop to next item.
    (
        $itop:expr, [ {$fpart:expr}.$fwidth:expr $(; $part:tt.$width:expr)* ], $mask:expr, $test:expr, $ty:ty
    ) => (
        __inst_gen_decode!($itop - $fwidth, [ $($part.$width);* ],
                           $mask | (bits!(!0 as $ty,     0 => ($fwidth - 1)) << ($itop - $fwidth)),
                           $test | (bits!($fpart as $ty, 0 => ($fwidth - 1)) << ($itop - $fwidth)), $ty);
    );

    // We don't care about the named (`foo.n`) parts. Reduces item list. Reduces $itop to next item.
    (
        $itop:expr, [ $fpart:tt.$fwidth:expr $(; $part:tt.$width:expr)* ], $mask:expr, $test:expr, $ty:ty
    ) => (
        // Move counter but otherwise pass it right through
        __inst_gen_decode!($itop - $fwidth, [ $($part.$width);* ], $mask, $test, $ty);
    );

    // Skip filler (`{}.n`) parts. Reduces item list. Reduces $itop to next item.
    (
        $itop:expr, [ {}.$fwidth:expr $(; $part:tt.$width:expr)* ], $mask:expr, $test:expr, $ty:ty
    ) => (
        // Move counter but otherwise pass it right through
        __inst_gen_decode!($itop - $fwidth, [ $($part.$width);* ], $mask, $test, $ty);
    );

    // Once item list is empty, finally produce our end result: the `decodable` function.
    (
        $itop:expr, [ ], $mask:expr, $test:expr, $ty:ty
    ) => (
        #[inline(always)]
        pub fn decodable(encoding: $ty) -> bool {
            assert!($itop == 0, format!("{} encoded bits do not add up!", module_path!()));
            encoding & $mask == $test
        }
    )
}

#[macro_export]
macro_rules! define_inst {
    ($name:ident: $ty:ty, $($part:tt.$width:expr);* ) => (
        pub mod $name {
            __inst_gen_bf!(::std::mem::size_of::<$ty>()*8, [ $($part.$width);* ], { }, $ty);
            __inst_gen_decode!(::std::mem::size_of::<$ty>()*8, [ $($part.$width);* ], 0, 0, $ty);
        }
    )
}

// Usage:
// define_insts!(Foo: ty {
//     with [ constraints ]
//       or [ constraints ]...
//     {
//         bar: [ constraints ],...
//     }
//     ...
// });
#[macro_export]
macro_rules! define_insts {
    ($enumname:ident: $ty:ty, {
        $(
            with $([ $($wpart:tt.$wwidth:expr);* ])or*
            {
                $( $name:ident: [ $($part:tt.$width:expr);* ] ),*
            }
        )*
    }) => (
        $($( define_inst!($name: $ty, $($part.$width);*); )*)*

        #[derive(Debug)]
        #[allow(non_camel_case_types)]
        pub enum $enumname {
            $($( $name($name::InstrDesc), )*)*
            Unknown
        }

        impl $enumname {
            pub fn decode(encoding: $ty) -> $enumname {
                $(
                    if $({ __inst_gen_decode!(::std::mem::size_of::<$ty>()*8, [ $($wpart.$wwidth);* ], 0, 0, $ty);
                         decodable(encoding) })||* {
                    $(
                        if $name::decodable(encoding) {
                            return $enumname::$name($name::InstrDesc::new(encoding))
                        }
                    )*
                    }
                )*

                $enumname::Unknown
            }
        }
    )
}

#[cfg(test)]
mod test {
    define_inst!(add_1: u16, {0b0001110}.7;immed_3.3;rn.3;rd.3);
    define_inst!(ldrh: u32, cond.4; {0b000}.3; p_bit.1; u_bit.1; i_bit.1; w_bit.1;
                            {0b1}.1; rn.4; rd.4; addr_mode.4; {0b1011}.4; addr_mode_.4);

    #[test]
    fn decode_add1() {
        assert!(add_1::decodable(0b0001110000000000));
        assert!(!add_1::decodable(0b0011110000000000));
    }

    #[test]
    fn decode_ldrh() {
        let ldrh_bits = 0b11100000110101001001000010110100;
        assert!(ldrh::decodable(ldrh_bits));

        let desc = ldrh::InstrDesc::new(0b11100000110101001001000010110100);
        assert_eq!(bf!(desc.cond), 0b1110);
        assert_eq!(bf!(desc.rn), 4);
        assert_eq!(bf!(desc.rd), 9);
        assert!(!ldrh::decodable(0b11100000110101001001000011110100));
    }
}<|endoftext|>


<commit_before>//! 16-bit signed and unsigned font-units

/// 16-bit signed quantity in font design units.
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
pub struct FWord(i16);

/// 16-bit unsigned quantity in font design units.
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
pub struct UfWord(u16);

impl FWord {
    pub fn new(raw: i16) -> Self {
        Self(raw)
    }

    pub fn to_i16(self) -> i16 {
        self.0
    }

    /// The representation of this number as a big-endian byte array.
    pub fn to_be_bytes(self) -> [u8; 2] {
        self.0.to_be_bytes()
    }
}

impl UfWord {
    pub fn new(raw: u16) -> Self {
        Self(raw)
    }

    pub fn to_u16(self) -> u16 {
        self.0
    }

    /// The representation of this number as a big-endian byte array.
    pub fn to_be_bytes(self) -> [u8; 2] {
        self.0.to_be_bytes()
    }
}

impl std::fmt::Display for FWord {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        self.0.fmt(f)
    }
}

impl std::fmt::Display for UfWord {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        self.0.fmt(f)
    }
}

crate::newtype_scalar!(FWord, [u8; 2]);
crate::newtype_scalar!(UfWord, [u8; 2]);
//TODO: we can add addition/etc as needed
<commit_msg>More basic traits for FWord and UfWord<commit_after>//! 16-bit signed and unsigned font-units

/// 16-bit signed quantity in font design units.
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
pub struct FWord(i16);

/// 16-bit unsigned quantity in font design units.
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
pub struct UfWord(u16);

impl FWord {
    pub fn new(raw: i16) -> Self {
        Self(raw)
    }

    pub fn to_i16(self) -> i16 {
        self.0
    }

    /// The representation of this number as a big-endian byte array.
    pub fn to_be_bytes(self) -> [u8; 2] {
        self.0.to_be_bytes()
    }
}

impl UfWord {
    pub fn new(raw: u16) -> Self {
        Self(raw)
    }

    pub fn to_u16(self) -> u16 {
        self.0
    }

    /// The representation of this number as a big-endian byte array.
    pub fn to_be_bytes(self) -> [u8; 2] {
        self.0.to_be_bytes()
    }
}

impl std::fmt::Display for FWord {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        self.0.fmt(f)
    }
}

impl std::fmt::Display for UfWord {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        self.0.fmt(f)
    }
}

impl From<u16> for UfWord {
    fn from(src: u16) -> Self {
        UfWord(src)
    }
}

impl From<i16> for FWord {
    fn from(src: i16) -> Self {
        FWord(src)
    }
}

impl From<FWord> for i16 {
    fn from(src: FWord) -> Self {
        src.0
    }
}

impl From<UfWord> for u16 {
    fn from(src: UfWord) -> Self {
        src.0
    }
}

crate::newtype_scalar!(FWord, [u8; 2]);
crate::newtype_scalar!(UfWord, [u8; 2]);
//TODO: we can add addition/etc as needed
<|endoftext|>