<commit_before>#![feature(
    pin,
    async_await,
    await_macro,
    futures_api,
    arbitrary_self_types,
    proc_macro_hygiene,
    impl_trait_in_bindings
)]

mod registry {
    use bytes::Bytes;
    use futures::{
        future::{ready, Ready},
        prelude::*,
    };
    use serde::{Deserialize, Serialize};
    use std::{
        io,
        pin::Pin,
        sync::Arc,
        task::{LocalWaker, Poll},
    };
    use tarpc::{
        client::{self, Client},
        context,
    };

    /// A request to a named service.
    #[derive(Serialize, Deserialize)]
    pub struct ServiceRequest {
        service_name: String,
        request: Bytes,
    }

    /// A response from a named service.
    #[derive(Serialize, Deserialize)]
    pub struct ServiceResponse {
        response: Bytes,
    }

    /// A list of registered services.
    pub struct Registry<Services> {
        registrations: Services,
    }

    impl Default for Registry<Nil> {
        fn default() -> Self {
            Registry { registrations: Nil }
        }
    }

    impl<Services: MaybeServe + Sync> Registry<Services> {
        /// Returns a function that serves requests for the registered services.
        pub fn serve(
            self,
        ) -> impl FnOnce(context::Context, ServiceRequest)
            -> Either<Services::Future, Ready<io::Result<ServiceResponse>>>
                         + Clone {
            let registrations = Arc::new(self.registrations);
            move |cx, req: ServiceRequest| match registrations.serve(cx, &req) {
                Some(serve) => Either::Left(serve),
                None => Either::Right(ready(Err(io::Error::new(
                    io::ErrorKind::NotFound,
                    format!("Service '{}' not registered", req.service_name),
                )))),
            }
        }

        /// Registers `serve` with the given `name` using the given serialization scheme.
        pub fn register<S, Req, Resp, RespFut, Ser, De>(
            self,
            name: String,
            serve: S,
            deserialize: De,
            serialize: Ser)
            -> Registry<Registration<impl Serve + Send + 'static, Services>>
            where
                Req: Send,
                S: FnOnce(context::Context, Req) -> RespFut + Send + 'static + Clone,
                RespFut: Future<Output=io::Result<Resp>> + Send + 'static,
                De: FnOnce(Bytes) -> io::Result<Req> + Send + 'static + Clone,
                Ser: FnOnce(Resp) -> io::Result<Bytes> + Send + 'static + Clone,
        {
            let registrations = Registration {
                name: name,
                serve: move |cx, req: Bytes| {
                    async move {
                        let req = deserialize.clone()(req)?;
                        let response = await!(serve.clone()(cx, req))?;
                        let response = serialize.clone()(response)?;
                        Ok(ServiceResponse { response })
                    }
                },
                rest: self.registrations,
            };
            Registry { registrations }
        }
    }

    /// Creates a client that sends requests to a service
    /// named `service_name`, over the given channel, using
    /// the specified serialization scheme.
    pub fn new_client<Req, Resp, Ser, De>(
        service_name: String,
        channel: &client::Channel<ServiceRequest, ServiceResponse>,
        mut serialize: Ser,
        mut deserialize: De,
    ) -> client::MapResponse<
        client::WithRequest<
            client::Channel<ServiceRequest, ServiceResponse>,
            impl FnMut(Req) -> ServiceRequest,
        >,
        impl FnMut(ServiceResponse) -> Resp,
    >
    where
        Req: Send + 'static,
        Resp: Send + 'static,
        De: FnMut(Bytes) -> io::Result<Resp> + Clone + Send + 'static,
        Ser: FnMut(Req) -> io::Result<Bytes> + Clone + Send + 'static,
    {
        channel
            .clone()
            .with_request(move |req| {
                ServiceRequest {
                    service_name: service_name.clone(),
                    // TODO: shouldn't need to unwrap here. Maybe with_request should allow for
                    // returning Result.
                    request: serialize(req).unwrap(),
                }
            })
            // TODO: same thing. Maybe this should be more like and_then rather than map.
            .map_response(move |resp| deserialize(resp.response).unwrap())
    }

    /// Serves a request.
    ///
    /// This trait is mostly an implementation detail that isn't used outside of the registry
    /// internals.
    pub trait Serve: Clone + Send + 'static {
        type Response: Future<Output = io::Result<ServiceResponse>> + Send + 'static;
        fn serve(self, cx: context::Context, request: Bytes) -> Self::Response;
    }

    /// Serves a request if the request is for a registered service.
    ///
    /// This trait is mostly an implementation detail that isn't used outside of the registry
    /// internals.
    pub trait MaybeServe: Send + 'static {
        type Future: Future<Output = io::Result<ServiceResponse>> + Send + 'static;

        fn serve(&self, cx: context::Context, request: &ServiceRequest) -> Option<Self::Future>;
    }

    /// A registry starting with service S, followed by Rest.
    ///
    /// This type is mostly an implementation detail that is not used directly
    /// outside of the registry internals.
    pub struct Registration<S, Rest> {
        /// The registered service's name. Must be unique across all registered services.
        name: String,
        /// The registered service.
        serve: S,
        /// Any remaining registered services.
        rest: Rest,
    }

    /// An empty registry.
    ///
    /// This type is mostly an implementation detail that is not used directly
    /// outside of the registry internals.
    pub struct Nil;

    impl MaybeServe for Nil {
        type Future = futures::future::Ready<io::Result<ServiceResponse>>;

        fn serve(&self, _: context::Context, _: &ServiceRequest) -> Option<Self::Future> {
            None
        }
    }

    impl<S, Rest> MaybeServe for Registration<S, Rest>
    where
        S: Serve,
        Rest: MaybeServe,
    {
        type Future = Either<S::Response, Rest::Future>;

        fn serve(&self, cx: context::Context, request: &ServiceRequest) -> Option<Self::Future> {
            if self.name == request.service_name {
                Some(Either::Left(self.serve.clone().serve(cx, request.request.clone())))
            } else {
                self.rest.serve(cx, request).map(Either::Right)
            }
        }
    }

    /// Wraps either of two future types that both resolve to the same output type.
    #[derive(Debug)]
    #[must_use = "futures do nothing unless polled"]
    pub enum Either<Left, Right> {
        Left(Left),
        Right(Right),
    }

    impl<Output, Left, Right> Future for Either<Left, Right>
    where
        Left: Future<Output = Output>,
        Right: Future<Output = Output>
    {
        type Output = Output;

        fn poll(self: Pin<&mut Self>, waker: &LocalWaker) -> Poll<Output> {
            unsafe {
                match Pin::get_mut_unchecked(self) {
                    Either::Left(car) => Pin::new_unchecked(car).poll(waker),
                    Either::Right(cdr) => Pin::new_unchecked(cdr).poll(waker),
                }
            }
        }
    }

    impl<Resp, F> Serve for F
    where
        F: FnOnce(context::Context, Bytes) -> Resp + Clone + Send + 'static,
        Resp: Future<Output = io::Result<ServiceResponse>> + Send + 'static
    {
        type Response = Resp;

        fn serve(self, cx: context::Context, request: Bytes) -> Resp {
            self(cx, request)
        }
    }
}

// Example
use bytes::Bytes;
use futures::{
    future::{ready, Ready},
    prelude::*,
};
use serde::{Deserialize, Serialize};
use std::{
    collections::HashMap,
    io,
    sync::{Arc, RwLock},
};
use tarpc::{client, context, server::Handler};

fn deserialize<Req>(req: Bytes) -> io::Result<Req>
where
    Req: for<'a> Deserialize<'a> + Send,
{
    bincode::deserialize(req.as_ref()).map_err(|e| io::Error::new(io::ErrorKind::Other, e))
}

fn serialize<Resp>(resp: Resp) -> io::Result<Bytes>
where
    Resp: Serialize,
{
    Ok(bincode::serialize(&resp)
        .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?
        .into())
}

mod write_service {
    tarpc::service! {
        rpc write(key: String, value: String);
    }
}

mod read_service {
    tarpc::service! {
        rpc read(key: String) -> Option<String>;
    }
}

#[derive(Debug, Default, Clone)]
struct Server {
    data: Arc<RwLock<HashMap<String, String>>>,
}

impl write_service::Service for Server {
    type WriteFut = Ready<()>;

    fn write(self, _: context::Context, key: String, value: String) -> Self::WriteFut {
        self.data.write().unwrap().insert(key, value);
        ready(())
    }
}

impl read_service::Service for Server {
    type ReadFut = Ready<Option<String>>;

    fn read(self, _: context::Context, key: String) -> Self::ReadFut {
        ready(self.data.read().unwrap().get(&key).cloned())
    }
}

trait DefaultSpawn {
    fn spawn(self);
}

impl<F> DefaultSpawn for F
where
    F: Future<Output = ()> + Send + 'static,
{
    fn spawn(self) {
        tokio_executor::spawn(self.unit_error().boxed().compat())
    }
}

struct BincodeRegistry<Services> {
    registry: registry::Registry<Services>,
}

impl Default for BincodeRegistry<registry::Nil> {
    fn default() -> Self {
        BincodeRegistry { registry: registry::Registry::default() }
    }
}

impl<Services: registry::MaybeServe + Sync> BincodeRegistry<Services> {
    fn serve(self) -> impl FnOnce(context::Context, registry::ServiceRequest)
        -> registry::Either<Services::Future, Ready<io::Result<registry::ServiceResponse>>> + Clone
    {
        self.registry.serve()
    }

    fn register<S, Req, Resp, RespFut>(
        self,
        name: String,
        serve: S,
    ) -> BincodeRegistry<registry::Registration<impl registry::Serve + Send + 'static, Services>>
    where
        Req: for<'a> Deserialize<'a> + Send + 'static,
        Resp: Serialize + 'static,
        S: FnOnce(context::Context, Req) -> RespFut + Send + 'static + Clone,
        RespFut: Future<Output = io::Result<Resp>> + Send + 'static,
    {
        let registry = self.registry.register(name, serve, deserialize, serialize);
        BincodeRegistry { registry }
    }
}

pub fn new_client<Req, Resp>(
    service_name: String,
    channel: &client::Channel<registry::ServiceRequest, registry::ServiceResponse>,
) -> client::MapResponse<
    client::WithRequest<
        client::Channel<registry::ServiceRequest, registry::ServiceResponse>,
        impl FnMut(Req) -> registry::ServiceRequest,
    >,
    impl FnMut(registry::ServiceResponse) -> Resp,
>
where
    Req: Serialize + Send + 'static,
    Resp: for<'a> Deserialize<'a> + Send + 'static,
{
    registry::new_client(service_name, channel, serialize, deserialize)
}

async fn run() -> io::Result<()> {
    let server = Server::default();
    let registry = BincodeRegistry::default()
        .register(
            "WriteService".to_string(),
            write_service::serve(server.clone()),
        )
        .register(
            "ReadService".to_string(),
            read_service::serve(server.clone()),
        );

    let listener = bincode_transport::listen(&"0.0.0.0:0".parse().unwrap())?;
    let server_addr = listener.local_addr();
    let server = tarpc::Server::default()
        .incoming(listener)
        .take(1)
        .respond_with(registry.serve());
    tokio_executor::spawn(server.unit_error().boxed().compat());

    let transport = await!(bincode_transport::connect(&server_addr))?;
    let channel = await!(client::new(client::Config::default(), transport))?;

    let write_client = new_client("WriteService".to_string(), &channel);
    let mut write_client = write_service::Client::from(write_client);

    let read_client = new_client("ReadService".to_string(), &channel);
    let mut read_client = read_service::Client::from(read_client);

    await!(write_client.write(context::current(), "key".to_string(), "val".to_string()))?;
    let val = await!(read_client.read(context::current(), "key".to_string()))?;
    println!("{:?}", val);

    Ok(())
}

fn main() {
    tarpc::init(futures::compat::TokioDefaultSpawner);
    tokio::run(run().boxed().map_err(|e| panic!(e)).boxed().compat());
}
<commit_msg>Cargo fmt<commit_after>#![feature(
    pin,
    async_await,
    await_macro,
    futures_api,
    arbitrary_self_types,
    proc_macro_hygiene,
    impl_trait_in_bindings
)]

mod registry {
    use bytes::Bytes;
    use futures::{
        future::{ready, Ready},
        prelude::*,
    };
    use serde::{Deserialize, Serialize};
    use std::{
        io,
        pin::Pin,
        sync::Arc,
        task::{LocalWaker, Poll},
    };
    use tarpc::{
        client::{self, Client},
        context,
    };

