<commit_before>// Copyright 2013 The GLFW-RS Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Private callback support functions.

use libc::{c_double, c_int, c_uint};
use std::mem;

use super::*;

macro_rules! callback(
    (
        type Args = ($($arg:ident: $arg_ty:ty),*);
        type Callback = $Callback:ident;
        let ext_set = $ext_set:expr;
        fn callback($($ext_arg:ident: $ext_arg_ty:ty),*) $call:expr
    ) => (
        local_data_key!(CALLBACK_KEY: Box<Object<Args> + 'static>)

        type Args = ($($arg_ty),*,);

        trait Object<T> {
            fn call(&self, args: T);
        }

        impl<UserData> Object<Args> for ::Callback<fn($($arg_ty),*, &UserData), UserData> {
            fn call(&self, ($($arg),*,): Args) {
                (self.f)($($arg),*, &self.data);
            }
        }

        pub fn set<UserData: 'static>(f: ::$Callback<UserData>) {
            CALLBACK_KEY.replace(Some(box f as Box<Object<Args> + 'static>));
            ($ext_set)(Some(callback));
        }

        pub fn unset() {
            CALLBACK_KEY.replace(None);
            ($ext_set)(None);
        }

        extern "C" fn callback($($ext_arg: $ext_arg_ty),*) {
            match CALLBACK_KEY.get() {
                Some(cb) => unsafe { cb.call($call) },
                _ => {}
            }
        }
    )
)

pub mod error {
    use libc::{c_int, c_char};
    use std::mem;
    use std::string;

    callback!(
        type Args = (error: ::Error, description: String);
        type Callback = ErrorCallback;
        let ext_set = |cb| unsafe { ::ffi::glfwSetErrorCallback(cb) };
        fn callback(error: c_int, description: *const c_char) {
            (mem::transmute(error), string::String::from_raw_buf(
                description as *const u8))
        }
    )
}

pub mod monitor {
    use libc::{c_int};
    use std::mem;
    use std::kinds::marker;

    callback!(
        type Args = (monitor: ::Monitor, event: ::MonitorEvent);
        type Callback = MonitorCallback;
        let ext_set = |cb| unsafe { ::ffi::glfwSetMonitorCallback(cb) };
        fn callback(monitor: *mut ::ffi::GLFWmonitor, event: c_int) {
            let monitor = ::Monitor {
                ptr: monitor,
                no_copy: marker::NoCopy,
                no_send: marker::NoSend,
                no_share: marker::NoSync,
            };
            (monitor, mem::transmute(event))
        }
    )
}

unsafe fn get_sender<'a>(window: &'a *mut ffi::GLFWwindow) -> &'a Sender<(f64, WindowEvent)> {
    mem::transmute(ffi::glfwGetWindowUserPointer(*window))
}

macro_rules! window_callback(
    (fn $name:ident () => $event:ident) => (
        pub extern "C" fn $name(window: *mut ffi::GLFWwindow) {
            unsafe { get_sender(&window).send((ffi::glfwGetTime() as f64, WindowEvent::$event)); }
        }
     );
    (fn $name:ident ($($ext_arg:ident: $ext_arg_ty:ty),*) => $event:ident($($arg_conv:expr),*)) => (
        pub extern "C" fn $name(window: *mut ffi::GLFWwindow $(, $ext_arg: $ext_arg_ty)*) {
            unsafe { get_sender(&window).send((ffi::glfwGetTime() as f64, WindowEvent::$event($($arg_conv),*))); }
        }
     );
)

window_callback!(fn window_pos_callback(xpos: c_int, ypos: c_int)                           => PosEvent(xpos as i32, ypos as i32))
window_callback!(fn window_size_callback(width: c_int, height: c_int)                       => SizeEvent(width as i32, height as i32))
window_callback!(fn window_close_callback()                                                 => CloseEvent)
window_callback!(fn window_refresh_callback()                                               => RefreshEvent)
window_callback!(fn window_focus_callback(focused: c_int)                                   => FocusEvent(focused == ffi::TRUE))
window_callback!(fn window_iconify_callback(iconified: c_int)                               => IconifyEvent(iconified == ffi::TRUE))
window_callback!(fn framebuffer_size_callback(width: c_int, height: c_int)                  => FramebufferSizeEvent(width as i32, height as i32))
window_callback!(fn mouse_button_callback(button: c_int, action: c_int, mods: c_int)        => MouseButtonEvent(mem::transmute(button), mem::transmute(action), Modifiers::from_bits(mods).unwrap()))
window_callback!(fn cursor_pos_callback(xpos: c_double, ypos: c_double)                     => CursorPosEvent(xpos as f64, ypos as f64))
window_callback!(fn cursor_enter_callback(entered: c_int)                                   => CursorEnterEvent(entered == ffi::TRUE))
window_callback!(fn scroll_callback(xpos: c_double, ypos: c_double)                         => ScrollEvent(xpos as f64, ypos as f64))
window_callback!(fn key_callback(key: c_int, scancode: c_int, action: c_int, mods: c_int)   => KeyEvent(mem::transmute(key), scancode, mem::transmute(action), Modifiers::from_bits(mods).unwrap()))
window_callback!(fn char_callback(character: c_uint)                                        => CharEvent(::std::char::from_u32(character).unwrap()))
<commit_msg>Fix for thread local storage changes<commit_after>// Copyright 2013 The GLFW-RS Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Private callback support functions.

use libc::{c_double, c_int, c_uint};
use std::mem;

use super::*;

macro_rules! callback(
    (
        type Args = ($($arg:ident: $arg_ty:ty),*);
        type Callback = $Callback:ident;
        let ext_set = $ext_set:expr;
        fn callback($($ext_arg:ident: $ext_arg_ty:ty),*) $call:expr
    ) => (
        thread_local!(static CALLBACK_KEY: RefCell<Option<Box<Object<Args> + 'static>>> = RefCell::new(None))

        type Args = ($($arg_ty),*,);

        trait Object<T> {
            fn call(&self, args: T);
        }

        impl<UserData> Object<Args> for ::Callback<fn($($arg_ty),*, &UserData), UserData> {
            fn call(&self, ($($arg),*,): Args) {
                (self.f)($($arg),*, &self.data);
            }
        }

        pub fn set<UserData: 'static>(f: ::$Callback<UserData>) {
            let mut boxed_cb = Some(box f as Box<Object<Args> + 'static>);
            CALLBACK_KEY.with(|cb| {
                *cb.borrow_mut() = boxed_cb.take();
            });
            ($ext_set)(Some(callback));
        }

        pub fn unset() {
            CALLBACK_KEY.with(|cb| {
                *cb.borrow_mut() = None;
            });
            ($ext_set)(None);
        }

        extern "C" fn callback($($ext_arg: $ext_arg_ty),*) {
            CALLBACK_KEY.with(|cb| {
                match *cb.borrow() {
                    Some(ref cb) => unsafe { cb.call($call) },
                    _ => {}
                }
            })
        }
    )
)

pub mod error {
    use libc::{c_int, c_char};
    use std::cell::RefCell;
    use std::mem;
    use std::string;

    callback!(
        type Args = (error: ::Error, description: String);
        type Callback = ErrorCallback;
        let ext_set = |cb| unsafe { ::ffi::glfwSetErrorCallback(cb) };
        fn callback(error: c_int, description: *const c_char) {
            (mem::transmute(error), string::String::from_raw_buf(
                description as *const u8))
        }
    )
}

pub mod monitor {
    use libc::{c_int};
    use std::cell::RefCell;
    use std::mem;
    use std::kinds::marker;

    callback!(
        type Args = (monitor: ::Monitor, event: ::MonitorEvent);
        type Callback = MonitorCallback;
        let ext_set = |cb| unsafe { ::ffi::glfwSetMonitorCallback(cb) };
        fn callback(monitor: *mut ::ffi::GLFWmonitor, event: c_int) {
            let monitor = ::Monitor {
                ptr: monitor,
                no_copy: marker::NoCopy,
                no_send: marker::NoSend,
                no_share: marker::NoSync,
            };
            (monitor, mem::transmute(event))
        }
    )
}

unsafe fn get_sender<'a>(window: &'a *mut ffi::GLFWwindow) -> &'a Sender<(f64, WindowEvent)> {
    mem::transmute(ffi::glfwGetWindowUserPointer(*window))
}

macro_rules! window_callback(
    (fn $name:ident () => $event:ident) => (
        pub extern "C" fn $name(window: *mut ffi::GLFWwindow) {
            unsafe { get_sender(&window).send((ffi::glfwGetTime() as f64, WindowEvent::$event)); }
        }
     );
    (fn $name:ident ($($ext_arg:ident: $ext_arg_ty:ty),*) => $event:ident($($arg_conv:expr),*)) => (
        pub extern "C" fn $name(window: *mut ffi::GLFWwindow $(, $ext_arg: $ext_arg_ty)*) {
            unsafe { get_sender(&window).send((ffi::glfwGetTime() as f64, WindowEvent::$event($($arg_conv),*))); }
        }
     );
)

