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

use collections::borrow::ToOwned;
use net_traits::image::base::{Image, load_from_memory};
use net_traits::image_cache_task::{ImageState, ImageCacheTask, ImageCacheChan, ImageCacheCommand, ImageCacheResult};
use net_traits::load_whole_resource;
use std::collections::HashMap;
use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::mem;
use std::sync::Arc;
use std::sync::mpsc::{channel, Sender, Receiver, Select};
use util::resource_files::resources_dir_path;
use util::task::spawn_named;
use util::taskpool::TaskPool;
use url::Url;
use net_traits::{AsyncResponseTarget, ControlMsg, LoadData, ResponseAction, ResourceTask, LoadConsumer};
use net_traits::image_cache_task::ImageResponder;

///
/// TODO(gw): Remaining work on image cache:
///     * Make use of the prefetch support in various parts of the code.
///     * Experiment with changing the image 'key' from being a url to a resource id
///         This might be a decent performance win and/or memory saving in some cases (esp. data urls)
///     * Profile time in GetImageIfAvailable - might be worth caching these results per paint / layout task.
///

/// Represents an image that is either being loaded
/// by the resource task, or decoded by a worker thread.
struct PendingLoad {
    bytes: Vec<u8>,
    result: Option<Result<(), String>>,
    listeners: Vec<ImageListener>,
}

impl PendingLoad {
    fn new() -> PendingLoad {
        PendingLoad {
            bytes: vec!(),
            result: None,
            listeners: vec!(),
        }
    }

    fn add_listener(&mut self, listener: ImageListener) {
        self.listeners.push(listener);
    }
}

/// Represents an image that has completed loading.
/// Images that fail to load (due to network or decode
/// failure) are still stored here, so that they aren't
/// fetched again.
struct CompletedLoad {
    image: Option<Arc<Image>>,
}

impl CompletedLoad {
    fn new(image: Option<Arc<Image>>) -> CompletedLoad {
        CompletedLoad {
            image: image,
        }
    }
}

/// Stores information to notify a client when the state
/// of an image changes.
struct ImageListener {
    sender: ImageCacheChan,
    responder: Option<Box<ImageResponder>>,
}

impl ImageListener {
    fn new(sender: ImageCacheChan, responder: Option<Box<ImageResponder>>) -> ImageListener {
        ImageListener {
            sender: sender,
            responder: responder,
        }
    }

    fn notify(self, image: Option<Arc<Image>>) {
        let ImageCacheChan(ref sender) = self.sender;
        let msg = ImageCacheResult {
            responder: self.responder,
            image: image,
        };
        sender.send(msg).ok();
    }
}

struct ResourceLoadInfo {
    action: ResponseAction,
    url: Url,
}

struct ResourceListener {
    url: Url,
    sender: Sender<ResourceLoadInfo>,
}

impl AsyncResponseTarget for ResourceListener {
    fn invoke_with_listener(&self, action: ResponseAction) {
        self.sender.send(ResourceLoadInfo {
            action: action,
            url: self.url.clone(),
        }).unwrap();
    }
}

/// Implementation of the image cache
struct ImageCache {
    // Receive commands from clients
    cmd_receiver: Receiver<ImageCacheCommand>,

    // Receive notifications from the resource task
    progress_receiver: Receiver<ResourceLoadInfo>,
    progress_sender: Sender<ResourceLoadInfo>,

    // Receive notifications from the decoder thread pool
    decoder_receiver: Receiver<DecoderMsg>,
    decoder_sender: Sender<DecoderMsg>,

    // Worker threads for decoding images.
    task_pool: TaskPool,

    // Resource task handle
    resource_task: ResourceTask,

    // Images that are loading over network, or decoding.
    pending_loads: HashMap<Url, PendingLoad>,

    // Images that have finished loading (successful or not)
    completed_loads: HashMap<Url, CompletedLoad>,

    // The placeholder image used when an image fails to load
    placeholder_image: Option<Arc<Image>>,
}

/// Message that the decoder worker threads send to main image cache task.
struct DecoderMsg {
    url: Url,
    image: Option<Image>,
}

/// The types of messages that the main image cache task receives.
enum SelectResult {
    Command(ImageCacheCommand),
    Progress(ResourceLoadInfo),
    Decoder(DecoderMsg),
}

impl ImageCache {
    fn run(&mut self) {
        let mut exit_sender: Option<Sender<()>> = None;

        loop {
            let result = {
                let sel = Select::new();

                let mut cmd_handle = sel.handle(&self.cmd_receiver);
                let mut progress_handle = sel.handle(&self.progress_receiver);
                let mut decoder_handle = sel.handle(&self.decoder_receiver);

                unsafe {
                    cmd_handle.add();
                    progress_handle.add();
                    decoder_handle.add();
                }

                let ret = sel.wait();

                if ret == cmd_handle.id() {
                    SelectResult::Command(self.cmd_receiver.recv().unwrap())
                } else if ret == decoder_handle.id() {
                    SelectResult::Decoder(self.decoder_receiver.recv().unwrap())
                } else {
                    SelectResult::Progress(self.progress_receiver.recv().unwrap())
                }
            };

            match result {
                SelectResult::Command(cmd) => {
                    exit_sender = self.handle_cmd(cmd);
                }
                SelectResult::Progress(msg) => {
                    self.handle_progress(msg);
                }
                SelectResult::Decoder(msg) => {
                    self.handle_decoder(msg);
                }
            }

            // Can only exit when all pending loads are complete.
            if let Some(ref exit_sender) = exit_sender {
                if self.pending_loads.len() == 0 {
                    exit_sender.send(()).unwrap();
                    break;
                }
            }
        }
    }

    // Handle a request from a client
    fn handle_cmd(&mut self, cmd: ImageCacheCommand) -> Option<Sender<()>> {
        match cmd {
            ImageCacheCommand::Exit(sender) => {
                return Some(sender);
            }
            ImageCacheCommand::RequestImage(url, result_chan, responder) => {
                self.request_image(url, result_chan, responder);
            }
            ImageCacheCommand::GetImageIfAvailable(url, consumer) => {
                let result = match self.completed_loads.get(&url) {
                    Some(completed_load) => {
                        completed_load.image.clone().ok_or(ImageState::LoadError)
                    }
                    None => {
                        let pending_load = self.pending_loads.get(&url);
                        Err(pending_load.map_or(ImageState::NotRequested, |_| ImageState::Pending))
                    }
                };
                consumer.send(result).unwrap();
            }
        };

        None
    }

    // Handle progress messages from the resource task
    fn handle_progress(&mut self, msg: ResourceLoadInfo) {
        match msg.action {
            ResponseAction::HeadersAvailable(_) => {}
            ResponseAction::DataAvailable(data) => {
                let pending_load = self.pending_loads.get_mut(&msg.url).unwrap();
                pending_load.bytes.push_all(&data);
            }
            ResponseAction::ResponseComplete(result) => {
                match result {
                    Ok(()) => {
                        let pending_load = self.pending_loads.get_mut(&msg.url).unwrap();
                        pending_load.result = Some(result);

                        let bytes = mem::replace(&mut pending_load.bytes, vec!());
                        let url = msg.url.clone();
                        let sender = self.decoder_sender.clone();

                        self.task_pool.execute(move || {
                            let image = load_from_memory(&bytes);
                            let msg = DecoderMsg {
                                url: url,
                                image: image
                            };
                            sender.send(msg).unwrap();
                        });
                    }
                    Err(_) => {
                        let placeholder_image = self.placeholder_image.clone();
                        self.complete_load(msg.url, placeholder_image);
                    }
                }
            }
        }
    }

    // Handle a message from one of the decoder worker threads
    fn handle_decoder(&mut self, msg: DecoderMsg) {
        let image = msg.image.map(Arc::new);
        self.complete_load(msg.url, image);
    }

    // Change state of a url from pending -> loaded.
    fn complete_load(&mut self, url: Url, image: Option<Arc<Image>>) {
        let pending_load = self.pending_loads.remove(&url).unwrap();

        let completed_load = CompletedLoad::new(image.clone());
        self.completed_loads.insert(url, completed_load);

        for listener in pending_load.listeners.into_iter() {
            listener.notify(image.clone());
        }
    }

    // Request an image from the cache
    fn request_image(&mut self, url: Url, result_chan: ImageCacheChan, responder: Option<Box<ImageResponder>>) {
        let image_listener = ImageListener::new(result_chan, responder);

        // Check if already completed
        match self.completed_loads.get(&url) {
            Some(completed_load) => {
                // It's already completed, return a notify straight away
                image_listener.notify(completed_load.image.clone());
            }
            None => {
                // Check if the load is already pending
                match self.pending_loads.entry(url.clone()) {
                    Occupied(mut e) => {
                        // It's pending, so add the listener for state changes
                        let pending_load = e.get_mut();
                        pending_load.add_listener(image_listener);
                    }
                    Vacant(e) => {
                        // A new load request! Add the pending load and request
                        // it from the resource task.
                        let mut pending_load = PendingLoad::new();
                        pending_load.add_listener(image_listener);
                        e.insert(pending_load);

                        let load_data = LoadData::new(url.clone(), None);
                        let listener = box ResourceListener {
                            url: url,
                            sender: self.progress_sender.clone(),
                        };
                        self.resource_task.send(ControlMsg::Load(load_data, LoadConsumer::Listener(listener))).unwrap();
                    }
                }
            }
        }
    }
}

/// Create a new image cache.
pub fn new_image_cache_task(resource_task: ResourceTask) -> ImageCacheTask {
    let (cmd_sender, cmd_receiver) = channel();
    let (progress_sender, progress_receiver) = channel();
    let (decoder_sender, decoder_receiver) = channel();

    spawn_named("ImageCacheThread".to_owned(), move || {

        // Preload the placeholder image, used when images fail to load.
        let mut placeholder_url = resources_dir_path();
        // TODO (Savago): replace for a prettier one.
        placeholder_url.push("rippy.jpg");
        let url = Url::from_file_path(&*placeholder_url).unwrap();
        let placeholder_image = match load_whole_resource(&resource_task, url) {
            Err(..) => {
                debug!("image_cache_task: failed loading the placeholder.");
                None
            }
            Ok((_, image_data)) => {
                Some(Arc::new(load_from_memory(&image_data).unwrap()))
            }
        };

        let mut cache = ImageCache {
            cmd_receiver: cmd_receiver,
            progress_sender: progress_sender,
            progress_receiver: progress_receiver,
            decoder_sender: decoder_sender,
            decoder_receiver: decoder_receiver,
            task_pool: TaskPool::new(4),
            pending_loads: HashMap::new(),
            completed_loads: HashMap::new(),
            resource_task: resource_task,
            placeholder_image: placeholder_image,
        };

        cache.run();
    });

    ImageCacheTask::new(cmd_sender)
}
<commit_msg>Auto merge of #5987 - Adenilson:rmComment01, r=jdm<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use collections::borrow::ToOwned;
use net_traits::image::base::{Image, load_from_memory};
use net_traits::image_cache_task::{ImageState, ImageCacheTask, ImageCacheChan, ImageCacheCommand, ImageCacheResult};
use net_traits::load_whole_resource;
use std::collections::HashMap;
use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::mem;
use std::sync::Arc;
use std::sync::mpsc::{channel, Sender, Receiver, Select};
use util::resource_files::resources_dir_path;
use util::task::spawn_named;
use util::taskpool::TaskPool;
use url::Url;
use net_traits::{AsyncResponseTarget, ControlMsg, LoadData, ResponseAction, ResourceTask, LoadConsumer};
use net_traits::image_cache_task::ImageResponder;

