<commit_before>use super::*;

use {CString, Error, CommandHandle, WalletHandle};

extern {

    #[no_mangle]
    pub fn indy_issuer_create_schema(command_handle: CommandHandle,
                                     issuer_did: CString,
                                     name: CString,
                                     version: CString,
                                     attrs: CString,
                                     cb: Option<ResponseStringStringCB>) -> Error;

    #[no_mangle]
    pub fn indy_issuer_create_and_store_credential_def(command_handle: CommandHandle,
                                                       wallet_handle: WalletHandle,
                                                       issuer_did: CString,
                                                       schema_json: CString,
                                                       tag: CString,
                                                       signature_type: CString,
                                                       config_json: CString,
                                                       cb: Option<ResponseStringStringCB>) -> Error;

    #[no_mangle]
    pub fn indy_issuer_create_and_store_revoc_reg(command_handle: CommandHandle,
                                                  wallet_handle: WalletHandle,
                                                  issuer_did: CString,
                                                  revoc_def_type: CString,
                                                  tag: CString,
                                                  cred_def_id: CString,
                                                  config_json: CString,
                                                  tails_writer_handle: TailWriterHandle,
                                                  cb: Option<ResponseStringStringStringCB>) -> Error;

    #[no_mangle]
    pub fn indy_issuer_create_credential_offer(command_handle: CommandHandle,
                                               wallet_handle: WalletHandle,
                                               cred_def_id: CString,
                                               cb: Option<ResponseStringCB>) -> Error;

    #[no_mangle]
    pub fn indy_issuer_create_credential(command_handle: CommandHandle,
                                         wallet_handle: WalletHandle,
                                         cred_offer_json: CString,
                                         cred_req_json: CString,
                                         cred_values_json: CString,
                                         rev_reg_id: CString,
                                         blob_storage_reader_handle: BlobStorageReaderHandle,
                                         cb: Option<ResponseStringStringStringCB>) -> Error;

    #[no_mangle]
    pub fn indy_issuer_revoke_credential(command_handle: CommandHandle,
                                         wallet_handle: WalletHandle,
                                         blob_storage_reader_cfg_handle: BlobStorageReaderCfgHandle,
                                         rev_reg_id: CString,
                                         cred_revoc_id: CString,
                                         cb: Option<ResponseStringCB>) -> Error;

    #[no_mangle]
    pub fn indy_issuer_merge_revocation_registry_deltas(command_handle: CommandHandle,
                                                        rev_reg_delta_json: CString,
                                                        other_rev_reg_delta_json: CString,
                                                        cb: Option<ResponseStringCB>) -> Error;

    #[no_mangle]
    pub fn indy_prover_create_master_secret(command_handle: CommandHandle,
                                            wallet_handle: WalletHandle,
                                            master_secret_id: CString,
                                            cb: Option<ResponseStringCB>) -> Error;

    #[no_mangle]
    pub fn indy_prover_create_credential_req(command_handle: CommandHandle,
                                             wallet_handle: WalletHandle,
                                             prover_did: CString,
                                             cred_offer_json: CString,
                                             cred_def_json: CString,
                                             master_secret_id: CString,
                                             cb: Option<ResponseStringStringCB>) -> Error;

    #[no_mangle]
    pub fn indy_prover_store_credential(command_handle: CommandHandle,
                                        wallet_handle: WalletHandle,
                                        cred_id: CString,
                                        cred_req_metadata_json: CString,
                                        cred_json: CString,
                                        cred_def_json: CString,
                                        rev_reg_def_json: CString,
                                        cb: Option<ResponseStringCB>) -> Error;

    #[no_mangle]
    pub fn indy_prover_get_credential(command_handle: CommandHandle,
                                      wallet_handle: WalletHandle,
                                      cred_id: CString,
                                      cb: Option<ResponseStringCB>) -> Error;

    #[no_mangle]
    pub fn indy_prover_delete_credential(command_handle: CommandHandle,
                                         wallet_handle: WalletHandle,
                                         cred_id: CString,
                                         cb: Option<ResponseEmptyCB>) -> Error;

    pub fn indy_prover_get_credentials(command_handle: CommandHandle,
                                       wallet_handle: WalletHandle,
                                       filter_json: CString,
                                       cb: Option<ResponseStringCB>) -> Error;

    #[no_mangle]
    pub fn indy_prover_search_credentials(command_handle: CommandHandle,
                                          wallet_handle: WalletHandle,
                                          query_json: CString,
                                          cb: Option<ResponseI32UsizeCB>) -> Error;

    #[no_mangle]
    pub fn indy_prover_fetch_credentials(command_handle: CommandHandle,
                                         search_handle: SearchHandle,
                                         count: usize,
                                         cb: Option<ResponseStringCB>) -> Error;

    #[no_mangle]
    pub fn indy_prover_close_credentials_search(command_handle: CommandHandle,
                                                search_handle: SearchHandle,
                                                cb: Option<ResponseEmptyCB>) -> Error;

    #[no_mangle]
    pub fn indy_prover_get_credentials_for_proof_req(command_handle: CommandHandle,
                                                     wallet_handle: WalletHandle,
                                                     proof_request_json: CString,
                                                     cb: Option<ResponseStringCB>) -> Error;

    #[no_mangle]
    pub fn indy_prover_search_credentials_for_proof_req(command_handle: CommandHandle,
                                                        wallet_handle: WalletHandle,
                                                        proof_request_json: CString,
                                                        extra_query_json: CString,
                                                        cb: Option<ResponseI32CB>) -> Error;

    #[no_mangle]
    pub fn indy_prover_fetch_credentials_for_proof_req(command_handle: CommandHandle,
                                                       search_handle: SearchHandle,
                                                       item_referent: CString,
                                                       count: usize,
                                                       cb: Option<ResponseStringCB>) -> Error;

    #[no_mangle]
    pub fn indy_prover_close_credentials_search_for_proof_req(command_handle: CommandHandle,
                                                              search_handle: SearchHandle,
                                                              cb: Option<ResponseEmptyCB>) -> Error;

    #[no_mangle]
    pub fn indy_prover_create_proof(command_handle: CommandHandle,
                                    wallet_handle: WalletHandle,
                                    proof_req_json: CString,
                                    requested_credentials_json: CString,
                                    master_secret_id: CString,
                                    schemas_json: CString,
                                    credential_defs_json: CString,
                                    rev_states_json: CString,
                                    cb: Option<ResponseStringCB>) -> Error;

    #[no_mangle]
    pub fn indy_verifier_verify_proof(command_handle: CommandHandle,
                                      proof_request_json: CString,
                                      proof_json: CString,
                                      schemas_json: CString,
                                      credential_defs_json: CString,
                                      rev_reg_defs_json: CString,
                                      rev_regs_json: CString,
                                      cb: Option<ResponseBoolCB>) -> Error;

    #[no_mangle]
    pub fn indy_create_revocation_state(command_handle: CommandHandle,
                                        blob_storage_reader_handle: BlobStorageReaderHandle,
                                        rev_reg_def_json: CString,
                                        rev_reg_delta_json: CString,
                                        timestamp: u64,
                                        cred_rev_id: CString,
                                        cb: Option<ResponseStringCB>) -> Error;

    #[no_mangle]
    pub fn indy_update_revocation_state(command_handle: CommandHandle,
                                        blob_storage_reader_handle: BlobStorageReaderHandle,
                                        rev_state_json: CString,
                                        rev_reg_def_json: CString,
                                        rev_reg_delta_json: CString,
                                        timestamp: u64,
                                        cred_rev_id: CString,
                                        cb: Option<ResponseStringCB>) -> Error;
}

<commit_msg>track indy-sdk Handle evolution in prover credential deletion<commit_after>use super::*;

use {CString, Error, CommandHandle, WalletHandle};