window_callback!(fn window_pos_callback(xpos: c_int, ypos: c_int)                           => PosEvent(xpos as i32, ypos as i32))
window_callback!(fn window_size_callback(width: c_int, height: c_int)                       => SizeEvent(width as i32, height as i32))
window_callback!(fn window_close_callback()                                                 => CloseEvent)
window_callback!(fn window_refresh_callback()                                               => RefreshEvent)
window_callback!(fn window_focus_callback(focused: c_int)                                   => FocusEvent(focused == ffi::TRUE))
window_callback!(fn window_iconify_callback(iconified: c_int)                               => IconifyEvent(iconified == ffi::TRUE))
window_callback!(fn framebuffer_size_callback(width: c_int, height: c_int)                  => FramebufferSizeEvent(width as i32, height as i32))
window_callback!(fn mouse_button_callback(button: c_int, action: c_int, mods: c_int)        => MouseButtonEvent(mem::transmute(button), mem::transmute(action), Modifiers::from_bits(mods).unwrap()))
window_callback!(fn cursor_pos_callback(xpos: c_double, ypos: c_double)                     => CursorPosEvent(xpos as f64, ypos as f64))
window_callback!(fn cursor_enter_callback(entered: c_int)                                   => CursorEnterEvent(entered == ffi::TRUE))
window_callback!(fn scroll_callback(xpos: c_double, ypos: c_double)                         => ScrollEvent(xpos as f64, ypos as f64))
window_callback!(fn key_callback(key: c_int, scancode: c_int, action: c_int, mods: c_int)   => KeyEvent(mem::transmute(key), scancode, mem::transmute(action), Modifiers::from_bits(mods).unwrap()))
window_callback!(fn char_callback(character: c_uint)                                        => CharEvent(::std::char::from_u32(character).unwrap()))
<|endoftext|>


<commit_before>/// Conditional compilation depending on whether Serde is built with support for
/// 128-bit integers.
///
/// Data formats that wish to support Rust compiler versions older than 1.26 may
/// place the i128 / u128 methods of their Serializer and Deserializer behind
/// this macro.
///
/// Data formats that require a minimum Rust compiler version of at least 1.26
/// do not need to bother with this macro and may assume support for 128-bit
/// integers.
///
/// ```edition2018
/// # use serde::private::ser::Error;
/// #
/// # struct MySerializer;
/// #
/// use serde::{serde_if_integer128, Serializer};
///
/// impl Serializer for MySerializer {
///     type Ok = ();
///     type Error = Error;
///
///     fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
///         /* ... */
/// #         unimplemented!()
///     }
///
///     /* ... */
///
///     serde_if_integer128! {
///         fn serialize_i128(self, v: i128) -> Result<Self::Ok, Self::Error> {
///             /* ... */
/// #             unimplemented!()
///         }
///
///         fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error> {
///             /* ... */
/// #             unimplemented!()
///         }
///     }
/// #
/// #     serde::__serialize_unimplemented! {
/// #         bool i8 i16 i32 u8 u16 u32 u64 f32 f64 char str bytes none some
/// #         unit unit_struct unit_variant newtype_struct newtype_variant seq
/// #         tuple tuple_struct tuple_variant map struct struct_variant
/// #     }
/// }
/// ```
///
/// When Serde is built with support for 128-bit integers, this macro expands
/// transparently into just the input tokens.
///
/// ```edition2018
/// macro_rules! serde_if_integer128 {
///     ($($tt:tt)*) => {
///         $($tt)*
///     };
/// }
/// ```
///
/// When built without support for 128-bit integers, this macro expands to
/// nothing.
///
/// ```edition2018
/// macro_rules! serde_if_integer128 {
///     ($($tt:tt)*) => {};
/// }
/// ```
#[cfg(integer128)]
#[macro_export]
macro_rules! serde_if_integer128 {
    ($($tt:tt)*) => {
        $($tt)*
    };
}

#[cfg(not(integer128))]
#[macro_export]
#[doc(hidden)]
macro_rules! serde_if_integer128 {
    ($($tt:tt)*) => {};
}
<commit_msg>Update docs for serde_if_integer128<commit_after>/// Conditional compilation depending on whether Serde is built with support for
/// 128-bit integers.
///
/// Data formats that wish to support Rust compiler versions older than 1.26
/// (or targets that lack 128-bit integers) may place the i128 / u128 methods
/// of their Serializer and Deserializer behind this macro.
///
/// Data formats that require a minimum Rust compiler version of at least 1.26,
/// or do not target platforms that lack 128-bit integers, do not need to
/// bother with this macro and may assume support for 128-bit integers.
///
/// ```edition2018
/// # use serde::private::ser::Error;
/// #
/// # struct MySerializer;
/// #
/// use serde::{serde_if_integer128, Serializer};
///
/// impl Serializer for MySerializer {
///     type Ok = ();
///     type Error = Error;
///
///     fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
///         /* ... */
/// #         unimplemented!()
///     }
///
///     /* ... */
///
///     serde_if_integer128! {
///         fn serialize_i128(self, v: i128) -> Result<Self::Ok, Self::Error> {
///             /* ... */
/// #             unimplemented!()
///         }
///
///         fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error> {
///             /* ... */
/// #             unimplemented!()
///         }
///     }
/// #
/// #     serde::__serialize_unimplemented! {
/// #         bool i8 i16 i32 u8 u16 u32 u64 f32 f64 char str bytes none some
/// #         unit unit_struct unit_variant newtype_struct newtype_variant seq
/// #         tuple tuple_struct tuple_variant map struct struct_variant
/// #     }
/// }
/// ```
///
/// When Serde is built with support for 128-bit integers, this macro expands
/// transparently into just the input tokens.
///
/// ```edition2018
/// macro_rules! serde_if_integer128 {
///     ($($tt:tt)*) => {
///         $($tt)*
///     };
/// }
/// ```
///
/// When built without support for 128-bit integers, this macro expands to
/// nothing.
///
/// ```edition2018
/// macro_rules! serde_if_integer128 {
///     ($($tt:tt)*) => {};
/// }
/// ```
#[cfg(integer128)]
#[macro_export]
macro_rules! serde_if_integer128 {
    ($($tt:tt)*) => {
        $($tt)*
    };
}

#[cfg(not(integer128))]
#[macro_export]
#[doc(hidden)]
macro_rules! serde_if_integer128 {
    ($($tt:tt)*) => {};
}
<|endoftext|>


<commit_before>use std::{error, fmt};

use serde::{ser, de};

use token::Token;