    /// A request to a named service.
    #[derive(Serialize, Deserialize)]
    pub struct ServiceRequest {
        service_name: String,
        request: Bytes,
    }

    /// A response from a named service.
    #[derive(Serialize, Deserialize)]
    pub struct ServiceResponse {
        response: Bytes,
    }

    /// A list of registered services.
    pub struct Registry<Services> {
        registrations: Services,
    }

    impl Default for Registry<Nil> {
        fn default() -> Self {
            Registry { registrations: Nil }
        }
    }

    impl<Services: MaybeServe + Sync> Registry<Services> {
        /// Returns a function that serves requests for the registered services.
        pub fn serve(
            self,
        ) -> impl FnOnce(context::Context, ServiceRequest)
            -> Either<Services::Future, Ready<io::Result<ServiceResponse>>>
                         + Clone {
            let registrations = Arc::new(self.registrations);
            move |cx, req: ServiceRequest| match registrations.serve(cx, &req) {
                Some(serve) => Either::Left(serve),
                None => Either::Right(ready(Err(io::Error::new(
                    io::ErrorKind::NotFound,
                    format!("Service '{}' not registered", req.service_name),
                )))),
            }
        }

        /// Registers `serve` with the given `name` using the given serialization scheme.
        pub fn register<S, Req, Resp, RespFut, Ser, De>(
            self,
            name: String,
            serve: S,
            deserialize: De,
            serialize: Ser,
        ) -> Registry<Registration<impl Serve + Send + 'static, Services>>
        where
            Req: Send,
            S: FnOnce(context::Context, Req) -> RespFut + Send + 'static + Clone,
            RespFut: Future<Output = io::Result<Resp>> + Send + 'static,
            De: FnOnce(Bytes) -> io::Result<Req> + Send + 'static + Clone,
            Ser: FnOnce(Resp) -> io::Result<Bytes> + Send + 'static + Clone,
        {
            let registrations = Registration {
                name: name,
                serve: move |cx, req: Bytes| {
                    async move {
                        let req = deserialize.clone()(req)?;
                        let response = await!(serve.clone()(cx, req))?;
                        let response = serialize.clone()(response)?;
                        Ok(ServiceResponse { response })
                    }
                },
                rest: self.registrations,
            };
            Registry { registrations }
        }
    }

    /// Creates a client that sends requests to a service
    /// named `service_name`, over the given channel, using
    /// the specified serialization scheme.
    pub fn new_client<Req, Resp, Ser, De>(
        service_name: String,
        channel: &client::Channel<ServiceRequest, ServiceResponse>,
        mut serialize: Ser,
        mut deserialize: De,
    ) -> client::MapResponse<
        client::WithRequest<
            client::Channel<ServiceRequest, ServiceResponse>,
            impl FnMut(Req) -> ServiceRequest,
        >,
        impl FnMut(ServiceResponse) -> Resp,
    >
    where
        Req: Send + 'static,
        Resp: Send + 'static,
        De: FnMut(Bytes) -> io::Result<Resp> + Clone + Send + 'static,
        Ser: FnMut(Req) -> io::Result<Bytes> + Clone + Send + 'static,
    {
        channel
            .clone()
            .with_request(move |req| {
                ServiceRequest {
                    service_name: service_name.clone(),
                    // TODO: shouldn't need to unwrap here. Maybe with_request should allow for
                    // returning Result.
                    request: serialize(req).unwrap(),
                }
            })
            // TODO: same thing. Maybe this should be more like and_then rather than map.
            .map_response(move |resp| deserialize(resp.response).unwrap())
    }

    /// Serves a request.
    ///
    /// This trait is mostly an implementation detail that isn't used outside of the registry
    /// internals.
    pub trait Serve: Clone + Send + 'static {
        type Response: Future<Output = io::Result<ServiceResponse>> + Send + 'static;
        fn serve(self, cx: context::Context, request: Bytes) -> Self::Response;
    }

    /// Serves a request if the request is for a registered service.
    ///
    /// This trait is mostly an implementation detail that isn't used outside of the registry
    /// internals.
    pub trait MaybeServe: Send + 'static {
        type Future: Future<Output = io::Result<ServiceResponse>> + Send + 'static;

        fn serve(&self, cx: context::Context, request: &ServiceRequest) -> Option<Self::Future>;
    }

    /// A registry starting with service S, followed by Rest.
    ///
    /// This type is mostly an implementation detail that is not used directly
    /// outside of the registry internals.
    pub struct Registration<S, Rest> {
        /// The registered service's name. Must be unique across all registered services.
        name: String,
        /// The registered service.
        serve: S,
        /// Any remaining registered services.
        rest: Rest,
    }

    /// An empty registry.
    ///
    /// This type is mostly an implementation detail that is not used directly
    /// outside of the registry internals.
    pub struct Nil;

    impl MaybeServe for Nil {
        type Future = futures::future::Ready<io::Result<ServiceResponse>>;

        fn serve(&self, _: context::Context, _: &ServiceRequest) -> Option<Self::Future> {
            None
        }
    }

    impl<S, Rest> MaybeServe for Registration<S, Rest>
    where
        S: Serve,
        Rest: MaybeServe,
    {
        type Future = Either<S::Response, Rest::Future>;

        fn serve(&self, cx: context::Context, request: &ServiceRequest) -> Option<Self::Future> {
            if self.name == request.service_name {
                Some(Either::Left(
                    self.serve.clone().serve(cx, request.request.clone()),
                ))
            } else {
                self.rest.serve(cx, request).map(Either::Right)
            }
        }
    }

    /// Wraps either of two future types that both resolve to the same output type.
    #[derive(Debug)]
    #[must_use = "futures do nothing unless polled"]
    pub enum Either<Left, Right> {
        Left(Left),
        Right(Right),
    }

    impl<Output, Left, Right> Future for Either<Left, Right>
    where
        Left: Future<Output = Output>,
        Right: Future<Output = Output>,
    {
        type Output = Output;

        fn poll(self: Pin<&mut Self>, waker: &LocalWaker) -> Poll<Output> {
            unsafe {
                match Pin::get_mut_unchecked(self) {
                    Either::Left(car) => Pin::new_unchecked(car).poll(waker),
                    Either::Right(cdr) => Pin::new_unchecked(cdr).poll(waker),
                }
            }
        }
    }

    impl<Resp, F> Serve for F
    where
        F: FnOnce(context::Context, Bytes) -> Resp + Clone + Send + 'static,
        Resp: Future<Output = io::Result<ServiceResponse>> + Send + 'static,
    {
        type Response = Resp;

        fn serve(self, cx: context::Context, request: Bytes) -> Resp {
            self(cx, request)
        }
    }
}

// Example
use bytes::Bytes;
use futures::{
    future::{ready, Ready},
    prelude::*,
};
use serde::{Deserialize, Serialize};
use std::{
    collections::HashMap,
    io,
    sync::{Arc, RwLock},
};
use tarpc::{client, context, server::Handler};

fn deserialize<Req>(req: Bytes) -> io::Result<Req>
where
    Req: for<'a> Deserialize<'a> + Send,
{
    bincode::deserialize(req.as_ref()).map_err(|e| io::Error::new(io::ErrorKind::Other, e))
}

fn serialize<Resp>(resp: Resp) -> io::Result<Bytes>
where
    Resp: Serialize,
{
    Ok(bincode::serialize(&resp)
        .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?
        .into())
}

mod write_service {
    tarpc::service! {
        rpc write(key: String, value: String);
    }
}

mod read_service {
    tarpc::service! {
        rpc read(key: String) -> Option<String>;
    }
}

#[derive(Debug, Default, Clone)]
struct Server {
    data: Arc<RwLock<HashMap<String, String>>>,
}

impl write_service::Service for Server {
    type WriteFut = Ready<()>;

    fn write(self, _: context::Context, key: String, value: String) -> Self::WriteFut {
        self.data.write().unwrap().insert(key, value);
        ready(())
    }
}

impl read_service::Service for Server {
    type ReadFut = Ready<Option<String>>;

    fn read(self, _: context::Context, key: String) -> Self::ReadFut {
        ready(self.data.read().unwrap().get(&key).cloned())
    }
}

trait DefaultSpawn {
    fn spawn(self);
}

impl<F> DefaultSpawn for F
where
    F: Future<Output = ()> + Send + 'static,
{
    fn spawn(self) {
        tokio_executor::spawn(self.unit_error().boxed().compat())
    }
}

struct BincodeRegistry<Services> {
    registry: registry::Registry<Services>,
}

impl Default for BincodeRegistry<registry::Nil> {
    fn default() -> Self {
        BincodeRegistry {
            registry: registry::Registry::default(),
        }
    }
}

impl<Services: registry::MaybeServe + Sync> BincodeRegistry<Services> {
    fn serve(
        self,
    ) -> impl FnOnce(
        context::Context, registry::ServiceRequest
    ) -> registry::Either<
        Services::Future,
        Ready<io::Result<registry::ServiceResponse>>,
    > + Clone {
        self.registry.serve()
    }

    fn register<S, Req, Resp, RespFut>(
        self,
        name: String,
        serve: S,
    ) -> BincodeRegistry<registry::Registration<impl registry::Serve + Send + 'static, Services>>
    where
        Req: for<'a> Deserialize<'a> + Send + 'static,
        Resp: Serialize + 'static,
        S: FnOnce(context::Context, Req) -> RespFut + Send + 'static + Clone,
        RespFut: Future<Output = io::Result<Resp>> + Send + 'static,
    {
        let registry = self.registry.register(name, serve, deserialize, serialize);
        BincodeRegistry { registry }
    }
}

pub fn new_client<Req, Resp>(
    service_name: String,
    channel: &client::Channel<registry::ServiceRequest, registry::ServiceResponse>,
) -> client::MapResponse<
    client::WithRequest<
        client::Channel<registry::ServiceRequest, registry::ServiceResponse>,
        impl FnMut(Req) -> registry::ServiceRequest,
    >,
    impl FnMut(registry::ServiceResponse) -> Resp,
>
where
    Req: Serialize + Send + 'static,
    Resp: for<'a> Deserialize<'a> + Send + 'static,
{
    registry::new_client(service_name, channel, serialize, deserialize)
}

async fn run() -> io::Result<()> {
    let server = Server::default();
    let registry = BincodeRegistry::default()
        .register(
            "WriteService".to_string(),
            write_service::serve(server.clone()),
        )
        .register(
            "ReadService".to_string(),
            read_service::serve(server.clone()),
        );

    let listener = bincode_transport::listen(&"0.0.0.0:0".parse().unwrap())?;
    let server_addr = listener.local_addr();
    let server = tarpc::Server::default()
        .incoming(listener)
        .take(1)
        .respond_with(registry.serve());
    tokio_executor::spawn(server.unit_error().boxed().compat());

    let transport = await!(bincode_transport::connect(&server_addr))?;
    let channel = await!(client::new(client::Config::default(), transport))?;

    let write_client = new_client("WriteService".to_string(), &channel);
    let mut write_client = write_service::Client::from(write_client);

    let read_client = new_client("ReadService".to_string(), &channel);
    let mut read_client = read_service::Client::from(read_client);

    await!(write_client.write(context::current(), "key".to_string(), "val".to_string()))?;
    let val = await!(read_client.read(context::current(), "key".to_string()))?;
    println!("{:?}", val);

    Ok(())
}

fn main() {
    tarpc::init(futures::compat::TokioDefaultSpawner);
    tokio::run(run().boxed().map_err(|e| panic!(e)).boxed().compat());
}
<|endoftext|>


<commit_before>//! CLI tool to use the functions provided by the [cranelift-wasm](../cranelift_wasm/index.html)
//! crate.
//!
//! Reads Wasm binary files, translates the functions' code to Cranelift IR.
#![cfg_attr(
    feature = "cargo-clippy",
    allow(too_many_arguments, cyclomatic_complexity)
)]

use cranelift_codegen::print_errors::{pretty_error, pretty_verifier_error};
use cranelift_codegen::settings::FlagsOrIsa;
use cranelift_codegen::Context;
use cranelift_codegen::timing;
use cranelift_entity::EntityRef;
use cranelift_wasm::{
    translate_module, DummyEnvironment, FuncIndex, ModuleEnvironment, ReturnMode,
};
use std::error::Error;
use std::path::Path;
use std::path::PathBuf;
use term;
use utils::{parse_sets_and_triple, read_to_end};
use wabt::wat2wasm;