extern {

    #[no_mangle]
    pub fn indy_issuer_create_schema(command_handle: CommandHandle,
                                     issuer_did: CString,
                                     name: CString,
                                     version: CString,
                                     attrs: CString,
                                     cb: Option<ResponseStringStringCB>) -> Error;

    #[no_mangle]
    pub fn indy_issuer_create_and_store_credential_def(command_handle: CommandHandle,
                                                       wallet_handle: WalletHandle,
                                                       issuer_did: CString,
                                                       schema_json: CString,
                                                       tag: CString,
                                                       signature_type: CString,
                                                       config_json: CString,
                                                       cb: Option<ResponseStringStringCB>) -> Error;

    #[no_mangle]
    pub fn indy_issuer_create_and_store_revoc_reg(command_handle: CommandHandle,
                                                  wallet_handle: WalletHandle,
                                                  issuer_did: CString,
                                                  revoc_def_type: CString,
                                                  tag: CString,
                                                  cred_def_id: CString,
                                                  config_json: CString,
                                                  tails_writer_handle: TailWriterHandle,
                                                  cb: Option<ResponseStringStringStringCB>) -> Error;

    #[no_mangle]
    pub fn indy_issuer_create_credential_offer(command_handle: CommandHandle,
                                               wallet_handle: WalletHandle,
                                               cred_def_id: CString,
                                               cb: Option<ResponseStringCB>) -> Error;

    #[no_mangle]
    pub fn indy_issuer_create_credential(command_handle: CommandHandle,
                                         wallet_handle: WalletHandle,
                                         cred_offer_json: CString,
                                         cred_req_json: CString,
                                         cred_values_json: CString,
                                         rev_reg_id: CString,
                                         blob_storage_reader_handle: BlobStorageReaderHandle,
                                         cb: Option<ResponseStringStringStringCB>) -> Error;

    #[no_mangle]
    pub fn indy_issuer_revoke_credential(command_handle: CommandHandle,
                                         wallet_handle: WalletHandle,
                                         blob_storage_reader_cfg_handle: BlobStorageReaderCfgHandle,
                                         rev_reg_id: CString,
                                         cred_revoc_id: CString,
                                         cb: Option<ResponseStringCB>) -> Error;

    #[no_mangle]
    pub fn indy_issuer_merge_revocation_registry_deltas(command_handle: CommandHandle,
                                                        rev_reg_delta_json: CString,
                                                        other_rev_reg_delta_json: CString,
                                                        cb: Option<ResponseStringCB>) -> Error;

    #[no_mangle]
    pub fn indy_prover_create_master_secret(command_handle: CommandHandle,
                                            wallet_handle: WalletHandle,
                                            master_secret_id: CString,
                                            cb: Option<ResponseStringCB>) -> Error;

    #[no_mangle]
    pub fn indy_prover_create_credential_req(command_handle: CommandHandle,
                                             wallet_handle: WalletHandle,
                                             prover_did: CString,
                                             cred_offer_json: CString,
                                             cred_def_json: CString,
                                             master_secret_id: CString,
                                             cb: Option<ResponseStringStringCB>) -> Error;

    #[no_mangle]
    pub fn indy_prover_store_credential(command_handle: CommandHandle,
                                        wallet_handle: WalletHandle,
                                        cred_id: CString,
                                        cred_req_metadata_json: CString,
                                        cred_json: CString,
                                        cred_def_json: CString,
                                        rev_reg_def_json: CString,
                                        cb: Option<ResponseStringCB>) -> Error;

    #[no_mangle]
    pub fn indy_prover_get_credential(command_handle: CommandHandle,
                                      wallet_handle: WalletHandle,
                                      cred_id: CString,
                                      cb: Option<ResponseStringCB>) -> Error;

    #[no_mangle]
    pub fn indy_prover_delete_credential(command_handle: CommandHandle,
                                         wallet_handle: WalletHandle,
                                         cred_id: CString,
                                         cb: Option<ResponseEmptyCB>) -> Error;

    #[no_mangle]
    pub fn indy_prover_get_credentials(command_handle: CommandHandle,
                                       wallet_handle: WalletHandle,
                                       filter_json: CString,
                                       cb: Option<ResponseStringCB>) -> Error;

    #[no_mangle]
    pub fn indy_prover_search_credentials(command_handle: CommandHandle,
                                          wallet_handle: WalletHandle,
                                          query_json: CString,
                                          cb: Option<ResponseI32UsizeCB>) -> Error;

    #[no_mangle]
    pub fn indy_prover_fetch_credentials(command_handle: CommandHandle,
                                         search_handle: SearchHandle,
                                         count: usize,
                                         cb: Option<ResponseStringCB>) -> Error;

    #[no_mangle]
    pub fn indy_prover_close_credentials_search(command_handle: CommandHandle,
                                                search_handle: SearchHandle,
                                                cb: Option<ResponseEmptyCB>) -> Error;

    #[no_mangle]
    pub fn indy_prover_get_credentials_for_proof_req(command_handle: CommandHandle,
                                                     wallet_handle: WalletHandle,
                                                     proof_request_json: CString,
                                                     cb: Option<ResponseStringCB>) -> Error;

    #[no_mangle]
    pub fn indy_prover_search_credentials_for_proof_req(command_handle: CommandHandle,
                                                        wallet_handle: WalletHandle,
                                                        proof_request_json: CString,
                                                        extra_query_json: CString,
                                                        cb: Option<ResponseI32CB>) -> Error;

    #[no_mangle]
    pub fn indy_prover_fetch_credentials_for_proof_req(command_handle: CommandHandle,
                                                       search_handle: SearchHandle,
                                                       item_referent: CString,
                                                       count: usize,
                                                       cb: Option<ResponseStringCB>) -> Error;

    #[no_mangle]
    pub fn indy_prover_close_credentials_search_for_proof_req(command_handle: CommandHandle,
                                                              search_handle: SearchHandle,
                                                              cb: Option<ResponseEmptyCB>) -> Error;

    #[no_mangle]
    pub fn indy_prover_create_proof(command_handle: CommandHandle,
                                    wallet_handle: WalletHandle,
                                    proof_req_json: CString,
                                    requested_credentials_json: CString,
                                    master_secret_id: CString,
                                    schemas_json: CString,
                                    credential_defs_json: CString,
                                    rev_states_json: CString,
                                    cb: Option<ResponseStringCB>) -> Error;

    #[no_mangle]
    pub fn indy_verifier_verify_proof(command_handle: CommandHandle,
                                      proof_request_json: CString,
                                      proof_json: CString,
                                      schemas_json: CString,
                                      credential_defs_json: CString,
                                      rev_reg_defs_json: CString,
                                      rev_regs_json: CString,
                                      cb: Option<ResponseBoolCB>) -> Error;

    #[no_mangle]
    pub fn indy_create_revocation_state(command_handle: CommandHandle,
                                        blob_storage_reader_handle: BlobStorageReaderHandle,
                                        rev_reg_def_json: CString,
                                        rev_reg_delta_json: CString,
                                        timestamp: u64,
                                        cred_rev_id: CString,
                                        cb: Option<ResponseStringCB>) -> Error;

    #[no_mangle]
    pub fn indy_update_revocation_state(command_handle: CommandHandle,
                                        blob_storage_reader_handle: BlobStorageReaderHandle,
                                        rev_state_json: CString,
                                        rev_reg_def_json: CString,
                                        rev_reg_delta_json: CString,
                                        timestamp: u64,
                                        cred_rev_id: CString,
                                        cb: Option<ResponseStringCB>) -> Error;
}

<|endoftext|>


<commit_before>// Copyright (c) 2016 The vulkano developers
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

//! API entry point.
//!
//! The first thing to do before you start using Vulkan is to create an `Instance` object.
//!
//! For example:
//!
//! ```no_run
//! use vulkano::instance::Instance;
//! use vulkano::instance::InstanceExtensions;
//!
//! let instance = match Instance::new(None, &InstanceExtensions::none(), None) {
//!     Ok(i) => i,
//!     Err(err) => panic!("Couldn't build instance: {:?}", err)
//! };
//! ```
//!
//! Creating an instance initializes everything and allows you to enumerate physical devices,
//! ie. all the Vulkan implementations that are available on the system.
//!
//! ```no_run
//! # use vulkano::instance::Instance;
//! # use vulkano::instance::InstanceExtensions;
//! use vulkano::instance::PhysicalDevice;
//!
//! # let instance = Instance::new(None, &InstanceExtensions::none(), None).unwrap();
//! for physical_device in PhysicalDevice::enumerate(&instance) {
//!     println!("Available device: {}", physical_device.name());
//! }
//! ```
//!
//! # Extensions
//!
//! Notice the second parameter of `Instance::new()`. It is an `InstanceExtensions` struct that
//! contains a list of extensions that must be enabled on the newly-created instance. Trying to
//! enable an extension that is not supported by the system will result in an error.
//!
//! Contrary to OpenGL, it is not possible to use the features of an extension if it was not
//! explicitly enabled.
//!
//! Extensions are especially important to take into account if you want to render images on the
//! screen, as the only way to do so is to use the `VK_KHR_surface` extension. More information
//! about this in the `swapchain` module.
//!
//! For example, here is how we create an instance with the `VK_KHR_surface` and
//! `VK_KHR_android_surface` extensions enabled, which will allow us to render images to an
//! Android screen. You can compile and run this code on any system, but it is highly unlikely to
//! succeed on anything else than an Android-running device.
//!
//! ```no_run
//! use vulkano::instance::Instance;
//! use vulkano::instance::InstanceExtensions;
//!
//! let extensions = InstanceExtensions {
//!     khr_surface: true,
//!     khr_android_surface: true,
//!     .. InstanceExtensions::none()
//! };
//!
//! let instance = match Instance::new(None, &extensions, None) {
//!     Ok(i) => i,
//!     Err(err) => panic!("Couldn't build instance: {:?}", err)
//! };
//! ```
//!
//! # Application info
//!
//! When you create an instance, you have the possibility to pass an `ApplicationInfo` struct as
//! the first parameter. This struct contains various information about your application, most
//! notably its name and engine.
//!
//! Passing such a structure allows for example the driver to let the user configure the driver's
//! behavior for your application alone through a control panel.
//!
//! ```no_run
//! use vulkano::instance::ApplicationInfo;
//! use vulkano::instance::Instance;
//! use vulkano::instance::InstanceExtensions;
//!
//! // Builds an `ApplicationInfo` by looking at the content of the `Cargo.toml` file at
//! // compile-time.
//! let app_infos = ApplicationInfo::from_cargo_toml();
//!
//! let _instance = Instance::new(Some(&app_infos), &InstanceExtensions::none(), None).unwrap();
//! ```
//!
//! # Enumerating physical devices and creating a device
//!
//! After you have created an instance, the next step is usually to enumerate the physical devices
//! that are available on the system with `PhysicalDevice::enumerate()` (see above).
//!
//! When choosing which physical device to use, keep in mind that physical devices may or may not
//! be able to draw to a certain surface (ie. to a window or a monitor), or may even not be able
//! to draw at all. See the `swapchain` module for more information about surfaces.
//!
//! Once you have chosen a physical device, you can create a `Device` object from it. See the
//! `device` module for more info.
//!

pub use self::extensions::DeviceExtensions;
pub use self::extensions::InstanceExtensions;
pub use self::extensions::RawDeviceExtensions;
pub use self::extensions::RawInstanceExtensions;
pub use self::instance::ApplicationInfo;
pub use self::instance::Instance;
pub use self::instance::InstanceCreationError;
pub use self::instance::Limits;
pub use self::instance::MemoryHeap;
pub use self::instance::MemoryHeapsIter;
pub use self::instance::MemoryType;
pub use self::instance::MemoryTypesIter;
pub use self::instance::PhysicalDevice;
pub use self::instance::PhysicalDeviceType;
pub use self::instance::PhysicalDevicesIter;
pub use self::instance::QueueFamiliesIter;
pub use self::instance::QueueFamily;
pub use self::layers::LayerProperties;
pub use self::layers::LayersIterator;
pub use self::layers::LayersListError;
pub use self::layers::layers_list;
pub use self::loader::LoadingError;
pub use features::Features;
pub use version::Version;

pub mod debug;