#[derive(Clone, PartialEq, Debug)]
pub enum Error {
    SyntaxError,
    EndOfStreamError,
    UnknownFieldError(String),
    UnknownVariantError(String),
    MissingFieldError(&'static str),
    DuplicateFieldError(&'static str),
    InvalidName(&'static str),
    InvalidValue(String),
    UnexpectedToken(Token<'static>),
    ValueError(de::value::Error),
}

impl ser::Error for Error {
    fn custom<T: Into<String>>(_: T) -> Error {
        Error::SyntaxError
    }

    fn invalid_value(msg: &str) -> Error {
        Error::InvalidValue(msg.to_owned())
    }
}

impl de::Error for Error {
    fn custom<T: Into<String>>(_: T) -> Error {
        Error::SyntaxError
    }

    fn end_of_stream() -> Error {
        Error::EndOfStreamError
    }

    fn invalid_value(msg: &str) -> Error {
        Error::InvalidValue(msg.to_owned())
    }

    fn unknown_field(field: &str) -> Error {
        Error::UnknownFieldError(field.to_owned())
    }

    fn unknown_variant(variant: &str) -> Error {
        Error::UnknownVariantError(variant.to_owned())
    }

    fn missing_field(field: &'static str) -> Error {
        Error::MissingFieldError(field)
    }

    fn duplicate_field(field: &'static str) -> Error {
        Error::DuplicateFieldError(field)
    }
}

impl fmt::Display for Error {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        formatter.write_str(format!("{:?}", self).as_ref())
    }
}

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

    fn cause(&self) -> Option<&error::Error> {
        None
    }
}
<commit_msg>Add message to CustomError<commit_after>use std::{error, fmt};

use serde::{ser, de};

use token::Token;

#[derive(Clone, PartialEq, Debug)]
pub enum Error {
    CustomError(String),
    EndOfStreamError,
    UnknownFieldError(String),
    UnknownVariantError(String),
    MissingFieldError(&'static str),
    DuplicateFieldError(&'static str),
    InvalidName(&'static str),
    InvalidValue(String),
    UnexpectedToken(Token<'static>),
    ValueError(de::value::Error),
}

impl ser::Error for Error {
    fn custom<T: Into<String>>(msg: T) -> Error {
        Error::CustomError(msg.into())
    }

    fn invalid_value(msg: &str) -> Error {
        Error::InvalidValue(msg.to_owned())
    }
}

impl de::Error for Error {
    fn custom<T: Into<String>>(msg: T) -> Error {
        Error::CustomError(msg.into())
    }

    fn end_of_stream() -> Error {
        Error::EndOfStreamError
    }

    fn invalid_value(msg: &str) -> Error {
        Error::InvalidValue(msg.to_owned())
    }

    fn unknown_field(field: &str) -> Error {
        Error::UnknownFieldError(field.to_owned())
    }

    fn unknown_variant(variant: &str) -> Error {
        Error::UnknownVariantError(variant.to_owned())
    }

    fn missing_field(field: &'static str) -> Error {
        Error::MissingFieldError(field)
    }

    fn duplicate_field(field: &'static str) -> Error {
        Error::DuplicateFieldError(field)
    }
}

impl fmt::Display for Error {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        formatter.write_str(format!("{:?}", self).as_ref())
    }
}

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

    fn cause(&self) -> Option<&error::Error> {
        None
    }
}
<|endoftext|>


<commit_before>// The MIT License (MIT)
//
// Copyright (c) 2013 Jeremy Letang (letang.jeremy@gmail.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#![crate_name = "simple_player"]

extern crate ears;

use std::io::stdin;
use std::io::stdout;
use std::io::Write;

use ears::{Music, AudioController};
use ears::State::{Playing, Stopped, Paused};

fn main() {

    // Read the inputs
    let mut stdin = stdin();

    print!("Insert the path to an audio file : ");
   	stdout().flush().ok();

    let mut line = String::new();
    line.push_str("C:/Develop/ears/target/debug/spawn_7.wav");
   // stdin.read_line(&mut line).ok();
    //unsafe { line.as_mut_vec().pop(); }
    //unsafe { line.as_mut_vec().pop(); }

    // Try to create the music
    let mut music = match Music::new(&line[..]) {
        Some(music) => music,
        None        => panic!("Cannot load the music.")
    };

    // Play it
    music.play();

    loop {
        // Make your choice
        println!("Commands :\n\tPlay  : l\n\tPause : p\n\tStop  : s\n\tExit  : x\n");
        let mut cmd = String::new();
        stdin.read_line(&mut cmd).ok();
        match &cmd[..] {
            "l\n"    => music.play(),
            "p\n"    => music.pause(),
            "s\n"    => music.stop(),
            "x\n"    => { music.stop(); break; },
            _       => println!("Unknwon command.")
        }
        match music.get_state() {
            Playing => println!("State : Playing"),
            Stopped => println!("State : Stopped"),
            Paused  => println!("State : Paused"),
            _       => unreachable!()
        };
    }
    println!("Goodbye!");
}<commit_msg>fix simple_player example<commit_after>// The MIT License (MIT)
//
// Copyright (c) 2013 Jeremy Letang (letang.jeremy@gmail.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#![crate_name = "simple_player"]

extern crate ears;

use std::io::stdin;
use std::io::stdout;
use std::io::Write;

use ears::{Music, AudioController};
use ears::State::{Playing, Stopped, Paused};

fn main() {

    // Read the inputs
    let mut stdin = stdin();

    print!("Insert the path to an audio file : ");
   	stdout().flush().ok();

    let mut line = String::new();
    stdin.read_line(&mut line).ok();
    loop {
    	match &line[line.len()-1..] {
    		"\n" => { line.pop(); () },
    		"\r" => { line.pop(); () },
    		_ => { break; },
    	}
    }

    // Try to create the music
    let mut music = match Music::new(&line[..]) {
        Some(music) => music,
        None        => panic!("Cannot load the music.")
    };

    // Play it
    music.play();

    loop {
        // Make your choice
        println!("Commands :\n\tPlay  : l\n\tPause : p\n\tStop  : s\n\tExit  : x\n");
        let mut cmd = String::new();
        stdin.read_line(&mut cmd).ok();
        match &cmd[..1] {
            "l" => music.play(),
            "p" => music.pause(),
            "s" => music.stop(),
            "x" => { music.stop(); break; },
            _ => println!("Unknwon command.")
        }
        match music.get_state() {
            Playing => println!("State : Playing"),
            Stopped => println!("State : Stopped"),
            Paused  => println!("State : Paused"),
            _       => unreachable!()
        };
    }
    println!("Goodbye!");
}<|endoftext|>


<commit_before>// Copyright 2016 Pierre Talbot (IRCAM)

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

//     http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use middle::analysis::ast::*;
use std::mem::swap;
use std::collections::HashMap;

/// Well-formedness attributes, it represents the possible behavior of an expression.
#[derive(Clone, Copy, PartialEq, Eq)]
struct WFA
{
  can_fail: bool,
  can_succeed: bool,
  always_consume: bool,
}

impl WFA
{
  fn all_true() -> Self {
    WFA {
      can_fail: true,
      can_succeed: true,
      always_consume: true
    }
  }

  fn always_succeed() -> Self {
    WFA {
      can_fail: false,
      can_succeed: true,
      always_consume: false
    }
  }
}

pub struct WellFormedness<'a: 'c, 'b: 'a, 'c>
{
  grammar: &'c AGrammar<'a, 'b>,
  recursion_path: Vec<(Ident, bool)>,
  consumed_input: bool,
  rules_wfa: HashMap<Ident, WFA>,
  reached_fixpoint: bool,
  well_formed: bool
}

// Start with an empty set of the expression attributes.

impl<'a, 'b, 'c> WellFormedness<'a, 'b, 'c>
{
  pub fn analyse(grammar: AGrammar<'a, 'b>) -> Partial<AGrammar<'a, 'b>> {
    if WellFormedness::is_well_formed(&grammar) {
      Partial::Value(grammar)
    } else {
      Partial::Nothing
    }
  }

  fn is_well_formed(grammar: &'c AGrammar<'a, 'b>) -> bool {
    let mut analyser = WellFormedness::new(grammar);
    analyser.visit_rules();
    analyser.well_formed
  }

  fn new(grammar: &'c AGrammar<'a, 'b>) -> Self {
    WellFormedness {
      grammar: grammar,
      recursion_path: vec![],
      consumed_input: false,
      rules_wfa: grammar.rules.iter()
        .map(|rule| (rule.ident(), WFA::all_true()))
        .collect(),
      reached_fixpoint: false,
      well_formed: true
    }
  }

  fn visit_rules(&mut self) {
    while !self.reached_fixpoint && self.well_formed {
      self.reached_fixpoint = true;
      for rule in self.grammar.rules.iter() {
        self.visit_rule(rule.ident());
        if !self.well_formed { break; }
      }
    }
  }

  fn visit_rule(&mut self, rule: Ident) -> WFA {
    if self.is_rec(rule) {
      if !self.consume_input_since(rule) && !self.consumed_input {
        self.error_left_recursion(rule);
      }
    }
    else {
      self.push_rule_in_path(rule);
      let wfa = self.visit_rule_expr(rule);
      self.pop_rule_in_path();
      self.fixpoint_update(wfa, rule);
    }
    self.rules_wfa[&rule]
  }

  fn visit_rule_expr(&mut self, rule: Ident) -> WFA {
    let expr_idx = self.grammar.expr_index_of_rule(rule);
    self.visit_expr(expr_idx)
  }

  fn push_rule_in_path(&mut self, rule: Ident) {
    self.recursion_path.push((rule, self.consumed_input));
    self.consumed_input = false;
  }

  fn pop_rule_in_path(&mut self) {
    let (_, old_consumed_input) = self.recursion_path.pop().unwrap();
    self.consumed_input = old_consumed_input;
  }

  fn fixpoint_update(&mut self, wfa: WFA, rule: Ident) {
    if wfa != self.rules_wfa[&rule] {
      self.reached_fixpoint = false;
      *self.rules_wfa.get_mut(&rule).unwrap() = wfa;
    }
  }

  fn is_rec(&self, rule: Ident) -> bool {
    self.recursion_path.iter().any(|&(r,_)| r == rule)
  }

  fn rec_path_from(&self, rule: Ident) -> Vec<(Ident, bool)> {
    self.recursion_path.iter().cloned()
      .rev()
      .take_while(|&(r, _)| r != rule)
      .collect()
  }

  fn consume_input_since(&self, rule: Ident) -> bool {
    let mut has_consumed = false;
    for (_, consumed_input) in self.rec_path_from(rule) {
      has_consumed |= consumed_input;
    }
    has_consumed
  }

  fn save(&self) -> bool {
    self.consumed_input
  }

  fn restore(&mut self, savepoint: bool) {
    self.consumed_input = savepoint;
  }

  fn error_left_recursion(&mut self, rule_id: Ident) {
    self.well_formed = false;
    let rule = self.grammar.find_rule_by_ident(rule_id);
    let mut rec_path: Vec<_> = vec![rule_id];
    rec_path.extend(self.rec_path_from(rule_id).into_iter()
      .map(|(r,_)| r)
      .rev());
    self.grammar.span_err(rule.span(), format!(
      "Left-recursion is not supported in Oak; the following rule cycle \
      do not consume any input and would therefore loop forever\n\
      Detected cycle: {}\n\
      Solution: Rewrite one of the incriminated rules such that it \
      consumes at least one atom in the input before calling \
      the next one. Usually, left-recursion is rewritten with a \
      repeat operator (`e*` or `e+`).",
      display_path_cycle(&rec_path)));
  }

  fn error_never_succeed(&mut self, expr_idx: usize) {
    self.well_formed = false;
    self.grammar.span_err(self.grammar[expr_idx].span(), format!(
      "Expression will never succeed.\n\
      Solution: Remove this expression."));
  }

  fn error_loop_repeat(&mut self, expr_idx: usize) {
    self.well_formed = false;
    self.grammar.span_err(self.grammar[expr_idx].span(), format!(
      "Infinite loop detected. A repeat operator (`e*` or `e+`) will \
      never stop because the sub-expression does not consume input.\n\
      Solution: Rewrite the expression such that it consumes at least \
      one atom in the input or get rid of the repeat operator."));
  }

  fn error_unreachable_branches(&mut self, choice: usize, always_succeed_branch: usize)
  {
    self.well_formed = false;
    self.grammar.span_err(self.grammar[choice].span(), format!(
      "Unreachable branch in a choice expression. We detected that \
      some branches cannot be reached in this expression.\n\
      Solution: Either remove (or rewrite) this branch or move it \
      in the end of the choice expression."));
    self.grammar.span_note(self.grammar[always_succeed_branch].span(), format!(
      "Branch always succeeding"
    ));
  }
}

impl<'a, 'b, 'c> ExprByIndex for WellFormedness<'a, 'b, 'c>
{
  fn expr_by_index(&self, index: usize) -> Expression {
    self.grammar.expr_by_index(index).clone()
  }
}

impl<'a, 'b, 'c> Visitor<WFA> for WellFormedness<'a, 'b, 'c>
{
  fn visit_expr(&mut self, this: usize) -> WFA {
    let mut wfa = walk_expr(self, this);
    assert!(wfa.can_fail || wfa.can_succeed,
      "Expression must either fails or succeeds.");
    if wfa.can_fail && !wfa.can_succeed {
      self.error_never_succeed(this);
      wfa.can_succeed = true; // Error-recovery.
    }
    wfa
  }

  fn visit_str_literal(&mut self, _this: usize, literal: String) -> WFA {
    let mut wfa = WFA::all_true();
    if literal.is_empty() {
      wfa.can_fail = false;
      wfa.always_consume = false;
    }
    wfa
  }

  fn visit_non_terminal_symbol(&mut self, _this: usize, rule: Ident) -> WFA {
    self.visit_rule(rule)
  }

  fn visit_atom(&mut self, _this: usize) -> WFA {
    WFA::all_true()
  }

  fn visit_repeat(&mut self, this: usize, child: usize) -> WFA {
    let child_wfa = self.visit_expr(child);
    if child_wfa.can_succeed && !child_wfa.always_consume {
      self.error_loop_repeat(this);
      WFA::all_true()
    }
    else {
      child_wfa
    }
  }

  fn visit_zero_or_more(&mut self, this: usize, child: usize) -> WFA {
    self.visit_repeat(this, child);
    WFA::always_succeed()
  }

  fn visit_optional(&mut self, _this: usize, child: usize) -> WFA {
    self.visit_expr(child);
    WFA::always_succeed()
  }

  fn visit_syntactic_predicate(&mut self, _this: usize, child: usize) -> WFA {
    let child_wfa = self.visit_expr(child);
    let mut wfa = child_wfa;
    wfa.always_consume = false;
    wfa
  }

  fn visit_not_predicate(&mut self, this: usize, child: usize) -> WFA {
    let mut wfa = self.visit_syntactic_predicate(this, child);
    swap(&mut wfa.can_succeed, &mut wfa.can_fail);
    wfa
  }

  fn visit_choice(&mut self, this: usize, children: Vec<usize>) -> WFA {
    let mut wfa = WFA {
      can_fail: true,
      can_succeed: false,
      always_consume: true
    };
    for i in 0..children.len() {
      let child = children[i];
      let savepoint = self.save();
      let child_wfa = self.visit_expr(child);
      self.restore(savepoint);
      wfa.can_fail &= child_wfa.can_fail;
      wfa.can_succeed |= child_wfa.can_succeed;
      wfa.always_consume &= child_wfa.always_consume;
      if i != children.len() - 1 && !child_wfa.can_fail {
        self.error_unreachable_branches(this, children[i]);
        return wfa;
      }
    }
    wfa
  }

  fn visit_sequence(&mut self, _this: usize, children: Vec<usize>) -> WFA {
    let savepoint = self.save();
    let mut wfa = WFA {
      can_fail: false,
      can_succeed: true,
      always_consume: false
    };
    for child in children {
      let child_wfa = self.visit_expr(child);
      wfa.can_fail |= child_wfa.can_fail;
      wfa.can_succeed &= child_wfa.can_succeed;
      wfa.always_consume |= child_wfa.always_consume;
      if child_wfa.always_consume {
        self.consumed_input = true;
      }
    }
    self.restore(savepoint);
    wfa
  }
}
<commit_msg>[Error][Reporting] Avoid reporting more than once the same error on the same expression in the well-formedness analysis.<commit_after>// Copyright 2016 Pierre Talbot (IRCAM)

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

//     http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use middle::analysis::ast::*;
use std::mem::swap;
use std::collections::{HashMap, HashSet};

/// Well-formedness attributes, it represents the possible behavior of an expression.
#[derive(Clone, Copy, PartialEq, Eq)]
struct WFA
{
  can_fail: bool,
  can_succeed: bool,
  always_consume: bool,
}

impl WFA
{
  fn all_true() -> Self {
    WFA {
      can_fail: true,
      can_succeed: true,
      always_consume: true
    }
  }

  fn always_succeed() -> Self {
    WFA {
      can_fail: false,
      can_succeed: true,
      always_consume: false
    }
  }
}

pub struct WellFormedness<'a: 'c, 'b: 'a, 'c>
{
  grammar: &'c AGrammar<'a, 'b>,
  recursion_path: Vec<(Ident, bool)>,
  consumed_input: bool,
  rules_wfa: HashMap<Ident, WFA>,
  reached_fixpoint: bool,
  well_formed: bool,
  errors: HashSet<usize> // Whether we already spot an error on this rule (to avoid multi-reporting).
}

// Start with an empty set of the expression attributes.

impl<'a, 'b, 'c> WellFormedness<'a, 'b, 'c>
{
  pub fn analyse(grammar: AGrammar<'a, 'b>) -> Partial<AGrammar<'a, 'b>> {
    if WellFormedness::is_well_formed(&grammar) {
      Partial::Value(grammar)
    } else {
      Partial::Nothing
    }
  }

  fn is_well_formed(grammar: &'c AGrammar<'a, 'b>) -> bool {
    let mut analyser = WellFormedness::new(grammar);
    analyser.visit_rules();
    analyser.well_formed
  }

  fn new(grammar: &'c AGrammar<'a, 'b>) -> Self {
    WellFormedness {
      grammar: grammar,
      recursion_path: vec![],
      consumed_input: false,
      rules_wfa: grammar.rules.iter()
        .map(|rule| (rule.ident(), WFA::all_true()))
        .collect(),
      reached_fixpoint: false,
      well_formed: true,
      errors: HashSet::new()
    }
  }

  fn visit_rules(&mut self) {
    while !self.reached_fixpoint && self.well_formed {
      self.reached_fixpoint = true;
      for rule in self.grammar.rules.iter() {
        self.visit_rule(rule.ident());
        if !self.well_formed { break; }
      }
    }
  }

  fn visit_rule(&mut self, rule: Ident) -> WFA {
    if self.is_rec(rule) {
      if !self.consume_input_since(rule) && !self.consumed_input {
        self.error_left_recursion(rule);
      }
    }
    else {
      self.push_rule_in_path(rule);
      let wfa = self.visit_rule_expr(rule);
      self.pop_rule_in_path();
      self.fixpoint_update(wfa, rule);
    }
    self.rules_wfa[&rule]
  }

  fn visit_rule_expr(&mut self, rule: Ident) -> WFA {
    let expr_idx = self.grammar.expr_index_of_rule(rule);
    self.visit_expr(expr_idx)
  }

  fn push_rule_in_path(&mut self, rule: Ident) {
    self.recursion_path.push((rule, self.consumed_input));
    self.consumed_input = false;
  }

  fn pop_rule_in_path(&mut self) {
    let (_, old_consumed_input) = self.recursion_path.pop().unwrap();
    self.consumed_input = old_consumed_input;
  }

  fn fixpoint_update(&mut self, wfa: WFA, rule: Ident) {
    if wfa != self.rules_wfa[&rule] {
      self.reached_fixpoint = false;
      *self.rules_wfa.get_mut(&rule).unwrap() = wfa;
    }
  }

  fn is_rec(&self, rule: Ident) -> bool {
    self.recursion_path.iter().any(|&(r,_)| r == rule)
  }

  fn rec_path_from(&self, rule: Ident) -> Vec<(Ident, bool)> {
    self.recursion_path.iter().cloned()
      .rev()
      .take_while(|&(r, _)| r != rule)
      .collect()
  }

  fn consume_input_since(&self, rule: Ident) -> bool {
    let mut has_consumed = false;
    for (_, consumed_input) in self.rec_path_from(rule) {
      has_consumed |= consumed_input;
    }
    has_consumed
  }

  fn save(&self) -> bool {
    self.consumed_input
  }

  fn restore(&mut self, savepoint: bool) {
    self.consumed_input = savepoint;
  }

  fn error_left_recursion(&mut self, rule_id: Ident) {
    self.well_formed = false;
    let rule = self.grammar.find_rule_by_ident(rule_id);
    if self.register_error(rule.expr_idx) {
      let mut rec_path: Vec<_> = vec![rule_id];
      rec_path.extend(self.rec_path_from(rule_id).into_iter()
        .map(|(r,_)| r)
        .rev());
      self.grammar.span_err(rule.span(), format!(
        "Left-recursion is not supported in Oak; the following rule cycle \
        do not consume any input and would therefore loop forever\n\
        Detected cycle: {}\n\
        Solution: Rewrite one of the incriminated rules such that it \
        consumes at least one atom in the input before calling \
        the next one. Usually, left-recursion is rewritten with a \
        repeat operator (`e*` or `e+`).",
        display_path_cycle(&rec_path)));
    }
  }

  fn error_never_succeed(&mut self, expr_idx: usize) {
    if self.register_error(expr_idx) {
      self.well_formed = false;
      self.grammar.span_err(self.grammar[expr_idx].span(), format!(
        "Expression will never succeed.\n\
        Solution: Remove this expression."));
    }
  }

  fn error_loop_repeat(&mut self, expr_idx: usize) {
    if self.register_error(expr_idx) {
      self.well_formed = false;
      self.grammar.span_err(self.grammar[expr_idx].span(), format!(
        "Infinite loop detected. A repeat operator (`e*` or `e+`) will \
        never stop because the sub-expression does not consume input.\n\
        Solution: Rewrite the expression such that it consumes at least \
        one atom in the input or get rid of the repeat operator."));
    }
  }

  fn error_unreachable_branches(&mut self, choice: usize, always_succeed_branch: usize)
  {
    if self.register_error(always_succeed_branch) {
      self.well_formed = false;
      self.grammar.span_err(self.grammar[choice].span(), format!(
        "Unreachable branch in a choice expression. We detected that \
        some branches cannot be reached in this expression.\n\
        Solution: Either remove (or rewrite) this branch or move it \
        in the end of the choice expression."));
      self.grammar.span_note(self.grammar[always_succeed_branch].span(), format!(
        "Branch always succeeding"
      ));
    }
  }

  fn register_error(&mut self, expr_idx: usize) -> bool {
    self.errors.insert(expr_idx)
  }
}

impl<'a, 'b, 'c> ExprByIndex for WellFormedness<'a, 'b, 'c>
{
  fn expr_by_index(&self, index: usize) -> Expression {
    self.grammar.expr_by_index(index).clone()
  }
}

impl<'a, 'b, 'c> Visitor<WFA> for WellFormedness<'a, 'b, 'c>
{
  fn visit_expr(&mut self, this: usize) -> WFA {
    let mut wfa = walk_expr(self, this);
    assert!(wfa.can_fail || wfa.can_succeed,
      "Expression must either fails or succeeds.");
    if wfa.can_fail && !wfa.can_succeed {
      self.error_never_succeed(this);
      wfa.can_succeed = true; // Error-recovery.
    }
    wfa
  }

  fn visit_str_literal(&mut self, _this: usize, literal: String) -> WFA {
    let mut wfa = WFA::all_true();
    if literal.is_empty() {
      wfa.can_fail = false;
      wfa.always_consume = false;
    }
    wfa
  }

  fn visit_non_terminal_symbol(&mut self, _this: usize, rule: Ident) -> WFA {
    self.visit_rule(rule)
  }

  fn visit_atom(&mut self, _this: usize) -> WFA {
    WFA::all_true()
  }

  fn visit_repeat(&mut self, this: usize, child: usize) -> WFA {
    let child_wfa = self.visit_expr(child);
    if child_wfa.can_succeed && !child_wfa.always_consume {
      self.error_loop_repeat(this);
      WFA::all_true()
    }
    else {
      child_wfa
    }
  }

  fn visit_zero_or_more(&mut self, this: usize, child: usize) -> WFA {
    self.visit_repeat(this, child);
    WFA::always_succeed()
  }

  fn visit_optional(&mut self, _this: usize, child: usize) -> WFA {
    self.visit_expr(child);
    WFA::always_succeed()
  }

  fn visit_syntactic_predicate(&mut self, _this: usize, child: usize) -> WFA {
    let child_wfa = self.visit_expr(child);
    let mut wfa = child_wfa;
    wfa.always_consume = false;
    wfa
  }

  fn visit_not_predicate(&mut self, this: usize, child: usize) -> WFA {
    let mut wfa = self.visit_syntactic_predicate(this, child);
    swap(&mut wfa.can_succeed, &mut wfa.can_fail);
    wfa
  }

  fn visit_choice(&mut self, this: usize, children: Vec<usize>) -> WFA {
    let mut wfa = WFA {
      can_fail: true,
      can_succeed: false,
      always_consume: true
    };
    for i in 0..children.len() {
      let child = children[i];
      let savepoint = self.save();
      let child_wfa = self.visit_expr(child);
      self.restore(savepoint);
      wfa.can_fail &= child_wfa.can_fail;
      wfa.can_succeed |= child_wfa.can_succeed;
      wfa.always_consume &= child_wfa.always_consume;
      if i != children.len() - 1 && !child_wfa.can_fail {
        self.error_unreachable_branches(this, children[i]);
        return wfa;
      }
    }
    wfa
  }

  fn visit_sequence(&mut self, _this: usize, children: Vec<usize>) -> WFA {
    let savepoint = self.save();
    let mut wfa = WFA {
      can_fail: false,
      can_succeed: true,
      always_consume: false
    };
    for child in children {
      let child_wfa = self.visit_expr(child);
      wfa.can_fail |= child_wfa.can_fail;
      wfa.can_succeed &= child_wfa.can_succeed;
      wfa.always_consume |= child_wfa.always_consume;
      if child_wfa.always_consume {
        self.consumed_input = true;
      }
    }
    self.restore(savepoint);
    wfa
  }
}
<|endoftext|>


<commit_before>//! Logging for Alacritty.
//!
//! The main executable is supposed to call `initialize()` exactly once during
//! startup. All logging messages are written to stdout, given that their
//! log-level is sufficient for the level configured in `cli::Options`.

use std::env;
use std::fs::{File, OpenOptions};
use std::io::{self, LineWriter, Stdout, Write};
use std::path::PathBuf;
use std::process;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, Mutex};

use glutin::event_loop::EventLoopProxy;
use log::{self, Level};

use crate::cli::Options;
use crate::event::Event;
use crate::message_bar::{Message, MessageType};

/// Name for the environment variable containing the log file's path.
const ALACRITTY_LOG_ENV: &str = "ALACRITTY_LOG";
/// List of targets which will be logged by Alacritty.
const ALLOWED_TARGETS: [&str; 4] =
    ["alacritty_terminal", "alacritty_config_derive", "alacritty", "crossfont"];

pub fn initialize(
    options: &Options,
    event_proxy: EventLoopProxy<Event>,
) -> Result<Option<PathBuf>, log::SetLoggerError> {
    log::set_max_level(options.log_level);

    let logger = Logger::new(event_proxy);
    let path = logger.file_path();
    log::set_boxed_logger(Box::new(logger))?;

    Ok(path)
}

pub struct Logger {
    logfile: Mutex<OnDemandLogFile>,
    stdout: Mutex<LineWriter<Stdout>>,
    event_proxy: Mutex<EventLoopProxy<Event>>,
}

impl Logger {
    fn new(event_proxy: EventLoopProxy<Event>) -> Self {
        let logfile = Mutex::new(OnDemandLogFile::new());
        let stdout = Mutex::new(LineWriter::new(io::stdout()));

        Logger { logfile, stdout, event_proxy: Mutex::new(event_proxy) }
    }

    fn file_path(&self) -> Option<PathBuf> {
        if let Ok(logfile) = self.logfile.lock() {
            Some(logfile.path().clone())
        } else {
            None
        }
    }

    /// Log a record to the message bar.
    fn message_bar_log(&self, record: &log::Record<'_>, logfile_path: &str) {
        let event_proxy = match self.event_proxy.lock() {
            Ok(event_proxy) => event_proxy,
            Err(_) => return,
        };

        #[cfg(not(windows))]
        let env_var = format!("${}", ALACRITTY_LOG_ENV);
        #[cfg(windows)]
        let env_var = format!("%{}%", ALACRITTY_LOG_ENV);

        let message = format!(
            "[{}] See log at {} ({}):\n{}",
            record.level(),
            logfile_path,
            env_var,
            record.args(),
        );
        let message_type = match record.level() {
            Level::Error => MessageType::Error,
            Level::Warn => MessageType::Warning,
            _ => unreachable!(),
        };

        let mut message = Message::new(message, message_type);
        message.set_target(record.target().to_owned());

        let _ = event_proxy.send_event(Event::Message(message));
    }
}

impl log::Log for Logger {
    fn enabled(&self, metadata: &log::Metadata<'_>) -> bool {
        metadata.level() <= log::max_level()
    }

    fn log(&self, record: &log::Record<'_>) {
        // Get target crate.
        let index = record.target().find(':').unwrap_or_else(|| record.target().len());
        let target = &record.target()[..index];

        // Only log our own crates.
        if !self.enabled(record.metadata()) || !ALLOWED_TARGETS.contains(&target) {
            return;
        }

        // Create log message for the given `record` and `target`.
        let message = create_log_message(record, target);

        if let Ok(mut logfile) = self.logfile.lock() {
            // Write to logfile.
            let _ = logfile.write_all(message.as_ref());

            // Write to message bar.
            if record.level() <= Level::Warn {
                self.message_bar_log(record, &logfile.path.to_string_lossy());
            }
        }

        // Write to stdout.
        if let Ok(mut stdout) = self.stdout.lock() {
            let _ = stdout.write_all(message.as_ref());
        }
    }

    fn flush(&self) {}
}

fn create_log_message(record: &log::Record<'_>, target: &str) -> String {
    let now = time::strftime("%F %T.%f", &time::now()).unwrap();
    let mut message = format!("[{}] [{:<5}] [{}] ", now, record.level(), target);

    // Alignment for the lines after the first new line character in the payload. We don't deal
    // with fullwidth/unicode chars here, so just `message.len()` is sufficient.
    let alignment = message.len();

    // Push lines with added extra padding on the next line, which is trimmed later.
    let lines = record.args().to_string();
    for line in lines.split('\n') {
        let line = format!("{}\n{:width$}", line, "", width = alignment);
        message.push_str(&line);
    }

    // Drop extra trailing alignment.
    message.truncate(message.len() - alignment);
    message
}

struct OnDemandLogFile {
    file: Option<LineWriter<File>>,
    created: Arc<AtomicBool>,
    path: PathBuf,
}

impl OnDemandLogFile {
    fn new() -> Self {
        let mut path = env::temp_dir();
        path.push(format!("Alacritty-{}.log", process::id()));

        // Set log path as an environment variable.
        env::set_var(ALACRITTY_LOG_ENV, path.as_os_str());

        OnDemandLogFile { path, file: None, created: Arc::new(AtomicBool::new(false)) }
    }

    fn file(&mut self) -> Result<&mut LineWriter<File>, io::Error> {
        // Allow to recreate the file if it has been deleted at runtime.
        if self.file.is_some() && !self.path.as_path().exists() {
            self.file = None;
        }

        // Create the file if it doesn't exist yet.
        if self.file.is_none() {
            let file = OpenOptions::new().append(true).create(true).open(&self.path);

            match file {
                Ok(file) => {
                    self.file = Some(io::LineWriter::new(file));
                    self.created.store(true, Ordering::Relaxed);
                    let _ =
                        writeln!(io::stdout(), "Created log file at \"{}\"", self.path.display());
                },
                Err(e) => {
                    let _ = writeln!(io::stdout(), "Unable to create log file: {}", e);
                    return Err(e);
                },
            }
        }

        Ok(self.file.as_mut().unwrap())
    }

    fn path(&self) -> &PathBuf {
        &self.path
    }
}

impl Write for OnDemandLogFile {
    fn write(&mut self, buf: &[u8]) -> Result<usize, io::Error> {
        self.file()?.write(buf)
    }

    fn flush(&mut self) -> Result<(), io::Error> {
        self.file()?.flush()
    }
}
<commit_msg>Log dependency warnings/errors at trace level<commit_after>//! Logging for Alacritty.
//!
//! The main executable is supposed to call `initialize()` exactly once during
//! startup. All logging messages are written to stdout, given that their
//! log-level is sufficient for the level configured in `cli::Options`.

use std::env;
use std::fs::{File, OpenOptions};
use std::io::{self, LineWriter, Stdout, Write};
use std::path::PathBuf;
use std::process;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, Mutex};

use glutin::event_loop::EventLoopProxy;
use log::{self, Level, LevelFilter};

use crate::cli::Options;
use crate::event::Event;
use crate::message_bar::{Message, MessageType};

/// Name for the environment variable containing the log file's path.
const ALACRITTY_LOG_ENV: &str = "ALACRITTY_LOG";
/// List of targets which will be logged by Alacritty.
const ALLOWED_TARGETS: [&str; 4] =
    ["alacritty_terminal", "alacritty_config_derive", "alacritty", "crossfont"];

pub fn initialize(
    options: &Options,
    event_proxy: EventLoopProxy<Event>,
) -> Result<Option<PathBuf>, log::SetLoggerError> {
    log::set_max_level(options.log_level);

    let logger = Logger::new(event_proxy);
    let path = logger.file_path();
    log::set_boxed_logger(Box::new(logger))?;

    Ok(path)
}

pub struct Logger {
    logfile: Mutex<OnDemandLogFile>,
    stdout: Mutex<LineWriter<Stdout>>,
    event_proxy: Mutex<EventLoopProxy<Event>>,
}

impl Logger {
    fn new(event_proxy: EventLoopProxy<Event>) -> Self {
        let logfile = Mutex::new(OnDemandLogFile::new());
        let stdout = Mutex::new(LineWriter::new(io::stdout()));

        Logger { logfile, stdout, event_proxy: Mutex::new(event_proxy) }
    }

    fn file_path(&self) -> Option<PathBuf> {
        if let Ok(logfile) = self.logfile.lock() {
            Some(logfile.path().clone())
        } else {
            None
        }
    }

    /// Log a record to the message bar.
    fn message_bar_log(&self, record: &log::Record<'_>, logfile_path: &str) {
        let event_proxy = match self.event_proxy.lock() {
            Ok(event_proxy) => event_proxy,
            Err(_) => return,
        };

        #[cfg(not(windows))]
        let env_var = format!("${}", ALACRITTY_LOG_ENV);
        #[cfg(windows)]
        let env_var = format!("%{}%", ALACRITTY_LOG_ENV);

        let message = format!(
            "[{}] See log at {} ({}):\n{}",
            record.level(),
            logfile_path,
            env_var,
            record.args(),
        );
        let message_type = match record.level() {
            Level::Error => MessageType::Error,
            Level::Warn => MessageType::Warning,
            _ => unreachable!(),
        };

        let mut message = Message::new(message, message_type);
        message.set_target(record.target().to_owned());

        let _ = event_proxy.send_event(Event::Message(message));
    }
}

impl log::Log for Logger {
    fn enabled(&self, metadata: &log::Metadata<'_>) -> bool {
        metadata.level() <= log::max_level()
    }

    fn log(&self, record: &log::Record<'_>) {
        // Get target crate.
        let index = record.target().find(':').unwrap_or_else(|| record.target().len());
        let target = &record.target()[..index];

        // Only log our own crates, except when logging at Level::Trace.
        if !self.enabled(record.metadata()) || !is_allowed_target(record.level(), target) {
            return;
        }

        // Create log message for the given `record` and `target`.
        let message = create_log_message(record, target);

        if let Ok(mut logfile) = self.logfile.lock() {
            // Write to logfile.
            let _ = logfile.write_all(message.as_ref());

            // Write to message bar.
            if record.level() <= Level::Warn {
                self.message_bar_log(record, &logfile.path.to_string_lossy());
            }
        }

        // Write to stdout.
        if let Ok(mut stdout) = self.stdout.lock() {
            let _ = stdout.write_all(message.as_ref());
        }
    }

    fn flush(&self) {}
}

fn create_log_message(record: &log::Record<'_>, target: &str) -> String {
    let now = time::strftime("%F %T.%f", &time::now()).unwrap();
    let mut message = format!("[{}] [{:<5}] [{}] ", now, record.level(), target);

    // Alignment for the lines after the first new line character in the payload. We don't deal
    // with fullwidth/unicode chars here, so just `message.len()` is sufficient.
    let alignment = message.len();

    // Push lines with added extra padding on the next line, which is trimmed later.
    let lines = record.args().to_string();
    for line in lines.split('\n') {
        let line = format!("{}\n{:width$}", line, "", width = alignment);
        message.push_str(&line);
    }

    // Drop extra trailing alignment.
    message.truncate(message.len() - alignment);
    message
}

/// Check if log messages from a crate should be logged.
fn is_allowed_target(level: Level, target: &str) -> bool {
    match (level, log::max_level()) {
        (Level::Error, LevelFilter::Trace) | (Level::Warn, LevelFilter::Trace) => true,
        _ => ALLOWED_TARGETS.contains(&target),
    }
}

struct OnDemandLogFile {
    file: Option<LineWriter<File>>,
    created: Arc<AtomicBool>,
    path: PathBuf,
}

impl OnDemandLogFile {
    fn new() -> Self {
        let mut path = env::temp_dir();
        path.push(format!("Alacritty-{}.log", process::id()));

        // Set log path as an environment variable.
        env::set_var(ALACRITTY_LOG_ENV, path.as_os_str());

        OnDemandLogFile { path, file: None, created: Arc::new(AtomicBool::new(false)) }
    }

    fn file(&mut self) -> Result<&mut LineWriter<File>, io::Error> {
        // Allow to recreate the file if it has been deleted at runtime.
        if self.file.is_some() && !self.path.as_path().exists() {
            self.file = None;
        }

        // Create the file if it doesn't exist yet.
        if self.file.is_none() {
            let file = OpenOptions::new().append(true).create(true).open(&self.path);

            match file {
                Ok(file) => {
                    self.file = Some(io::LineWriter::new(file));
                    self.created.store(true, Ordering::Relaxed);
                    let _ =
                        writeln!(io::stdout(), "Created log file at \"{}\"", self.path.display());
                },
                Err(e) => {
                    let _ = writeln!(io::stdout(), "Unable to create log file: {}", e);
                    return Err(e);
                },
            }
        }

        Ok(self.file.as_mut().unwrap())
    }

    fn path(&self) -> &PathBuf {
        &self.path
    }
}

impl Write for OnDemandLogFile {
    fn write(&mut self, buf: &[u8]) -> Result<usize, io::Error> {
        self.file()?.write(buf)
    }

    fn flush(&mut self) -> Result<(), io::Error> {
        self.file()?.flush()
    }
}
<|endoftext|>


<commit_before>// See LICENSE file for copyright and license details.

use std;
use gl;
use gl::types::{GLuint, GLsizeiptr};
use cgmath::matrix::{Matrix, Mat4, Mat3, ToMat4};
use cgmath::vector::{Vec2, Vec3};
use cgmath::angle;
use core::misc::deg_to_rad;
use core::types::{Size2, MInt};
use visualizer::types::{MFloat};

pub use load_gl_funcs_with = gl::load_with;

pub enum MeshRenderMode {
    Triangles,
    Lines,
}

impl MeshRenderMode {
    fn to_gl_type(&self) -> GLuint {
        match *self {
            Triangles => gl::TRIANGLES,
            Lines => gl::LINES,
        }
    }
}

pub fn tr(m: Mat4<MFloat>, v: Vec3<MFloat>) -> Mat4<MFloat> {
    let mut t = Mat4::<MFloat>::identity();
    *t.mut_cr(3, 0) = v.x;
    *t.mut_cr(3, 1) = v.y;
    *t.mut_cr(3, 2) = v.z;
    m.mul_m(&t)
}

pub fn rot_x(m: Mat4<MFloat>, angle: MFloat) -> Mat4<MFloat> {
    let rad = angle::rad(deg_to_rad(angle));
    let r = Mat3::from_angle_x(rad).to_mat4();
    m.mul_m(&r)
}

pub fn rot_z(m: Mat4<MFloat>, angle: MFloat) -> Mat4<MFloat> {
    let rad = angle::rad(deg_to_rad(angle));
    let r = Mat3::from_angle_z(rad).to_mat4();
    m.mul_m(&r)
}

pub fn init_opengl() {
    gl::Enable(gl::DEPTH_TEST);
    gl::Enable(gl::BLEND);
    gl::BlendFunc(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA);
}

pub fn set_clear_color(r: MFloat, g: MFloat, b: MFloat) {
    gl::ClearColor(r, g, b, 1.0);
}

pub fn clear_screen() {
    gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT);
}

pub fn set_viewport(size: Size2<MInt>) {
    gl::Viewport(0, 0, size.w, size.h);
}

pub struct Vao {
    priv id: GLuint,
}

impl Vao {
    pub fn new() -> Vao {
        let mut id = 0;
        unsafe {
            gl::GenVertexArrays(1, &mut id);
        }
        let vao = Vao{id: id};
        vao.bind();
        gl::EnableVertexAttribArray(id);
        vao
    }