macro_rules! vprintln {
    ($x: expr, $($tts:tt)*) => {
        if $x {
            println!($($tts)*);
        }
    }
}

macro_rules! vprint {
    ($x: expr, $($tts:tt)*) => {
        if $x {
            print!($($tts)*);
        }
    }
}

pub fn run(
    files: Vec<String>,
    flag_verbose: bool,
    flag_just_decode: bool,
    flag_check_translation: bool,
    flag_print: bool,
    flag_set: &[String],
    flag_triple: &str,
    flag_print_size: bool,
    flag_report_times: bool,
) -> Result<(), String> {
    let parsed = parse_sets_and_triple(flag_set, flag_triple)?;

    for filename in files {
        let path = Path::new(&filename);
        let name = String::from(path.as_os_str().to_string_lossy());
        handle_module(
            flag_verbose,
            flag_just_decode,
            flag_check_translation,
            flag_print,
            flag_print_size,
            flag_report_times,
            &path.to_path_buf(),
            &name,
            parsed.as_fisa(),
        )?;
    }
    Ok(())
}

fn handle_module(
    flag_verbose: bool,
    flag_just_decode: bool,
    flag_check_translation: bool,
    flag_print: bool,
    flag_print_size: bool,
    flag_report_times: bool,
    path: &PathBuf,
    name: &str,
    fisa: FlagsOrIsa,
) -> Result<(), String> {
    let mut terminal = term::stdout().unwrap();
    let _ = terminal.fg(term::color::YELLOW);
    vprint!(flag_verbose, "Handling: ");
    let _ = terminal.reset();
    vprintln!(flag_verbose, "\"{}\"", name);
    let _ = terminal.fg(term::color::MAGENTA);
    vprint!(flag_verbose, "Translating... ");
    let _ = terminal.reset();

    let mut module_binary =
        read_to_end(path.clone()).map_err(|err| String::from(err.description()))?;

    if !module_binary.starts_with(&[b'\0', b'a', b's', b'm']) {
        module_binary = match wat2wasm(&module_binary) {
            Ok(data) => data,
            Err(e) => return Err(String::from(e.description())),
        };
    }

    let isa = match fisa.isa {
        Some(isa) => isa,
        None => {
            return Err(String::from(
                "Error: the wasm command requires an explicit isa.",
            ))
        }
    };

    let mut dummy_environ = DummyEnvironment::with_triple_flags(
        isa.triple().clone(),
        fisa.flags.clone(),
        ReturnMode::NormalReturns,
    );
    translate_module(&module_binary, &mut dummy_environ).map_err(|e| e.to_string())?;

    let _ = terminal.fg(term::color::GREEN);
    vprintln!(flag_verbose, "ok");
    let _ = terminal.reset();

    if flag_just_decode {
        if !flag_print {
            return Ok(());
        }

        let num_func_imports = dummy_environ.get_num_func_imports();
        for (def_index, func) in dummy_environ.info.function_bodies.iter() {
            let func_index = num_func_imports + def_index.index();
            let mut context = Context::new();
            context.func = func.clone();
            if let Some(start_func) = dummy_environ.info.start_func {
                if func_index == start_func.index() {
                    println!("; Selected as wasm start function");
                }
            }
            vprintln!(flag_verbose, "");
            for export_name in
                &dummy_environ.info.functions[FuncIndex::new(func_index)].export_names
            {
                println!("; Exported as \"{}\"", export_name);
            }
            println!("{}", context.func.display(None));
            vprintln!(flag_verbose, "");
        }
        let _ = terminal.reset();
        return Ok(());
    }

    let _ = terminal.fg(term::color::MAGENTA);
    if flag_check_translation {
        vprint!(flag_verbose, "Checking... ");
    } else {
        vprint!(flag_verbose, "Compiling... ");
    }
    let _ = terminal.reset();

    if flag_print_size {
        vprintln!(flag_verbose, "");
    }

    let num_func_imports = dummy_environ.get_num_func_imports();
    let mut total_module_code_size = 0;
    let mut context = Context::new();
    for (def_index, func) in dummy_environ.info.function_bodies.iter() {
        context.func = func.clone();

        let func_index = num_func_imports + def_index.index();
        if flag_check_translation {
            if let Err(errors) = context.verify(fisa) {
                return Err(pretty_verifier_error(&context.func, fisa.isa, None, errors));
            }
        } else {
            let compiled_size = context
                .compile(isa)
                .map_err(|err| pretty_error(&context.func, fisa.isa, err))?;
            if flag_print_size {
                println!(
                    "Function #{} code size: {} bytes",
                    func_index, compiled_size
                );
                total_module_code_size += compiled_size;
                println!(
                    "Function #{} bytecode size: {} bytes",
                    func_index,
                    dummy_environ.func_bytecode_sizes[def_index.index()]
                );
            }
        }

        if flag_print {
            vprintln!(flag_verbose, "");
            if let Some(start_func) = dummy_environ.info.start_func {
                if func_index == start_func.index() {
                    println!("; Selected as wasm start function");
                }
            }
            for export_name in
                &dummy_environ.info.functions[FuncIndex::new(func_index)].export_names
            {
                println!("; Exported as \"{}\"", export_name);
            }
            println!("{}", context.func.display(fisa.isa));
            vprintln!(flag_verbose, "");
        }

        context.clear();
    }

    if !flag_check_translation && flag_print_size {
        println!("Total module code size: {} bytes", total_module_code_size);
        let total_bytecode_size: usize = dummy_environ.func_bytecode_sizes.iter().sum();
        println!("Total module bytecode size: {} bytes", total_bytecode_size);
    }

    if flag_report_times {
        println!("{}", timing::take_current());
    }

    let _ = terminal.fg(term::color::GREEN);
    vprintln!(flag_verbose, "ok");
    let _ = terminal.reset();
    Ok(())
}
<commit_msg>Remove use of deprecated APIs.<commit_after>//! CLI tool to use the functions provided by the [cranelift-wasm](../cranelift_wasm/index.html)
//! crate.
//!
//! Reads Wasm binary files, translates the functions' code to Cranelift IR.
#![cfg_attr(
    feature = "cargo-clippy",
    allow(too_many_arguments, cyclomatic_complexity)
)]

use cranelift_codegen::print_errors::{pretty_error, pretty_verifier_error};
use cranelift_codegen::settings::FlagsOrIsa;
use cranelift_codegen::timing;
use cranelift_codegen::Context;
use cranelift_entity::EntityRef;
use cranelift_wasm::{
    translate_module, DummyEnvironment, FuncIndex, ModuleEnvironment, ReturnMode,
};
use std::error::Error;
use std::path::Path;
use std::path::PathBuf;
use term;
use utils::{parse_sets_and_triple, read_to_end};
use wabt::wat2wasm;

macro_rules! vprintln {
    ($x: expr, $($tts:tt)*) => {
        if $x {
            println!($($tts)*);
        }
    }
}

macro_rules! vprint {
    ($x: expr, $($tts:tt)*) => {
        if $x {
            print!($($tts)*);
        }
    }
}

pub fn run(
    files: Vec<String>,
    flag_verbose: bool,
    flag_just_decode: bool,
    flag_check_translation: bool,
    flag_print: bool,
    flag_set: &[String],
    flag_triple: &str,
    flag_print_size: bool,
    flag_report_times: bool,
) -> Result<(), String> {
    let parsed = parse_sets_and_triple(flag_set, flag_triple)?;

    for filename in files {
        let path = Path::new(&filename);
        let name = String::from(path.as_os_str().to_string_lossy());
        handle_module(
            flag_verbose,
            flag_just_decode,
            flag_check_translation,
            flag_print,
            flag_print_size,
            flag_report_times,
            &path.to_path_buf(),
            &name,
            parsed.as_fisa(),
        )?;
    }
    Ok(())
}

fn handle_module(
    flag_verbose: bool,
    flag_just_decode: bool,
    flag_check_translation: bool,
    flag_print: bool,
    flag_print_size: bool,
    flag_report_times: bool,
    path: &PathBuf,
    name: &str,
    fisa: FlagsOrIsa,
) -> Result<(), String> {
    let mut terminal = term::stdout().unwrap();
    let _ = terminal.fg(term::color::YELLOW);
    vprint!(flag_verbose, "Handling: ");
    let _ = terminal.reset();
    vprintln!(flag_verbose, "\"{}\"", name);
    let _ = terminal.fg(term::color::MAGENTA);
    vprint!(flag_verbose, "Translating... ");
    let _ = terminal.reset();

    let mut module_binary = read_to_end(path.clone()).map_err(|err| err.to_string())?;

    if !module_binary.starts_with(&[b'\0', b'a', b's', b'm']) {
        module_binary = match wat2wasm(&module_binary) {
            Ok(data) => data,
            Err(e) => return Err(e.to_string()),
        };
    }

    let isa = match fisa.isa {
        Some(isa) => isa,
        None => {
            return Err(String::from(
                "Error: the wasm command requires an explicit isa.",
            ))
        }
    };

    let mut dummy_environ = DummyEnvironment::with_triple_flags(
        isa.triple().clone(),
        fisa.flags.clone(),
        ReturnMode::NormalReturns,
    );
    translate_module(&module_binary, &mut dummy_environ).map_err(|e| e.to_string())?;

    let _ = terminal.fg(term::color::GREEN);
    vprintln!(flag_verbose, "ok");
    let _ = terminal.reset();

    if flag_just_decode {
        if !flag_print {
            return Ok(());
        }

        let num_func_imports = dummy_environ.get_num_func_imports();
        for (def_index, func) in dummy_environ.info.function_bodies.iter() {
            let func_index = num_func_imports + def_index.index();
            let mut context = Context::new();
            context.func = func.clone();
            if let Some(start_func) = dummy_environ.info.start_func {
                if func_index == start_func.index() {
                    println!("; Selected as wasm start function");
                }
            }
            vprintln!(flag_verbose, "");
            for export_name in
                &dummy_environ.info.functions[FuncIndex::new(func_index)].export_names
            {
                println!("; Exported as \"{}\"", export_name);
            }
            println!("{}", context.func.display(None));
            vprintln!(flag_verbose, "");
        }
        let _ = terminal.reset();
        return Ok(());
    }

    let _ = terminal.fg(term::color::MAGENTA);
    if flag_check_translation {
        vprint!(flag_verbose, "Checking... ");
    } else {
        vprint!(flag_verbose, "Compiling... ");
    }
    let _ = terminal.reset();

    if flag_print_size {
        vprintln!(flag_verbose, "");
    }

    let num_func_imports = dummy_environ.get_num_func_imports();
    let mut total_module_code_size = 0;
    let mut context = Context::new();
    for (def_index, func) in dummy_environ.info.function_bodies.iter() {
        context.func = func.clone();

        let func_index = num_func_imports + def_index.index();
        if flag_check_translation {
            if let Err(errors) = context.verify(fisa) {
                return Err(pretty_verifier_error(&context.func, fisa.isa, None, errors));
            }
        } else {
            let compiled_size = context
                .compile(isa)
                .map_err(|err| pretty_error(&context.func, fisa.isa, err))?;
            if flag_print_size {
                println!(
                    "Function #{} code size: {} bytes",
                    func_index, compiled_size
                );
                total_module_code_size += compiled_size;
                println!(
                    "Function #{} bytecode size: {} bytes",
                    func_index,
                    dummy_environ.func_bytecode_sizes[def_index.index()]
                );
            }
        }

        if flag_print {
            vprintln!(flag_verbose, "");
            if let Some(start_func) = dummy_environ.info.start_func {
                if func_index == start_func.index() {
                    println!("; Selected as wasm start function");
                }
            }
            for export_name in
                &dummy_environ.info.functions[FuncIndex::new(func_index)].export_names
            {
                println!("; Exported as \"{}\"", export_name);
            }
            println!("{}", context.func.display(fisa.isa));
            vprintln!(flag_verbose, "");
        }

        context.clear();
    }

    if !flag_check_translation && flag_print_size {
        println!("Total module code size: {} bytes", total_module_code_size);
        let total_bytecode_size: usize = dummy_environ.func_bytecode_sizes.iter().sum();
        println!("Total module bytecode size: {} bytes", total_bytecode_size);
    }

    if flag_report_times {
        println!("{}", timing::take_current());
    }

    let _ = terminal.fg(term::color::GREEN);
    vprintln!(flag_verbose, "ok");
    let _ = terminal.reset();
    Ok(())
}
<|endoftext|>