///
/// TODO(gw): Remaining work on image cache:
///     * Make use of the prefetch support in various parts of the code.
///     * Experiment with changing the image 'key' from being a url to a resource id
///         This might be a decent performance win and/or memory saving in some cases (esp. data urls)
///     * Profile time in GetImageIfAvailable - might be worth caching these results per paint / layout task.
///

/// Represents an image that is either being loaded
/// by the resource task, or decoded by a worker thread.
struct PendingLoad {
    bytes: Vec<u8>,
    result: Option<Result<(), String>>,
    listeners: Vec<ImageListener>,
}

impl PendingLoad {
    fn new() -> PendingLoad {
        PendingLoad {
            bytes: vec!(),
            result: None,
            listeners: vec!(),
        }
    }

    fn add_listener(&mut self, listener: ImageListener) {
        self.listeners.push(listener);
    }
}

/// Represents an image that has completed loading.
/// Images that fail to load (due to network or decode
/// failure) are still stored here, so that they aren't
/// fetched again.
struct CompletedLoad {
    image: Option<Arc<Image>>,
}

impl CompletedLoad {
    fn new(image: Option<Arc<Image>>) -> CompletedLoad {
        CompletedLoad {
            image: image,
        }
    }
}

/// Stores information to notify a client when the state
/// of an image changes.
struct ImageListener {
    sender: ImageCacheChan,
    responder: Option<Box<ImageResponder>>,
}

impl ImageListener {
    fn new(sender: ImageCacheChan, responder: Option<Box<ImageResponder>>) -> ImageListener {
        ImageListener {
            sender: sender,
            responder: responder,
        }
    }

    fn notify(self, image: Option<Arc<Image>>) {
        let ImageCacheChan(ref sender) = self.sender;
        let msg = ImageCacheResult {
            responder: self.responder,
            image: image,
        };
        sender.send(msg).ok();
    }
}

struct ResourceLoadInfo {
    action: ResponseAction,
    url: Url,
}

struct ResourceListener {
    url: Url,
    sender: Sender<ResourceLoadInfo>,
}

impl AsyncResponseTarget for ResourceListener {
    fn invoke_with_listener(&self, action: ResponseAction) {
        self.sender.send(ResourceLoadInfo {
            action: action,
            url: self.url.clone(),
        }).unwrap();
    }
}

/// Implementation of the image cache
struct ImageCache {
    // Receive commands from clients
    cmd_receiver: Receiver<ImageCacheCommand>,

    // Receive notifications from the resource task
    progress_receiver: Receiver<ResourceLoadInfo>,
    progress_sender: Sender<ResourceLoadInfo>,

    // Receive notifications from the decoder thread pool
    decoder_receiver: Receiver<DecoderMsg>,
    decoder_sender: Sender<DecoderMsg>,

    // Worker threads for decoding images.
    task_pool: TaskPool,

    // Resource task handle
    resource_task: ResourceTask,

    // Images that are loading over network, or decoding.
    pending_loads: HashMap<Url, PendingLoad>,

    // Images that have finished loading (successful or not)
    completed_loads: HashMap<Url, CompletedLoad>,

    // The placeholder image used when an image fails to load
    placeholder_image: Option<Arc<Image>>,
}

/// Message that the decoder worker threads send to main image cache task.
struct DecoderMsg {
    url: Url,
    image: Option<Image>,
}

/// The types of messages that the main image cache task receives.
enum SelectResult {
    Command(ImageCacheCommand),
    Progress(ResourceLoadInfo),
    Decoder(DecoderMsg),
}

impl ImageCache {
    fn run(&mut self) {
        let mut exit_sender: Option<Sender<()>> = None;

        loop {
            let result = {
                let sel = Select::new();

                let mut cmd_handle = sel.handle(&self.cmd_receiver);
                let mut progress_handle = sel.handle(&self.progress_receiver);
                let mut decoder_handle = sel.handle(&self.decoder_receiver);

                unsafe {
                    cmd_handle.add();
                    progress_handle.add();
                    decoder_handle.add();
                }

                let ret = sel.wait();

                if ret == cmd_handle.id() {
                    SelectResult::Command(self.cmd_receiver.recv().unwrap())
                } else if ret == decoder_handle.id() {
                    SelectResult::Decoder(self.decoder_receiver.recv().unwrap())
                } else {
                    SelectResult::Progress(self.progress_receiver.recv().unwrap())
                }
            };

            match result {
                SelectResult::Command(cmd) => {
                    exit_sender = self.handle_cmd(cmd);
                }
                SelectResult::Progress(msg) => {
                    self.handle_progress(msg);
                }
                SelectResult::Decoder(msg) => {
                    self.handle_decoder(msg);
                }
            }

            // Can only exit when all pending loads are complete.
            if let Some(ref exit_sender) = exit_sender {
                if self.pending_loads.len() == 0 {
                    exit_sender.send(()).unwrap();
                    break;
                }
            }
        }
    }

    // Handle a request from a client
    fn handle_cmd(&mut self, cmd: ImageCacheCommand) -> Option<Sender<()>> {
        match cmd {
            ImageCacheCommand::Exit(sender) => {
                return Some(sender);
            }
            ImageCacheCommand::RequestImage(url, result_chan, responder) => {
                self.request_image(url, result_chan, responder);
            }
            ImageCacheCommand::GetImageIfAvailable(url, consumer) => {
                let result = match self.completed_loads.get(&url) {
                    Some(completed_load) => {
                        completed_load.image.clone().ok_or(ImageState::LoadError)
                    }
                    None => {
                        let pending_load = self.pending_loads.get(&url);
                        Err(pending_load.map_or(ImageState::NotRequested, |_| ImageState::Pending))
                    }
                };
                consumer.send(result).unwrap();
            }
        };

        None
    }

    // Handle progress messages from the resource task
    fn handle_progress(&mut self, msg: ResourceLoadInfo) {
        match msg.action {
            ResponseAction::HeadersAvailable(_) => {}
            ResponseAction::DataAvailable(data) => {
                let pending_load = self.pending_loads.get_mut(&msg.url).unwrap();
                pending_load.bytes.push_all(&data);
            }
            ResponseAction::ResponseComplete(result) => {
                match result {
                    Ok(()) => {
                        let pending_load = self.pending_loads.get_mut(&msg.url).unwrap();
                        pending_load.result = Some(result);

                        let bytes = mem::replace(&mut pending_load.bytes, vec!());
                        let url = msg.url.clone();
                        let sender = self.decoder_sender.clone();

                        self.task_pool.execute(move || {
                            let image = load_from_memory(&bytes);
                            let msg = DecoderMsg {
                                url: url,
                                image: image
                            };
                            sender.send(msg).unwrap();
                        });
                    }
                    Err(_) => {
                        let placeholder_image = self.placeholder_image.clone();
                        self.complete_load(msg.url, placeholder_image);
                    }
                }
            }
        }
    }

    // Handle a message from one of the decoder worker threads
    fn handle_decoder(&mut self, msg: DecoderMsg) {
        let image = msg.image.map(Arc::new);
        self.complete_load(msg.url, image);
    }

    // Change state of a url from pending -> loaded.
    fn complete_load(&mut self, url: Url, image: Option<Arc<Image>>) {
        let pending_load = self.pending_loads.remove(&url).unwrap();

        let completed_load = CompletedLoad::new(image.clone());
        self.completed_loads.insert(url, completed_load);

        for listener in pending_load.listeners.into_iter() {
            listener.notify(image.clone());
        }
    }

    // Request an image from the cache
    fn request_image(&mut self, url: Url, result_chan: ImageCacheChan, responder: Option<Box<ImageResponder>>) {
        let image_listener = ImageListener::new(result_chan, responder);

        // Check if already completed
        match self.completed_loads.get(&url) {
            Some(completed_load) => {
                // It's already completed, return a notify straight away
                image_listener.notify(completed_load.image.clone());
            }
            None => {
                // Check if the load is already pending
                match self.pending_loads.entry(url.clone()) {
                    Occupied(mut e) => {
                        // It's pending, so add the listener for state changes
                        let pending_load = e.get_mut();
                        pending_load.add_listener(image_listener);
                    }
                    Vacant(e) => {
                        // A new load request! Add the pending load and request
                        // it from the resource task.
                        let mut pending_load = PendingLoad::new();
                        pending_load.add_listener(image_listener);
                        e.insert(pending_load);

                        let load_data = LoadData::new(url.clone(), None);
                        let listener = box ResourceListener {
                            url: url,
                            sender: self.progress_sender.clone(),
                        };
                        self.resource_task.send(ControlMsg::Load(load_data, LoadConsumer::Listener(listener))).unwrap();
                    }
                }
            }
        }
    }
}

/// Create a new image cache.
pub fn new_image_cache_task(resource_task: ResourceTask) -> ImageCacheTask {
    let (cmd_sender, cmd_receiver) = channel();
    let (progress_sender, progress_receiver) = channel();
    let (decoder_sender, decoder_receiver) = channel();

    spawn_named("ImageCacheThread".to_owned(), move || {

        // Preload the placeholder image, used when images fail to load.
        let mut placeholder_url = resources_dir_path();
        placeholder_url.push("rippy.jpg");
        let url = Url::from_file_path(&*placeholder_url).unwrap();
        let placeholder_image = match load_whole_resource(&resource_task, url) {
            Err(..) => {
                debug!("image_cache_task: failed loading the placeholder.");
                None
            }
            Ok((_, image_data)) => {
                Some(Arc::new(load_from_memory(&image_data).unwrap()))
            }
        };

        let mut cache = ImageCache {
            cmd_receiver: cmd_receiver,
            progress_sender: progress_sender,
            progress_receiver: progress_receiver,
            decoder_sender: decoder_sender,
            decoder_receiver: decoder_receiver,
            task_pool: TaskPool::new(4),
            pending_loads: HashMap::new(),
            completed_loads: HashMap::new(),
            resource_task: resource_task,
            placeholder_image: placeholder_image,
        };

        cache.run();
    });

    ImageCacheTask::new(cmd_sender)
}
<|endoftext|>


<commit_before>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library 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
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

#[macro_export]
macro_rules! generate_error_imports {
    () => {
        use std::error::Error;
        use std::fmt::Error as FmtError;
        use std::fmt::{Display, Formatter};

        use $crate::into::IntoError;
    }
}

#[macro_export]
macro_rules! generate_error_module {
    ( $exprs:item ) => {
        pub mod error {
            generate_error_imports!();
            $exprs
        }
    }
}