    pub fn bind(&self) {
        gl::BindVertexArray(self.id);
    }

    pub fn unbind(&self) {
        gl::BindVertexArray(0);
    }

    pub fn draw_array(&self, mesh_mode: MeshRenderMode, faces_count: MInt) {
        let starting_index = 0;
        let vertices_count = faces_count * 3;
        let mode = mesh_mode.to_gl_type();
        gl::DrawArrays(mode, starting_index, vertices_count);
    }
}

impl Drop for Vao {
    fn drop(&mut self) {
        unsafe {
            gl::DeleteVertexArrays(1, &self.id);
        }
    }
}

pub struct Vbo {
    priv id: GLuint,
}

fn get_new_vbo_id() -> GLuint {
    let mut id = 0;
    unsafe {
        gl::GenBuffers(1, &mut id);
    }
    id
}

impl Vbo {
    pub fn from_data<T>(data: &[T]) -> Vbo {
        let vbo = Vbo{id: get_new_vbo_id()};
        vbo.bind();
        let size = std::mem::size_of::<T>();
        let buf_size = (data.len() * size) as GLsizeiptr;
        unsafe {
            let data_ptr = std::cast::transmute(&data[0]);
            gl::BufferData(
                gl::ARRAY_BUFFER,
                buf_size,
                data_ptr,
                gl::STATIC_DRAW,
            );
        }
        vbo
    }