<commit_before>/*
fdct is a Rust translation of jfdctint.c from the
Independent JPEG Group's libjpeg version 9a
obtained from http://www.ijg.org/files/jpegsr9a.zip
It comes with the following conditions of distribution and use:

	In plain English:

	1. We don't promise that this software works.  (But if you find any bugs,
		please let us know!)
	2. You can use this software for whatever you want.  You don't have to pay us.
	3. You may not pretend that you wrote this software.  If you use it in a
	   program, you must acknowledge somewhere in your documentation that
	   you've used the IJG code.

	In legalese:

	The authors make NO WARRANTY or representation, either express or implied,
	with respect to this software, its quality, accuracy, merchantability, or
	fitness for a particular purpose.  This software is provided "AS IS", and you,
	its user, assume the entire risk as to its quality and accuracy.

	This software is copyright (C) 1991-2014, Thomas G. Lane, Guido Vollbeding.
	All Rights Reserved except as specified below.

	Permission is hereby granted to use, copy, modify, and distribute this
	software (or portions thereof) for any purpose, without fee, subject to these
	conditions:
	(1) If any part of the source code for this software is distributed, then this
	README file must be included, with this copyright and no-warranty notice
	unaltered; and any additions, deletions, or changes to the original files
	must be clearly indicated in accompanying documentation.
	(2) If only executable code is distributed, then the accompanying
	documentation must state that "this software is based in part on the work of
	the Independent JPEG Group".
	(3) Permission for use of this software is granted only if the user accepts
	full responsibility for any undesirable consequences; the authors accept
	NO LIABILITY for damages of any kind.

	These conditions apply to any software derived from or based on the IJG code,
	not just to the unmodified library.  If you use our work, you ought to
	acknowledge us.

	Permission is NOT granted for the use of any IJG author's name or company name
	in advertising or publicity relating to this software or products derived from
	it.  This software may be referred to only as "the Independent JPEG Group's
	software".

	We specifically permit and encourage the use of this software as the basis of
	commercial products, provided that all warranty or liability claims are
	assumed by the product vendor.
*/

static CONST_BITS: i32 = 13;
static PASS1_BITS: i32 = 2;

static FIX_0_298631336: i32 = 2446;
static FIX_0_390180644: i32 = 3196;
static FIX_0_541196100: i32 = 4433;
static FIX_0_765366865: i32 = 6270;
static FIX_0_899976223: i32 = 7373;
static FIX_1_175875602: i32 = 9633;
static FIX_1_501321110: i32 = 12_299;
static FIX_1_847759065: i32 = 15_137;
static FIX_1_961570560: i32 = 16_069;
static FIX_2_053119869: i32 = 16_819;
static FIX_2_562915447: i32 = 20_995;
static FIX_3_072711026: i32 = 25_172;

pub(crate) fn fdct(samples: &[u8], coeffs: &mut [i32]) {
    // Pass 1: process rows.
    // Results are scaled by sqrt(8) compared to a true DCT
    // furthermore we scale the results by 2**PASS1_BITS
    for y in 0usize..8 {
        let y0 = y * 8;

        // Even part
        let t0 = i32::from(samples[y0]) + i32::from(samples[y0 + 7]);
        let t1 = i32::from(samples[y0 + 1]) + i32::from(samples[y0 + 6]);
        let t2 = i32::from(samples[y0 + 2]) + i32::from(samples[y0 + 5]);
        let t3 = i32::from(samples[y0 + 3]) + i32::from(samples[y0 + 4]);

        let t10 = t0 + t3;
        let t12 = t0 - t3;
        let t11 = t1 + t2;
        let t13 = t1 - t2;

        let t0 = i32::from(samples[y0]) - i32::from(samples[y0 + 7]);
        let t1 = i32::from(samples[y0 + 1]) - i32::from(samples[y0 + 6]);
        let t2 = i32::from(samples[y0 + 2]) - i32::from(samples[y0 + 5]);
        let t3 = i32::from(samples[y0 + 3]) - i32::from(samples[y0 + 4]);

        // Apply unsigned -> signed conversion
        coeffs[y0] = (t10 + t11 - 8 * 128) << PASS1_BITS as usize;
        coeffs[y0 + 4] = (t10 - t11) << PASS1_BITS as usize;

        let mut z1 = (t12 + t13) * FIX_0_541196100;
        // Add fudge factor here for final descale
        z1 += 1 << (CONST_BITS - PASS1_BITS - 1) as usize;

        coeffs[y0 + 2] = (z1 + t12 * FIX_0_765366865) >> (CONST_BITS - PASS1_BITS) as usize;
        coeffs[y0 + 6] = (z1 - t13 * FIX_1_847759065) >> (CONST_BITS - PASS1_BITS) as usize;

        // Odd part
        let t12 = t0 + t2;
        let t13 = t1 + t3;

        let mut z1 = (t12 + t13) * FIX_1_175875602;
        // Add fudge factor here for final descale
        z1 += 1 << (CONST_BITS - PASS1_BITS - 1) as usize;

        let mut t12 = t12 * (-FIX_0_390180644);
        let mut t13 = t13 * (-FIX_1_961570560);
        t12 += z1;
        t13 += z1;

        let z1 = (t0 + t3) * (-FIX_0_899976223);
        let mut t0 = t0 * FIX_1_501321110;
        let mut t3 = t3 * FIX_0_298631336;
        t0 += z1 + t12;
        t3 += z1 + t13;

        let z1 = (t1 + t2) * (-FIX_2_562915447);
        let mut t1 = t1 * FIX_3_072711026;
        let mut t2 = t2 * FIX_2_053119869;
        t1 += z1 + t13;
        t2 += z1 + t12;

        coeffs[y0 + 1] = t0 >> (CONST_BITS - PASS1_BITS) as usize;
        coeffs[y0 + 3] = t1 >> (CONST_BITS - PASS1_BITS) as usize;
        coeffs[y0 + 5] = t2 >> (CONST_BITS - PASS1_BITS) as usize;
        coeffs[y0 + 7] = t3 >> (CONST_BITS - PASS1_BITS) as usize;
    }

    // Pass 2: process columns
    // We remove the PASS1_BITS scaling but leave the results scaled up an
    // overall factor of 8
    for x in (0usize..8).rev() {
        // Even part
        let t0 = coeffs[x] + coeffs[x + 8 * 7];
        let t1 = coeffs[x + 8] + coeffs[x + 8 * 6];
        let t2 = coeffs[x + 8 * 2] + coeffs[x + 8 * 5];
        let t3 = coeffs[x + 8 * 3] + coeffs[x + 8 * 4];

        // Add fudge factor here for final descale
        let t10 = t0 + t3 + (1 << (PASS1_BITS - 1) as usize);
        let t12 = t0 - t3;
        let t11 = t1 + t2;
        let t13 = t1 - t2;

        let t0 = coeffs[x] - coeffs[x + 8 * 7];
        let t1 = coeffs[x + 8] - coeffs[x + 8 * 6];
        let t2 = coeffs[x + 8 * 2] - coeffs[x + 8 * 5];
        let t3 = coeffs[x + 8 * 3] - coeffs[x + 8 * 4];

        coeffs[x] = (t10 + t11) >> PASS1_BITS as usize;
        coeffs[x + 8 * 4] = (t10 - t11) >> PASS1_BITS as usize;

        let mut z1 = (t12 + t13) * FIX_0_541196100;
        // Add fudge factor here for final descale
        z1 += 1 << (CONST_BITS + PASS1_BITS - 1) as usize;

        coeffs[x + 8 * 2] = (z1 + t12 * FIX_0_765366865) >> (CONST_BITS + PASS1_BITS) as usize;
        coeffs[x + 8 * 6] = (z1 - t13 * FIX_1_847759065) >> (CONST_BITS + PASS1_BITS) as usize;

        // Odd part
        let t12 = t0 + t2;
        let t13 = t1 + t3;

        let mut z1 = (t12 + t13) * FIX_1_175875602;
        // Add fudge factor here for final descale
        z1 += 1 << (CONST_BITS - PASS1_BITS - 1) as usize;

        let mut t12 = t12 * (-FIX_0_390180644);
        let mut t13 = t13 * (-FIX_1_961570560);
        t12 += z1;
        t13 += z1;

        let z1 = (t0 + t3) * (-FIX_0_899976223);
        let mut t0 = t0 * FIX_1_501321110;
        let mut t3 = t3 * FIX_0_298631336;
        t0 += z1 + t12;
        t3 += z1 + t13;

        let z1 = (t1 + t2) * (-FIX_2_562915447);
        let mut t1 = t1 * FIX_3_072711026;
        let mut t2 = t2 * FIX_2_053119869;
        t1 += z1 + t13;
        t2 += z1 + t12;

        coeffs[x + 8] = t0 >> (CONST_BITS + PASS1_BITS) as usize;
        coeffs[x + 8 * 3] = t1 >> (CONST_BITS + PASS1_BITS) as usize;
        coeffs[x + 8 * 5] = t2 >> (CONST_BITS + PASS1_BITS) as usize;
        coeffs[x + 8 * 7] = t3 >> (CONST_BITS + PASS1_BITS) as usize;
    }
}
<commit_msg>Specify size of fdct input to enable SIMD and bound elision<commit_after>/*
fdct is a Rust translation of jfdctint.c from the
Independent JPEG Group's libjpeg version 9a
obtained from http://www.ijg.org/files/jpegsr9a.zip
It comes with the following conditions of distribution and use:

	In plain English:

	1. We don't promise that this software works.  (But if you find any bugs,
		please let us know!)
	2. You can use this software for whatever you want.  You don't have to pay us.
	3. You may not pretend that you wrote this software.  If you use it in a
	   program, you must acknowledge somewhere in your documentation that
	   you've used the IJG code.

	In legalese:

	The authors make NO WARRANTY or representation, either express or implied,
	with respect to this software, its quality, accuracy, merchantability, or
	fitness for a particular purpose.  This software is provided "AS IS", and you,
	its user, assume the entire risk as to its quality and accuracy.

	This software is copyright (C) 1991-2014, Thomas G. Lane, Guido Vollbeding.
	All Rights Reserved except as specified below.

	Permission is hereby granted to use, copy, modify, and distribute this
	software (or portions thereof) for any purpose, without fee, subject to these
	conditions:
	(1) If any part of the source code for this software is distributed, then this
	README file must be included, with this copyright and no-warranty notice
	unaltered; and any additions, deletions, or changes to the original files
	must be clearly indicated in accompanying documentation.
	(2) If only executable code is distributed, then the accompanying
	documentation must state that "this software is based in part on the work of
	the Independent JPEG Group".
	(3) Permission for use of this software is granted only if the user accepts
	full responsibility for any undesirable consequences; the authors accept
	NO LIABILITY for damages of any kind.

	These conditions apply to any software derived from or based on the IJG code,
	not just to the unmodified library.  If you use our work, you ought to
	acknowledge us.

	Permission is NOT granted for the use of any IJG author's name or company name
	in advertising or publicity relating to this software or products derived from
	it.  This software may be referred to only as "the Independent JPEG Group's
	software".

	We specifically permit and encourage the use of this software as the basis of
	commercial products, provided that all warranty or liability claims are
	assumed by the product vendor.
*/

static CONST_BITS: i32 = 13;
static PASS1_BITS: i32 = 2;

static FIX_0_298631336: i32 = 2446;
static FIX_0_390180644: i32 = 3196;
static FIX_0_541196100: i32 = 4433;
static FIX_0_765366865: i32 = 6270;
static FIX_0_899976223: i32 = 7373;
static FIX_1_175875602: i32 = 9633;
static FIX_1_501321110: i32 = 12_299;
static FIX_1_847759065: i32 = 15_137;
static FIX_1_961570560: i32 = 16_069;
static FIX_2_053119869: i32 = 16_819;
static FIX_2_562915447: i32 = 20_995;
static FIX_3_072711026: i32 = 25_172;