#[macro_export]
macro_rules! generate_custom_error_types {
    {
        $name: ident,
        $kindname: ident,
        $customMemberTypeName: ident,
        $($kind:ident => $string:expr),*
    } => {
        #[derive(Clone, Copy, Debug, PartialEq)]
        pub enum $kindname {
            $( $kind ),*
        }

        impl Display for $kindname {

            fn fmt(&self, fmt: &mut Formatter) -> Result<(), FmtError> {
                let s = match *self {
                    $( $kindname::$kind => $string ),*
                };
                try!(write!(fmt, "{}", s));
                Ok(())
            }

        }

        impl IntoError for $kindname {
            type Target = $name;

            fn into_error(self) -> Self::Target {
                $name::new(self, None)
            }

            fn into_error_with_cause(self, cause: Box<Error>) -> Self::Target {
                $name::new(self, Some(cause))
            }

        }

        #[derive(Debug)]
        pub struct $name {
            err_type: $kindname,
            cause: Option<Box<Error>>,
            custom_data: Option<$customMemberTypeName>,
        }

        impl $name {

            pub fn new(errtype: $kindname, cause: Option<Box<Error>>) -> $name {
                $name {
                    err_type: errtype,
                    cause: cause,
                    custom_data: None,
                }
            }

            #[allow(dead_code)]
            pub fn err_type(&self) -> $kindname {
                self.err_type
            }

            #[allow(dead_code)]
            pub fn with_custom_data(mut self, custom: $customMemberTypeName) -> $name {
                self.custom_data = Some(custom);
                self
            }

        }

        impl Into<$name> for $kindname {

            fn into(self) -> $name {
                $name::new(self, None)
            }

        }

        impl Display for $name {

            fn fmt(&self, fmt: &mut Formatter) -> Result<(), FmtError> {
                try!(write!(fmt, "[{}]", self.err_type));
                match self.custom_data {
                    Some(ref c) => write!(fmt, "{}", c),
                    None => Ok(()),
                }
            }

        }

        impl Error for $name {

            fn description(&self) -> &str {
                match self.err_type {
                    $( $kindname::$kind => $string ),*
                }
            }

            fn cause(&self) -> Option<&Error> {
                self.cause.as_ref().map(|e| &**e)
            }

        }

    }
}

#[macro_export]
macro_rules! generate_result_helper {
    (
        $name: ident,
        $kindname: ident
    ) => {
        /// Trait to replace
        ///
        /// ```ignore
        /// foo.map_err(Box::new).map_err(|e| SomeType::SomeErrorKind.into_error_with_cause(e))
        /// // or:
        /// foo.map_err(|e| SomeType::SomeErrorKind.into_error_with_cause(Box::new(e)))
        /// ```
        ///
        /// with much nicer
        ///
        /// ```ignore
        /// foo.map_err_into(SomeType::SomeErrorKind)
        /// ```
        ///
        pub trait MapErrInto<T> {
            fn map_err_into(self, error_kind: $kindname) -> Result<T, $name>;
        }

        impl<T, E: Error + 'static> MapErrInto<T> for Result<T, E> {

            fn map_err_into(self, error_kind: $kindname) -> Result<T, $name> {
                self.map_err(Box::new)
                    .map_err(|e| error_kind.into_error_with_cause(e))
            }

        }
    }
}

#[macro_export]
macro_rules! generate_option_helper {
    (
        $name: ident,
        $kindname: ident
    ) => {
        /// Trait to replace
        ///
        /// ```ignore
        /// foo.ok_or(SomeType::SomeErrorKind.into_error())
        /// ```
        ///
        /// with
        ///
        /// ```ignore
        /// foo.ok_or_errkind(SomeType::SomeErrorKind)
        /// ```
        pub trait OkOrErr<T> {
            fn ok_or_errkind(self, kind: $kindname) -> Result<T, $name>;
        }

        impl<T> OkOrErr<T> for Option<T> {

            fn ok_or_errkind(self, kind: $kindname) -> Result<T, $name> {
                self.ok_or(kind.into_error())
            }

        }
    }
}

#[macro_export]
macro_rules! generate_error_types {
    (
        $name: ident,
        $kindname: ident,
        $($kind:ident => $string:expr),*
    ) => {
        #[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Copy)]
        pub struct SomeNotExistingTypeWithATypeNameNoOneWillEverChoose {}

        impl Display for SomeNotExistingTypeWithATypeNameNoOneWillEverChoose {
            fn fmt(&self, _: &mut Formatter) -> Result<(), FmtError> {
                Ok(())
            }
        }

        generate_custom_error_types!($name, $kindname,
                                     SomeNotExistingTypeWithATypeNameNoOneWillEverChoose,
                                     $($kind => $string),*);

        generate_result_helper!($name, $kindname);
        generate_option_helper!($name, $kindname);
    }
}

#[cfg(test)]
#[allow(dead_code)]
mod test {

    generate_error_module!(
        generate_error_types!(TestError, TestErrorKind,
            TestErrorKindA => "testerrorkind a",
            TestErrorKindB => "testerrorkind B");
    );

    #[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Copy)]
    pub struct CustomData {
        pub test: i32,
        pub othr: i64,
    }

    impl Display for CustomData {
        fn fmt(&self, fmt: &mut Formatter) -> Result<(), FmtError> {
            Ok(())
        }
    }

    generate_error_imports!();

    #[allow(dead_code)]
    generate_custom_error_types!(CustomTestError, CustomTestErrorKind,
        CustomData,
        CustomErrorKindA => "customerrorkind a",
        CustomErrorKindB => "customerrorkind B");

    // Allow dead code here.
    // We wrote this to show that custom test types can be implemented.
    #[allow(dead_code)]
    impl CustomTestError {
        pub fn test(&self) -> i32 {
            match self.custom_data {
                Some(t) => t.test,
                None => 0,
            }
        }

        pub fn bar(&self) -> i64 {
            match self.custom_data {
                Some(t) => t.othr,
                None => 0,
            }
        }
    }

    #[test]
    fn test_a() {
        use self::error::{TestError, TestErrorKind};

        let kind = TestErrorKind::TestErrorKindA;
        assert_eq!(String::from("testerrorkind a"), format!("{}", kind));

        let e = TestError::new(kind, None);
        assert_eq!(String::from("[testerrorkind a]"), format!("{}", e));
    }

    #[test]
    fn test_b() {
        use self::error::{TestError, TestErrorKind};

        let kind = TestErrorKind::TestErrorKindB;
        assert_eq!(String::from("testerrorkind B"), format!("{}", kind));

        let e = TestError::new(kind, None);
        assert_eq!(String::from("[testerrorkind B]"), format!("{}", e));

    }

    #[test]
    fn test_ab() {
        use std::error::Error;
        use self::error::{TestError, TestErrorKind};

        let kinda = TestErrorKind::TestErrorKindA;
        let kindb = TestErrorKind::TestErrorKindB;
        assert_eq!(String::from("testerrorkind a"), format!("{}", kinda));
        assert_eq!(String::from("testerrorkind B"), format!("{}", kindb));

        let e = TestError::new(kinda, Some(Box::new(TestError::new(kindb, None))));
        assert_eq!(String::from("[testerrorkind a]"), format!("{}", e));
        assert_eq!(TestErrorKind::TestErrorKindA, e.err_type());
        assert_eq!(String::from("[testerrorkind B]"), format!("{}", e.cause().unwrap()));
    }

    pub mod anothererrormod {
        generate_error_imports!();
        generate_error_types!(TestError, TestErrorKind,
            TestErrorKindA => "testerrorkind a",
            TestErrorKindB => "testerrorkind B");
    }

    #[test]
    fn test_other_a() {
        use self::anothererrormod::{TestError, TestErrorKind};

        let kind = TestErrorKind::TestErrorKindA;
        assert_eq!(String::from("testerrorkind a"), format!("{}", kind));

        let e = TestError::new(kind, None);
        assert_eq!(String::from("[testerrorkind a]"), format!("{}", e));
    }

    #[test]
    fn test_other_b() {
        use self::anothererrormod::{TestError, TestErrorKind};

        let kind = TestErrorKind::TestErrorKindB;
        assert_eq!(String::from("testerrorkind B"), format!("{}", kind));

        let e = TestError::new(kind, None);
        assert_eq!(String::from("[testerrorkind B]"), format!("{}", e));

    }

    #[test]
    fn test_other_ab() {
        use std::error::Error;
        use self::anothererrormod::{TestError, TestErrorKind};

        let kinda = TestErrorKind::TestErrorKindA;
        let kindb = TestErrorKind::TestErrorKindB;
        assert_eq!(String::from("testerrorkind a"), format!("{}", kinda));
        assert_eq!(String::from("testerrorkind B"), format!("{}", kindb));

        let e = TestError::new(kinda, Some(Box::new(TestError::new(kindb, None))));
        assert_eq!(String::from("[testerrorkind a]"), format!("{}", e));
        assert_eq!(TestErrorKind::TestErrorKindA, e.err_type());
        assert_eq!(String::from("[testerrorkind B]"), format!("{}", e.cause().unwrap()));
    }

    #[test]
    fn test_error_kind_mapping() {
        use std::io::{Error, ErrorKind};
        use self::error::MapErrInto;
        use self::error::TestErrorKind;

        let err : Result<(), _> = Err(Error::new(ErrorKind::Other, ""));
        let err : Result<(), _> = err.map_err_into(TestErrorKind::TestErrorKindA);

        assert!(err.is_err());
        let err = err.unwrap_err();

        match err.err_type() {
            TestErrorKind::TestErrorKindA => assert!(true),
            _ => assert!(false),
        }
    }

    #[test]
    fn test_error_kind_double_mapping() {
        use std::io::{Error, ErrorKind};
        use self::error::MapErrInto;
        use self::error::TestErrorKind;

        let err : Result<(), _> = Err(Error::new(ErrorKind::Other, ""));
        let err : Result<(), _> = err.map_err_into(TestErrorKind::TestErrorKindA)
                                     .map_err_into(TestErrorKind::TestErrorKindB);

        assert!(err.is_err());
        let err = err.unwrap_err();
        match err.err_type() {
            TestErrorKind::TestErrorKindB => assert!(true),
            _ => assert!(false),
        }

        // not sure how to test that the inner error is of TestErrorKindA, actually...
        match err.cause() {
            Some(_) => assert!(true),
            None    => assert!(false),
        }

    }

    #[test]
    fn test_error_option_good() {
        use self::error::OkOrErr;
        use self::error::TestErrorKind;

        let something = Some(1);
        match something.ok_or_errkind(TestErrorKind::TestErrorKindA) {
            Ok(1) => assert!(true),
            _     => assert!(false),
        }
    }

    #[test]
    fn test_error_option_bad() {
        use self::error::OkOrErr;
        use self::error::TestErrorKind;

        let something : Option<i32> = None;
        match something.ok_or_errkind(TestErrorKind::TestErrorKindA) {
            Ok(_)  => assert!(false),
            Err(_) => assert!(true),
        }
    }

}
<commit_msg>Remove unused variable<commit_after>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library 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
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

#[macro_export]
macro_rules! generate_error_imports {
    () => {
        use std::error::Error;
        use std::fmt::Error as FmtError;
        use std::fmt::{Display, Formatter};

        use $crate::into::IntoError;
    }
}

#[macro_export]
macro_rules! generate_error_module {
    ( $exprs:item ) => {
        pub mod error {
            generate_error_imports!();
            $exprs
        }
    }
}