    pub fn bind(&self) {
        gl::BindBuffer(gl::ARRAY_BUFFER, self.id);
    }
}

impl Drop for Vbo {
    fn drop(&mut self) {
        unsafe {
            gl::DeleteBuffers(1, &self.id);
        }
    }
}

pub fn read_pixel_bytes(
    win_size: Size2<MInt>,
    mouse_pos: Vec2<MInt>,
) -> (MInt, MInt, MInt, MInt) {
    let height = win_size.h;
    let reverted_h = height - mouse_pos.y;
    let data: [u8, ..4] = [0, 0, 0, 0]; // mut
    unsafe {
        let data_ptr = std::cast::transmute(&data[0]);
        gl::ReadPixels(
            mouse_pos.x, reverted_h, 1, 1,
            gl::RGBA,
            gl::UNSIGNED_BYTE,
            data_ptr
        );
    }
    (data[0] as MInt, data[1] as MInt, data[2] as MInt, data[3] as MInt)
}

// vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab:
<commit_msg>Vbo: check len != 0<commit_after>// See LICENSE file for copyright and license details.

use std;
use gl;
use gl::types::{GLuint, GLsizeiptr};
use cgmath::matrix::{Matrix, Mat4, Mat3, ToMat4};
use cgmath::vector::{Vec2, Vec3};
use cgmath::angle;
use core::misc::deg_to_rad;
use core::types::{Size2, MInt};
use visualizer::types::{MFloat};

pub use load_gl_funcs_with = gl::load_with;

pub enum MeshRenderMode {
    Triangles,
    Lines,
}

impl MeshRenderMode {
    fn to_gl_type(&self) -> GLuint {
        match *self {
            Triangles => gl::TRIANGLES,
            Lines => gl::LINES,
        }
    }
}

pub fn tr(m: Mat4<MFloat>, v: Vec3<MFloat>) -> Mat4<MFloat> {
    let mut t = Mat4::<MFloat>::identity();
    *t.mut_cr(3, 0) = v.x;
    *t.mut_cr(3, 1) = v.y;
    *t.mut_cr(3, 2) = v.z;
    m.mul_m(&t)
}

pub fn rot_x(m: Mat4<MFloat>, angle: MFloat) -> Mat4<MFloat> {
    let rad = angle::rad(deg_to_rad(angle));
    let r = Mat3::from_angle_x(rad).to_mat4();
    m.mul_m(&r)
}

pub fn rot_z(m: Mat4<MFloat>, angle: MFloat) -> Mat4<MFloat> {
    let rad = angle::rad(deg_to_rad(angle));
    let r = Mat3::from_angle_z(rad).to_mat4();
    m.mul_m(&r)
}

pub fn init_opengl() {
    gl::Enable(gl::DEPTH_TEST);
    gl::Enable(gl::BLEND);
    gl::BlendFunc(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA);
}

pub fn set_clear_color(r: MFloat, g: MFloat, b: MFloat) {
    gl::ClearColor(r, g, b, 1.0);
}

pub fn clear_screen() {
    gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT);
}