pub(crate) fn fdct(samples: &[u8; 64], coeffs: &mut [i32; 64]) {
    // Pass 1: process rows.
    // Results are scaled by sqrt(8) compared to a true DCT
    // furthermore we scale the results by 2**PASS1_BITS
    for y in 0usize..8 {
        let y0 = y * 8;

        // Even part
        let t0 = i32::from(samples[y0]) + i32::from(samples[y0 + 7]);
        let t1 = i32::from(samples[y0 + 1]) + i32::from(samples[y0 + 6]);
        let t2 = i32::from(samples[y0 + 2]) + i32::from(samples[y0 + 5]);
        let t3 = i32::from(samples[y0 + 3]) + i32::from(samples[y0 + 4]);

        let t10 = t0 + t3;
        let t12 = t0 - t3;
        let t11 = t1 + t2;
        let t13 = t1 - t2;

        let t0 = i32::from(samples[y0]) - i32::from(samples[y0 + 7]);
        let t1 = i32::from(samples[y0 + 1]) - i32::from(samples[y0 + 6]);
        let t2 = i32::from(samples[y0 + 2]) - i32::from(samples[y0 + 5]);
        let t3 = i32::from(samples[y0 + 3]) - i32::from(samples[y0 + 4]);

        // Apply unsigned -> signed conversion
        coeffs[y0] = (t10 + t11 - 8 * 128) << PASS1_BITS as usize;
        coeffs[y0 + 4] = (t10 - t11) << PASS1_BITS as usize;

        let mut z1 = (t12 + t13) * FIX_0_541196100;
        // Add fudge factor here for final descale
        z1 += 1 << (CONST_BITS - PASS1_BITS - 1) as usize;

        coeffs[y0 + 2] = (z1 + t12 * FIX_0_765366865) >> (CONST_BITS - PASS1_BITS) as usize;
        coeffs[y0 + 6] = (z1 - t13 * FIX_1_847759065) >> (CONST_BITS - PASS1_BITS) as usize;

        // Odd part
        let t12 = t0 + t2;
        let t13 = t1 + t3;

        let mut z1 = (t12 + t13) * FIX_1_175875602;
        // Add fudge factor here for final descale
        z1 += 1 << (CONST_BITS - PASS1_BITS - 1) as usize;

        let mut t12 = t12 * (-FIX_0_390180644);
        let mut t13 = t13 * (-FIX_1_961570560);
        t12 += z1;
        t13 += z1;

        let z1 = (t0 + t3) * (-FIX_0_899976223);
        let mut t0 = t0 * FIX_1_501321110;
        let mut t3 = t3 * FIX_0_298631336;
        t0 += z1 + t12;
        t3 += z1 + t13;

        let z1 = (t1 + t2) * (-FIX_2_562915447);
        let mut t1 = t1 * FIX_3_072711026;
        let mut t2 = t2 * FIX_2_053119869;
        t1 += z1 + t13;
        t2 += z1 + t12;

        coeffs[y0 + 1] = t0 >> (CONST_BITS - PASS1_BITS) as usize;
        coeffs[y0 + 3] = t1 >> (CONST_BITS - PASS1_BITS) as usize;
        coeffs[y0 + 5] = t2 >> (CONST_BITS - PASS1_BITS) as usize;
        coeffs[y0 + 7] = t3 >> (CONST_BITS - PASS1_BITS) as usize;
    }

    // Pass 2: process columns
    // We remove the PASS1_BITS scaling but leave the results scaled up an
    // overall factor of 8
    for x in (0usize..8).rev() {
        // Even part
        let t0 = coeffs[x] + coeffs[x + 8 * 7];
        let t1 = coeffs[x + 8] + coeffs[x + 8 * 6];
        let t2 = coeffs[x + 8 * 2] + coeffs[x + 8 * 5];
        let t3 = coeffs[x + 8 * 3] + coeffs[x + 8 * 4];

        // Add fudge factor here for final descale
        let t10 = t0 + t3 + (1 << (PASS1_BITS - 1) as usize);
        let t12 = t0 - t3;
        let t11 = t1 + t2;
        let t13 = t1 - t2;

        let t0 = coeffs[x] - coeffs[x + 8 * 7];
        let t1 = coeffs[x + 8] - coeffs[x + 8 * 6];
        let t2 = coeffs[x + 8 * 2] - coeffs[x + 8 * 5];
        let t3 = coeffs[x + 8 * 3] - coeffs[x + 8 * 4];

        coeffs[x] = (t10 + t11) >> PASS1_BITS as usize;
        coeffs[x + 8 * 4] = (t10 - t11) >> PASS1_BITS as usize;

        let mut z1 = (t12 + t13) * FIX_0_541196100;
        // Add fudge factor here for final descale
        z1 += 1 << (CONST_BITS + PASS1_BITS - 1) as usize;

        coeffs[x + 8 * 2] = (z1 + t12 * FIX_0_765366865) >> (CONST_BITS + PASS1_BITS) as usize;
        coeffs[x + 8 * 6] = (z1 - t13 * FIX_1_847759065) >> (CONST_BITS + PASS1_BITS) as usize;

        // Odd part
        let t12 = t0 + t2;
        let t13 = t1 + t3;

        let mut z1 = (t12 + t13) * FIX_1_175875602;
        // Add fudge factor here for final descale
        z1 += 1 << (CONST_BITS - PASS1_BITS - 1) as usize;

        let mut t12 = t12 * (-FIX_0_390180644);
        let mut t13 = t13 * (-FIX_1_961570560);
        t12 += z1;
        t13 += z1;

        let z1 = (t0 + t3) * (-FIX_0_899976223);
        let mut t0 = t0 * FIX_1_501321110;
        let mut t3 = t3 * FIX_0_298631336;
        t0 += z1 + t12;
        t3 += z1 + t13;

        let z1 = (t1 + t2) * (-FIX_2_562915447);
        let mut t1 = t1 * FIX_3_072711026;
        let mut t2 = t2 * FIX_2_053119869;
        t1 += z1 + t13;
        t2 += z1 + t12;

        coeffs[x + 8] = t0 >> (CONST_BITS + PASS1_BITS) as usize;
        coeffs[x + 8 * 3] = t1 >> (CONST_BITS + PASS1_BITS) as usize;
        coeffs[x + 8 * 5] = t2 >> (CONST_BITS + PASS1_BITS) as usize;
        coeffs[x + 8 * 7] = t3 >> (CONST_BITS + PASS1_BITS) as usize;
    }
}
<|endoftext|>


<commit_before>use super::{read_uint, write_uint, ByMode, BySpeed, GameId, Mode, Speed};
use byteorder::{ReadBytesExt as _, WriteBytesExt as _};
use std::io::{self, Read, Write};

#[derive(Debug, Eq, PartialEq)]
struct Header {
    mode: Mode,
    speed: Speed,
    games: u8, // up to 15
}

impl Header {
    pub fn read<R: Read>(reader: &mut R) -> io::Result<Header> {
        let n = reader.read_u8()?;
        Ok(Header {
            mode: Mode::from_rated(n & 1 == 1),
            speed: match (n >> 1) & 7 {
                0 => Speed::Ultrabullet,
                1 => Speed::Bullet,
                2 => Speed::Blitz,
                3 => Speed::Rapid,
                4 => Speed::Classical,
                5 => Speed::Correspondence,
                _ => return Err(io::ErrorKind::InvalidData.into()),
            },
            games: n >> 4,
        })
    }

    pub fn write<W: Write>(&self, writer: &mut W) -> io::Result<()> {
        writer.write_u8(
            (if self.mode.is_rated() { 1 } else { 0 })
                | (match self.speed {
                    Speed::Ultrabullet => 0,
                    Speed::Bullet => 1,
                    Speed::Blitz => 2,
                    Speed::Rapid => 3,
                    Speed::Classical => 4,
                    Speed::Correspondence => 5,
                } << 1)
                | (self.games << 4),
        )
    }
}

#[derive(Debug)]
struct Stats {
    white: u64,
    draw: u64,
    black: u64,
}

impl Stats {
    pub fn read<R: Read>(reader: &mut R) -> io::Result<Stats> {
        Ok(Stats {
            white: read_uint(reader)?,
            draw: read_uint(reader)?,
            black: read_uint(reader)?,
        })
    }

    pub fn write<W: Write>(&self, writer: &mut W) -> io::Result<()> {
        write_uint(writer, self.white)?;
        write_uint(writer, self.draw)?;
        write_uint(writer, self.black)
    }
}

type Group = BySpeed<ByMode<(Stats, Vec<(u8, GameId)>)>>;

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

    #[test]
    fn test_header_roundtrip() {
        let header = Header {
            mode: Mode::Rated,
            speed: Speed::Correspondence,
            games: 15,
        };

        let mut writer = Cursor::new(Vec::new());
        header.write(&mut writer).unwrap();

        let mut reader = Cursor::new(writer.into_inner());
        assert_eq!(Header::read(&mut reader).unwrap(), header);
    }
}
<commit_msg>code golf boolean to u8<commit_after>use super::{read_uint, write_uint, ByMode, BySpeed, GameId, Mode, Speed};
use byteorder::{ReadBytesExt as _, WriteBytesExt as _};
use std::io::{self, Read, Write};

#[derive(Debug, Eq, PartialEq)]
struct Header {
    mode: Mode,
    speed: Speed,
    games: u8, // up to 15
}

impl Header {
    pub fn read<R: Read>(reader: &mut R) -> io::Result<Header> {
        let n = reader.read_u8()?;
        Ok(Header {
            mode: Mode::from_rated(n & 1 == 1),
            speed: match (n >> 1) & 7 {
                0 => Speed::Ultrabullet,
                1 => Speed::Bullet,
                2 => Speed::Blitz,
                3 => Speed::Rapid,
                4 => Speed::Classical,
                5 => Speed::Correspondence,
                _ => return Err(io::ErrorKind::InvalidData.into()),
            },
            games: n >> 4,
        })
    }

    pub fn write<W: Write>(&self, writer: &mut W) -> io::Result<()> {
        writer.write_u8(
            self.mode.is_rated() as u8
                | (match self.speed {
                    Speed::Ultrabullet => 0,
                    Speed::Bullet => 1,
                    Speed::Blitz => 2,
                    Speed::Rapid => 3,
                    Speed::Classical => 4,
                    Speed::Correspondence => 5,
                } << 1)
                | (self.games << 4),
        )
    }
}

#[derive(Debug)]
struct Stats {
    white: u64,
    draw: u64,
    black: u64,
}

impl Stats {
    pub fn read<R: Read>(reader: &mut R) -> io::Result<Stats> {
        Ok(Stats {
            white: read_uint(reader)?,
            draw: read_uint(reader)?,
            black: read_uint(reader)?,
        })
    }

    pub fn write<W: Write>(&self, writer: &mut W) -> io::Result<()> {
        write_uint(writer, self.white)?;
        write_uint(writer, self.draw)?;
        write_uint(writer, self.black)
    }
}

type Group = BySpeed<ByMode<(Stats, Vec<(u8, GameId)>)>>;

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

    #[test]
    fn test_header_roundtrip() {
        let header = Header {
            mode: Mode::Rated,
            speed: Speed::Correspondence,
            games: 15,
        };

        let mut writer = Cursor::new(Vec::new());
        header.write(&mut writer).unwrap();

        let mut reader = Cursor::new(writer.into_inner());
        assert_eq!(Header::read(&mut reader).unwrap(), header);
    }
}
<|endoftext|>


<commit_before>// Copyright © 2016, Canal TP and/or its affiliates. All rights reserved.
//
// This file is part of Navitia,
//     the software to build cool stuff with public transport.
//
// Hope you'll enjoy and contribute to this project,
//     powered by Canal TP (www.canaltp.fr).
// Help us simplify mobility and open public transport:
//     a non ending quest to the responsive locomotion way of traveling!
//
// LICENCE: This program is free software; you can redistribute it
// and/or modify it under the terms of the GNU Affero General Public
// License as published by the Free Software Foundation, either
// version 3 of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public
// License along with this program. If not, see
// <http://www.gnu.org/licenses/>.
//
// Stay tuned using
// twitter @navitia
// IRC #navitia on freenode
// https://groups.google.com/d/forum/navitia
// www.navitia.io

extern crate mimir;
extern crate osmpbfreader;

use ::admin_geofinder::AdminGeoFinder;
use ::boundaries::{build_boundary, make_centroid};
use std::collections::{BTreeSet, BTreeMap};
use super::utils::*;
use super::OsmPbfReader;

pub type PoiTypes = BTreeMap<String, BTreeSet<String>>;
pub type PoisVec = Vec<mimir::Poi>;

#[derive(Debug)]
struct PoiMatcher {
    poi_types: PoiTypes,
}

impl PoiMatcher {
    pub fn new(types: PoiTypes) -> PoiMatcher {
        PoiMatcher { poi_types: types }
    }

    pub fn is_poi(&self, obj: &osmpbfreader::OsmObj) -> bool {
        self.poi_types.iter().any(|(poi_tag, poi_types)| {
            obj.tags().get(poi_tag).map_or(false, |poi_type| poi_types.contains(poi_type))
        })
    }
}