#[macro_export]
macro_rules! generate_custom_error_types {
    {
        $name: ident,
        $kindname: ident,
        $customMemberTypeName: ident,
        $($kind:ident => $string:expr),*
    } => {
        #[derive(Clone, Copy, Debug, PartialEq)]
        pub enum $kindname {
            $( $kind ),*
        }

        impl Display for $kindname {

            fn fmt(&self, fmt: &mut Formatter) -> Result<(), FmtError> {
                let s = match *self {
                    $( $kindname::$kind => $string ),*
                };
                try!(write!(fmt, "{}", s));
                Ok(())
            }

        }

        impl IntoError for $kindname {
            type Target = $name;

            fn into_error(self) -> Self::Target {
                $name::new(self, None)
            }

            fn into_error_with_cause(self, cause: Box<Error>) -> Self::Target {
                $name::new(self, Some(cause))
            }

        }

        #[derive(Debug)]
        pub struct $name {
            err_type: $kindname,
            cause: Option<Box<Error>>,
            custom_data: Option<$customMemberTypeName>,
        }

        impl $name {

            pub fn new(errtype: $kindname, cause: Option<Box<Error>>) -> $name {
                $name {
                    err_type: errtype,
                    cause: cause,
                    custom_data: None,
                }
            }

            #[allow(dead_code)]
            pub fn err_type(&self) -> $kindname {
                self.err_type
            }

            #[allow(dead_code)]
            pub fn with_custom_data(mut self, custom: $customMemberTypeName) -> $name {
                self.custom_data = Some(custom);
                self
            }

        }

        impl Into<$name> for $kindname {

            fn into(self) -> $name {
                $name::new(self, None)
            }

        }

        impl Display for $name {

            fn fmt(&self, fmt: &mut Formatter) -> Result<(), FmtError> {
                try!(write!(fmt, "[{}]", self.err_type));
                match self.custom_data {
                    Some(ref c) => write!(fmt, "{}", c),
                    None => Ok(()),
                }
            }

        }

        impl Error for $name {

            fn description(&self) -> &str {
                match self.err_type {
                    $( $kindname::$kind => $string ),*
                }
            }

            fn cause(&self) -> Option<&Error> {
                self.cause.as_ref().map(|e| &**e)
            }

        }

    }
}

#[macro_export]
macro_rules! generate_result_helper {
    (
        $name: ident,
        $kindname: ident
    ) => {
        /// Trait to replace
        ///
        /// ```ignore
        /// foo.map_err(Box::new).map_err(|e| SomeType::SomeErrorKind.into_error_with_cause(e))
        /// // or:
        /// foo.map_err(|e| SomeType::SomeErrorKind.into_error_with_cause(Box::new(e)))
        /// ```
        ///
        /// with much nicer
        ///
        /// ```ignore
        /// foo.map_err_into(SomeType::SomeErrorKind)
        /// ```
        ///
        pub trait MapErrInto<T> {
            fn map_err_into(self, error_kind: $kindname) -> Result<T, $name>;
        }

        impl<T, E: Error + 'static> MapErrInto<T> for Result<T, E> {

            fn map_err_into(self, error_kind: $kindname) -> Result<T, $name> {
                self.map_err(Box::new)
                    .map_err(|e| error_kind.into_error_with_cause(e))
            }

        }
    }
}

#[macro_export]
macro_rules! generate_option_helper {
    (
        $name: ident,
        $kindname: ident
    ) => {
        /// Trait to replace
        ///
        /// ```ignore
        /// foo.ok_or(SomeType::SomeErrorKind.into_error())
        /// ```
        ///
        /// with
        ///
        /// ```ignore
        /// foo.ok_or_errkind(SomeType::SomeErrorKind)
        /// ```
        pub trait OkOrErr<T> {
            fn ok_or_errkind(self, kind: $kindname) -> Result<T, $name>;
        }

        impl<T> OkOrErr<T> for Option<T> {

            fn ok_or_errkind(self, kind: $kindname) -> Result<T, $name> {
                self.ok_or(kind.into_error())
            }

        }
    }
}

#[macro_export]
macro_rules! generate_error_types {
    (
        $name: ident,
        $kindname: ident,
        $($kind:ident => $string:expr),*
    ) => {
        #[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Copy)]
        pub struct SomeNotExistingTypeWithATypeNameNoOneWillEverChoose {}

        impl Display for SomeNotExistingTypeWithATypeNameNoOneWillEverChoose {
            fn fmt(&self, _: &mut Formatter) -> Result<(), FmtError> {
                Ok(())
            }
        }

        generate_custom_error_types!($name, $kindname,
                                     SomeNotExistingTypeWithATypeNameNoOneWillEverChoose,
                                     $($kind => $string),*);

        generate_result_helper!($name, $kindname);
        generate_option_helper!($name, $kindname);
    }
}

#[cfg(test)]
#[allow(dead_code)]
mod test {

    generate_error_module!(
        generate_error_types!(TestError, TestErrorKind,
            TestErrorKindA => "testerrorkind a",
            TestErrorKindB => "testerrorkind B");
    );

    #[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Copy)]
    pub struct CustomData {
        pub test: i32,
        pub othr: i64,
    }

    impl Display for CustomData {
        fn fmt(&self, _: &mut Formatter) -> Result<(), FmtError> {
            Ok(())
        }
    }

    generate_error_imports!();

    #[allow(dead_code)]
    generate_custom_error_types!(CustomTestError, CustomTestErrorKind,
        CustomData,
        CustomErrorKindA => "customerrorkind a",
        CustomErrorKindB => "customerrorkind B");

    // Allow dead code here.
    // We wrote this to show that custom test types can be implemented.
    #[allow(dead_code)]
    impl CustomTestError {
        pub fn test(&self) -> i32 {
            match self.custom_data {
                Some(t) => t.test,
                None => 0,
            }
        }

        pub fn bar(&self) -> i64 {
            match self.custom_data {
                Some(t) => t.othr,
                None => 0,
            }
        }
    }

    #[test]
    fn test_a() {
        use self::error::{TestError, TestErrorKind};

        let kind = TestErrorKind::TestErrorKindA;
        assert_eq!(String::from("testerrorkind a"), format!("{}", kind));

        let e = TestError::new(kind, None);
        assert_eq!(String::from("[testerrorkind a]"), format!("{}", e));
    }

    #[test]
    fn test_b() {
        use self::error::{TestError, TestErrorKind};

        let kind = TestErrorKind::TestErrorKindB;
        assert_eq!(String::from("testerrorkind B"), format!("{}", kind));

        let e = TestError::new(kind, None);
        assert_eq!(String::from("[testerrorkind B]"), format!("{}", e));

    }

    #[test]
    fn test_ab() {
        use std::error::Error;
        use self::error::{TestError, TestErrorKind};

        let kinda = TestErrorKind::TestErrorKindA;
        let kindb = TestErrorKind::TestErrorKindB;
        assert_eq!(String::from("testerrorkind a"), format!("{}", kinda));
        assert_eq!(String::from("testerrorkind B"), format!("{}", kindb));

        let e = TestError::new(kinda, Some(Box::new(TestError::new(kindb, None))));
        assert_eq!(String::from("[testerrorkind a]"), format!("{}", e));
        assert_eq!(TestErrorKind::TestErrorKindA, e.err_type());
        assert_eq!(String::from("[testerrorkind B]"), format!("{}", e.cause().unwrap()));
    }

    pub mod anothererrormod {
        generate_error_imports!();
        generate_error_types!(TestError, TestErrorKind,
            TestErrorKindA => "testerrorkind a",
            TestErrorKindB => "testerrorkind B");
    }

    #[test]
    fn test_other_a() {
        use self::anothererrormod::{TestError, TestErrorKind};

        let kind = TestErrorKind::TestErrorKindA;
        assert_eq!(String::from("testerrorkind a"), format!("{}", kind));

        let e = TestError::new(kind, None);
        assert_eq!(String::from("[testerrorkind a]"), format!("{}", e));
    }

    #[test]
    fn test_other_b() {
        use self::anothererrormod::{TestError, TestErrorKind};

        let kind = TestErrorKind::TestErrorKindB;
        assert_eq!(String::from("testerrorkind B"), format!("{}", kind));

        let e = TestError::new(kind, None);
        assert_eq!(String::from("[testerrorkind B]"), format!("{}", e));

    }

    #[test]
    fn test_other_ab() {
        use std::error::Error;
        use self::anothererrormod::{TestError, TestErrorKind};

        let kinda = TestErrorKind::TestErrorKindA;
        let kindb = TestErrorKind::TestErrorKindB;
        assert_eq!(String::from("testerrorkind a"), format!("{}", kinda));
        assert_eq!(String::from("testerrorkind B"), format!("{}", kindb));

        let e = TestError::new(kinda, Some(Box::new(TestError::new(kindb, None))));
        assert_eq!(String::from("[testerrorkind a]"), format!("{}", e));
        assert_eq!(TestErrorKind::TestErrorKindA, e.err_type());
        assert_eq!(String::from("[testerrorkind B]"), format!("{}", e.cause().unwrap()));
    }

    #[test]
    fn test_error_kind_mapping() {
        use std::io::{Error, ErrorKind};
        use self::error::MapErrInto;
        use self::error::TestErrorKind;

        let err : Result<(), _> = Err(Error::new(ErrorKind::Other, ""));
        let err : Result<(), _> = err.map_err_into(TestErrorKind::TestErrorKindA);

        assert!(err.is_err());
        let err = err.unwrap_err();

        match err.err_type() {
            TestErrorKind::TestErrorKindA => assert!(true),
            _ => assert!(false),
        }
    }

    #[test]
    fn test_error_kind_double_mapping() {
        use std::io::{Error, ErrorKind};
        use self::error::MapErrInto;
        use self::error::TestErrorKind;

        let err : Result<(), _> = Err(Error::new(ErrorKind::Other, ""));
        let err : Result<(), _> = err.map_err_into(TestErrorKind::TestErrorKindA)
                                     .map_err_into(TestErrorKind::TestErrorKindB);

        assert!(err.is_err());
        let err = err.unwrap_err();
        match err.err_type() {
            TestErrorKind::TestErrorKindB => assert!(true),
            _ => assert!(false),
        }

        // not sure how to test that the inner error is of TestErrorKindA, actually...
        match err.cause() {
            Some(_) => assert!(true),
            None    => assert!(false),
        }

    }

    #[test]
    fn test_error_option_good() {
        use self::error::OkOrErr;
        use self::error::TestErrorKind;

        let something = Some(1);
        match something.ok_or_errkind(TestErrorKind::TestErrorKindA) {
            Ok(1) => assert!(true),
            _     => assert!(false),
        }
    }

    #[test]
    fn test_error_option_bad() {
        use self::error::OkOrErr;
        use self::error::TestErrorKind;

        let something : Option<i32> = None;
        match something.ok_or_errkind(TestErrorKind::TestErrorKindA) {
            Ok(_)  => assert!(false),
            Err(_) => assert!(true),
        }
    }

}
<|endoftext|>


<commit_before>use std::thread;
use std::iter;

extern crate env_logger;

extern crate grpc;
extern crate long_tests;
extern crate futures;

use futures::stream::Stream;
use futures::stream;
use futures::Future;

use long_tests::long_tests_pb::*;
use long_tests::long_tests_pb_grpc::*;

use grpc::futures_grpc::GrpcStreamSend;
use grpc::futures_grpc::GrpcFutureSend;
use grpc::error::GrpcError;

use std::env;

fn main() {
    let args: Vec<String> = env::args().collect();
    if args.len() < 2 {
        panic!("too few args")
    }

    let client = LongTestsClient::new("localhost", 23432, false).expect("init");

    let cmd = &args[1];
    if cmd == "echo" {

    } else {
        panic!("unknown command: {}", cmd);
    }
}
<commit_msg>Long tests that shows that client may hung because it ignores window<commit_after>use std::thread;
use std::iter;

extern crate env_logger;

extern crate grpc;
extern crate long_tests;
extern crate futures;

use futures::stream::Stream;
use futures::stream;
use futures::Future;

use long_tests::long_tests_pb::*;
use long_tests::long_tests_pb_grpc::*;

use grpc::futures_grpc::GrpcStreamSend;
use grpc::futures_grpc::GrpcFutureSend;
use grpc::error::GrpcError;

use std::env;