pub fn set_viewport(size: Size2<MInt>) {
    gl::Viewport(0, 0, size.w, size.h);
}

pub struct Vao {
    priv id: GLuint,
}

impl Vao {
    pub fn new() -> Vao {
        let mut id = 0;
        unsafe {
            gl::GenVertexArrays(1, &mut id);
        }
        let vao = Vao{id: id};
        vao.bind();
        gl::EnableVertexAttribArray(id);
        vao
    }

    pub fn bind(&self) {
        gl::BindVertexArray(self.id);
    }

    pub fn unbind(&self) {
        gl::BindVertexArray(0);
    }

    pub fn draw_array(&self, mesh_mode: MeshRenderMode, faces_count: MInt) {
        let starting_index = 0;
        let vertices_count = faces_count * 3;
        let mode = mesh_mode.to_gl_type();
        gl::DrawArrays(mode, starting_index, vertices_count);
    }
}

impl Drop for Vao {
    fn drop(&mut self) {
        unsafe {
            gl::DeleteVertexArrays(1, &self.id);
        }
    }
}

pub struct Vbo {
    priv id: GLuint,
}

fn get_new_vbo_id() -> GLuint {
    let mut id = 0;
    unsafe {
        gl::GenBuffers(1, &mut id);
    }
    id
}