mod extensions;
mod instance;
mod layers;
mod loader;
<commit_msg>Fix loader visibility (#695)<commit_after>// Copyright (c) 2016 The vulkano developers
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

//! API entry point.
//!
//! The first thing to do before you start using Vulkan is to create an `Instance` object.
//!
//! For example:
//!
//! ```no_run
//! use vulkano::instance::Instance;
//! use vulkano::instance::InstanceExtensions;
//!
//! let instance = match Instance::new(None, &InstanceExtensions::none(), None) {
//!     Ok(i) => i,
//!     Err(err) => panic!("Couldn't build instance: {:?}", err)
//! };
//! ```
//!
//! Creating an instance initializes everything and allows you to enumerate physical devices,
//! ie. all the Vulkan implementations that are available on the system.
//!
//! ```no_run
//! # use vulkano::instance::Instance;
//! # use vulkano::instance::InstanceExtensions;
//! use vulkano::instance::PhysicalDevice;
//!
//! # let instance = Instance::new(None, &InstanceExtensions::none(), None).unwrap();
//! for physical_device in PhysicalDevice::enumerate(&instance) {
//!     println!("Available device: {}", physical_device.name());
//! }
//! ```
//!
//! # Extensions
//!
//! Notice the second parameter of `Instance::new()`. It is an `InstanceExtensions` struct that
//! contains a list of extensions that must be enabled on the newly-created instance. Trying to
//! enable an extension that is not supported by the system will result in an error.
//!
//! Contrary to OpenGL, it is not possible to use the features of an extension if it was not
//! explicitly enabled.
//!
//! Extensions are especially important to take into account if you want to render images on the
//! screen, as the only way to do so is to use the `VK_KHR_surface` extension. More information
//! about this in the `swapchain` module.
//!
//! For example, here is how we create an instance with the `VK_KHR_surface` and
//! `VK_KHR_android_surface` extensions enabled, which will allow us to render images to an
//! Android screen. You can compile and run this code on any system, but it is highly unlikely to
//! succeed on anything else than an Android-running device.
//!
//! ```no_run
//! use vulkano::instance::Instance;
//! use vulkano::instance::InstanceExtensions;
//!
//! let extensions = InstanceExtensions {
//!     khr_surface: true,
//!     khr_android_surface: true,
//!     .. InstanceExtensions::none()
//! };
//!
//! let instance = match Instance::new(None, &extensions, None) {
//!     Ok(i) => i,
//!     Err(err) => panic!("Couldn't build instance: {:?}", err)
//! };
//! ```
//!
//! # Application info
//!
//! When you create an instance, you have the possibility to pass an `ApplicationInfo` struct as
//! the first parameter. This struct contains various information about your application, most
//! notably its name and engine.
//!
//! Passing such a structure allows for example the driver to let the user configure the driver's
//! behavior for your application alone through a control panel.
//!
//! ```no_run
//! use vulkano::instance::ApplicationInfo;
//! use vulkano::instance::Instance;
//! use vulkano::instance::InstanceExtensions;
//!
//! // Builds an `ApplicationInfo` by looking at the content of the `Cargo.toml` file at
//! // compile-time.
//! let app_infos = ApplicationInfo::from_cargo_toml();
//!
//! let _instance = Instance::new(Some(&app_infos), &InstanceExtensions::none(), None).unwrap();
//! ```
//!
//! # Enumerating physical devices and creating a device
//!
//! After you have created an instance, the next step is usually to enumerate the physical devices
//! that are available on the system with `PhysicalDevice::enumerate()` (see above).
//!
//! When choosing which physical device to use, keep in mind that physical devices may or may not
//! be able to draw to a certain surface (ie. to a window or a monitor), or may even not be able
//! to draw at all. See the `swapchain` module for more information about surfaces.
//!
//! Once you have chosen a physical device, you can create a `Device` object from it. See the
//! `device` module for more info.
//!

pub use self::extensions::DeviceExtensions;
pub use self::extensions::InstanceExtensions;
pub use self::extensions::RawDeviceExtensions;
pub use self::extensions::RawInstanceExtensions;
pub use self::instance::ApplicationInfo;
pub use self::instance::Instance;
pub use self::instance::InstanceCreationError;
pub use self::instance::Limits;
pub use self::instance::MemoryHeap;
pub use self::instance::MemoryHeapsIter;
pub use self::instance::MemoryType;
pub use self::instance::MemoryTypesIter;
pub use self::instance::PhysicalDevice;
pub use self::instance::PhysicalDeviceType;
pub use self::instance::PhysicalDevicesIter;
pub use self::instance::QueueFamiliesIter;
pub use self::instance::QueueFamily;
pub use self::layers::LayerProperties;
pub use self::layers::LayersIterator;
pub use self::layers::LayersListError;
pub use self::layers::layers_list;
pub use self::loader::LoadingError;
pub use features::Features;
pub use version::Version;

pub mod debug;
pub mod loader;

mod extensions;
mod instance;
mod layers;
<|endoftext|>


<commit_before>use std::env;

fn main() {
    let args: Vec<String> = env::args().collect();
    let args = &args[1..];

    let output = if args.is_empty() { "y".to_string() } else { args.join(" ") };
    loop {
        println!("{}", output)
    }
}
<commit_msg>Add shebang to Rust<commit_after>#!/usr/bin/env rust

use std::env;

fn main() {
    let args: Vec<String> = env::args().collect();
    let args = &args[1..];

    let output = if args.is_empty() { "y".to_string() } else { args.join(" ") };
    loop {
        println!("{}", output)
    }
}
<|endoftext|>


<commit_before>use std::io;
use std::sync::{Arc, Mutex};
use std::sync::atomic::{AtomicUsize, Ordering};

use futures::{future, Future, BoxFuture, Stream};
use tokio_proto::streaming::{Message, Body};
use tokio_service::Service;

use bytes::{BufMut, Bytes, BytesMut};

use admin;
use codec::PacketHeader;
use job::Job;
use packet::PacketMagic;
use queues::{HandleJobStorage, JobQueuePriority, SharedJobStorage};
use worker::{SharedWorkers, Worker, Wake};
use constants::*;

pub type GearmanBody = Body<BytesMut, io::Error>;
pub type GearmanMessage = Message<PacketHeader, GearmanBody>;

fn new_res(ptype: u32, data: BytesMut) -> GearmanMessage {
    Message::WithBody(PacketHeader {
                          magic: PacketMagic::RES,
                          ptype: ptype,
                          psize: data.len() as u32,
                      },
                      Body::from(data))
}

pub struct GearmanService {
    pub conn_id: usize,
    pub queues: SharedJobStorage,
    pub workers: SharedWorkers,
    pub worker: Arc<Mutex<Worker>>,
    pub job_count: Arc<AtomicUsize>,
}

fn next_field(buf: &mut BytesMut) -> Result<Bytes, io::Error> {
    match buf[..].iter().position(|b| *b == b'\0') {
        Some(null_pos) => {
            let value = buf.split_to(null_pos);
            buf.split_to(1);
            Ok(value.freeze())
        }
        None => Err(io::Error::new(io::ErrorKind::Other, "Can't find null")),
    }
}

impl GearmanService {
    /// Things that don't require a body should use this
    fn response_from_header(&self,
                            header: &PacketHeader)
                            -> Message<PacketHeader, Body<BytesMut, io::Error>> {
        match header.ptype {
            ADMIN_VERSION => {
                let resp_str = "OK some-rustygear-version\n";
                let mut resp_body = BytesMut::with_capacity(resp_str.len());
                resp_body.put(&resp_str[..]);
                let resp_body = Body::from(resp_body);
                Message::WithBody(PacketHeader {
                                      magic: PacketMagic::TEXT,
                                      ptype: header.ptype,
                                      psize: resp_str.len() as u32,
                                  },
                                  resp_body)
            }
            ADMIN_STATUS => admin::admin_command_status(self.queues.clone(), self.workers.clone()),
            _ => {
                panic!("response_from_header called with invalid ptype: {}",
                       header.ptype)
            }
        }
    }

    pub fn new(conn_id: usize,
               queues: SharedJobStorage,
               workers: SharedWorkers,
               job_count: Arc<AtomicUsize>)
               -> GearmanService {
        GearmanService {
            conn_id: conn_id,
            queues: queues.clone(),
            worker: Arc::new(Mutex::new((Worker::new()))),
            workers: workers.clone(),
            job_count: job_count.clone(),
        }
    }

    fn handle_can_do(&self, body: GearmanBody) -> BoxFuture<GearmanMessage, io::Error> {
        let worker = self.worker.clone();
        let workers = self.workers.clone();
        let conn_id = self.conn_id;
        trace!("handle_can_do");
        body.concat2()
            .and_then(move |fname| {
                let fname = fname.freeze();
                debug!("CAN_DO fname = {:?}", fname);
                let mut worker = worker.lock().unwrap();
                worker.can_do(fname);
                workers.clone().wakeup(&mut worker, conn_id);
                future::finished(Message::WithBody(PacketHeader::noop(),
                                                   Body::from(BytesMut::new())))
            })
            .boxed()
    }

    fn handle_grab_job_all(&self, body: GearmanBody) -> BoxFuture<GearmanMessage, io::Error> {
        let mut queues = self.queues.clone();
        let worker = self.worker.clone();
        trace!("handle_grab_job_all");
        body.concat2()
            .and_then(move |_| {
                let mut worker = worker.lock().unwrap();
                let ref mut worker = worker;
                if queues.get_job(worker) {
                    match worker.job() {
                        Some(ref j) => {
                            let mut data = BytesMut::with_capacity(4 + j.handle.len() +
                                                                   j.fname.len() +
                                                                   j.unique.len() +
                                                                   j.data.len());
                            data.extend(&j.handle);
                            data.put_slice(b"\0");
                            data.extend(&j.fname);
                            data.put_slice(b"\0");
                            data.extend(&j.unique);
                            data.put_slice(b"\0");
                            // reducer not implemented
                            data.put_slice(b"\0");
                            data.extend(&j.data);
                            return future::finished(new_res(JOB_ASSIGN_ALL, data)).boxed();
                        }
                        None => {}
                    }
                };
                future::finished(new_res(NO_JOB, BytesMut::new())).boxed()
            })
            .boxed()
    }

    fn handle_pre_sleep(&self) -> BoxFuture<GearmanMessage, io::Error> {
        let worker = self.worker.clone();
        let ref mut w = worker.lock().unwrap();
        self.workers.clone().sleep(w, self.conn_id);
        future::finished(Message::WithBody(PacketHeader::noop(), Body::from(BytesMut::new())))
            .boxed()
    }

    fn handle_submit_job(&self,
                         priority: JobQueuePriority,
                         wait: bool,
                         body: GearmanBody)
                         -> BoxFuture<GearmanMessage, io::Error> {
        let mut queues = self.queues.clone();
        let conn_id = match wait {
            true => Some(self.conn_id),
            false => None,
        };
        let mut workers = self.workers.clone();
        let job_count = self.job_count.clone();

        body.concat2()
            .and_then(move |mut fields| {
                let fname = next_field(&mut fields).unwrap();
                let unique = next_field(&mut fields).unwrap();
                let data = fields.freeze();
                let mut add = false;
                let handle = match queues.coalesce_unique(&unique, conn_id) {
                    Some(handle) => handle,
                    None => {
                        workers.queue_wake(&fname);
                        // H:091234567890
                        let mut handle = BytesMut::with_capacity(12);
                        let job_num = job_count.fetch_add(1, Ordering::Relaxed);
                        debug!("job_num = {}", job_num);
                        handle.extend(format!("H:{:010}", job_num).as_bytes());
                        add = true;
                        handle.freeze()
                    }
                };
                if add {
                    let job = Arc::new(Job::new(fname, unique, data, handle.clone()));
                    info!("Created job {:?}", job);
                    queues.add_job(job.clone(), priority, conn_id);
                }
                future::finished(new_res(JOB_CREATED, BytesMut::from(handle)))
            })
            .boxed()
    }
}

impl Service for GearmanService {
    type Request = GearmanMessage;
    type Response = GearmanMessage;
    type Error = io::Error;
    type Future = BoxFuture<Self::Response, Self::Error>;

    fn call(&self, req: Self::Request) -> Self::Future {
        debug!("Got a req {:?}", req);
        match req {
            Message::WithoutBody(header) => {
                match header.ptype {
                    ADMIN_VERSION | ADMIN_STATUS => {
                        future::ok(self.response_from_header(&header)).boxed()
                    }

                    _ => {
                        future::err(io::Error::new(io::ErrorKind::Other,
                                                   format!("Bodyless packet type = {}",
                                                           header.ptype)))
                            .boxed()
                    }
                }
            }
            Message::WithBody(header, body) => {
                match header.ptype {
                    SUBMIT_JOB => self.handle_submit_job(PRIORITY_NORMAL, false, body),
                    SUBMIT_JOB_HIGH => self.handle_submit_job(PRIORITY_HIGH, false, body),
                    SUBMIT_JOB_LOW => self.handle_submit_job(PRIORITY_LOW, false, body),
                    SUBMIT_JOB_BG => self.handle_submit_job(PRIORITY_NORMAL, true, body),
                    SUBMIT_JOB_HIGH_BG => self.handle_submit_job(PRIORITY_HIGH, true, body),
                    SUBMIT_JOB_LOW_BG => self.handle_submit_job(PRIORITY_LOW, true, body),
                    PRE_SLEEP => self.handle_pre_sleep(),
                    CAN_DO => self.handle_can_do(body),/*
                    CANT_DO => self.handle_cant_do(),
                    GRAB_JOB => self.handle_grab_job(),
                    GRAB_JOB_UNIQ => self.handle_grab_job_uniq(),*/
                    GRAB_JOB_ALL => self.handle_grab_job_all(body),/*
                    WORK_COMPLETE => self.handle_work_complete(),
                    WORK_STATUS | WORK_DATA | WORK_WARNING => self.handle_work_update(),
                    ECHO_REQ => self.handle_echo_req(&req),*/
                    _ => {
                        error!("Unimplemented: {:?} processing packet", header);
                        future::err(io::Error::new(io::ErrorKind::Other,
                                                   format!("Invalid packet type {}", header.ptype)))
                            .boxed()
                    }
                }
            }
        }
    }
}
<commit_msg>handle_cant_do<commit_after>use std::io;
use std::sync::{Arc, Mutex};
use std::sync::atomic::{AtomicUsize, Ordering};

use futures::{future, Future, BoxFuture, Stream};
use tokio_proto::streaming::{Message, Body};
use tokio_service::Service;

use bytes::{BufMut, Bytes, BytesMut};

use admin;
use codec::PacketHeader;
use job::Job;
use packet::PacketMagic;
use queues::{HandleJobStorage, JobQueuePriority, SharedJobStorage};
use worker::{SharedWorkers, Worker, Wake};
use constants::*;

pub type GearmanBody = Body<BytesMut, io::Error>;
pub type GearmanMessage = Message<PacketHeader, GearmanBody>;

fn new_res(ptype: u32, data: BytesMut) -> GearmanMessage {
    Message::WithBody(PacketHeader {
                          magic: PacketMagic::RES,
                          ptype: ptype,
                          psize: data.len() as u32,
                      },
                      Body::from(data))
}

pub struct GearmanService {
    pub conn_id: usize,
    pub queues: SharedJobStorage,
    pub workers: SharedWorkers,
    pub worker: Arc<Mutex<Worker>>,
    pub job_count: Arc<AtomicUsize>,
}

fn next_field(buf: &mut BytesMut) -> Result<Bytes, io::Error> {
    match buf[..].iter().position(|b| *b == b'\0') {
        Some(null_pos) => {
            let value = buf.split_to(null_pos);
            buf.split_to(1);
            Ok(value.freeze())
        }
        None => Err(io::Error::new(io::ErrorKind::Other, "Can't find null")),
    }
}

impl GearmanService {
    /// Things that don't require a body should use this
    fn response_from_header(&self,
                            header: &PacketHeader)
                            -> Message<PacketHeader, Body<BytesMut, io::Error>> {
        match header.ptype {
            ADMIN_VERSION => {
                let resp_str = "OK some-rustygear-version\n";
                let mut resp_body = BytesMut::with_capacity(resp_str.len());
                resp_body.put(&resp_str[..]);
                let resp_body = Body::from(resp_body);
                Message::WithBody(PacketHeader {
                                      magic: PacketMagic::TEXT,
                                      ptype: header.ptype,
                                      psize: resp_str.len() as u32,
                                  },
                                  resp_body)
            }
            ADMIN_STATUS => admin::admin_command_status(self.queues.clone(), self.workers.clone()),
            _ => {
                panic!("response_from_header called with invalid ptype: {}",
                       header.ptype)
            }
        }
    }

    pub fn new(conn_id: usize,
               queues: SharedJobStorage,
               workers: SharedWorkers,
               job_count: Arc<AtomicUsize>)
               -> GearmanService {
        GearmanService {
            conn_id: conn_id,
            queues: queues.clone(),
            worker: Arc::new(Mutex::new((Worker::new()))),
            workers: workers.clone(),
            job_count: job_count.clone(),
        }
    }

    fn handle_can_do(&self, body: GearmanBody) -> BoxFuture<GearmanMessage, io::Error> {
        let worker = self.worker.clone();
        let workers = self.workers.clone();
        let conn_id = self.conn_id;
        trace!("handle_can_do");
        body.concat2()
            .and_then(move |fname| {
                let fname = fname.freeze();
                debug!("CAN_DO fname = {:?}", fname);
                let mut worker = worker.lock().unwrap();
                worker.can_do(fname);
                workers.clone().wakeup(&mut worker, conn_id);
                future::finished(Message::WithBody(PacketHeader::noop(),
                                                   Body::from(BytesMut::new())))
            })
            .boxed()
    }

    fn handle_cant_do(&self, body: GearmanBody) -> BoxFuture<GearmanMessage, io::Error> {
        let worker = self.worker.clone();
        body.concat2()
            .and_then(move |fname| {
                let fname = fname.freeze();
                debug!("CANT_DO fname = {:?}", fname);
                let mut worker = worker.lock().unwrap();
                worker.cant_do(&fname);
                future::finished(Message::WithBody(PacketHeader::noop(),
                                                   Body::from(BytesMut::new())))
            })
            .boxed()
    }

    fn handle_grab_job_all(&self, body: GearmanBody) -> BoxFuture<GearmanMessage, io::Error> {
        let mut queues = self.queues.clone();
        let worker = self.worker.clone();
        trace!("handle_grab_job_all");
        body.concat2()
            .and_then(move |_| {
                let mut worker = worker.lock().unwrap();
                let ref mut worker = worker;
                if queues.get_job(worker) {
                    match worker.job() {
                        Some(ref j) => {
                            let mut data = BytesMut::with_capacity(4 + j.handle.len() +
                                                                   j.fname.len() +
                                                                   j.unique.len() +
                                                                   j.data.len());
                            data.extend(&j.handle);
                            data.put_slice(b"\0");
                            data.extend(&j.fname);
                            data.put_slice(b"\0");
                            data.extend(&j.unique);
                            data.put_slice(b"\0");
                            // reducer not implemented
                            data.put_slice(b"\0");
                            data.extend(&j.data);
                            return future::finished(new_res(JOB_ASSIGN_ALL, data)).boxed();
                        }
                        None => {}
                    }
                };
                future::finished(new_res(NO_JOB, BytesMut::new())).boxed()
            })
            .boxed()
    }

    fn handle_pre_sleep(&self) -> BoxFuture<GearmanMessage, io::Error> {
        let worker = self.worker.clone();
        let ref mut w = worker.lock().unwrap();
        self.workers.clone().sleep(w, self.conn_id);
        future::finished(Message::WithBody(PacketHeader::noop(), Body::from(BytesMut::new())))
            .boxed()
    }

    fn handle_submit_job(&self,
                         priority: JobQueuePriority,
                         wait: bool,
                         body: GearmanBody)
                         -> BoxFuture<GearmanMessage, io::Error> {
        let mut queues = self.queues.clone();
        let conn_id = match wait {
            true => Some(self.conn_id),
            false => None,
        };
        let mut workers = self.workers.clone();
        let job_count = self.job_count.clone();

        body.concat2()
            .and_then(move |mut fields| {
                let fname = next_field(&mut fields).unwrap();
                let unique = next_field(&mut fields).unwrap();
                let data = fields.freeze();
                let mut add = false;
                let handle = match queues.coalesce_unique(&unique, conn_id) {
                    Some(handle) => handle,
                    None => {
                        workers.queue_wake(&fname);
                        // H:091234567890
                        let mut handle = BytesMut::with_capacity(12);
                        let job_num = job_count.fetch_add(1, Ordering::Relaxed);
                        debug!("job_num = {}", job_num);
                        handle.extend(format!("H:{:010}", job_num).as_bytes());
                        add = true;
                        handle.freeze()
                    }
                };
                if add {
                    let job = Arc::new(Job::new(fname, unique, data, handle.clone()));
                    info!("Created job {:?}", job);
                    queues.add_job(job.clone(), priority, conn_id);
                }
                future::finished(new_res(JOB_CREATED, BytesMut::from(handle)))
            })
            .boxed()
    }
}

impl Service for GearmanService {
    type Request = GearmanMessage;
    type Response = GearmanMessage;
    type Error = io::Error;
    type Future = BoxFuture<Self::Response, Self::Error>;

    fn call(&self, req: Self::Request) -> Self::Future {
        debug!("Got a req {:?}", req);
        match req {
            Message::WithoutBody(header) => {
                match header.ptype {
                    ADMIN_VERSION | ADMIN_STATUS => {
                        future::ok(self.response_from_header(&header)).boxed()
                    }

                    _ => {
                        future::err(io::Error::new(io::ErrorKind::Other,
                                                   format!("Bodyless packet type = {}",
                                                           header.ptype)))
                            .boxed()
                    }
                }
            }
            Message::WithBody(header, body) => {
                match header.ptype {
                    SUBMIT_JOB => self.handle_submit_job(PRIORITY_NORMAL, false, body),
                    SUBMIT_JOB_HIGH => self.handle_submit_job(PRIORITY_HIGH, false, body),
                    SUBMIT_JOB_LOW => self.handle_submit_job(PRIORITY_LOW, false, body),
                    SUBMIT_JOB_BG => self.handle_submit_job(PRIORITY_NORMAL, true, body),
                    SUBMIT_JOB_HIGH_BG => self.handle_submit_job(PRIORITY_HIGH, true, body),
                    SUBMIT_JOB_LOW_BG => self.handle_submit_job(PRIORITY_LOW, true, body),
                    PRE_SLEEP => self.handle_pre_sleep(),
                    CAN_DO => self.handle_can_do(body),
                    CANT_DO => self.handle_cant_do(body),/*
                    GRAB_JOB => self.handle_grab_job(),
                    GRAB_JOB_UNIQ => self.handle_grab_job_uniq(),*/
                    GRAB_JOB_ALL => self.handle_grab_job_all(body),/*
                    WORK_COMPLETE => self.handle_work_complete(),
                    WORK_STATUS | WORK_DATA | WORK_WARNING => self.handle_work_update(),
                    ECHO_REQ => self.handle_echo_req(&req),*/
                    _ => {
                        error!("Unimplemented: {:?} processing packet", header);
                        future::err(io::Error::new(io::ErrorKind::Other,
                                                   format!("Invalid packet type {}", header.ptype)))
                            .boxed()
                    }
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>
//! Utilities for loading and using textures

use std::io;
use std::ptr;
use std::fmt;
use std::error;
use std::path::{Path, PathBuf};
use std::fs::File;
use png;
use gl;
use gl::types::*;

/// A wraper around a OpenGL texture object which can be modified
#[derive(Debug)]
pub struct Texture {
    texture: GLuint,
    pub format: TextureFormat,
    pub width: u32,
    pub height: u32,
}

impl Texture {
    /// Creates a texture from a raw OpenGL handle and some additional data. Intended for internal
    /// use only, use with care!
    pub fn from_raw(texture: GLuint, format: TextureFormat, width: u32, height: u32) -> Texture {
        Texture {
            texture: texture,
            format: format,
            width: width,
            height: height,
        }
    }

    /// Creates a texture from a image file.
    pub fn from_file<P>(path: P) -> Result<Texture, TextureError> where P: AsRef<Path> {
        let mut texture = Texture::new();
        texture.load_file(path)?;
        Ok(texture)
    }

    /// Creates a new texture without any ascociated data
    pub fn new() -> Texture {
        let mut texture = 0;

        unsafe {
            gl::GenTextures(1, &mut texture);
            gl::BindTexture(gl::TEXTURE_2D, texture);
            gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::NEAREST as GLint);
            gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::NEAREST as GLint);
        }

        Texture {
            texture: texture,
            format: TextureFormat::RGB_8,
            width: 0,
            height: 0,
        }
    }

    /// Attempts to load data from the given image file into this texture. Note that
    /// it is usually more convenient to create a new texture from a file using
    /// [`from_file(path)`](struct.Texture.html#method.from_file)
    ///
    /// # Example
    /// ```rust,no_run
    /// use gondola::texture::Texture;
    ///
    /// let mut texture = Texture::new();
    /// texture.load_file("assets/test.png").expect("Failed to load texture");
    /// ```
    pub fn load_file<P>(&mut self, path: P) -> Result<(), TextureError> where P: AsRef<Path> {
        let path = path.as_ref();
        let (info, data) = load_image(path)?;
        let texture_format = match (info.color_type, info.bit_depth) {
            (png::ColorType::RGBA, png::BitDepth::Eight) => TextureFormat::RGBA_8,
            (png::ColorType::RGB, png::BitDepth::Eight)  => TextureFormat::RGB_8,
            other => {
                let message = format!(
                    "Unsuported texture format ({:?}, {:?}) in \"{}\" ({}:{})",
                    other.0, other.1,
                    path.to_string_lossy(),
                    file!(), line!()
                );
                return Err(TextureError { source: path.to_owned(), error: io::Error::new(io::ErrorKind::Other, message) });
            }
        };
        self.load_data(&data, info.width, info.height, texture_format);
        Ok(())
    }

    /// Sets the data this texture points to
    pub fn load_data(&mut self, data: &[u8], width: u32, height: u32, format: TextureFormat) {
        unsafe {
            gl::BindTexture(gl::TEXTURE_2D, self.texture);
            gl::TexImage2D(gl::TEXTURE_2D, 0, // Mipmap level
                           format as GLint, // Internal format
                           width as GLsizei, height as GLsizei, 0, // Size and border
                           format.unsized_format(), // Data format
                           gl::UNSIGNED_BYTE, data.as_ptr() as *const GLvoid);
        }

        self.width = width;
        self.height = height;
        self.format = format;
    }

    /// Sets the data in a sub-region of this texture. The data is expected to be in the
    /// format this texture was initialized to. This texture needs to be initialized
    /// before this method can be used.
    /// Note that there is a debug assertion in place to ensure that the given region
    /// is within the bounds of this texture. If debug assertions are not enabled this
    /// function will return without taking any action.
    pub fn load_data_to_region(&mut self, data: &[u8], x: u32, y: u32, width: u32, height: u32) {
        if x + width > self.width && y + height > self.height {
            debug_assert!(false, "Invalid region passed ({}:{}) Region: (x: {}, y: {}, width: {}, height: {})",
                          file!(), line!(),
                          x, y, width, height);
            return;
        }
        unsafe {
            // OpenGL is allowed to expect rows in pixel data to be aligned
            // at powers of two. This ensures that any data will be accepted.
            gl::PixelStorei(gl::PACK_ALIGNMENT, 1);
            gl::PixelStorei(gl::UNPACK_ALIGNMENT, 1);

            gl::BindTexture(gl::TEXTURE_2D, self.texture);
            gl::TexSubImage2D(gl::TEXTURE_2D, 0,
                              x as GLint, y as GLint,
                              width as GLsizei, height as GLsizei,
                              self.format.unsized_format(), // It is unclear whether opengl allows a different format here
                              gl::UNSIGNED_BYTE, data.as_ptr() as *const GLvoid);
        }
    }

    /// Converts this texture to a empty texture of the given size. The contents
    /// of the texture after this operation are undefined.
    pub fn initialize(&mut self, width: u32, height: u32, format: TextureFormat) {
        unsafe {
            gl::BindTexture(gl::TEXTURE_2D, self.texture);
            gl::TexImage2D(gl::TEXTURE_2D, 0, // Mipmap level
                           format as GLint, // Internal format
                           width as GLsizei, height as GLsizei, 0, // Size and border
                           format.unsized_format(), // Data format
                           gl::UNSIGNED_BYTE, ptr::null());
        }

        self.width = width;
        self.height = height;
        self.format = format;
    }

    /// Binds this texture to the given texture unit.
    pub fn bind(&self, unit: u32) {
        unsafe {
            gl::ActiveTexture(gl::TEXTURE0 + unit);
            gl::BindTexture(gl::TEXTURE_2D, self.texture);
        }
    }

    /// Sets the filter that is applied when this texture is rendered at a size larger
    /// or smaller sizes than the native size of the texture. A separate filter can be
    /// set for magnification and minification.
    pub fn set_filter(&mut self, mag: TextureFilter, min: TextureFilter) {
        unsafe {
            gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, mag as GLint);
            gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, min as GLint);
        }
    }

    /// Sets the texture filter, allowing for a separate filter to be used when mipmapping
    pub fn set_mipmap_filter(&mut self, mag: TextureFilter, mipmap_mag: TextureFilter,
                             min: TextureFilter, mipmap_min: TextureFilter) {
        unsafe {
            gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, TextureFilter::mipmap_filter(mag, mipmap_mag) as GLint);
            gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, TextureFilter::mipmap_filter(min, mipmap_min) as GLint);
        }
    }

    /// Sets the swizzle mask of this texture. The swizzle mask specifies how data stored
    /// in this texture is seen by other parts of OpenGL. This includes texture samplers
    /// in shaders. This is usefull when using textures with only one or two components
    /// per pixel.
    ///
    /// For example, given a texture with only a red component (That is, its
    /// format is `TextureFormat::R_8` or similar), a texture sampler in a shader will
    /// normaly get a value of type `(r, 0.0, 0.0, 1.0)`. By setting the swizzle mask
    /// to `(SwizzleComp::One, SwizzleComp::One, SwizzleComp::One, SwizzleComp::Red)`
    /// shaders will now see `(1.0, 1.0, 1.0, r)`.
    pub fn set_swizzle_mask(&mut self, masks: (SwizzleComp, SwizzleComp, SwizzleComp, SwizzleComp)) {
        unsafe {
            let masks = [masks.0 as GLint, masks.1 as GLint, masks.2 as GLint, masks.3 as GLint];
            gl::TexParameteriv(gl::TEXTURE_2D, gl::TEXTURE_SWIZZLE_RGBA, &masks as *const _);
        }
    }
}