fn single_num_arg_or(cmd_args: &[String], or: u64) -> u64 {
    if cmd_args.len() == 0 {
        or
    } else if cmd_args.len() == 1 {
        cmd_args[0].parse().expect("failed to parse as u64")
    } else {
        panic!("too many args");
    }
}

fn run_echo(client: LongTestsAsyncClient, cmd_args: &[String]) {
    let count = single_num_arg_or(cmd_args, 1);

    println!("running {} iterations of echo", count);

    for i in 0..count {
        let payload = format!("payload {}", i);

        let mut req = EchoRequest::new();
        req.set_payload(payload.clone());

        let r = client.echo(req).wait().unwrap();

        assert!(payload == r.get_payload());
    }

    println!("done");
}

fn main() {
    env_logger::init().unwrap();

    let args: Vec<String> = env::args().collect();
    if args.len() < 2 {
        panic!("too few args")
    }

    let client = LongTestsAsyncClient::new("localhost", 23432, false).expect("init");

    let cmd = &args[1];
    let cmd_args = &args[2..];
    if cmd == "echo" {
        run_echo(client, cmd_args);
    } else {
        panic!("unknown command: {}", cmd);
    }
}
<|endoftext|>


<commit_before>//! Abstractions for page tables and other paging related structures.

pub use self::page_table::*;
pub use self::recursive::*;

use addr::{VirtAddr, PhysAddr};
use core::ops::{Add, AddAssign, Sub, SubAssign};
use ux::*;

mod page_table;
mod recursive;

/// The default page size on x86_64.
pub const PAGE_SIZE: u16 = 4096;

/// A virtual 4kB page.
#[derive(Debug, Clone, PartialEq, PartialOrd)]
pub struct Page {
   number: u64,
}

impl Page {
    /// Returns the page that contains the given virtual address.
    pub fn containing_address(address: VirtAddr) -> Page {
        Page { number: address.as_u64() / u64::from(PAGE_SIZE) }
    }

    pub fn from_page_table_indices(p4_index: u9, p3_index: u9, p2_index: u9, p1_index: u9)
        -> Page
    {
        use bit_field::BitField;

        let mut addr = 0;
        addr.set_bits(39..48, u64::from(p4_index));
        addr.set_bits(30..39, u64::from(p3_index));
        addr.set_bits(21..30, u64::from(p2_index));
        addr.set_bits(12..21, u64::from(p1_index));
        Page::containing_address(VirtAddr::new(addr))
    }

    /// Returns the start address of the page.
    pub fn start_address(&self) -> VirtAddr {
        VirtAddr::new(self.number * u64::from(PAGE_SIZE))
    }

    /// Returns the level 4 page table index of this page.
    pub fn p4_index(&self) -> u9 {
        self.start_address().p4_index()
    }

    /// Returns the level 3 page table index of this page.
    pub fn p3_index(&self) -> u9 {
        self.start_address().p3_index()
    }

    /// Returns the level 2 page table index of this page.
    pub fn p2_index(&self) -> u9 {
        self.start_address().p2_index()
    }

    /// Returns the level 1 page table index of this page.
    pub fn p1_index(&self) -> u9 {
        self.start_address().p1_index()
    }

    pub fn range(start: Page, end: Page) -> PageRange {
        PageRange { start, end }
    }

    pub fn range_inclusive(start: Page, end: Page) -> PageRangeInclusive {
        PageRangeInclusive { start, end }
    }
}

impl Add<u64> for Page {
    type Output = Self;
    fn add(self, rhs: u64) -> Self::Output {
        Page::containing_address(self.start_address() + rhs * u64::from(PAGE_SIZE))
    }
}

impl AddAssign<u64> for Page {
    fn add_assign(&mut self, rhs: u64) {
        *self = self.clone() + rhs;
    }
}

impl Sub<u64> for Page {
    type Output = Self;
    fn sub(self, rhs: u64) -> Self::Output {
        Page::containing_address(self.start_address() - rhs * u64::from(PAGE_SIZE))
    }
}

impl SubAssign<u64> for Page {
    fn sub_assign(&mut self, rhs: u64) {
        *self = self.clone() - rhs;
    }
}

pub struct PageRange {
    pub start: Page,
    pub end: Page,
}

impl Iterator for PageRange {
    type Item = Page;

    fn next(&mut self) -> Option<Page> {
        if self.start < self.end {
            let page = self.start.clone();
            self.start += 1;
            Some(page)
        } else {
            None
        }
    }
}

pub struct PageRangeInclusive {
    pub start: Page,
    pub end: Page,
}

impl Iterator for PageRangeInclusive {
    type Item = Page;

    fn next(&mut self) -> Option<Page> {
        if self.start <= self.end {
            let page = self.start.clone();
            self.start += 1;
            Some(page)
        } else {
            None
        }
    }
}

/// A physical 4kB frame.
#[derive(Debug, Clone, PartialEq, PartialOrd)]
pub struct PhysFrame {
   number: u64,
}

impl PhysFrame {
    /// Returns the frame that contains the given physical address.
    pub fn containing_address(address: PhysAddr) -> PhysFrame {
        PhysFrame { number: address.as_u64() / u64::from(PAGE_SIZE) }
    }

    /// Returns the start address of the page.
    pub fn start_address(&self) -> PhysAddr {
        PhysAddr::new(self.number * u64::from(PAGE_SIZE))
    }
}

impl Add<u64> for PhysFrame {
    type Output = Self;
    fn add(self, rhs: u64) -> Self::Output {
        PhysFrame::containing_address(self.start_address() + rhs * u64::from(PAGE_SIZE))
    }
}

impl AddAssign<u64> for PhysFrame {
    fn add_assign(&mut self, rhs: u64) {
        *self = self.clone() + rhs;
    }
}

impl Sub<u64> for PhysFrame {
    type Output = Self;
    fn sub(self, rhs: u64) -> Self::Output {
        PhysFrame::containing_address(self.start_address() - rhs * u64::from(PAGE_SIZE))
    }
}

impl SubAssign<u64> for PhysFrame {
    fn sub_assign(&mut self, rhs: u64) {
        *self = self.clone() - rhs;
    }
}
<commit_msg>Add PhysFrameRange and PhysFrameRangeInclusive types<commit_after>//! Abstractions for page tables and other paging related structures.

pub use self::page_table::*;
pub use self::recursive::*;

use addr::{VirtAddr, PhysAddr};
use core::ops::{Add, AddAssign, Sub, SubAssign};
use ux::*;

mod page_table;
mod recursive;

/// The default page size on x86_64.
pub const PAGE_SIZE: u16 = 4096;

/// A virtual 4kB page.
#[derive(Debug, Clone, PartialEq, PartialOrd)]
pub struct Page {
   number: u64,
}

impl Page {
    /// Returns the page that contains the given virtual address.
    pub fn containing_address(address: VirtAddr) -> Page {
        Page { number: address.as_u64() / u64::from(PAGE_SIZE) }
    }

    pub fn from_page_table_indices(p4_index: u9, p3_index: u9, p2_index: u9, p1_index: u9)
        -> Page
    {
        use bit_field::BitField;

        let mut addr = 0;
        addr.set_bits(39..48, u64::from(p4_index));
        addr.set_bits(30..39, u64::from(p3_index));
        addr.set_bits(21..30, u64::from(p2_index));
        addr.set_bits(12..21, u64::from(p1_index));
        Page::containing_address(VirtAddr::new(addr))
    }

    /// Returns the start address of the page.
    pub fn start_address(&self) -> VirtAddr {
        VirtAddr::new(self.number * u64::from(PAGE_SIZE))
    }

    /// Returns the level 4 page table index of this page.
    pub fn p4_index(&self) -> u9 {
        self.start_address().p4_index()
    }

    /// Returns the level 3 page table index of this page.
    pub fn p3_index(&self) -> u9 {
        self.start_address().p3_index()
    }

    /// Returns the level 2 page table index of this page.
    pub fn p2_index(&self) -> u9 {
        self.start_address().p2_index()
    }

    /// Returns the level 1 page table index of this page.
    pub fn p1_index(&self) -> u9 {
        self.start_address().p1_index()
    }

    pub fn range(start: Page, end: Page) -> PageRange {
        PageRange { start, end }
    }

    pub fn range_inclusive(start: Page, end: Page) -> PageRangeInclusive {
        PageRangeInclusive { start, end }
    }
}

impl Add<u64> for Page {
    type Output = Self;
    fn add(self, rhs: u64) -> Self::Output {
        Page::containing_address(self.start_address() + rhs * u64::from(PAGE_SIZE))
    }
}

impl AddAssign<u64> for Page {
    fn add_assign(&mut self, rhs: u64) {
        *self = self.clone() + rhs;
    }
}

impl Sub<u64> for Page {
    type Output = Self;
    fn sub(self, rhs: u64) -> Self::Output {
        Page::containing_address(self.start_address() - rhs * u64::from(PAGE_SIZE))
    }
}

impl SubAssign<u64> for Page {
    fn sub_assign(&mut self, rhs: u64) {
        *self = self.clone() - rhs;
    }
}

pub struct PageRange {
    pub start: Page,
    pub end: Page,
}

impl Iterator for PageRange {
    type Item = Page;

    fn next(&mut self) -> Option<Page> {
        if self.start < self.end {
            let page = self.start.clone();
            self.start += 1;
            Some(page)
        } else {
            None
        }
    }
}

pub struct PageRangeInclusive {
    pub start: Page,
    pub end: Page,
}

impl Iterator for PageRangeInclusive {
    type Item = Page;

    fn next(&mut self) -> Option<Page> {
        if self.start <= self.end {
            let page = self.start.clone();
            self.start += 1;
            Some(page)
        } else {
            None
        }
    }
}

/// A physical 4kB frame.
#[derive(Debug, Clone, PartialEq, PartialOrd)]
pub struct PhysFrame {
   number: u64,
}

impl PhysFrame {
    /// Returns the frame that contains the given physical address.
    pub fn containing_address(address: PhysAddr) -> PhysFrame {
        PhysFrame { number: address.as_u64() / u64::from(PAGE_SIZE) }
    }

    /// Returns the start address of the page.
    pub fn start_address(&self) -> PhysAddr {
        PhysAddr::new(self.number * u64::from(PAGE_SIZE))
    }

    pub fn range(start: PhysFrame, end: PhysFrame) -> PhysFrameRange {
        PhysFrameRange { start, end }
    }

    pub fn range_inclusive(start: PhysFrame, end: PhysFrame) -> PhysFrameRangeInclusive {
        PhysFrameRangeInclusive { start, end }
    }
}

impl Add<u64> for PhysFrame {
    type Output = Self;
    fn add(self, rhs: u64) -> Self::Output {
        PhysFrame::containing_address(self.start_address() + rhs * u64::from(PAGE_SIZE))
    }
}

impl AddAssign<u64> for PhysFrame {
    fn add_assign(&mut self, rhs: u64) {
        *self = self.clone() + rhs;
    }
}

impl Sub<u64> for PhysFrame {
    type Output = Self;
    fn sub(self, rhs: u64) -> Self::Output {
        PhysFrame::containing_address(self.start_address() - rhs * u64::from(PAGE_SIZE))
    }
}

impl SubAssign<u64> for PhysFrame {
    fn sub_assign(&mut self, rhs: u64) {
        *self = self.clone() - rhs;
    }
}

pub struct PhysFrameRange {
    pub start: PhysFrame,
    pub end: PhysFrame,
}