pub fn default_amenity_types() -> BTreeSet<String> {
    ["university",
     "hospital",
     "post_office",
     "bicycle_rental",
     "bicycle_parking",
     "parking",
     "police",
     "townhall"]
        .iter()
        .map(|&k| k.to_string())
        .collect()
}

pub fn default_leisure_types() -> BTreeSet<String> {
    ["garden", "park"]
        .iter()
        .map(|&k| k.to_string())
        .collect()
}

fn parse_poi(osmobj: &osmpbfreader::OsmObj,
             obj_map: &BTreeMap<osmpbfreader::OsmId, osmpbfreader::OsmObj>,
             admins_geofinder: &AdminGeoFinder,
             city_level: u32)
             -> Option<mimir::Poi> {
    let (id, coord) = match *osmobj {
        osmpbfreader::OsmObj::Node(ref node) => {
            (format_poi_id("node", node.id), mimir::Coord::new(node.lat, node.lon))
        }
        osmpbfreader::OsmObj::Way(ref way) => {
            (format_poi_id("way", way.id), get_way_coord(obj_map, way))
        }
        osmpbfreader::OsmObj::Relation(ref relation) => {
            (format_poi_id("relation", relation.id),
             make_centroid(&build_boundary(&relation, &obj_map)))
        }
    };

    let name = osmobj.tags().get("name").map_or("", |name| name);

    if coord.is_default() {
        info!("The poi {} is rejected, cause: without coordinates.", id);
        return None;
    }

    if name == "" {
        info!("The poi {} is rejected, cause: without name.", id);
        return None;
    }

    let adms = admins_geofinder.get(&coord);
    let zip_codes = match osmobj.tags().get("addr:postcode") {
        Some(val) if !val.is_empty() => vec![val.clone()],
        _ => get_zip_codes_from_admins(&adms),
    };
    Some(mimir::Poi {
        id: id,
        name: name.to_string(),
        label: format_label(&adms, city_level, name),
        coord: coord,
        zip_codes: zip_codes,
        administrative_regions: adms,
        weight: 1,
    })
}

fn format_poi_id(_type: &str, id: i64) -> String {
    format!("poi:osm:{}:{}", _type, id)
}

pub fn pois(pbf: &mut OsmPbfReader,
            poi_types: PoiTypes,
            admins_geofinder: &AdminGeoFinder,
            city_level: u32)
            -> PoisVec {
    let matcher = PoiMatcher::new(poi_types);
    let objects = osmpbfreader::get_objs_and_deps(pbf, |o| matcher.is_poi(o)).unwrap();
    objects.iter()
    	.filter_map(|(_, obj)| {
    	        if matcher.is_poi(&obj) {
    	        	parse_poi(obj, &objects, admins_geofinder, city_level)
    	        } else {
    	            None
    	        }
    	})
    	.collect()
}

pub fn compute_poi_weight(pois_vec: &mut PoisVec, city_level: u32) {
    for poi in pois_vec {
        for admin in &mut poi.administrative_regions {
            if admin.level == city_level {
                poi.weight = admin.weight.get();
                break;
            }
        }
    }
}
<commit_msg>refactoring<commit_after>// Copyright © 2016, Canal TP and/or its affiliates. All rights reserved.
//
// This file is part of Navitia,
//     the software to build cool stuff with public transport.
//
// Hope you'll enjoy and contribute to this project,
//     powered by Canal TP (www.canaltp.fr).
// Help us simplify mobility and open public transport:
//     a non ending quest to the responsive locomotion way of traveling!
//
// LICENCE: This program is free software; you can redistribute it
// and/or modify it under the terms of the GNU Affero General Public
// License as published by the Free Software Foundation, either
// version 3 of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public
// License along with this program. If not, see
// <http://www.gnu.org/licenses/>.
//
// Stay tuned using
// twitter @navitia
// IRC #navitia on freenode
// https://groups.google.com/d/forum/navitia
// www.navitia.io

extern crate mimir;
extern crate osmpbfreader;

use ::admin_geofinder::AdminGeoFinder;
use ::boundaries::{build_boundary, make_centroid};
use std::collections::{BTreeSet, BTreeMap};
use super::utils::*;
use super::OsmPbfReader;

pub type PoiTypes = BTreeMap<String, BTreeSet<String>>;
pub type PoisVec = Vec<mimir::Poi>;

#[derive(Debug)]
struct PoiMatcher {
    poi_types: PoiTypes,
}

impl PoiMatcher {
    pub fn new(types: PoiTypes) -> PoiMatcher {
        PoiMatcher { poi_types: types }
    }

    pub fn is_poi(&self, obj: &osmpbfreader::OsmObj) -> bool {
        self.poi_types.iter().any(|(poi_tag, poi_types)| {
            obj.tags().get(poi_tag).map_or(false, |poi_type| poi_types.contains(poi_type))
        })
    }
}

pub fn default_amenity_types() -> BTreeSet<String> {
    ["university",
     "hospital",
     "post_office",
     "bicycle_rental",
     "bicycle_parking",
     "parking",
     "police",
     "townhall"]
        .iter()
        .map(|&k| k.to_string())
        .collect()
}

pub fn default_leisure_types() -> BTreeSet<String> {
    ["garden", "park"]
        .iter()
        .map(|&k| k.to_string())
        .collect()
}

fn parse_poi(osmobj: &osmpbfreader::OsmObj,
             obj_map: &BTreeMap<osmpbfreader::OsmId, osmpbfreader::OsmObj>,
             admins_geofinder: &AdminGeoFinder,
             city_level: u32)
             -> Option<mimir::Poi> {
    let (id, coord) = match *osmobj {
        osmpbfreader::OsmObj::Node(ref node) => {
            (format_poi_id("node", node.id), mimir::Coord::new(node.lat, node.lon))
        }
        osmpbfreader::OsmObj::Way(ref way) => {
            (format_poi_id("way", way.id), get_way_coord(obj_map, way))
        }
        osmpbfreader::OsmObj::Relation(ref relation) => {
            (format_poi_id("relation", relation.id),
             make_centroid(&build_boundary(&relation, &obj_map)))
        }
    };

    let name = osmobj.tags().get("name").map_or("", |name| name);

    if coord.is_default() {
        info!("The poi {} is rejected, cause: without coordinates.", id);
        return None;
    }

    if name == "" {
        info!("The poi {} is rejected, cause: without name.", id);
        return None;
    }

    let adms = admins_geofinder.get(&coord);
    let zip_codes = match osmobj.tags().get("addr:postcode") {
        Some(val) if !val.is_empty() => vec![val.clone()],
        _ => get_zip_codes_from_admins(&adms),
    };
    Some(mimir::Poi {
        id: id,
        name: name.to_string(),
        label: format_label(&adms, city_level, name),
        coord: coord,
        zip_codes: zip_codes,
        administrative_regions: adms,
        weight: 1,
    })
}

fn format_poi_id(_type: &str, id: i64) -> String {
    format!("poi:osm:{}:{}", _type, id)
}

pub fn pois(pbf: &mut OsmPbfReader,
            poi_types: PoiTypes,
            admins_geofinder: &AdminGeoFinder,
            city_level: u32)
            -> PoisVec {
    let matcher = PoiMatcher::new(poi_types);
    let objects = osmpbfreader::get_objs_and_deps(pbf, |o| matcher.is_poi(o)).unwrap();
    objects.iter()
    	.filter(|&(_, obj)| matcher.is_poi(&obj))
    	.filter_map(|(_, obj)| parse_poi(obj, &objects, admins_geofinder, city_level))
    	.collect()
}

pub fn compute_poi_weight(pois_vec: &mut PoisVec, city_level: u32) {
    for poi in pois_vec {
        for admin in &mut poi.administrative_regions {
            if admin.level == city_level {
                poi.weight = admin.weight.get();
                break;
            }
        }
    }
}
<|endoftext|>


<commit_before>//! Types used in the registry.

use std::fmt::{Debug, Display, Formatter};

use std::sync::Arc;
use rustc_serialize::{Encodable, Decodable};
use rustc_serialize::json::{Json, ToJson};

/// How much access things have
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum RegistryAccess {
    Public,
    Lua,
    Private
}

/// Values stored in the registry
pub struct RegistryValue {
    access: RegistryAccess,
    object: Arc<Json>
}

//#[derive(RustcSeralizeable)]
struct Point {
    x: u32,
    y: u32
}

impl RegistryValue {

    pub fn new<T>(access: RegistryAccess, data: T) -> RegistryValue
        where T: ToJson  {
        RegistryValue {
            access: access,
            object: Arc::new(data.to_json())
        }
    }

    /// What access the module has to it
    pub fn access(&self) -> RegistryAccess {
        self.access
    }

    /// Gets the json of a registry value
    pub fn get_json(&self) -> Arc<Json> {
        self.object.clone()
    }
}
<commit_msg>Add derive debug to RegistryValue<commit_after>//! Types used in the registry.

use std::fmt::{Debug, Display, Formatter};

use std::sync::Arc;
use rustc_serialize::{Encodable, Decodable};
use rustc_serialize::json::{Json, ToJson};

/// How much access things have
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum RegistryAccess {
    Public,
    Lua,
    Private
}

/// Values stored in the registry
#[derive(Debug)]
pub struct RegistryValue {
    access: RegistryAccess,
    object: Arc<Json>
}

impl RegistryValue {
    /// Creates a new RegistryValue
    pub fn new<T>(access: RegistryAccess, data: T) -> RegistryValue
        where T: ToJson  {
        RegistryValue {
            access: access,
            object: Arc::new(data.to_json())
        }
    }

    /// What access the module has to it
    pub fn access(&self) -> RegistryAccess {
        self.access
    }

    /// Gets the json of a registry value
    pub fn get_json(&self) -> Arc<Json> {
        self.object.clone()
    }
}
<|endoftext|>


<commit_before>use tensor::Tensor;
use num::traits::cast;
use Numeric;

impl<T: Numeric> Tensor<T> {
    /// Returns a new tensor with the elements converted to the selected type.
    ///
    /// ```
    /// use numeric::Tensor;
    ///
    /// let tdouble = Tensor::new(vec![1.0f64, 2.0, 3.0]);
    /// let tsingle = tdouble.convert::<f32>();
    /// ```
    pub fn convert<D: Numeric>(&self) -> Tensor<D> {
        let mut t = Tensor::zeros(&self.shape);
        for i in 0..self.size() {
            t[i] = cast(self[i]).unwrap();
        }
        t
    }

    /// Short-hand for `convert::<f32>()`.
    pub fn to_f32(&self) -> Tensor<f32> {
        self.convert::<f32>()
    }

    /// Short-hand for `convert::<f64>()`.
    pub fn to_f65(&self) -> Tensor<f64> {
        self.convert::<f64>()
    }
}
<commit_msg>Function to_f64 accidentally called to_f65<commit_after>use tensor::Tensor;
use num::traits::cast;
use Numeric;

impl<T: Numeric> Tensor<T> {
    /// Returns a new tensor with the elements converted to the selected type.
    ///
    /// ```
    /// use numeric::Tensor;
    ///
    /// let tdouble = Tensor::new(vec![1.0f64, 2.0, 3.0]);
    /// let tsingle = tdouble.convert::<f32>();
    /// ```
    pub fn convert<D: Numeric>(&self) -> Tensor<D> {
        let mut t = Tensor::zeros(&self.shape);
        for i in 0..self.size() {
            t[i] = cast(self[i]).unwrap();
        }
        t
    }

    /// Short-hand for `convert::<f32>()`.
    pub fn to_f32(&self) -> Tensor<f32> {
        self.convert::<f32>()
    }

    /// Short-hand for `convert::<f64>()`.
    pub fn to_f64(&self) -> Tensor<f64> {
        self.convert::<f64>()
    }
}
<|endoftext|>


<commit_before>use std::io::{self, Write};
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};

pub fn heading(content: &str) {
    let mut stdout = StandardStream::stdout(ColorChoice::Always);

    match stdout.set_color(ColorSpec::new().set_fg(Some(Color::Cyan))) {
        Ok(_) => (),
        Err(error) => panic!("There was a problem: {:?}", error),
    }

    match writeln!(&mut stdout, "\n{}\n{}", content, underline(content, "=")) {
        Ok(_) => (),
        Err(error) => panic!("There was a problem: {:?}", error),
    }

    match stdout.reset() {
        Ok(_) => (),
        Err(error) => panic!("There was a problem: {:?}", error),
    }
}