impl Drop for Texture {
    fn drop(&mut self) {
        unsafe {
            gl::DeleteTextures(1, &self.texture);
        }
    }
}

/// Loads image data from a file
fn load_image(path: &Path) -> Result<(png::OutputInfo, Vec<u8>), TextureError> {
    let file = match File::open(path) {
        Ok(file) => file,
        Err(err) => return Err(TextureError { source: path.to_owned(), error: err }),
    };

    let decoder = png::Decoder::new(file);

    let (info, mut reader) = match decoder.read_info() {
        Ok(result) => result,
        Err(err) => return Err(TextureError { source: path.to_owned(), error: err.into() }),
    };

    let mut buf = vec![0; info.buffer_size()];

    match reader.next_frame(&mut buf) {
        Ok(()) => {},
        Err(err) => return Err(TextureError { source: path.to_owned(), error: err.into() }),
    };

    Ok((info, buf))
}

/// Represents an OpenGL texture filter.
#[repr(u32)] // GLenum is u32
#[derive(Debug, Copy, Clone)]
pub enum TextureFilter {
    Nearest = gl::NEAREST,
    Linear  = gl::LINEAR
}
impl TextureFilter {
    /// Retrieves a OpenGL mipmap filter for mipmaping. The returned `GLenum` can
    /// be used in the same scenarios as ´TextureFilter::* as GLenum´
    fn mipmap_filter(normal: TextureFilter, mipmap: TextureFilter) -> GLenum {
        match normal {
            TextureFilter::Nearest => match mipmap {
                TextureFilter::Nearest => gl::NEAREST_MIPMAP_NEAREST,
                TextureFilter::Linear => gl::NEAREST_MIPMAP_LINEAR,
            },
            TextureFilter::Linear => match mipmap {
                TextureFilter::Nearest => gl::LINEAR_MIPMAP_NEAREST,
                TextureFilter::Linear => gl::LINEAR_MIPMAP_LINEAR,
            },
        }
    }
}