impl Vbo {
    pub fn from_data<T>(data: &[T]) -> Vbo {
        let vbo = Vbo{id: get_new_vbo_id()};
        vbo.bind();
        let size = std::mem::size_of::<T>();
        let buf_size = (data.len() * size) as GLsizeiptr;
        if data.len() != 0 {
            unsafe {
                let data_ptr = std::cast::transmute(&data[0]);
                gl::BufferData(
                    gl::ARRAY_BUFFER,
                    buf_size,
                    data_ptr,
                    gl::STATIC_DRAW,
                );
            }
        }
        vbo
    }

    pub fn bind(&self) {
        gl::BindBuffer(gl::ARRAY_BUFFER, self.id);
    }
}

impl Drop for Vbo {
    fn drop(&mut self) {
        unsafe {
            gl::DeleteBuffers(1, &self.id);
        }
    }
}

pub fn read_pixel_bytes(
    win_size: Size2<MInt>,
    mouse_pos: Vec2<MInt>,
) -> (MInt, MInt, MInt, MInt) {
    let height = win_size.h;
    let reverted_h = height - mouse_pos.y;
    let data: [u8, ..4] = [0, 0, 0, 0]; // mut
    unsafe {
        let data_ptr = std::cast::transmute(&data[0]);
        gl::ReadPixels(
            mouse_pos.x, reverted_h, 1, 1,
            gl::RGBA,
            gl::UNSIGNED_BYTE,
            data_ptr
        );
    }
    (data[0] as MInt, data[1] as MInt, data[2] as MInt, data[3] as MInt)
}

// vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab:
<|endoftext|>


<commit_before>use std::time::Duration;

use crate::transport::smtp::{client::SmtpConnection, error::Error, SmtpClient};

use r2d2::{ManageConnection, Pool};

/// Configuration for a connection pool
#[derive(Debug, Clone)]
#[allow(missing_copy_implementations)]
#[cfg_attr(docsrs, doc(cfg(feature = "r2d2")))]
pub struct PoolConfig {
    min_idle: u32,
    max_size: u32,
    connection_timeout: Duration,
    idle_timeout: Duration,
}

impl PoolConfig {
    /// Create a new pool configuration with default values
    pub fn new() -> Self {
        Self::default()
    }

    /// Minimum number of idle connections
    ///
    /// Defaults to `0`
    pub fn min_idle(mut self, min_idle: u32) -> Self {
        self.min_idle = min_idle;
        self
    }

    /// Maximum number of pooled connections
    ///
    /// Defaults to `10`
    pub fn max_size(mut self, max_size: u32) -> Self {
        self.min_idle = max_size;
        self
    }

    /// Connection timeout
    ///
    /// Defaults to `30 seconds`
    pub fn connection_timeout(mut self, connection_timeout: Duration) -> Self {
        self.connection_timeout = connection_timeout;
        self
    }

    /// Connection idle timeout
    ///
    /// Defaults to `60 seconds`
    pub fn idle_timeout(mut self, idle_timeout: Duration) -> Self {
        self.idle_timeout = idle_timeout;
        self
    }

    pub(crate) fn build<C: ManageConnection>(&self, client: C) -> Pool<C> {
        Pool::builder()
            .min_idle(Some(self.min_idle))
            .max_size(self.max_size)
            .connection_timeout(self.connection_timeout)
            .idle_timeout(Some(self.idle_timeout))
            .build_unchecked(client)
    }
}

impl Default for PoolConfig {
    fn default() -> Self {
        Self {
            min_idle: 0,
            max_size: 10,
            connection_timeout: Duration::from_secs(30),
            idle_timeout: Duration::from_secs(60),
        }
    }
}

impl ManageConnection for SmtpClient {
    type Connection = SmtpConnection;
    type Error = Error;

    fn connect(&self) -> Result<Self::Connection, Error> {
        self.connection()
    }

    fn is_valid(&self, conn: &mut Self::Connection) -> Result<(), Error> {
        if conn.test_connected() {
            return Ok(());
        }
        Err(Error::Client("is not connected anymore"))
    }