pub fn subheading(content: &str) {
    let mut stdout = StandardStream::stdout(ColorChoice::Always);

    match stdout.set_color(ColorSpec::new().set_fg(Some(Color::Cyan))) {
        Ok(_) => (),
        Err(error) => panic!("There was a problem: {:?}", error),
    }

    match writeln!(&mut stdout, "\n{}\n{}", content, underline(content, "-")) {
        Ok(_) => (),
        Err(error) => panic!("There was a problem: {:?}", error),
    }

    match stdout.reset() {
        Ok(_) => (),
        Err(error) => panic!("There was a problem: {:?}", error),
    }
}

pub fn progress(content: String) {
    let mut stdout = io::stdout();

    match writeln!(&mut stdout, "\n{}", content) {
        Ok(_) => (),
        Err(error) => panic!("There was a problem: {:?}", error),
    }
}

pub fn info(content: String) {
    let mut stdout = io::stdout();

    match writeln!(&mut stdout, "\n{}", content) {
        Ok(_) => (),
        Err(error) => panic!("There was a problem: {:?}", error),
    }
}

pub fn error(content: String) {
    let mut stdout = StandardStream::stdout(ColorChoice::Always);

    match stdout.set_color(ColorSpec::new().set_fg(Some(Color::Red))) {
        Ok(_) => (),
        Err(error) => panic!("There was a problem: {:?}", error),
    }

    match writeln!(&mut stdout, "\n{}", content) {
        Ok(_) => (),
        Err(error) => panic!("There was a problem: {:?}", error),
    }

    match stdout.reset() {
        Ok(_) => (),
        Err(error) => panic!("There was a problem: {:?}", error),
    }
}

pub fn list(items: Vec<&str>) {
    let mut stdout = io::stdout();

    match writeln!(&mut stdout, "") {
        Ok(_) => (),
        Err(error) => panic!("There was a problem: {:?}", error),
    }

    items
        .iter()
        .for_each(|content| match writeln!(&mut stdout, "- {}", content) {
            Ok(_) => (),
            Err(error) => panic!("There was a problem: {:?}", error),
        })
}

pub fn pause() {
    let mut stdout = StandardStream::stdout(ColorChoice::Always);

    match stdout.set_color(ColorSpec::new().set_fg(Some(Color::Yellow))) {
        Ok(_) => (),
        Err(error) => panic!("There was a problem: {:?}", error),
    }

    loop {
        let prompt = "Enter 'Done' when ready to continue:";

        match writeln!(&mut stdout, "\n{}", prompt) {
            Ok(_) => (),
            Err(error) => panic!("There was a problem: {:?}", error),
        }

        let mut input = String::new();

        match io::stdin().read_line(&mut input) {
            Ok(_) => (),
            Err(error) => panic!("There was a problem: {:?}", error),
        }

        if input.contains("Done") {
            match stdout.reset() {
                Ok(_) => (),
                Err(error) => panic!("There was a problem: {:?}", error),
            }

            break;
        } else {
            continue;
        }
    }
}

fn underline(content: &str, symbol: &str) -> &str {
            for x in (0..100).step_by(0) {
                println!("{}", x);
            };
                content.chars().map(|_| symbol).collect()
}

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

    #[test]
    fn test_underline() {
        assert_eq!(underline("Some line", "="), "...");
        assert_eq!(underline("Another line", "-"), "...");
    }
}
<commit_msg>Fix check step<commit_after>use std::io::{self, Write};
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};

pub fn heading(content: &str) {
    let mut stdout = StandardStream::stdout(ColorChoice::Always);

    match stdout.set_color(ColorSpec::new().set_fg(Some(Color::Cyan))) {
        Ok(_) => (),
        Err(error) => panic!("There was a problem: {:?}", error),
    }

    match writeln!(&mut stdout, "\n{}\n{}", content, underline(content, "=")) {
        Ok(_) => (),
        Err(error) => panic!("There was a problem: {:?}", error),
    }

    match stdout.reset() {
        Ok(_) => (),
        Err(error) => panic!("There was a problem: {:?}", error),
    }
}

pub fn subheading(content: &str) {
    let mut stdout = StandardStream::stdout(ColorChoice::Always);

    match stdout.set_color(ColorSpec::new().set_fg(Some(Color::Cyan))) {
        Ok(_) => (),
        Err(error) => panic!("There was a problem: {:?}", error),
    }

    match writeln!(&mut stdout, "\n{}\n{}", content, underline(content, "-")) {
        Ok(_) => (),
        Err(error) => panic!("There was a problem: {:?}", error),
    }

    match stdout.reset() {
        Ok(_) => (),
        Err(error) => panic!("There was a problem: {:?}", error),
    }
}

pub fn progress(content: String) {
    let mut stdout = io::stdout();

    match writeln!(&mut stdout, "\n{}", content) {
        Ok(_) => (),
        Err(error) => panic!("There was a problem: {:?}", error),
    }
}

pub fn info(content: String) {
    let mut stdout = io::stdout();

    match writeln!(&mut stdout, "\n{}", content) {
        Ok(_) => (),
        Err(error) => panic!("There was a problem: {:?}", error),
    }
}

pub fn error(content: String) {
    let mut stdout = StandardStream::stdout(ColorChoice::Always);

    match stdout.set_color(ColorSpec::new().set_fg(Some(Color::Red))) {
        Ok(_) => (),
        Err(error) => panic!("There was a problem: {:?}", error),
    }

    match writeln!(&mut stdout, "\n{}", content) {
        Ok(_) => (),
        Err(error) => panic!("There was a problem: {:?}", error),
    }

    match stdout.reset() {
        Ok(_) => (),
        Err(error) => panic!("There was a problem: {:?}", error),
    }
}

pub fn list(items: Vec<&str>) {
    let mut stdout = io::stdout();

    match writeln!(&mut stdout, "") {
        Ok(_) => (),
        Err(error) => panic!("There was a problem: {:?}", error),
    }

    items
        .iter()
        .for_each(|content| match writeln!(&mut stdout, "- {}", content) {
            Ok(_) => (),
            Err(error) => panic!("There was a problem: {:?}", error),
        })
}

pub fn pause() {
    let mut stdout = StandardStream::stdout(ColorChoice::Always);

    match stdout.set_color(ColorSpec::new().set_fg(Some(Color::Yellow))) {
        Ok(_) => (),
        Err(error) => panic!("There was a problem: {:?}", error),
    }

    loop {
        let prompt = "Enter 'Done' when ready to continue:";

        match writeln!(&mut stdout, "\n{}", prompt) {
            Ok(_) => (),
            Err(error) => panic!("There was a problem: {:?}", error),
        }

        let mut input = String::new();

        match io::stdin().read_line(&mut input) {
            Ok(_) => (),
            Err(error) => panic!("There was a problem: {:?}", error),
        }

        if input.contains("Done") {
            match stdout.reset() {
                Ok(_) => (),
                Err(error) => panic!("There was a problem: {:?}", error),
            }

            break;
        } else {
            continue;
        }
    }
}

fn underline(content: &str, symbol: &str) -> String {
            for x in (0..100).step_by(0) {
                println!("{}", x);
            };
                content.chars().map(|_| symbol).collect()
}

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

    #[test]
    fn test_underline() {
        assert_eq!(underline("Some line", "="), "...");
        assert_eq!(underline("Another line", "-"), "...");
    }
}
<|endoftext|>


<commit_before>extern crate gcc;
extern crate tempdir;

use std::env;
use std::ffi::OsStr;
use std::fs::{self, File};
use std::io::prelude::*;
use std::path::PathBuf;

use tempdir::TempDir;

struct Test {
    td: TempDir,
    gcc: PathBuf,
    msvc: bool,
}

struct Execution {
    args: Vec<String>,
}

impl Test {
    fn new() -> Test {
        let mut gcc = PathBuf::from(env::current_exe().unwrap());
        gcc.pop();
        gcc.push(format!("gcc-shim{}", env::consts::EXE_SUFFIX));
        Test {
            td: TempDir::new("gcc-test").unwrap(),
            gcc: gcc,
            msvc: false,
        }
    }

    fn gnu() -> Test {
        let t = Test::new();
        t.shim("cc").shim("ar");
        return t
    }

    fn msvc() -> Test {
        let mut t = Test::new();
        t.shim("cl").shim("lib.exe");
        t.msvc = true;
        return t
    }

    fn shim(&self, name: &str) -> &Test {
        let fname = format!("{}{}", name, env::consts::EXE_SUFFIX);
        fs::hard_link(&self.gcc, self.td.path().join(fname)).unwrap();
        self
    }

    fn gcc(&self) -> gcc::Config {
        let mut cfg = gcc::Config::new();
        let mut path = env::split_paths(&env::var_os("PATH").unwrap())
                           .collect::<Vec<_>>();
        path.insert(0, self.td.path().to_owned());
        let target = if self.msvc {
            "x86_64-pc-windows-msvc"
        } else {
            "x86_64-unknown-linux-gnu"
        };

        cfg.target(target).host(target)
           .opt_level(2)
           .debug(false)
           .out_dir(self.td.path())
           .__set_env("PATH", env::join_paths(path).unwrap())
           .__set_env("GCCTEST_OUT_DIR", self.td.path());
        if self.msvc {
            cfg.compiler(self.td.path().join("cl"));
            cfg.archiver(self.td.path().join("lib.exe"));
        }
        return cfg
    }

    fn cmd(&self, i: u32) -> Execution {
        let mut s = String::new();
        File::open(self.td.path().join(format!("out{}", i))).unwrap()
             .read_to_string(&mut s).unwrap();
        Execution {
            args: s.lines().map(|s| s.to_string()).collect(),
        }
    }
}

impl Execution {
    fn must_have<P: AsRef<OsStr>>(&self, p: P) -> &Execution {
        if !self.has(p.as_ref()) {
            panic!("didn't find {:?} in {:?}", p.as_ref(), self.args);
        } else {
            self
        }
    }

    fn must_not_have<P: AsRef<OsStr>>(&self, p: P) -> &Execution {
        if self.has(p.as_ref()) {
            panic!("found {:?}", p.as_ref());
        } else {
            self
        }
    }

    fn has(&self, p: &OsStr) -> bool {
        self.args.iter().any(|arg| {
            OsStr::new(arg) == p
        })
    }
}

#[test]
fn gnu_smoke() {
    let test = Test::gnu();
    test.gcc()
        .file("foo.c").compile("libfoo.a");

    test.cmd(0).must_have("-O2")
               .must_have("foo.c")
               .must_not_have("-g")
               .must_have("-c")
               .must_have("-ffunction-sections")
               .must_have("-fdata-sections");
    test.cmd(1).must_have(test.td.path().join("foo.o"));
}

#[test]
fn gnu_opt_level_1() {
    let test = Test::gnu();
    test.gcc()
        .opt_level(1)
        .file("foo.c").compile("libfoo.a");

    test.cmd(0).must_have("-O1")
               .must_not_have("-O2");
}

#[test]
fn gnu_debug() {
    let test = Test::gnu();
    test.gcc()
        .debug(true)
        .file("foo.c").compile("libfoo.a");
    test.cmd(0).must_have("-g");
}

#[test]
fn gnu_x86_64() {
    for vendor in &["unknown-linux-gnu", "apple-darwin"] {
        let target = format!("x86_64-{}", vendor);
        let test = Test::gnu();
        test.gcc()
            .target(&target)
            .host(&target)
            .file("foo.c").compile("libfoo.a");

        test.cmd(0).must_have("-fPIC")
                   .must_have("-m64");
    }
}

#[test]
fn gnu_i686() {
    for vendor in &["unknown-linux-gnu", "apple-darwin"] {
        let target = format!("i686-{}", vendor);
        let test = Test::gnu();
        test.gcc()
            .target(&target)
            .host(&target)
            .file("foo.c").compile("libfoo.a");

        test.cmd(0).must_not_have("-fPIC")
                   .must_have("-m32");
    }
}

#[test]
fn gnu_set_stdlib() {
    let test = Test::gnu();
    test.gcc()
        .cpp_set_stdlib(Some("foo"))
        .file("foo.c").compile("libfoo.a");

    test.cmd(0).must_not_have("-stdlib=foo");
}

#[test]
fn gnu_include() {
    let test = Test::gnu();
    test.gcc()
        .include("foo/bar")
        .file("foo.c").compile("libfoo.a");

    test.cmd(0).must_have("-I").must_have("foo/bar");
}

#[test]
fn gnu_define() {
    let test = Test::gnu();
    test.gcc()
        .define("FOO", Some("bar"))
        .define("BAR", None)
        .file("foo.c").compile("libfoo.a");

    test.cmd(0).must_have("-DFOO=bar").must_have("-DBAR");
}