/// Represents a OpenGL texture format.
#[repr(u32)] // GLenum is u32
#[allow(non_camel_case_types, dead_code)]
#[derive(Debug, Copy, Clone)]
pub enum TextureFormat {
    RGBA_F32 = gl::RGBA32F,
    RGBA_F16 = gl::RGBA16F,
    RGB_F32  = gl::RGB32F,
    RGB_F16  = gl::RGB16F,
    R_F32    = gl::R32F,
    R_F16    = gl::R16F,

    RGBA_8   = gl::RGBA8,
    RGB_8    = gl::RGB8,
    R_8      = gl::R8,
}
impl TextureFormat {
    /// Retrieves the unsized version of the given format
    pub fn unsized_format(&self) -> GLenum {
        match *self {
            TextureFormat::RGBA_F32 | TextureFormat::RGBA_F16 | TextureFormat::RGBA_8 => gl::RGBA,
            TextureFormat::RGB_F32 | TextureFormat::RGB_F16 | TextureFormat::RGB_8 => gl::RGB,
            TextureFormat::R_F32 | TextureFormat::R_F16 | TextureFormat::R_8 => gl::RED,
        }
    }

    /// The OpenGL primitive associated with this color format.
    pub fn gl_primitive_enum(&self) -> GLenum {
        match *self {
            TextureFormat::RGBA_F32 | TextureFormat::RGB_F32 | TextureFormat::R_F32 => gl::FLOAT,
            TextureFormat::RGBA_F16 | TextureFormat::RGB_F16 | TextureFormat::R_F16 => gl::FLOAT,
            TextureFormat::RGBA_8 | TextureFormat::RGB_8 | TextureFormat::R_8 => gl::UNSIGNED_BYTE,
        }
    }