impl Iterator for PhysFrameRange {
    type Item = PhysFrame;

    fn next(&mut self) -> Option<PhysFrame> {
        if self.start < self.end {
            let frame = self.start.clone();
            self.start += 1;
            Some(frame)
        } else {
            None
        }
    }
}

pub struct PhysFrameRangeInclusive {
    pub start: PhysFrame,
    pub end: PhysFrame,
}

impl Iterator for PhysFrameRangeInclusive {
    type Item = PhysFrame;

    fn next(&mut self) -> Option<PhysFrame> {
        if self.start <= self.end {
            let frame = self.start.clone();
            self.start += 1;
            Some(frame)
        } else {
            None
        }
    }
}
<|endoftext|>


<commit_before>use bot::BotEnv;
use tasks::RunsTask;
use database::models::{Presence, PresenceKind};

use serenity::prelude::Mutex;
use serenity::model::gateway::Game;
use serenity::client::bridge::gateway::{ShardClientMessage, ShardRunnerMessage};
use serenity::client::bridge::gateway::ShardManager;

use diesel::prelude::*;

use chrono::Duration;

use rand::{Rng, thread_rng};

use std::sync::Arc;
use std::thread;

#[derive(Debug)]
pub struct RandomPresenceTask {
  next_sleep: i64,
  shard_manager: Arc<Mutex<ShardManager>>
}

impl RandomPresenceTask {
  pub fn new(shard_manager: Arc<Mutex<ShardManager>>) -> Self {
    RandomPresenceTask {
      next_sleep: 0,
      shard_manager
    }
  }
}

impl RunsTask for RandomPresenceTask {
  fn start(mut self, env: Arc<BotEnv>) {
    loop {
      if self.next_sleep == 0 {
        self.next_sleep = ::std::cmp::max(12, env.config.read().presence.change_frequency);
      }
      thread::sleep(Duration::seconds(self.next_sleep).to_std().unwrap());
      info!("Changing presence");
      let game = match random_game() {
        Some(g) => g,
        None => {
          info!("No presence");
          continue;
        }
      };
      let manager = self.shard_manager.lock();
      let runners = manager.runners.lock();
      for si in runners.values() {
        let message = ShardClientMessage::Runner(ShardRunnerMessage::SetGame(Some(game.clone())));
        if let Err(e) = si.runner_tx.send(message) {
          warn!("Could not tell shard to change presence: {}", e);
        }
      }
      info!("Done changing presence");
    }
  }
}

pub fn random_game() -> Option<Game> {
  let presences: Vec<Presence> = ::bot::CONNECTION.with(|c| {
    use database::schema::presences::dsl;
    dsl::presences.load(c).ok()
  })?;
  let presence = thread_rng().choose(&presences)?;
  let game_type = PresenceKind::from_i16(presence.kind)?.as_discord();
  Some(Game {
    kind: game_type,
    name: presence.content.clone(),
    url: None
  })
}
<commit_msg>fix: use new struct<commit_after>use bot::BotEnv;
use tasks::RunsTask;
use database::models::{Presence, PresenceKind};

use serenity::prelude::Mutex;
use serenity::model::gateway::Game;
use serenity::client::bridge::gateway::{ShardClientMessage, ShardRunnerMessage};
use serenity::gateway::InterMessage;
use serenity::client::bridge::gateway::ShardManager;

use diesel::prelude::*;

use chrono::Duration;

use rand::{Rng, thread_rng};

use std::sync::Arc;
use std::thread;

#[derive(Debug)]
pub struct RandomPresenceTask {
  next_sleep: i64,
  shard_manager: Arc<Mutex<ShardManager>>
}

impl RandomPresenceTask {
  pub fn new(shard_manager: Arc<Mutex<ShardManager>>) -> Self {
    RandomPresenceTask {
      next_sleep: 0,
      shard_manager
    }
  }
}

impl RunsTask for RandomPresenceTask {
  fn start(mut self, env: Arc<BotEnv>) {
    loop {
      if self.next_sleep == 0 {
        self.next_sleep = ::std::cmp::max(12, env.config.read().presence.change_frequency);
      }
      thread::sleep(Duration::seconds(self.next_sleep).to_std().unwrap());
      info!("Changing presence");
      let game = match random_game() {
        Some(g) => g,
        None => {
          info!("No presence");
          continue;
        }
      };
      let manager = self.shard_manager.lock();
      let runners = manager.runners.lock();
      for si in runners.values() {
        let message = InterMessage::Client(
          ShardClientMessage::Runner(ShardRunnerMessage::SetGame(Some(game.clone())))
        );
        if let Err(e) = si.runner_tx.send(message) {
          warn!("Could not tell shard to change presence: {}", e);
        }
      }
      info!("Done changing presence");
    }
  }
}

pub fn random_game() -> Option<Game> {
  let presences: Vec<Presence> = ::bot::CONNECTION.with(|c| {
    use database::schema::presences::dsl;
    dsl::presences.load(c).ok()
  })?;
  let presence = thread_rng().choose(&presences)?;
  let game_type = PresenceKind::from_i16(presence.kind)?.as_discord();
  Some(Game {
    kind: game_type,
    name: presence.content.clone(),
    url: None
  })
}
<|endoftext|>


<commit_before>//! Schannel credentials.
use winapi;
use secur32;
use std::io;
use std::mem;
use std::ptr;

use Inner;

lazy_static! {
    static ref UNISP_NAME: Vec<u8> = winapi::UNISP_NAME.bytes().chain(Some(0)).collect();
}

/// The communication direction that an `SchannelCred` will support.
#[derive(Copy, Debug, Clone, PartialEq, Eq)]
pub enum Direction {
    /// Server-side, inbound connections.
    Inbound,
    /// Client-side, outbound connections.
    Outbound,
}

/// Algorithms supported by Schannel.
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa375549(v=vs.85).aspx
#[derive(Debug, Copy, Clone)]
#[repr(u32)]
pub enum Algorithm {
    /// Advanced Encryption Standard (AES).
    Aes = winapi::CALG_AES,
    /// 128 bit AES.
    Aes128 = winapi::CALG_AES_128,
    /// 192 bit AES.
    Aes192 = winapi::CALG_AES_192,
    /// 256 bit AES.
    Aes256 = winapi::CALG_AES_256,
    /// Temporary algorithm identifier for handles of Diffie-Hellman–agreed keys.
    AgreedkeyAny = winapi::CALG_AGREEDKEY_ANY,
    /// An algorithm to create a 40-bit DES key that has parity bits and zeroed key bits to make
    /// its key length 64 bits.
    CylinkMek = winapi::CALG_CYLINK_MEK,
    /// DES encryption algorithm.
    Des = winapi::CALG_DES,
    /// DESX encryption algorithm.
    Desx = winapi::CALG_DESX,
    /// Diffie-Hellman ephemeral key exchange algorithm.
    DhEphem = winapi::CALG_DH_EPHEM,
    /// Diffie-Hellman store and forward key exchange algorithm.
    DhSf = winapi::CALG_DH_SF,
    /// DSA public key signature algorithm.
    DssSign = winapi::CALG_DSS_SIGN,
    /// Elliptic curve Diffie-Hellman key exchange algorithm.
    Ecdh = winapi::CALG_ECDH,
    // https://github.com/retep998/winapi-rs/issues/287
    // /// Ephemeral elliptic curve Diffie-Hellman key exchange algorithm.
    // EcdhEphem = winapi::CALG_ECDH_EPHEM,
    /// Elliptic curve digital signature algorithm.
    Ecdsa = winapi::CALG_ECDSA,
    /// One way function hashing algorithm.
    HashReplaceOwf = winapi::CALG_HASH_REPLACE_OWF,
    /// Hughes MD5 hashing algorithm.
    HughesMd5 = winapi::CALG_HUGHES_MD5,
    /// HMAC keyed hash algorithm.
    Hmac = winapi::CALG_HMAC,
    /// MAC keyed hash algorithm.
    Mac = winapi::CALG_MAC,
    /// MD2 hashing algorithm.
    Md2 = winapi::CALG_MD2,
    /// MD4 hashing algorithm.
    Md4 = winapi::CALG_MD4,
    /// MD5 hashing algorithm.
    Md5 = winapi::CALG_MD5,
    /// No signature algorithm..
    NoSign = winapi::CALG_NO_SIGN,
    /// RC2 block encryption algorithm.
    Rc2 = winapi::CALG_RC2,
    /// RC4 stream encryption algorithm.
    Rc4 = winapi::CALG_RC4,
    /// RC5 block encryption algorithm.
    Rc5 = winapi::CALG_RC5,
    /// RSA public key exchange algorithm.
    RsaKeyx = winapi::CALG_RSA_KEYX,
    /// RSA public key signature algorithm.
    RsaSign = winapi::CALG_RSA_SIGN,
    /// SHA hashing algorithm.
    Sha1 = winapi::CALG_SHA1,
    /// 256 bit SHA hashing algorithm.
    Sha256 = winapi::CALG_SHA_256,
    /// 384 bit SHA hashing algorithm.
    Sha384 = winapi::CALG_SHA_384,
    /// 512 bit SHA hashing algorithm.
    Sha512 = winapi::CALG_SHA_512,
    /// Triple DES encryption algorithm.
    TripleDes = winapi::CALG_3DES,
    /// Two-key triple DES encryption with effective key length equal to 112 bits.
    TripleDes112 = winapi::CALG_3DES_112,
    #[doc(hidden)]
    __ForExtensibility,
}

/// Protocols supported by Schannel.
#[derive(Debug, Copy, Clone)]
pub enum Protocol {
    /// Secure Sockets Layer 3.0
    Ssl3,
    /// Transport Layer Security 1.0
    Tls10,
    /// Transport Layer Security 1.1
    Tls11,
    /// Transport Layer Security 1.2
    Tls12,
    #[doc(hidden)]
    __ForExtensibility,
}

impl Protocol {
    fn dword(self, direction: Direction) -> winapi::DWORD {
        match (self, direction) {
            (Protocol::Ssl3, Direction::Inbound) => winapi::SP_PROT_SSL3_SERVER,
            (Protocol::Tls10, Direction::Inbound) => winapi::SP_PROT_TLS1_0_SERVER,
            (Protocol::Tls11, Direction::Inbound) => winapi::SP_PROT_TLS1_1_SERVER,
            (Protocol::Tls12, Direction::Inbound) => winapi::SP_PROT_TLS1_2_SERVER,
            (Protocol::Ssl3, Direction::Outbound) => winapi::SP_PROT_SSL3_CLIENT,
            (Protocol::Tls10, Direction::Outbound) => winapi::SP_PROT_TLS1_0_CLIENT,
            (Protocol::Tls11, Direction::Outbound) => winapi::SP_PROT_TLS1_1_CLIENT,
            (Protocol::Tls12, Direction::Outbound) => winapi::SP_PROT_TLS1_2_CLIENT,
            (Protocol::__ForExtensibility, _) => unreachable!(),
        }
    }
}

/// A builder type for `SchannelCred`s.
#[derive(Default, Debug)]
pub struct Builder {
    supported_algorithms: Option<Vec<Algorithm>>,
    enabled_protocols: Option<Vec<Protocol>>,
}

impl Builder {
    /// Returns a new `Builder`.
    pub fn new() -> Builder {
        Builder::default()
    }