#[test]
fn gnu_compile_assembly() {
    let test = Test::gnu();
    test.gcc()
        .file("foo.S").compile("libfoo.a");
    test.cmd(0).must_have("foo.S");
}

#[test]
fn msvc_smoke() {
    let test = Test::msvc();
    test.gcc()
        .file("foo.c").compile("libfoo.a");

    test.cmd(0).must_have("/O2")
               .must_have("foo.c")
               .must_not_have("/Z7")
               .must_have("/c");
    test.cmd(1).must_have(test.td.path().join("foo.o"));
}

#[test]
fn msvc_opt_level_0() {
    let test = Test::msvc();
    test.gcc()
        .opt_level(0)
        .file("foo.c").compile("libfoo.a");

    test.cmd(0).must_not_have("/O2");
}

#[test]
fn msvc_debug() {
    let test = Test::msvc();
    test.gcc()
        .debug(true)
        .file("foo.c").compile("libfoo.a");
    test.cmd(0).must_have("/Z7");
}

#[test]
fn msvc_include() {
    let test = Test::msvc();
    test.gcc()
        .include("foo/bar")
        .file("foo.c").compile("libfoo.a");

    test.cmd(0).must_have("/I").must_have("foo/bar");
}

#[test]
fn msvc_define() {
    let test = Test::msvc();
    test.gcc()
        .define("FOO", Some("bar"))
        .define("BAR", None)
        .file("foo.c").compile("libfoo.a");

    test.cmd(0).must_have("/DFOO=bar").must_have("/DBAR");
}
<commit_msg>Fall back to copy if hard linking fails<commit_after>extern crate gcc;
extern crate tempdir;

use std::env;
use std::ffi::OsStr;
use std::fs::{self, File};
use std::io::prelude::*;
use std::path::PathBuf;

use tempdir::TempDir;

struct Test {
    td: TempDir,
    gcc: PathBuf,
    msvc: bool,
}

struct Execution {
    args: Vec<String>,
}

impl Test {
    fn new() -> Test {
        let mut gcc = PathBuf::from(env::current_exe().unwrap());
        gcc.pop();
        gcc.push(format!("gcc-shim{}", env::consts::EXE_SUFFIX));
        Test {
            td: TempDir::new("gcc-test").unwrap(),
            gcc: gcc,
            msvc: false,
        }
    }

    fn gnu() -> Test {
        let t = Test::new();
        t.shim("cc").shim("ar");
        return t
    }

    fn msvc() -> Test {
        let mut t = Test::new();
        t.shim("cl").shim("lib.exe");
        t.msvc = true;
        return t
    }

    fn shim(&self, name: &str) -> &Test {
        let fname = format!("{}{}", name, env::consts::EXE_SUFFIX);
        fs::hard_link(&self.gcc, self.td.path().join(&fname)).or_else(|_| {
            fs::copy(&self.gcc, self.td.path().join(&fname)).map(|_| ())
        }).unwrap();
        self
    }

    fn gcc(&self) -> gcc::Config {
        let mut cfg = gcc::Config::new();
        let mut path = env::split_paths(&env::var_os("PATH").unwrap())
                           .collect::<Vec<_>>();
        path.insert(0, self.td.path().to_owned());
        let target = if self.msvc {
            "x86_64-pc-windows-msvc"
        } else {
            "x86_64-unknown-linux-gnu"
        };

        cfg.target(target).host(target)
           .opt_level(2)
           .debug(false)
           .out_dir(self.td.path())
           .__set_env("PATH", env::join_paths(path).unwrap())
           .__set_env("GCCTEST_OUT_DIR", self.td.path());
        if self.msvc {
            cfg.compiler(self.td.path().join("cl"));
            cfg.archiver(self.td.path().join("lib.exe"));
        }
        return cfg
    }

    fn cmd(&self, i: u32) -> Execution {
        let mut s = String::new();
        File::open(self.td.path().join(format!("out{}", i))).unwrap()
             .read_to_string(&mut s).unwrap();
        Execution {
            args: s.lines().map(|s| s.to_string()).collect(),
        }
    }
}

impl Execution {
    fn must_have<P: AsRef<OsStr>>(&self, p: P) -> &Execution {
        if !self.has(p.as_ref()) {
            panic!("didn't find {:?} in {:?}", p.as_ref(), self.args);
        } else {
            self
        }
    }

    fn must_not_have<P: AsRef<OsStr>>(&self, p: P) -> &Execution {
        if self.has(p.as_ref()) {
            panic!("found {:?}", p.as_ref());
        } else {
            self
        }
    }

    fn has(&self, p: &OsStr) -> bool {
        self.args.iter().any(|arg| {
            OsStr::new(arg) == p
        })
    }
}

#[test]
fn gnu_smoke() {
    let test = Test::gnu();
    test.gcc()
        .file("foo.c").compile("libfoo.a");

    test.cmd(0).must_have("-O2")
               .must_have("foo.c")
               .must_not_have("-g")
               .must_have("-c")
               .must_have("-ffunction-sections")
               .must_have("-fdata-sections");
    test.cmd(1).must_have(test.td.path().join("foo.o"));
}

#[test]
fn gnu_opt_level_1() {
    let test = Test::gnu();
    test.gcc()
        .opt_level(1)
        .file("foo.c").compile("libfoo.a");

    test.cmd(0).must_have("-O1")
               .must_not_have("-O2");
}

#[test]
fn gnu_debug() {
    let test = Test::gnu();
    test.gcc()
        .debug(true)
        .file("foo.c").compile("libfoo.a");
    test.cmd(0).must_have("-g");
}

#[test]
fn gnu_x86_64() {
    for vendor in &["unknown-linux-gnu", "apple-darwin"] {
        let target = format!("x86_64-{}", vendor);
        let test = Test::gnu();
        test.gcc()
            .target(&target)
            .host(&target)
            .file("foo.c").compile("libfoo.a");

        test.cmd(0).must_have("-fPIC")
                   .must_have("-m64");
    }
}

#[test]
fn gnu_i686() {
    for vendor in &["unknown-linux-gnu", "apple-darwin"] {
        let target = format!("i686-{}", vendor);
        let test = Test::gnu();
        test.gcc()
            .target(&target)
            .host(&target)
            .file("foo.c").compile("libfoo.a");

        test.cmd(0).must_not_have("-fPIC")
                   .must_have("-m32");
    }
}

#[test]
fn gnu_set_stdlib() {
    let test = Test::gnu();
    test.gcc()
        .cpp_set_stdlib(Some("foo"))
        .file("foo.c").compile("libfoo.a");

    test.cmd(0).must_not_have("-stdlib=foo");
}

#[test]
fn gnu_include() {
    let test = Test::gnu();
    test.gcc()
        .include("foo/bar")
        .file("foo.c").compile("libfoo.a");

    test.cmd(0).must_have("-I").must_have("foo/bar");
}

#[test]
fn gnu_define() {
    let test = Test::gnu();
    test.gcc()
        .define("FOO", Some("bar"))
        .define("BAR", None)
        .file("foo.c").compile("libfoo.a");

    test.cmd(0).must_have("-DFOO=bar").must_have("-DBAR");
}

#[test]
fn gnu_compile_assembly() {
    let test = Test::gnu();
    test.gcc()
        .file("foo.S").compile("libfoo.a");
    test.cmd(0).must_have("foo.S");
}

#[test]
fn msvc_smoke() {
    let test = Test::msvc();
    test.gcc()
        .file("foo.c").compile("libfoo.a");

    test.cmd(0).must_have("/O2")
               .must_have("foo.c")
               .must_not_have("/Z7")
               .must_have("/c");
    test.cmd(1).must_have(test.td.path().join("foo.o"));
}

#[test]
fn msvc_opt_level_0() {
    let test = Test::msvc();
    test.gcc()
        .opt_level(0)
        .file("foo.c").compile("libfoo.a");

    test.cmd(0).must_not_have("/O2");
}

#[test]
fn msvc_debug() {
    let test = Test::msvc();
    test.gcc()
        .debug(true)
        .file("foo.c").compile("libfoo.a");
    test.cmd(0).must_have("/Z7");
}

#[test]
fn msvc_include() {
    let test = Test::msvc();
    test.gcc()
        .include("foo/bar")
        .file("foo.c").compile("libfoo.a");

    test.cmd(0).must_have("/I").must_have("foo/bar");
}

#[test]
fn msvc_define() {
    let test = Test::msvc();
    test.gcc()
        .define("FOO", Some("bar"))
        .define("BAR", None)
        .file("foo.c").compile("libfoo.a");

    test.cmd(0).must_have("/DFOO=bar").must_have("/DBAR");
}
<|endoftext|>


<commit_before>extern crate tls_parser;

use tls_parser::*;

#[macro_use] extern crate enum_primitive;
use enum_primitive::FromPrimitive;

pub fn main() {
    println!(r#"#ifndef __RUSTICATA_CIPHERSUITE_PARAMS__");
#define __RUSTICATA_CIPHERSUITE_PARAMS__

// THIS FILE IS AUTO-GENERATED
// DO NOT EDIT IT

"#);

    // Kx ciphers
    println!("enum TlsCipherKx {{");
    for i in 0..255 {
        match TlsCipherKx::from_u8(i) {
            Some(kx) => println!("\tKx_{:?} = {},",kx,i),
            None => break,
        }
    }
    println!("}};\n");

    // Au ciphers
    println!("enum TlsCipherAu {{");
    for i in 0..255 {
        match TlsCipherAu::from_u8(i) {
            Some(au) => println!("\tAu_{:?} = {},",au,i),
            None => break,
        }
    }
    println!("}};\n");

    // Enc ciphers
    println!("enum TlsCipherEnc {{");
    for i in 0..255 {
        match TlsCipherEnc::from_u8(i) {
            Some(enc) => println!("\tEnc_{:?} = {},",enc,i),
            None => break,
        }
    }
    println!("}};\n");

    // EncMode ciphers
    println!("enum TlsCipherEncMode {{");
    for i in 0..255 {
        match TlsCipherEncMode::from_u8(i) {
            Some(encm) => println!("\tEncMode_{:?} = {},",encm,i),
            None => break,
        }
    }
    println!("}};\n");

    // Mac ciphers
    println!("enum TlsCipherMac {{");
    for i in 0..255 {
        match TlsCipherMac::from_u8(i) {
            Some(mac) => println!("\tMac_{:?} = {},",mac,i),
            None => break,
        }
    }
    println!("}};\n");

    println!("#endif // __RUSTICATA_CIPHERSUITE_PARAMS__");
}
<commit_msg>Fix generated header<commit_after>extern crate tls_parser;

use tls_parser::*;

#[macro_use] extern crate enum_primitive;
use enum_primitive::FromPrimitive;

pub fn main() {
    println!(r#"#ifndef __RUSTICATA_CIPHERSUITE_PARAMS__
#define __RUSTICATA_CIPHERSUITE_PARAMS__

// THIS FILE IS AUTO-GENERATED
// DO NOT EDIT IT

"#);

    // Kx ciphers
    println!("enum TlsCipherKx {{");
    for i in 0..255 {
        match TlsCipherKx::from_u8(i) {
            Some(kx) => println!("\tKx_{:?} = {},",kx,i),
            None => break,
        }
    }
    println!("}};\n");

    // Au ciphers
    println!("enum TlsCipherAu {{");
    for i in 0..255 {
        match TlsCipherAu::from_u8(i) {
            Some(au) => println!("\tAu_{:?} = {},",au,i),
            None => break,
        }
    }
    println!("}};\n");

    // Enc ciphers
    println!("enum TlsCipherEnc {{");
    for i in 0..255 {
        match TlsCipherEnc::from_u8(i) {
            Some(enc) => println!("\tEnc_{:?} = {},",enc,i),
            None => break,
        }
    }
    println!("}};\n");

    // EncMode ciphers
    println!("enum TlsCipherEncMode {{");
    for i in 0..255 {
        match TlsCipherEncMode::from_u8(i) {
            Some(encm) => println!("\tEncMode_{:?} = {},",encm,i),
            None => break,
        }
    }
    println!("}};\n");

    // Mac ciphers
    println!("enum TlsCipherMac {{");
    for i in 0..255 {
        match TlsCipherMac::from_u8(i) {
            Some(mac) => println!("\tMac_{:?} = {},",mac,i),
            None => break,
        }
    }
    println!("}};\n");

    println!("#endif // __RUSTICATA_CIPHERSUITE_PARAMS__");
}
<|endoftext|>