    /// The name of the OpenGL primitive associated with this color format.
    pub fn gl_primitive_enum_name(&self) -> &'static str {
        match *self {
            TextureFormat::RGBA_F32 | TextureFormat::RGB_F32 | TextureFormat::R_F32 => "GLfloat",
            TextureFormat::RGBA_F16 | TextureFormat::RGB_F16 | TextureFormat::R_F16 => "GLfloat",
            TextureFormat::RGBA_8 | TextureFormat::RGB_8 | TextureFormat::R_8 => "GLbyte",
        }
    }

    /// The number of components this color format has. For example, `RGB_8` has 3 components.
    pub fn components(&self) -> usize {
        match *self {
            TextureFormat::RGBA_F32 | TextureFormat::RGBA_F16 | TextureFormat::RGBA_8 => 4,
            TextureFormat::RGB_F32 | TextureFormat::RGB_F16 | TextureFormat::RGB_8 => 3,
            TextureFormat::R_F32 | TextureFormat::R_F16 | TextureFormat::R_8 => 1,
        }
    }
}

/// Components that a texture can be mapped to through swizzling. See
/// [`set_swizzle_mask`](struct.Texture.html#method.set_swizzle_mask)
/// for more info.
#[repr(u32)] // GLenum is u32
#[derive(Debug, Copy, Clone)]
pub enum SwizzleComp {
    Red     = gl::RED,
    Green   = gl::GREEN,
    Blue    = gl::BLUE,
    Alpha   = gl::ALPHA,
    One     = gl::ONE,
    Zero    = gl::ZERO,
}

/// A error which can occur during texture loading and creation.
#[derive(Debug)]
pub struct TextureError {
    source: PathBuf,
    error: io::Error,
}

impl error::Error for TextureError {
    fn description(&self) -> &str {
        self.error.description()
    }

    fn cause(&self) -> Option<&error::Error> {
        self.error.cause()
    }
}

impl fmt::Display for TextureError {
    fn fmt(&self, mut f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "For texture \"{}\": ", self.source.to_string_lossy())?;
        self.error.fmt(&mut f)?;
        Ok(())
    }
}
<commit_msg>Allow directly unbinding textures<commit_after>
//! Utilities for loading and using textures

use std::io;
use std::ptr;
use std::fmt;
use std::error;
use std::path::{Path, PathBuf};
use std::fs::File;
use png;
use gl;
use gl::types::*;

/// A wraper around a OpenGL texture object which can be modified
#[derive(Debug)]
pub struct Texture {
    texture: GLuint,
    pub format: TextureFormat,
    pub width: u32,
    pub height: u32,
}

impl Texture {
    /// Creates a texture from a raw OpenGL handle and some additional data. Intended for internal
    /// use only, use with care!
    pub fn from_raw(texture: GLuint, format: TextureFormat, width: u32, height: u32) -> Texture {
        Texture {
            texture: texture,
            format: format,
            width: width,
            height: height,
        }
    }

    /// Creates a texture from a image file.
    pub fn from_file<P>(path: P) -> Result<Texture, TextureError> where P: AsRef<Path> {
        let mut texture = Texture::new();
        texture.load_file(path)?;
        Ok(texture)
    }