    /// Sets the algorithms supported for credentials created from this builder.
    pub fn supported_algorithms(mut self, supported_algorithms: &[Algorithm]) -> Builder {
        assert!(supported_algorithms.iter()
            .all(|a| {
                match *a {
                    Algorithm::__ForExtensibility => false,
                    _ => true,
                }
            }));
        self.supported_algorithms = Some(supported_algorithms.to_owned());
        self
    }

    /// Sets the protocols enabled for credentials created from this builder.
    pub fn enabled_protocols(mut self, enabled_protocols: &[Protocol]) -> Builder {
        assert!(enabled_protocols.iter()
            .all(|a| {
                match *a {
                    Protocol::__ForExtensibility => false,
                    _ => true,
                }
            }));
        self.enabled_protocols = Some(enabled_protocols.to_owned());
        self
    }

    /// Creates a new `SchannelCred`.
    pub fn acquire(&self, direction: Direction) -> io::Result<SchannelCred> {
        unsafe {
            let mut handle = mem::uninitialized();
            let mut cred_data: winapi::SCHANNEL_CRED = mem::zeroed();
            cred_data.dwVersion = winapi::SCHANNEL_CRED_VERSION;
            cred_data.dwFlags = winapi::SCH_USE_STRONG_CRYPTO;
            if let Some(ref supported_algorithms) = self.supported_algorithms {
                cred_data.cSupportedAlgs = supported_algorithms.len() as winapi::DWORD;
                cred_data.palgSupportedAlgs = supported_algorithms.as_ptr() as *mut _;
            }
            if let Some(ref enabled_protocols) = self.enabled_protocols {
                cred_data.grbitEnabledProtocols = enabled_protocols.iter()
                    .map(|p| p.dword(direction))
                    .fold(0, |acc, p| acc | p);
            }

            let direction = match direction {
                Direction::Inbound => winapi::SECPKG_CRED_INBOUND,
                Direction::Outbound => winapi::SECPKG_CRED_OUTBOUND,
            };

            match secur32::AcquireCredentialsHandleA(ptr::null_mut(),
                                                     UNISP_NAME.as_ptr() as *const _ as *mut _,
                                                     direction,
                                                     ptr::null_mut(),
                                                     &mut cred_data as *mut _ as *mut _,
                                                     None,
                                                     ptr::null_mut(),
                                                     &mut handle,
                                                     ptr::null_mut()) {
                winapi::SEC_E_OK => Ok(SchannelCred(handle)),
                err => Err(io::Error::from_raw_os_error(err as i32)),
            }
        }
    }
}

/// An SChannel credential.
pub struct SchannelCred(winapi::CredHandle);

impl Drop for SchannelCred {
    fn drop(&mut self) {
        unsafe {
            secur32::FreeCredentialsHandle(&mut self.0);
        }
    }
}

impl Inner<winapi::CredHandle> for SchannelCred {
    unsafe fn from_inner(inner: winapi::CredHandle) -> SchannelCred {
        SchannelCred(inner)
    }

    fn as_inner(&self) -> winapi::CredHandle {
        self.0
    }

    fn get_mut(&mut self) -> &mut winapi::CredHandle {
        &mut self.0
    }
}

impl SchannelCred {
    /// Returns a builder.
    pub fn builder() -> Builder {
        Builder::new()
    }
}
<commit_msg>Move the SChannelCred Builder to &mut self<commit_after>//! Schannel credentials.
use winapi;
use secur32;
use std::io;
use std::mem;
use std::ptr;

use Inner;

lazy_static! {
    static ref UNISP_NAME: Vec<u8> = winapi::UNISP_NAME.bytes().chain(Some(0)).collect();
}

/// The communication direction that an `SchannelCred` will support.
#[derive(Copy, Debug, Clone, PartialEq, Eq)]
pub enum Direction {
    /// Server-side, inbound connections.
    Inbound,
    /// Client-side, outbound connections.
    Outbound,
}

/// Algorithms supported by Schannel.
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa375549(v=vs.85).aspx
#[derive(Debug, Copy, Clone)]
#[repr(u32)]
pub enum Algorithm {
    /// Advanced Encryption Standard (AES).
    Aes = winapi::CALG_AES,
    /// 128 bit AES.
    Aes128 = winapi::CALG_AES_128,
    /// 192 bit AES.
    Aes192 = winapi::CALG_AES_192,
    /// 256 bit AES.
    Aes256 = winapi::CALG_AES_256,
    /// Temporary algorithm identifier for handles of Diffie-Hellman–agreed keys.
    AgreedkeyAny = winapi::CALG_AGREEDKEY_ANY,
    /// An algorithm to create a 40-bit DES key that has parity bits and zeroed key bits to make
    /// its key length 64 bits.
    CylinkMek = winapi::CALG_CYLINK_MEK,
    /// DES encryption algorithm.
    Des = winapi::CALG_DES,
    /// DESX encryption algorithm.
    Desx = winapi::CALG_DESX,
    /// Diffie-Hellman ephemeral key exchange algorithm.
    DhEphem = winapi::CALG_DH_EPHEM,
    /// Diffie-Hellman store and forward key exchange algorithm.
    DhSf = winapi::CALG_DH_SF,
    /// DSA public key signature algorithm.
    DssSign = winapi::CALG_DSS_SIGN,
    /// Elliptic curve Diffie-Hellman key exchange algorithm.
    Ecdh = winapi::CALG_ECDH,
    // https://github.com/retep998/winapi-rs/issues/287
    // /// Ephemeral elliptic curve Diffie-Hellman key exchange algorithm.
    // EcdhEphem = winapi::CALG_ECDH_EPHEM,
    /// Elliptic curve digital signature algorithm.
    Ecdsa = winapi::CALG_ECDSA,
    /// One way function hashing algorithm.
    HashReplaceOwf = winapi::CALG_HASH_REPLACE_OWF,
    /// Hughes MD5 hashing algorithm.
    HughesMd5 = winapi::CALG_HUGHES_MD5,
    /// HMAC keyed hash algorithm.
    Hmac = winapi::CALG_HMAC,
    /// MAC keyed hash algorithm.
    Mac = winapi::CALG_MAC,
    /// MD2 hashing algorithm.
    Md2 = winapi::CALG_MD2,
    /// MD4 hashing algorithm.
    Md4 = winapi::CALG_MD4,
    /// MD5 hashing algorithm.
    Md5 = winapi::CALG_MD5,
    /// No signature algorithm..
    NoSign = winapi::CALG_NO_SIGN,
    /// RC2 block encryption algorithm.
    Rc2 = winapi::CALG_RC2,
    /// RC4 stream encryption algorithm.
    Rc4 = winapi::CALG_RC4,
    /// RC5 block encryption algorithm.
    Rc5 = winapi::CALG_RC5,
    /// RSA public key exchange algorithm.
    RsaKeyx = winapi::CALG_RSA_KEYX,
    /// RSA public key signature algorithm.
    RsaSign = winapi::CALG_RSA_SIGN,
    /// SHA hashing algorithm.
    Sha1 = winapi::CALG_SHA1,
    /// 256 bit SHA hashing algorithm.
    Sha256 = winapi::CALG_SHA_256,
    /// 384 bit SHA hashing algorithm.
    Sha384 = winapi::CALG_SHA_384,
    /// 512 bit SHA hashing algorithm.
    Sha512 = winapi::CALG_SHA_512,
    /// Triple DES encryption algorithm.
    TripleDes = winapi::CALG_3DES,
    /// Two-key triple DES encryption with effective key length equal to 112 bits.
    TripleDes112 = winapi::CALG_3DES_112,
    #[doc(hidden)]
    __ForExtensibility,
}

/// Protocols supported by Schannel.
#[derive(Debug, Copy, Clone)]
pub enum Protocol {
    /// Secure Sockets Layer 3.0
    Ssl3,
    /// Transport Layer Security 1.0
    Tls10,
    /// Transport Layer Security 1.1
    Tls11,
    /// Transport Layer Security 1.2
    Tls12,
    #[doc(hidden)]
    __ForExtensibility,
}

impl Protocol {
    fn dword(self, direction: Direction) -> winapi::DWORD {
        match (self, direction) {
            (Protocol::Ssl3, Direction::Inbound) => winapi::SP_PROT_SSL3_SERVER,
            (Protocol::Tls10, Direction::Inbound) => winapi::SP_PROT_TLS1_0_SERVER,
            (Protocol::Tls11, Direction::Inbound) => winapi::SP_PROT_TLS1_1_SERVER,
            (Protocol::Tls12, Direction::Inbound) => winapi::SP_PROT_TLS1_2_SERVER,
            (Protocol::Ssl3, Direction::Outbound) => winapi::SP_PROT_SSL3_CLIENT,
            (Protocol::Tls10, Direction::Outbound) => winapi::SP_PROT_TLS1_0_CLIENT,
            (Protocol::Tls11, Direction::Outbound) => winapi::SP_PROT_TLS1_1_CLIENT,
            (Protocol::Tls12, Direction::Outbound) => winapi::SP_PROT_TLS1_2_CLIENT,
            (Protocol::__ForExtensibility, _) => unreachable!(),
        }
    }
}

/// A builder type for `SchannelCred`s.
#[derive(Default, Debug)]
pub struct Builder {
    supported_algorithms: Option<Vec<Algorithm>>,
    enabled_protocols: Option<Vec<Protocol>>,
}

impl Builder {
    /// Returns a new `Builder`.
    pub fn new() -> Builder {
        Builder::default()
    }

    /// Sets the algorithms supported for credentials created from this builder.
    pub fn supported_algorithms(&mut self,
                                supported_algorithms: &[Algorithm])
                                -> &mut Builder {
        assert!(supported_algorithms.iter()
            .all(|a| {
                match *a {
                    Algorithm::__ForExtensibility => false,
                    _ => true,
                }
            }));
        self.supported_algorithms = Some(supported_algorithms.to_owned());
        self
    }

    /// Sets the protocols enabled for credentials created from this builder.
    pub fn enabled_protocols(&mut self,
                             enabled_protocols: &[Protocol])
                             -> &mut Builder {
        assert!(enabled_protocols.iter()
            .all(|a| {
                match *a {
                    Protocol::__ForExtensibility => false,
                    _ => true,
                }
            }));
        self.enabled_protocols = Some(enabled_protocols.to_owned());
        self
    }

    /// Creates a new `SchannelCred`.
    pub fn acquire(&self, direction: Direction) -> io::Result<SchannelCred> {
        unsafe {
            let mut handle = mem::uninitialized();
            let mut cred_data: winapi::SCHANNEL_CRED = mem::zeroed();
            cred_data.dwVersion = winapi::SCHANNEL_CRED_VERSION;
            cred_data.dwFlags = winapi::SCH_USE_STRONG_CRYPTO;
            if let Some(ref supported_algorithms) = self.supported_algorithms {
                cred_data.cSupportedAlgs = supported_algorithms.len() as winapi::DWORD;
                cred_data.palgSupportedAlgs = supported_algorithms.as_ptr() as *mut _;
            }
            if let Some(ref enabled_protocols) = self.enabled_protocols {
                cred_data.grbitEnabledProtocols = enabled_protocols.iter()
                    .map(|p| p.dword(direction))
                    .fold(0, |acc, p| acc | p);
            }

            let direction = match direction {
                Direction::Inbound => winapi::SECPKG_CRED_INBOUND,
                Direction::Outbound => winapi::SECPKG_CRED_OUTBOUND,
            };

            match secur32::AcquireCredentialsHandleA(ptr::null_mut(),
                                                     UNISP_NAME.as_ptr() as *const _ as *mut _,
                                                     direction,
                                                     ptr::null_mut(),
                                                     &mut cred_data as *mut _ as *mut _,
                                                     None,
                                                     ptr::null_mut(),
                                                     &mut handle,
                                                     ptr::null_mut()) {
                winapi::SEC_E_OK => Ok(SchannelCred(handle)),
                err => Err(io::Error::from_raw_os_error(err as i32)),
            }
        }
    }
}