    fn has_broken(&self, conn: &mut Self::Connection) -> bool {
        conn.has_broken()
    }
}
<commit_msg>fix(transport-smtp): Fix max_size setter for PoolConfig (#546)<commit_after>use std::time::Duration;

use crate::transport::smtp::{client::SmtpConnection, error::Error, SmtpClient};

use r2d2::{ManageConnection, Pool};

/// Configuration for a connection pool
#[derive(Debug, Clone)]
#[allow(missing_copy_implementations)]
#[cfg_attr(docsrs, doc(cfg(feature = "r2d2")))]
pub struct PoolConfig {
    min_idle: u32,
    max_size: u32,
    connection_timeout: Duration,
    idle_timeout: Duration,
}

impl PoolConfig {
    /// Create a new pool configuration with default values
    pub fn new() -> Self {
        Self::default()
    }

    /// Minimum number of idle connections
    ///
    /// Defaults to `0`
    pub fn min_idle(mut self, min_idle: u32) -> Self {
        self.min_idle = min_idle;
        self
    }

    /// Maximum number of pooled connections
    ///
    /// Defaults to `10`
    pub fn max_size(mut self, max_size: u32) -> Self {
        self.max_size = max_size;
        self
    }

    /// Connection timeout
    ///
    /// Defaults to `30 seconds`
    pub fn connection_timeout(mut self, connection_timeout: Duration) -> Self {
        self.connection_timeout = connection_timeout;
        self
    }

    /// Connection idle timeout
    ///
    /// Defaults to `60 seconds`
    pub fn idle_timeout(mut self, idle_timeout: Duration) -> Self {
        self.idle_timeout = idle_timeout;
        self
    }

    pub(crate) fn build<C: ManageConnection>(&self, client: C) -> Pool<C> {
        Pool::builder()
            .min_idle(Some(self.min_idle))
            .max_size(self.max_size)
            .connection_timeout(self.connection_timeout)
            .idle_timeout(Some(self.idle_timeout))
            .build_unchecked(client)
    }
}

impl Default for PoolConfig {
    fn default() -> Self {
        Self {
            min_idle: 0,
            max_size: 10,
            connection_timeout: Duration::from_secs(30),
            idle_timeout: Duration::from_secs(60),
        }
    }
}

impl ManageConnection for SmtpClient {
    type Connection = SmtpConnection;
    type Error = Error;

    fn connect(&self) -> Result<Self::Connection, Error> {
        self.connection()
    }

    fn is_valid(&self, conn: &mut Self::Connection) -> Result<(), Error> {
        if conn.test_connected() {
            return Ok(());
        }
        Err(Error::Client("is not connected anymore"))
    }

    fn has_broken(&self, conn: &mut Self::Connection) -> bool {
        conn.has_broken()
    }
}
<|endoftext|>


<commit_before>use traits::{Cipher, U8Array};

/// A `CipherState` can encrypt and decrypt data.
///
/// Mostly like `CipherState` in the spec, but must be created with a key.
pub struct CipherState<C: Cipher> {
    key: C::Key,
    n: u64,
}

impl<C> CipherState<C>
    where C: Cipher
{
    /// Name of cipher, e.g. “ChaChaPoly”.
    pub fn name() -> &'static str {
        C::name()
    }

    /// Create a new `CipherState` with a `key` and a nonce `n`.
    pub fn new(key: &[u8], n: u64) -> Self {
        CipherState {
            key: C::Key::from_slice(key),
            n: n,
        }
    }

    /// AEAD encryption.
    pub fn encrypt_ad(&mut self, authtext: &[u8], plaintext: &[u8], out: &mut [u8]) {
        C::encrypt(&self.key, self.n, authtext, plaintext, out);
        // This will fails when n == 2 ^ 64 - 1, complying to the spec.
        self.n = self.n.checked_add(1).unwrap();
    }

    /// AEAD decryption.
    pub fn decrypt_ad(&mut self,
                      authtext: &[u8],
                      ciphertext: &[u8],
                      out: &mut [u8])
                      -> Result<(), ()> {
        C::decrypt(&self.key, self.n, authtext, ciphertext, out)?;
        self.n = self.n.checked_add(1).unwrap();
        Ok(())
    }

    /// Encryption.
    pub fn encrypt(&mut self, plaintext: &[u8], out: &mut [u8]) {
        self.encrypt_ad(&[0u8; 0], plaintext, out)
    }

    /// Encryption, returns ciphertext as `Vec<u8>`.
    pub fn encrypt_vec(&mut self, plaintext: &[u8]) -> Vec<u8> {
        let mut out = vec![0u8; plaintext.len() + 16];
        self.encrypt(plaintext, &mut out);
        out
    }

    /// Decryption.
    pub fn decrypt(&mut self, ciphertext: &[u8], out: &mut [u8]) -> Result<(), ()> {
        self.decrypt_ad(&[0u8; 0], ciphertext, out)
    }

    /// Decryption, returns plaintext as `Vec<u8>`.
    pub fn decrypt_vec(&mut self, ciphertext: &[u8]) -> Result<Vec<u8>, ()> {
        let mut out = vec![0u8; ciphertext.len() - 16];
        self.decrypt(ciphertext, &mut out)?;
        Ok(out)
    }

    /// Get underlying cipher and nonce.
    ///
    /// This is useful for e.g. WireGuard. Because packets may be lost or arrive out of order,
    /// they would likely want to deal with nonces themselves.
    pub fn extract(self) -> (C::Key, u64) {
        (self.key, self.n)
    }
}
<commit_msg>Cipherstate: add doc about pancis<commit_after>use traits::{Cipher, U8Array};

/// A `CipherState` can encrypt and decrypt data.
///
/// Mostly like `CipherState` in the spec, but must be created with a key.
pub struct CipherState<C: Cipher> {
    key: C::Key,
    n: u64,
}

impl<C> CipherState<C>
    where C: Cipher
{
    /// Name of cipher, e.g. “ChaChaPoly”.
    pub fn name() -> &'static str {
        C::name()
    }

    /// Create a new `CipherState` with a `key` and a nonce `n`.
    pub fn new(key: &[u8], n: u64) -> Self {
        CipherState {
            key: C::Key::from_slice(key),
            n: n,
        }
    }

    /// AEAD encryption.
    ///
    /// # Panics
    ///
    /// When nonce reaches maximum u64, i.e. 2 ^ 64 - 1.
    pub fn encrypt_ad(&mut self, authtext: &[u8], plaintext: &[u8], out: &mut [u8]) {
        C::encrypt(&self.key, self.n, authtext, plaintext, out);
        // This will fail when n == 2 ^ 64 - 1, complying to the spec.
        self.n = self.n.checked_add(1).unwrap();
    }

    /// AEAD decryption.
    ///
    /// # Panics
    ///
    /// When nonce reaches maximum u64, i.e. 2 ^ 64 - 1.
    pub fn decrypt_ad(&mut self,
                      authtext: &[u8],
                      ciphertext: &[u8],
                      out: &mut [u8])
                      -> Result<(), ()> {
        C::decrypt(&self.key, self.n, authtext, ciphertext, out)?;
        self.n = self.n.checked_add(1).unwrap();
        Ok(())
    }

    /// Encryption.
    pub fn encrypt(&mut self, plaintext: &[u8], out: &mut [u8]) {
        self.encrypt_ad(&[0u8; 0], plaintext, out)
    }

    /// Encryption, returns ciphertext as `Vec<u8>`.
    pub fn encrypt_vec(&mut self, plaintext: &[u8]) -> Vec<u8> {
        let mut out = vec![0u8; plaintext.len() + 16];
        self.encrypt(plaintext, &mut out);
        out
    }

    /// Decryption.
    pub fn decrypt(&mut self, ciphertext: &[u8], out: &mut [u8]) -> Result<(), ()> {
        self.decrypt_ad(&[0u8; 0], ciphertext, out)
    }

    /// Decryption, returns plaintext as `Vec<u8>`.
    pub fn decrypt_vec(&mut self, ciphertext: &[u8]) -> Result<Vec<u8>, ()> {
        let mut out = vec![0u8; ciphertext.len() - 16];
        self.decrypt(ciphertext, &mut out)?;
        Ok(out)
    }

    /// Get underlying cipher and nonce.
    ///
    /// This is useful for e.g. WireGuard. Because packets may be lost or arrive out of order,
    /// they would likely want to deal with nonces themselves.
    pub fn extract(self) -> (C::Key, u64) {
        (self.key, self.n)
    }
}
<|endoftext|>


<commit_before>use std::io::Error as IoError;
use std::fmt::Display;
use serde_json::Error as SerdeError;
use clap::Error as ClapError;
use tempfile;
use atomicwrites;

/// the result type used for the whole application
pub type CtResult<T> = Result<T, CtError>;

/// the error type used for the whole application
error_type! {
    #[derive(Debug, Clone)]
    pub enum CtError {
        Msg(String) {
            desc (e) &e;
            from (s: &'static str) s.into();
            from (ie: IoError) ie.to_string();
            from (se: SerdeError) se.to_string();
            from (ce: ClapError) ce.to_string();
            from (pe: tempfile::PersistError) pe.to_string();
        },
    }
}

impl<E: Display> From<atomicwrites::Error<E>> for CtError {
    fn from(err: atomicwrites::Error<E>) -> CtError {
        CtError::Msg(format!("{}", err))
    }
}

pub trait OkOr {
    type R;

    fn ok_or<E>(self, err: E) -> Result<Self::R, E>;
}

impl OkOr for bool {
    type R = ();

    fn ok_or<E>(self, err: E) -> Result<Self::R, E> {
        if self {
            Ok(())
        } else {
            Err(err)
        }
    }
}
<commit_msg>Fix warnings of rustc 1.35<commit_after>use std::io::Error as IoError;
use std::fmt::Display;
use serde_json::Error as SerdeError;
use clap::Error as ClapError;
use tempfile;
use atomicwrites;

/// the result type used for the whole application
pub type CtResult<T> = Result<T, CtError>;

// the error type used for the whole application
error_type! {
    #[derive(Debug, Clone)]
    pub enum CtError {
        Msg(String) {
            desc (e) &e;
            from (s: &'static str) s.into();
            from (ie: IoError) ie.to_string();
            from (se: SerdeError) se.to_string();
            from (ce: ClapError) ce.to_string();
            from (pe: tempfile::PersistError) pe.to_string();
        },
    }
}

impl<E: Display> From<atomicwrites::Error<E>> for CtError {
    fn from(err: atomicwrites::Error<E>) -> CtError {
        CtError::Msg(format!("{}", err))
    }
}

pub trait OkOr {
    type R;

    fn ok_or<E>(self, err: E) -> Result<Self::R, E>;
}

impl OkOr for bool {
    type R = ();

    fn ok_or<E>(self, err: E) -> Result<Self::R, E> {
        if self {
            Ok(())
        } else {
            Err(err)
        }
    }
}
<|endoftext|>