    /// Creates a new texture without any ascociated data
    pub fn new() -> Texture {
        let mut texture = 0;

        unsafe {
            gl::GenTextures(1, &mut texture);
            gl::BindTexture(gl::TEXTURE_2D, texture);
            gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::NEAREST as GLint);
            gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::NEAREST as GLint);
        }

        Texture {
            texture: texture,
            format: TextureFormat::RGB_8,
            width: 0,
            height: 0,
        }
    }

    /// Attempts to load data from the given image file into this texture. Note that
    /// it is usually more convenient to create a new texture from a file using
    /// [`from_file(path)`](struct.Texture.html#method.from_file)
    ///
    /// # Example
    /// ```rust,no_run
    /// use gondola::texture::Texture;
    ///
    /// let mut texture = Texture::new();
    /// texture.load_file("assets/test.png").expect("Failed to load texture");
    /// ```
    pub fn load_file<P>(&mut self, path: P) -> Result<(), TextureError> where P: AsRef<Path> {
        let path = path.as_ref();
        let (info, data) = load_image(path)?;
        let texture_format = match (info.color_type, info.bit_depth) {
            (png::ColorType::RGBA, png::BitDepth::Eight) => TextureFormat::RGBA_8,
            (png::ColorType::RGB, png::BitDepth::Eight)  => TextureFormat::RGB_8,
            other => {
                let message = format!(
                    "Unsuported texture format ({:?}, {:?}) in \"{}\" ({}:{})",
                    other.0, other.1,
                    path.to_string_lossy(),
                    file!(), line!()
                );
                return Err(TextureError { source: path.to_owned(), error: io::Error::new(io::ErrorKind::Other, message) });
            }
        };
        self.load_data(&data, info.width, info.height, texture_format);
        Ok(())
    }

    /// Sets the data this texture points to
    pub fn load_data(&mut self, data: &[u8], width: u32, height: u32, format: TextureFormat) {
        unsafe {
            gl::BindTexture(gl::TEXTURE_2D, self.texture);
            gl::TexImage2D(gl::TEXTURE_2D, 0, // Mipmap level
                           format as GLint, // Internal format
                           width as GLsizei, height as GLsizei, 0, // Size and border
                           format.unsized_format(), // Data format
                           gl::UNSIGNED_BYTE, data.as_ptr() as *const GLvoid);
        }

        self.width = width;
        self.height = height;
        self.format = format;
    }

    /// Sets the data in a sub-region of this texture. The data is expected to be in the
    /// format this texture was initialized to. This texture needs to be initialized
    /// before this method can be used.
    /// Note that there is a debug assertion in place to ensure that the given region
    /// is within the bounds of this texture. If debug assertions are not enabled this
    /// function will return without taking any action.
    pub fn load_data_to_region(&mut self, data: &[u8], x: u32, y: u32, width: u32, height: u32) {
        if x + width > self.width && y + height > self.height {
            debug_assert!(false, "Invalid region passed ({}:{}) Region: (x: {}, y: {}, width: {}, height: {})",
                          file!(), line!(),
                          x, y, width, height);
            return;
        }
        unsafe {
            // OpenGL is allowed to expect rows in pixel data to be aligned
            // at powers of two. This ensures that any data will be accepted.
            gl::PixelStorei(gl::PACK_ALIGNMENT, 1);
            gl::PixelStorei(gl::UNPACK_ALIGNMENT, 1);

            gl::BindTexture(gl::TEXTURE_2D, self.texture);
            gl::TexSubImage2D(gl::TEXTURE_2D, 0,
                              x as GLint, y as GLint,
                              width as GLsizei, height as GLsizei,
                              self.format.unsized_format(), // It is unclear whether opengl allows a different format here
                              gl::UNSIGNED_BYTE, data.as_ptr() as *const GLvoid);
        }
    }

    /// Converts this texture to a empty texture of the given size. The contents
    /// of the texture after this operation are undefined.
    pub fn initialize(&mut self, width: u32, height: u32, format: TextureFormat) {
        unsafe {
            gl::BindTexture(gl::TEXTURE_2D, self.texture);
            gl::TexImage2D(gl::TEXTURE_2D, 0, // Mipmap level
                           format as GLint, // Internal format
                           width as GLsizei, height as GLsizei, 0, // Size and border
                           format.unsized_format(), // Data format
                           gl::UNSIGNED_BYTE, ptr::null());
        }

        self.width = width;
        self.height = height;
        self.format = format;
    }

    /// Binds this texture to the given texture unit.
    pub fn bind(&self, unit: u32) {
        unsafe {
            gl::ActiveTexture(gl::TEXTURE0 + unit);
            gl::BindTexture(gl::TEXTURE_2D, self.texture);
        }
    }

    /// Unbinds the texture at the given texture unit.
    pub fn unbind(unit: u32) {
        unsafe {
            gl::ActiveTexture(gl::TEXTURE0 + unit);
            gl::BindTexture(gl::TEXTURE_2D, 0);
        }
    }

    /// Sets the filter that is applied when this texture is rendered at a size larger
    /// or smaller sizes than the native size of the texture. A separate filter can be
    /// set for magnification and minification.
    pub fn set_filter(&mut self, mag: TextureFilter, min: TextureFilter) {
        unsafe {
            gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, mag as GLint);
            gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, min as GLint);
        }
    }

    /// Sets the texture filter, allowing for a separate filter to be used when mipmapping
    pub fn set_mipmap_filter(&mut self, mag: TextureFilter, mipmap_mag: TextureFilter,
                             min: TextureFilter, mipmap_min: TextureFilter) {
        unsafe {
            gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, TextureFilter::mipmap_filter(mag, mipmap_mag) as GLint);
            gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, TextureFilter::mipmap_filter(min, mipmap_min) as GLint);
        }
    }

    /// Sets the swizzle mask of this texture. The swizzle mask specifies how data stored
    /// in this texture is seen by other parts of OpenGL. This includes texture samplers
    /// in shaders. This is usefull when using textures with only one or two components
    /// per pixel.
    ///
    /// For example, given a texture with only a red component (That is, its
    /// format is `TextureFormat::R_8` or similar), a texture sampler in a shader will
    /// normaly get a value of type `(r, 0.0, 0.0, 1.0)`. By setting the swizzle mask
    /// to `(SwizzleComp::One, SwizzleComp::One, SwizzleComp::One, SwizzleComp::Red)`
    /// shaders will now see `(1.0, 1.0, 1.0, r)`.
    pub fn set_swizzle_mask(&mut self, masks: (SwizzleComp, SwizzleComp, SwizzleComp, SwizzleComp)) {
        unsafe {
            let masks = [masks.0 as GLint, masks.1 as GLint, masks.2 as GLint, masks.3 as GLint];
            gl::TexParameteriv(gl::TEXTURE_2D, gl::TEXTURE_SWIZZLE_RGBA, &masks as *const _);
        }
    }
}

impl Drop for Texture {
    fn drop(&mut self) {
        unsafe {
            gl::DeleteTextures(1, &self.texture);
        }
    }
}

/// Loads image data from a file
fn load_image(path: &Path) -> Result<(png::OutputInfo, Vec<u8>), TextureError> {
    let file = match File::open(path) {
        Ok(file) => file,
        Err(err) => return Err(TextureError { source: path.to_owned(), error: err }),
    };

    let decoder = png::Decoder::new(file);

    let (info, mut reader) = match decoder.read_info() {
        Ok(result) => result,
        Err(err) => return Err(TextureError { source: path.to_owned(), error: err.into() }),
    };

    let mut buf = vec![0; info.buffer_size()];

    match reader.next_frame(&mut buf) {
        Ok(()) => {},
        Err(err) => return Err(TextureError { source: path.to_owned(), error: err.into() }),
    };

    Ok((info, buf))
}

/// Represents an OpenGL texture filter.
#[repr(u32)] // GLenum is u32
#[derive(Debug, Copy, Clone)]
pub enum TextureFilter {
    Nearest = gl::NEAREST,
    Linear  = gl::LINEAR
}
impl TextureFilter {
    /// Retrieves a OpenGL mipmap filter for mipmaping. The returned `GLenum` can
    /// be used in the same scenarios as ´TextureFilter::* as GLenum´
    fn mipmap_filter(normal: TextureFilter, mipmap: TextureFilter) -> GLenum {
        match normal {
            TextureFilter::Nearest => match mipmap {
                TextureFilter::Nearest => gl::NEAREST_MIPMAP_NEAREST,
                TextureFilter::Linear => gl::NEAREST_MIPMAP_LINEAR,
            },
            TextureFilter::Linear => match mipmap {
                TextureFilter::Nearest => gl::LINEAR_MIPMAP_NEAREST,
                TextureFilter::Linear => gl::LINEAR_MIPMAP_LINEAR,
            },
        }
    }
}

/// Represents a OpenGL texture format.
#[repr(u32)] // GLenum is u32
#[allow(non_camel_case_types, dead_code)]
#[derive(Debug, Copy, Clone)]
pub enum TextureFormat {
    RGBA_F32 = gl::RGBA32F,
    RGBA_F16 = gl::RGBA16F,
    RGB_F32  = gl::RGB32F,
    RGB_F16  = gl::RGB16F,
    R_F32    = gl::R32F,
    R_F16    = gl::R16F,

    RGBA_8   = gl::RGBA8,
    RGB_8    = gl::RGB8,
    R_8      = gl::R8,
}
impl TextureFormat {
    /// Retrieves the unsized version of the given format
    pub fn unsized_format(&self) -> GLenum {
        match *self {
            TextureFormat::RGBA_F32 | TextureFormat::RGBA_F16 | TextureFormat::RGBA_8 => gl::RGBA,
            TextureFormat::RGB_F32 | TextureFormat::RGB_F16 | TextureFormat::RGB_8 => gl::RGB,
            TextureFormat::R_F32 | TextureFormat::R_F16 | TextureFormat::R_8 => gl::RED,
        }
    }

    /// The OpenGL primitive associated with this color format.
    pub fn gl_primitive_enum(&self) -> GLenum {
        match *self {
            TextureFormat::RGBA_F32 | TextureFormat::RGB_F32 | TextureFormat::R_F32 => gl::FLOAT,
            TextureFormat::RGBA_F16 | TextureFormat::RGB_F16 | TextureFormat::R_F16 => gl::FLOAT,
            TextureFormat::RGBA_8 | TextureFormat::RGB_8 | TextureFormat::R_8 => gl::UNSIGNED_BYTE,
        }
    }

    /// The name of the OpenGL primitive associated with this color format.
    pub fn gl_primitive_enum_name(&self) -> &'static str {
        match *self {
            TextureFormat::RGBA_F32 | TextureFormat::RGB_F32 | TextureFormat::R_F32 => "GLfloat",
            TextureFormat::RGBA_F16 | TextureFormat::RGB_F16 | TextureFormat::R_F16 => "GLfloat",
            TextureFormat::RGBA_8 | TextureFormat::RGB_8 | TextureFormat::R_8 => "GLbyte",
        }
    }

    /// The number of components this color format has. For example, `RGB_8` has 3 components.
    pub fn components(&self) -> usize {
        match *self {
            TextureFormat::RGBA_F32 | TextureFormat::RGBA_F16 | TextureFormat::RGBA_8 => 4,
            TextureFormat::RGB_F32 | TextureFormat::RGB_F16 | TextureFormat::RGB_8 => 3,
            TextureFormat::R_F32 | TextureFormat::R_F16 | TextureFormat::R_8 => 1,
        }
    }
}

/// Components that a texture can be mapped to through swizzling. See
/// [`set_swizzle_mask`](struct.Texture.html#method.set_swizzle_mask)
/// for more info.
#[repr(u32)] // GLenum is u32
#[derive(Debug, Copy, Clone)]
pub enum SwizzleComp {
    Red     = gl::RED,
    Green   = gl::GREEN,
    Blue    = gl::BLUE,
    Alpha   = gl::ALPHA,
    One     = gl::ONE,
    Zero    = gl::ZERO,
}

/// A error which can occur during texture loading and creation.
#[derive(Debug)]
pub struct TextureError {
    source: PathBuf,
    error: io::Error,
}

impl error::Error for TextureError {
    fn description(&self) -> &str {
        self.error.description()
    }

    fn cause(&self) -> Option<&error::Error> {
        self.error.cause()
    }
}

impl fmt::Display for TextureError {
    fn fmt(&self, mut f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "For texture \"{}\": ", self.source.to_string_lossy())?;
        self.error.fmt(&mut f)?;
        Ok(())
    }
}
<|endoftext|>


<commit_before>//! This module implements and describes common TTY methods & traits
use std::io::{self, Write};

use Result;
use config::Config;
use consts::KeyPress;
use line_buffer::LineBuffer;

/// Terminal state
pub trait RawMode: Sized {
    /// Disable RAW mode for the terminal.
    fn disable_raw_mode(&self) -> Result<()>;
}