/// An SChannel credential.
pub struct SchannelCred(winapi::CredHandle);

impl Drop for SchannelCred {
    fn drop(&mut self) {
        unsafe {
            secur32::FreeCredentialsHandle(&mut self.0);
        }
    }
}

impl Inner<winapi::CredHandle> for SchannelCred {
    unsafe fn from_inner(inner: winapi::CredHandle) -> SchannelCred {
        SchannelCred(inner)
    }

    fn as_inner(&self) -> winapi::CredHandle {
        self.0
    }

    fn get_mut(&mut self) -> &mut winapi::CredHandle {
        &mut self.0
    }
}

impl SchannelCred {
    /// Returns a builder.
    pub fn builder() -> Builder {
        Builder::new()
    }
}
<|endoftext|>


<commit_before>use proc_macro2::*;
use syn;

use meta::*;
use util::*;

pub fn derive(mut item: syn::DeriveInput) -> Result<TokenStream, Diagnostic> {
    let flags =
        MetaItem::with_name(&item.attrs, "diesel").unwrap_or_else(|| MetaItem::empty("diesel"));
    let struct_ty = ty_for_foreign_derive(&item, &flags)?;

    // To prevent double issue with mutable borrow below while creating where clause
    let initial_item = item.clone();

    let lifetimes = initial_item.generics.lifetimes().collect::<Vec<_>>();
    let ty_params = initial_item.generics.type_params().collect::<Vec<_>>();
    let const_params = initial_item.generics.const_params().collect::<Vec<_>>();

    {
        let where_clause = item
            .generics
            .where_clause
            .get_or_insert(parse_quote!(where));
        where_clause
            .predicates
            .push(parse_quote!(__DB: diesel::backend::Backend));
        where_clause
            .predicates
            .push(parse_quote!(__ST: diesel::sql_types::SingleValue));
        where_clause
            .predicates
            .push(parse_quote!(Self: FromSql<__ST, __DB>));
    }
    let (_, _, where_clause) = item.generics.split_for_impl();

    Ok(wrap_in_dummy_mod(quote! {
        use diesel::deserialize::{self, FromSql, Queryable};

        // Need to put __ST and __DB after lifetimes but before const params
        impl<#(#lifetimes,)* __ST, __DB, #(#ty_params,)* #(#const_params,)*> Queryable<__ST, __DB> for #struct_ty
        #where_clause
        {
            type Row = Self;

            fn build(row: Self::Row) -> deserialize::Result<Self> {
                Ok(row)
            }
        }
    }))
}
<commit_msg>Fixing confusing structure in from_sql_row<commit_after>use proc_macro2::*;
use syn;

use meta::*;
use util::*;

pub fn derive(mut item: syn::DeriveInput) -> Result<TokenStream, Diagnostic> {
    let flags =
        MetaItem::with_name(&item.attrs, "diesel").unwrap_or_else(|| MetaItem::empty("diesel"));
    let struct_ty = ty_for_foreign_derive(&item, &flags)?;

    {
        let where_clause = item
            .generics
            .where_clause
            .get_or_insert(parse_quote!(where));
        where_clause
            .predicates
            .push(parse_quote!(__DB: diesel::backend::Backend));
        where_clause
            .predicates
            .push(parse_quote!(__ST: diesel::sql_types::SingleValue));
        where_clause
            .predicates
            .push(parse_quote!(Self: FromSql<__ST, __DB>));
    }
    let (_, _, where_clause) = item.generics.split_for_impl();

    let lifetimes = item.generics.lifetimes().collect::<Vec<_>>();
    let ty_params = item.generics.type_params().collect::<Vec<_>>();
    let const_params = item.generics.const_params().collect::<Vec<_>>();

    Ok(wrap_in_dummy_mod(quote! {
        use diesel::deserialize::{self, FromSql, Queryable};

        // Need to put __ST and __DB after lifetimes but before const params
        impl<#(#lifetimes,)* __ST, __DB, #(#ty_params,)* #(#const_params,)*> Queryable<__ST, __DB> for #struct_ty
        #where_clause
        {
            type Row = Self;

            fn build(row: Self::Row) -> deserialize::Result<Self> {
                Ok(row)
            }
        }
    }))
}
<|endoftext|>


<commit_before>extern crate libc;

use x11::xlib;
use x11::xlib::{ Window, Display };

use std::boxed::Box;
use std::collections::HashMap;
use super::layout;
use super::WindowManager;

pub struct Workspace {
    root: Window,
    windows: Vec<Window>,
    pub layout: Box<layout::Layout>
}

impl Workspace {
    pub fn new() -> Workspace {
        Workspace {
            root: 0,
            windows: Vec::new(),
            layout: Box::new(layout::TilingLayout::new(layout::Direction::Horizontal))
        }
    }

    pub fn add(&mut self, window: Window) {
        self.windows.push(window);
    }

    pub fn remove(&mut self, window: Window) {
        let index = self.contain(window);
        match index {
            Some(i) => { self.windows.remove(i); }
            None => {}
        };
    }

    pub fn hide(&mut self, display: *mut Display) {
        for w in self.windows.iter() {
            unsafe{
                xlib::XUnmapWindow(display, *w);
            }
        }
    }

    pub fn show(&mut self, display: *mut Display) {
        for w in self.windows.iter() {
            unsafe{
                xlib::XMapWindow(display, *w);
            }
        }
    }

    pub fn contain(&self, window: Window) -> Option<usize>{
        self.windows.iter().position(|x| *x == window)
    }

    pub fn change_layout(&mut self, layout_type: layout::Type) {
        let t = self.layout.get_type();
        if t == layout_type {
            self.layout.toggle();
        }
        else{
            match layout_type {
                layout::Type::Tiling => {
                    let tmp = layout::TilingLayout::new(layout::Direction::Horizontal);
                    self.layout = Box::new(tmp);
                }
            }
        }
    }

    pub fn config(&self, display: *mut xlib::Display, screen_num: libc::c_int) {
        debug!("size {}", self.windows.len());
        self.layout.configure(&self.windows, display, screen_num);
    }
}

pub struct Workspaces {
    current: char,
    pub spaces: HashMap<char, Workspace>,
}

impl Workspaces {
    pub fn new() -> Workspaces {
        Workspaces {
            current: '1',
            spaces: HashMap::new()
        }
    }

    pub fn contain(&mut self, key: char) -> bool{
        self.spaces.contains_key(&key)
    }

    pub fn create(&mut self, key: char) {
        let space = Workspace::new();
        self.spaces.insert(key, space);
    }

    pub fn delete(&mut self, key: char) {
        self.spaces.remove(&key);
    }

    pub fn get(&mut self, key: char) -> Option<&mut Workspace>{
        self.spaces.get_mut(&key)
    }

    pub fn current(&mut self) -> &mut Workspace{
        self.spaces.get_mut(&self.current).unwrap()
    }

    pub fn current_name(&self) -> char {
        self.current
    }

    pub fn switch_current(&mut self, new: char, display: *mut Display){
        if new != self.current {
            if !self.contain(new) {
                self.create(new);
            }
            let old = self.current;
            self.current = new;

            match self.get(old) {
                Some(v) => {
                    v.hide(display);
                }
                None => {}
            }

            match self.get(new) {
                Some(v) => {
                    v.show(display);
                }
                None => {}
            }
        }
    }
}
<commit_msg>more workspace methods<commit_after>extern crate libc;

use x11::xlib;
use x11::xlib::{ Window, Display };

use std::boxed::Box;
use std::collections::HashMap;
use super::layout;
use super::WindowManager;

pub struct Workspace {
    root: Window,
    windows: Vec<Window>,
    layout: Box<layout::Layout>
}

impl Workspace {
    pub fn new() -> Workspace {
        Workspace {
            root: 0,
            windows: Vec::new(),
            layout: Box::new(layout::TilingLayout::new(layout::Direction::Horizontal))
        }
    }

    pub fn p(&self) {
        for w in self.windows.iter() {
            println!("{}", w);
        }
    }
    pub fn add(&mut self, window: Window) {
        let index = self.contain(window);
        match index {
            Some(i) => {}
            None => { self.windows.push(window) ;}
        }
    }

    pub fn remove(&mut self, window: Window) {
        let index = self.contain(window);
        match index {
            Some(i) => { self.windows.remove(i); }
            None => {}
        };
    }

    pub fn get(&self, index: usize) -> Window{
        self.windows[index]
    }

    pub fn size(&self) -> usize {
        self.windows.len()
    }

    pub fn hide(&mut self, display: *mut Display) {
        for w in self.windows.iter() {
            unsafe{
                xlib::XUnmapWindow(display, *w);
            }
        }
    }

    pub fn show(&mut self, display: *mut Display) {
        for w in self.windows.iter() {
            unsafe{
                xlib::XMapWindow(display, *w);
            }
        }
    }

    pub fn contain(&self, window: Window) -> Option<usize>{
        self.windows.iter().position(|x| *x == window)
    }

    pub fn change_layout(&mut self, layout_type: layout::Type) {
        let t = self.layout.get_type();
        if t == layout_type {
            self.layout.toggle();
        }
        else{
            match layout_type {
                layout::Type::Tiling => {
                    let tmp = layout::TilingLayout::new(layout::Direction::Horizontal);
                    self.layout = Box::new(tmp);
                }
            }
        }
    }

    pub fn config(&self, display: *mut xlib::Display, screen_num: libc::c_int) {
        debug!("size {}", self.windows.len());
        self.layout.configure(&self.windows, display, screen_num);
    }
}

pub struct Workspaces {
    current: char,
    pub spaces: HashMap<char, Workspace>,
}

impl Workspaces {
    pub fn new() -> Workspaces {
        Workspaces {
            current: '1',
            spaces: HashMap::new()
        }
    }

    pub fn contain(&mut self, key: char) -> bool{
        self.spaces.contains_key(&key)
    }

    pub fn create(&mut self, key: char) {
        let space = Workspace::new();
        self.spaces.insert(key, space);
    }

    pub fn delete(&mut self, key: char) {
        self.spaces.remove(&key);
    }

    pub fn get(&mut self, key: char) -> Option<&mut Workspace>{
        self.spaces.get_mut(&key)
    }

    pub fn current(&mut self) -> &mut Workspace {
        self.spaces.get_mut(&self.current).unwrap()
    }

    pub fn current_name(&self) -> char {
        self.current
    }

    pub fn switch_current(&mut self, new: char, display: *mut Display){
        if new != self.current {
            if !self.contain(new) {
                self.create(new);
            }
            let old = self.current;
            self.current = new;

            match self.get(old) {
                Some(v) => {
                    v.hide(display);
                }
                None => {}
            }

            match self.get(new) {
                Some(v) => {
                    v.show(display);
                }
                None => {}
            }
        }
    }

    pub fn move_window(&mut self, window: Window, from: char, to: char){
        if self.get(to).is_none(){
            self.create(to);
        }

        if from != to {
            match self.get(from) {
                Some(w) => { w.remove(window); }
                None => {}
            }
            match self.get(to) {
                Some(w) => { w.add(window); }
                None => {}
            }
        }
    }
}
<|endoftext|>