/// Translate bytes read from stdin to keys.
pub trait RawReader {
    /// Blocking read of key pressed.
    fn next_key(&mut self) -> Result<KeyPress>;
    /// For CTRL-V support
    #[cfg(unix)]
    fn next_char(&mut self) -> Result<char>;
}

#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
pub struct Position {
    pub col: usize,
    pub row: usize,
}

/// Display prompt, line and cursor in terminal output
pub trait Renderer {
    fn move_cursor(&mut self, old: Position, new: Position) -> Result<()>;

    /// Display prompt, line and cursor in terminal output
    fn refresh_line(
        &mut self,
        prompt: &str,
        prompt_size: Position,
        line: &LineBuffer,
        hint: Option<String>,
        current_row: usize,
        old_rows: usize,
    ) -> Result<(Position, Position)>;

    /// Calculate the number of columns and rows used to display `s` on a
    /// `cols` width terminal
    /// starting at `orig`.
    fn calculate_position(&self, s: &str, orig: Position) -> Position;

    fn write_and_flush(&mut self, buf: &[u8]) -> Result<()>;

    /// Beep, used for completion when there is nothing to complete or when all
    /// the choices were already shown.
    fn beep(&mut self) -> Result<()> {
        // TODO bell-style
        try!(io::stderr().write_all(b"\x07"));
        try!(io::stderr().flush());
        Ok(())
    }

    /// Clear the screen. Used to handle ctrl+l
    fn clear_screen(&mut self) -> Result<()>;

    /// Check if a SIGWINCH signal has been received
    fn sigwinch(&self) -> bool;
    /// Update the number of columns/rows in the current terminal.
    fn update_size(&mut self);
    /// Get the number of rows in the current terminal.
    fn get_columns(&self) -> usize;
    /// Get the number of rows in the current terminal.
    fn get_rows(&self) -> usize;
}

impl<'a, R: Renderer + ?Sized> Renderer for &'a mut R {
    fn move_cursor(&mut self, old: Position, new: Position) -> Result<()> {
        (**self).move_cursor(old, new)
    }
    fn refresh_line(
        &mut self,
        prompt: &str,
        prompt_size: Position,
        line: &LineBuffer,
        hint: Option<String>,
        current_row: usize,
        old_rows: usize,
    ) -> Result<(Position, Position)> {
        (**self).refresh_line(prompt, prompt_size, line, hint, current_row, old_rows)
    }
    fn calculate_position(&self, s: &str, orig: Position) -> Position {
        (**self).calculate_position(s, orig)
    }
    fn write_and_flush(&mut self, buf: &[u8]) -> Result<()> {
        (**self).write_and_flush(buf)
    }
    fn beep(&mut self) -> Result<()> {
        (**self).beep()
    }
    fn clear_screen(&mut self) -> Result<()> {
        (**self).clear_screen()
    }
    fn sigwinch(&self) -> bool {
        (**self).sigwinch()
    }
    fn update_size(&mut self) {
        (**self).update_size()
    }
    fn get_columns(&self) -> usize {
        (**self).get_columns()
    }
    fn get_rows(&self) -> usize {
        (**self).get_rows()
    }
}

/// Terminal contract
pub trait Term {
    type Reader: RawReader;
    type Writer: Renderer;
    type Mode: RawMode;

    fn new() -> Self;
    /// Check if current terminal can provide a rich line-editing user
    /// interface.
    fn is_unsupported(&self) -> bool;
    /// check if stdin is connected to a terminal.
    fn is_stdin_tty(&self) -> bool;
    /// Enable RAW mode for the terminal.
    fn enable_raw_mode(&self) -> Result<Self::Mode>;
    /// Create a RAW reader
    fn create_reader(&self, config: &Config) -> Result<Self::Reader>;
    /// Create a writer
    fn create_writer(&self) -> Self::Writer;
}

// If on Windows platform import Windows TTY module
// and re-export into mod.rs scope
#[cfg(all(windows, not(test)))]
mod windows;
#[cfg(all(windows, not(test)))]
pub use self::windows::*;

// If on Unix platform import Unix TTY module
// and re-export into mod.rs scope
#[cfg(all(unix, not(test)))]
mod unix;
#[cfg(all(unix, not(test)))]
pub use self::unix::*;

#[cfg(test)]
mod test;
#[cfg(test)]
pub use self::test::*;
<commit_msg>Fix typo in comment<commit_after>//! This module implements and describes common TTY methods & traits
use std::io::{self, Write};

use Result;
use config::Config;
use consts::KeyPress;
use line_buffer::LineBuffer;

/// Terminal state
pub trait RawMode: Sized {
    /// Disable RAW mode for the terminal.
    fn disable_raw_mode(&self) -> Result<()>;
}

/// Translate bytes read from stdin to keys.
pub trait RawReader {
    /// Blocking read of key pressed.
    fn next_key(&mut self) -> Result<KeyPress>;
    /// For CTRL-V support
    #[cfg(unix)]
    fn next_char(&mut self) -> Result<char>;
}

#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
pub struct Position {
    pub col: usize,
    pub row: usize,
}

/// Display prompt, line and cursor in terminal output
pub trait Renderer {
    fn move_cursor(&mut self, old: Position, new: Position) -> Result<()>;

    /// Display prompt, line and cursor in terminal output
    fn refresh_line(
        &mut self,
        prompt: &str,
        prompt_size: Position,
        line: &LineBuffer,
        hint: Option<String>,
        current_row: usize,
        old_rows: usize,
    ) -> Result<(Position, Position)>;

    /// Calculate the number of columns and rows used to display `s` on a
    /// `cols` width terminal
    /// starting at `orig`.
    fn calculate_position(&self, s: &str, orig: Position) -> Position;

    fn write_and_flush(&mut self, buf: &[u8]) -> Result<()>;

    /// Beep, used for completion when there is nothing to complete or when all
    /// the choices were already shown.
    fn beep(&mut self) -> Result<()> {
        // TODO bell-style
        try!(io::stderr().write_all(b"\x07"));
        try!(io::stderr().flush());
        Ok(())
    }

    /// Clear the screen. Used to handle ctrl+l
    fn clear_screen(&mut self) -> Result<()>;

    /// Check if a SIGWINCH signal has been received
    fn sigwinch(&self) -> bool;
    /// Update the number of columns/rows in the current terminal.
    fn update_size(&mut self);
    /// Get the number of columns in the current terminal.
    fn get_columns(&self) -> usize;
    /// Get the number of rows in the current terminal.
    fn get_rows(&self) -> usize;
}

impl<'a, R: Renderer + ?Sized> Renderer for &'a mut R {
    fn move_cursor(&mut self, old: Position, new: Position) -> Result<()> {
        (**self).move_cursor(old, new)
    }
    fn refresh_line(
        &mut self,
        prompt: &str,
        prompt_size: Position,
        line: &LineBuffer,
        hint: Option<String>,
        current_row: usize,
        old_rows: usize,
    ) -> Result<(Position, Position)> {
        (**self).refresh_line(prompt, prompt_size, line, hint, current_row, old_rows)
    }
    fn calculate_position(&self, s: &str, orig: Position) -> Position {
        (**self).calculate_position(s, orig)
    }
    fn write_and_flush(&mut self, buf: &[u8]) -> Result<()> {
        (**self).write_and_flush(buf)
    }
    fn beep(&mut self) -> Result<()> {
        (**self).beep()
    }
    fn clear_screen(&mut self) -> Result<()> {
        (**self).clear_screen()
    }
    fn sigwinch(&self) -> bool {
        (**self).sigwinch()
    }
    fn update_size(&mut self) {
        (**self).update_size()
    }
    fn get_columns(&self) -> usize {
        (**self).get_columns()
    }
    fn get_rows(&self) -> usize {
        (**self).get_rows()
    }
}

/// Terminal contract
pub trait Term {
    type Reader: RawReader;
    type Writer: Renderer;
    type Mode: RawMode;

    fn new() -> Self;
    /// Check if current terminal can provide a rich line-editing user
    /// interface.
    fn is_unsupported(&self) -> bool;
    /// check if stdin is connected to a terminal.
    fn is_stdin_tty(&self) -> bool;
    /// Enable RAW mode for the terminal.
    fn enable_raw_mode(&self) -> Result<Self::Mode>;
    /// Create a RAW reader
    fn create_reader(&self, config: &Config) -> Result<Self::Reader>;
    /// Create a writer
    fn create_writer(&self) -> Self::Writer;
}

// If on Windows platform import Windows TTY module
// and re-export into mod.rs scope
#[cfg(all(windows, not(test)))]
mod windows;
#[cfg(all(windows, not(test)))]
pub use self::windows::*;

// If on Unix platform import Unix TTY module
// and re-export into mod.rs scope
#[cfg(all(unix, not(test)))]
mod unix;
#[cfg(all(unix, not(test)))]
pub use self::unix::*;

#[cfg(test)]
mod test;
#[cfg(test)]
pub use self::test::*;
<|endoftext|>


<commit_before>
fn calculate_return(cost :f64, given :f64) -> f64 {
    return given - cost
}

#[test]
fn calculate_return_test(){
    assert!(calculate_return(13.23f64, 15.00f64) == 1.77f64, "expected {:?} is {:?}", 1.77f64, calculate_return(13.23f64, 15.00f64));
}

#[test]
fn calculate_return_test2(){
    assert!(calculate_return(132.23f64, 150.00f64) == 17.77f64, "expected {:?} is {:?}", 17.77f64, calculate_return(132.23f64, 150.00f64));
}

fn main() {
    println!("{}",calculate_return(123.45, 130.00));
}
<commit_msg>Let the tests for cost_return pass.<commit_after>
fn calculate_return(cost :f64, given :f64) -> f64 {
    return given - cost
}

#[test]
fn calculate_return_test(){
    assert_eq!(calculate_return(13.23f64, 15.00f64), 15f64-13.23f64);
}

#[test]
fn calculate_return_test2(){
    assert_eq!(calculate_return(132.23f64, 150.00f64), 150f64-132.23f64);
}

#[test]
fn calculate_return_test3(){
    assert_eq!(calculate_return(1f64, 2f64), 1f64);
}

fn main() {
    println!("{}",calculate_return(123.45, 130.00));
}
<|endoftext|>