<commit_before>// Copyright 2019 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use std::env;
use std::error::Error;
use std::fs::{self, File};
use std::io::Write;
use std::path::{Path, PathBuf};

type Result<T> = std::result::Result<T, Box<dyn Error>>;

struct ExternalProto {
    // Where to find protos during builds within cros_sdk. Relative to
    // $SYSROOT environment variable set by emerge builds.
    dir_relative_to_sysroot: &'static str,

    // Where to find protos during "cargo build" in a local developer
    // environment. Relative to the platform/crosvm/protos directory.
    dir_relative_to_us: &'static str,

    // *.proto file expected to exist in both of the above directories.
    proto_file_name: &'static str,

    // Code generated by proto compiler will be placed under
    // protos::generated::$module_name.
    module: &'static str,
}

// Rustfmt bug: https://github.com/rust-lang/rustfmt/issues/3498
#[rustfmt::skip]
static EXTERNAL_PROTOS: &[ExternalProto] = &[
    #[cfg(feature = "trunks")]
    ExternalProto {
        dir_relative_to_sysroot: "usr/include/chromeos/dbus/trunks",
        dir_relative_to_us: "../../../platform2/trunks",
        proto_file_name: "interface.proto",
        module: "trunks",
    },
];

struct LocalProto {
    // Corresponding to the input file src/$module.proto.
    module: &'static str,
}

#[rustfmt::skip]
static LOCAL_PROTOS: &[LocalProto] = &[
    #[cfg(feature = "plugin")]
    LocalProto { module: "plugin" },
];

fn main() -> Result<()> {
    let out_dir = env::var("OUT_DIR")?;
    let sysroot = env::var_os("SYSROOT");

    // Write out a Rust module that imports the modules generated by protoc.
    let generated = PathBuf::from(&out_dir).join("generated.rs");
    let out = File::create(generated)?;

    // Compile external protos.
    for proto in EXTERNAL_PROTOS {
        let dir = match &sysroot {
            Some(dir) => PathBuf::from(dir).join(proto.dir_relative_to_sysroot),
            None => PathBuf::from(proto.dir_relative_to_us),
        };
        let input_path = dir.join(proto.proto_file_name);
        protoc(proto.module, input_path, &out)?;
    }

    // Compile protos from the local src directory.
    for proto in LOCAL_PROTOS {
        let input_path = format!("src/{}.proto", proto.module);
        protoc(proto.module, input_path, &out)?;
    }

    Ok(())
}

// Compile a single proto file located at $input_path, placing the generated
// code at $OUT_DIR/$module and emitting the right `pub mod $module` into the
// output file.
fn protoc<P: AsRef<Path>>(module: &str, input_path: P, mut out: &File) -> Result<()> {
    let input_path = input_path.as_ref();
    let input_dir = input_path.parent().unwrap();

    // Place output in a subdirectory so that different protos with the same
    // common filename (like interface.proto) do not conflict.
    let out_dir = format!("{}/{}", env::var("OUT_DIR")?, module);
    fs::create_dir_all(&out_dir)?;

    // Invoke protobuf compiler.
    protoc_rust::run(protoc_rust::Args {
        out_dir: &out_dir,
        includes: &[input_dir.as_os_str().to_str().unwrap()],
        input: &[input_path.as_os_str().to_str().unwrap()],
        ..Default::default()
    })?;

    // Write out a `mod` that refers to the generated module.
    let file_stem = input_path.file_stem().unwrap().to_str().unwrap();
    writeln!(out, "#[path = \"{}/{}.rs\"]", out_dir, file_stem)?;
    writeln!(out, "pub mod {};", module)?;

    Ok(())
}
<commit_msg>clippy: Suppress warning from protoc_rust generated code<commit_after>// Copyright 2019 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use std::env;
use std::error::Error;
use std::fs::{self, File};
use std::io::Write;
use std::path::{Path, PathBuf};

type Result<T> = std::result::Result<T, Box<dyn Error>>;

struct ExternalProto {
    // Where to find protos during builds within cros_sdk. Relative to
    // $SYSROOT environment variable set by emerge builds.
    dir_relative_to_sysroot: &'static str,

    // Where to find protos during "cargo build" in a local developer
    // environment. Relative to the platform/crosvm/protos directory.
    dir_relative_to_us: &'static str,

    // *.proto file expected to exist in both of the above directories.
    proto_file_name: &'static str,

    // Code generated by proto compiler will be placed under
    // protos::generated::$module_name.
    module: &'static str,
}

// Rustfmt bug: https://github.com/rust-lang/rustfmt/issues/3498
#[rustfmt::skip]
static EXTERNAL_PROTOS: &[ExternalProto] = &[
    #[cfg(feature = "trunks")]
    ExternalProto {
        dir_relative_to_sysroot: "usr/include/chromeos/dbus/trunks",
        dir_relative_to_us: "../../../platform2/trunks",
        proto_file_name: "interface.proto",
        module: "trunks",
    },
];

struct LocalProto {
    // Corresponding to the input file src/$module.proto.
    module: &'static str,
}

#[rustfmt::skip]
static LOCAL_PROTOS: &[LocalProto] = &[
    #[cfg(feature = "plugin")]
    LocalProto { module: "plugin" },
];

fn main() -> Result<()> {
    let out_dir = env::var("OUT_DIR")?;
    let sysroot = env::var_os("SYSROOT");

    // Write out a Rust module that imports the modules generated by protoc.
    let generated = PathBuf::from(&out_dir).join("generated.rs");
    let out = File::create(generated)?;

    // Compile external protos.
    for proto in EXTERNAL_PROTOS {
        let dir = match &sysroot {
            Some(dir) => PathBuf::from(dir).join(proto.dir_relative_to_sysroot),
            None => PathBuf::from(proto.dir_relative_to_us),
        };
        let input_path = dir.join(proto.proto_file_name);
        protoc(proto.module, input_path, &out)?;
    }

    // Compile protos from the local src directory.
    for proto in LOCAL_PROTOS {
        let input_path = format!("src/{}.proto", proto.module);
        protoc(proto.module, input_path, &out)?;
    }

    Ok(())
}

// Compile a single proto file located at $input_path, placing the generated
// code at $OUT_DIR/$module and emitting the right `pub mod $module` into the
// output file.
fn protoc<P: AsRef<Path>>(module: &str, input_path: P, mut out: &File) -> Result<()> {
    let input_path = input_path.as_ref();
    let input_dir = input_path.parent().unwrap();

    // Place output in a subdirectory so that different protos with the same
    // common filename (like interface.proto) do not conflict.
    let out_dir = format!("{}/{}", env::var("OUT_DIR")?, module);
    fs::create_dir_all(&out_dir)?;

    // Invoke protobuf compiler.
    protoc_rust::run(protoc_rust::Args {
        out_dir: &out_dir,
        includes: &[input_dir.as_os_str().to_str().unwrap()],
        input: &[input_path.as_os_str().to_str().unwrap()],
        ..Default::default()
    })?;

    // Write out a `mod` that refers to the generated module.
    //
    // The lint suppression is because protoc-rust emits
    //   #![cfg_attr(feature = "cargo-clippy", allow(clippy))]
    // which still works but is deprecated in favor of tool attributes:
    //   #![allow(clippy::all)].
    let file_stem = input_path.file_stem().unwrap().to_str().unwrap();
    writeln!(out, "#[path = \"{}/{}.rs\"]", out_dir, file_stem)?;
    writeln!(out, "#[allow(renamed_and_removed_lints)]")?;
    writeln!(out, "pub mod {};", module)?;

    Ok(())
}
<|endoftext|>


<commit_before>// Copyright (C) 2016-2017 Sebastian Dröge <sebastian@centricular.com>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use libc::c_char;
use std::os::raw::c_void;
use std::ffi::CString;
use std::ptr;
use std::error::Error;
use std::fmt::{Display, Formatter};
use std::fmt::Error as FmtError;
use std::borrow::Cow;

use url::Url;

use utils::*;

#[macro_export]
macro_rules! error_msg(
// Plain strings
    ($err:expr, ($msg:expr), [$dbg:expr]) =>  {
        ErrorMessage::new(&$err, Some(From::from($msg)),
                          Some(From::from($dbg)),
                          file!(), module_path!(), line!())
    };
    ($err:expr, ($msg:expr)) => {
        ErrorMessage::new(&$err, Some(From::from($msg)),
                          None,
                          file!(), module_path!(), line!())
    };
    ($err:expr, [$dbg:expr]) => {
        ErrorMessage::new(&$err, None,
                          Some(From::from($dbg)),
                          file!(), module_path!(), line!())
    };

// Format strings
    ($err:expr, ($($msg:tt)*), [$($dbg:tt)*]) =>  { {
        ErrorMessage::new(&$err, Some(From::from(format!($($msg)*))),
                          From::from(Some(format!($($dbg)*))),
                          file!(), module_path!(), line!())
    }};
    ($err:expr, ($($msg:tt)*)) =>  { {
        ErrorMessage::new(&$err, Some(From::from(format!($($msg)*))),
                          None,
                          file!(), module_path!(), line!())
    }};

    ($err:expr, [$($dbg:tt)*]) =>  { {
        ErrorMessage::new(&$err, None,
                          Some(From::from(format!($($dbg)*))),
                          file!(), module_path!(), line!())
    }};
);

pub trait ToGError {
    fn to_gerror(&self) -> (u32, i32);
}

pub fn gst_library_error_domain() -> u32 {
    extern "C" {
        fn gst_library_error_quark() -> u32;
    }

    unsafe { gst_library_error_quark() }
}

pub fn gst_resource_error_domain() -> u32 {
    extern "C" {
        fn gst_resource_error_quark() -> u32;
    }

    unsafe { gst_resource_error_quark() }
}

#[derive(Debug)]
pub struct ErrorMessage {
    pub error_domain: u32,
    pub error_code: i32,
    pub message: Option<String>,
    pub debug: Option<String>,
    pub filename: &'static str,
    pub function: &'static str,
    pub line: u32,
}

impl ErrorMessage {
    pub fn new<T: ToGError>(error: &T,
                            message: Option<Cow<str>>,
                            debug: Option<Cow<str>>,
                            filename: &'static str,
                            function: &'static str,
                            line: u32)
                            -> ErrorMessage {
        let (gdomain, gcode) = error.to_gerror();

        ErrorMessage {
            error_domain: gdomain,
            error_code: gcode,
            message: message.map(|m| m.into_owned()),
            debug: debug.map(|d| d.into_owned()),
            filename: filename,
            function: function,
            line: line,
        }
    }

    pub unsafe fn post(&self, element: *mut c_void) {
        extern "C" {
            fn gst_rs_element_error(sink: *mut c_void,
                                    error_domain: u32,
                                    error_code: i32,
                                    message: *const c_char,
                                    debug: *const c_char,
                                    filename: *const c_char,
                                    function: *const c_char,
                                    line: u32);
        }

        let ErrorMessage { error_domain,
                           error_code,
                           ref message,
                           ref debug,
                           filename,
                           function,
                           line } = *self;

        let message_cstr = message.as_ref().map(|m| CString::new(m.as_bytes()).unwrap());
        let message_ptr = message_cstr.as_ref().map_or(ptr::null(), |m| m.as_ptr());

        let debug_cstr = debug.as_ref().map(|m| CString::new(m.as_bytes()).unwrap());
        let debug_ptr = debug_cstr.as_ref().map_or(ptr::null(), |m| m.as_ptr());

        let file_cstr = CString::new(filename.as_bytes()).unwrap();
        let file_ptr = file_cstr.as_ptr();

        let function_cstr = CString::new(function.as_bytes()).unwrap();
        let function_ptr = function_cstr.as_ptr();

        gst_rs_element_error(element,
                             error_domain,
                             error_code,
                             message_ptr,
                             debug_ptr,
                             file_ptr,
                             function_ptr,
                             line);
    }
}

#[derive(Debug)]
pub enum FlowError {
    NotLinked,
    Flushing,
    Eos,
    NotNegotiated(ErrorMessage),
    Error(ErrorMessage),
}

impl FlowError {
    pub fn to_native(&self) -> GstFlowReturn {
        match *self {
            FlowError::NotLinked => GstFlowReturn::NotLinked,
            FlowError::Flushing => GstFlowReturn::Flushing,
            FlowError::Eos => GstFlowReturn::Eos,
            FlowError::NotNegotiated(..) => GstFlowReturn::NotNegotiated,
            FlowError::Error(..) => GstFlowReturn::Error,
        }
    }
}

impl Display for FlowError {
    fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
        match *self {
            FlowError::NotLinked | FlowError::Flushing | FlowError::Eos => {
                f.write_str(self.description())
            }
            FlowError::NotNegotiated(ref m) => {
                f.write_fmt(format_args!("{}: {} ({})",
                                         self.description(),
                                         m.message.as_ref().map_or("None", |s| s.as_str()),
                                         m.debug.as_ref().map_or("None", |s| s.as_str())))
            }
            FlowError::Error(ref m) => {
                f.write_fmt(format_args!("{}: {} ({})",
                                         self.description(),
                                         m.message.as_ref().map_or("None", |s| s.as_str()),
                                         m.debug.as_ref().map_or("None", |s| s.as_str())))
            }
        }
    }
}

impl Error for FlowError {
    fn description(&self) -> &str {
        match *self {
            FlowError::NotLinked => "Not Linked",
            FlowError::Flushing => "Flushing",
            FlowError::Eos => "Eos",
            FlowError::NotNegotiated(..) => "Not Negotiated",
            FlowError::Error(..) => "Error",
        }
    }
}

#[derive(Debug)]
pub enum UriErrorKind {
    UnsupportedProtocol = 0,
    BadUri,
    BadState,
    BadReference,
}

#[derive(Debug)]
pub struct UriError {
    error_kind: UriErrorKind,
    message: Option<String>,
}

impl UriError {
    pub fn new(error_kind: UriErrorKind, message: Option<String>) -> UriError {
        UriError {
            error_kind: error_kind,
            message: message,
        }
    }

    pub fn message(&self) -> &Option<String> {
        &self.message
    }

    pub fn kind(&self) -> &UriErrorKind {
        &self.error_kind
    }

    pub unsafe fn into_gerror(self, err: *mut c_void) {
        extern "C" {
            fn g_set_error_literal(err: *mut c_void,
                                   domain: u32,
                                   code: i32,
                                   message: *const c_char);
            fn gst_uri_error_quark() -> u32;
        }

        if let Some(msg) = self.message {
            let cmsg = CString::new(msg.as_str()).unwrap();
            g_set_error_literal(err,
                                gst_uri_error_quark(),
                                self.error_kind as i32,
                                cmsg.as_ptr());
        } else {
            g_set_error_literal(err,
                                gst_uri_error_quark(),
                                self.error_kind as i32,
                                ptr::null());
        }
    }
}

impl Display for UriError {
    fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
        match self.message {
            None => f.write_str(self.description()),
            Some(ref message) => f.write_fmt(format_args!("{}: {}", self.description(), message)),
        }
    }
}

impl Error for UriError {
    fn description(&self) -> &str {
        match self.error_kind {
            UriErrorKind::UnsupportedProtocol => "Unsupported protocol",
            UriErrorKind::BadUri => "Bad URI",
            UriErrorKind::BadState => "Bad State",
            UriErrorKind::BadReference => "Bad Reference",
        }
    }
}

pub type UriValidator = Fn(&Url) -> Result<(), UriError>;

#[derive(Debug)]
pub struct PanicError;

impl ToGError for PanicError {
    fn to_gerror(&self) -> (u32, i32) {
        (gst_library_error_domain(), 1)
    }
}

#[macro_export]
macro_rules! panic_to_error(
    ($wrap:expr, $ret:expr, $code:block) => {{
        if $wrap.panicked.load(Ordering::Relaxed) {
            error_msg!(PanicError, ["Panicked"]).post($wrap.raw);
            return $ret;
        }

        let result = panic::catch_unwind(AssertUnwindSafe(|| $code));

        match result {
            Ok(result) => result,
            Err(err) => {
                $wrap.panicked.store(true, Ordering::Relaxed);
                if let Some(cause) = err.downcast_ref::<&str>() {
                    error_msg!(PanicError, ["Panicked: {}", cause]).post($wrap.raw);
                } else if let Some(cause) = err.downcast_ref::<String>() {
                    error_msg!(PanicError, ["Panicked: {}", cause]).post($wrap.raw);
                } else {
                    error_msg!(PanicError, ["Panicked"]).post($wrap.raw);
                }
                $ret
            }
        }
    }}
);
<commit_msg>Remove FlowError::NotLinked<commit_after>// Copyright (C) 2016-2017 Sebastian Dröge <sebastian@centricular.com>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use libc::c_char;
use std::os::raw::c_void;
use std::ffi::CString;
use std::ptr;
use std::error::Error;
use std::fmt::{Display, Formatter};
use std::fmt::Error as FmtError;
use std::borrow::Cow;

use url::Url;

use utils::*;

#[macro_export]
macro_rules! error_msg(
// Plain strings
    ($err:expr, ($msg:expr), [$dbg:expr]) =>  {
        ErrorMessage::new(&$err, Some(From::from($msg)),
                          Some(From::from($dbg)),
                          file!(), module_path!(), line!())
    };
    ($err:expr, ($msg:expr)) => {
        ErrorMessage::new(&$err, Some(From::from($msg)),
                          None,
                          file!(), module_path!(), line!())
    };
    ($err:expr, [$dbg:expr]) => {
        ErrorMessage::new(&$err, None,
                          Some(From::from($dbg)),
                          file!(), module_path!(), line!())
    };

// Format strings
    ($err:expr, ($($msg:tt)*), [$($dbg:tt)*]) =>  { {
        ErrorMessage::new(&$err, Some(From::from(format!($($msg)*))),
                          From::from(Some(format!($($dbg)*))),
                          file!(), module_path!(), line!())
    }};
    ($err:expr, ($($msg:tt)*)) =>  { {
        ErrorMessage::new(&$err, Some(From::from(format!($($msg)*))),
                          None,
                          file!(), module_path!(), line!())
    }};

    ($err:expr, [$($dbg:tt)*]) =>  { {
        ErrorMessage::new(&$err, None,
                          Some(From::from(format!($($dbg)*))),
                          file!(), module_path!(), line!())
    }};
);

pub trait ToGError {
    fn to_gerror(&self) -> (u32, i32);
}

pub fn gst_library_error_domain() -> u32 {
    extern "C" {
        fn gst_library_error_quark() -> u32;
    }

    unsafe { gst_library_error_quark() }
}

pub fn gst_resource_error_domain() -> u32 {
    extern "C" {
        fn gst_resource_error_quark() -> u32;
    }

    unsafe { gst_resource_error_quark() }
}

#[derive(Debug)]
pub struct ErrorMessage {
    pub error_domain: u32,
    pub error_code: i32,
    pub message: Option<String>,
    pub debug: Option<String>,
    pub filename: &'static str,
    pub function: &'static str,
    pub line: u32,
}

impl ErrorMessage {
    pub fn new<T: ToGError>(error: &T,
                            message: Option<Cow<str>>,
                            debug: Option<Cow<str>>,
                            filename: &'static str,
                            function: &'static str,
                            line: u32)
                            -> ErrorMessage {
        let (gdomain, gcode) = error.to_gerror();

        ErrorMessage {
            error_domain: gdomain,
            error_code: gcode,
            message: message.map(|m| m.into_owned()),
            debug: debug.map(|d| d.into_owned()),
            filename: filename,
            function: function,
            line: line,
        }
    }

    pub unsafe fn post(&self, element: *mut c_void) {
        extern "C" {
            fn gst_rs_element_error(sink: *mut c_void,
                                    error_domain: u32,
                                    error_code: i32,
                                    message: *const c_char,
                                    debug: *const c_char,
                                    filename: *const c_char,
                                    function: *const c_char,
                                    line: u32);
        }

        let ErrorMessage { error_domain,
                           error_code,
                           ref message,
                           ref debug,
                           filename,
                           function,
                           line } = *self;

        let message_cstr = message.as_ref().map(|m| CString::new(m.as_bytes()).unwrap());
        let message_ptr = message_cstr.as_ref().map_or(ptr::null(), |m| m.as_ptr());

        let debug_cstr = debug.as_ref().map(|m| CString::new(m.as_bytes()).unwrap());
        let debug_ptr = debug_cstr.as_ref().map_or(ptr::null(), |m| m.as_ptr());

        let file_cstr = CString::new(filename.as_bytes()).unwrap();
        let file_ptr = file_cstr.as_ptr();

        let function_cstr = CString::new(function.as_bytes()).unwrap();
        let function_ptr = function_cstr.as_ptr();

        gst_rs_element_error(element,
                             error_domain,
                             error_code,
                             message_ptr,
                             debug_ptr,
                             file_ptr,
                             function_ptr,
                             line);
    }
}

#[derive(Debug)]
pub enum FlowError {
    Flushing,
    Eos,
    NotNegotiated(ErrorMessage),
    Error(ErrorMessage),
}

impl FlowError {
    pub fn to_native(&self) -> GstFlowReturn {
        match *self {
            FlowError::Flushing => GstFlowReturn::Flushing,
            FlowError::Eos => GstFlowReturn::Eos,
            FlowError::NotNegotiated(..) => GstFlowReturn::NotNegotiated,
            FlowError::Error(..) => GstFlowReturn::Error,
        }
    }
}

impl Display for FlowError {
    fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
        match *self {
            FlowError::Flushing | FlowError::Eos => f.write_str(self.description()),
            FlowError::NotNegotiated(ref m) => {
                f.write_fmt(format_args!("{}: {} ({})",
                                         self.description(),
                                         m.message.as_ref().map_or("None", |s| s.as_str()),
                                         m.debug.as_ref().map_or("None", |s| s.as_str())))
            }
            FlowError::Error(ref m) => {
                f.write_fmt(format_args!("{}: {} ({})",
                                         self.description(),
                                         m.message.as_ref().map_or("None", |s| s.as_str()),
                                         m.debug.as_ref().map_or("None", |s| s.as_str())))
            }
        }
    }
}

impl Error for FlowError {
    fn description(&self) -> &str {
        match *self {
            FlowError::Flushing => "Flushing",
            FlowError::Eos => "Eos",
            FlowError::NotNegotiated(..) => "Not Negotiated",
            FlowError::Error(..) => "Error",
        }
    }
}

#[derive(Debug)]
pub enum UriErrorKind {
    UnsupportedProtocol = 0,
    BadUri,
    BadState,
    BadReference,
}

#[derive(Debug)]
pub struct UriError {
    error_kind: UriErrorKind,
    message: Option<String>,
}

impl UriError {
    pub fn new(error_kind: UriErrorKind, message: Option<String>) -> UriError {
        UriError {
            error_kind: error_kind,
            message: message,
        }
    }

    pub fn message(&self) -> &Option<String> {
        &self.message
    }

    pub fn kind(&self) -> &UriErrorKind {
        &self.error_kind
    }

    pub unsafe fn into_gerror(self, err: *mut c_void) {
        extern "C" {
            fn g_set_error_literal(err: *mut c_void,
                                   domain: u32,
                                   code: i32,
                                   message: *const c_char);
            fn gst_uri_error_quark() -> u32;
        }

        if let Some(msg) = self.message {
            let cmsg = CString::new(msg.as_str()).unwrap();
            g_set_error_literal(err,
                                gst_uri_error_quark(),
                                self.error_kind as i32,
                                cmsg.as_ptr());
        } else {
            g_set_error_literal(err,
                                gst_uri_error_quark(),
                                self.error_kind as i32,
                                ptr::null());
        }
    }
}

impl Display for UriError {
    fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
        match self.message {
            None => f.write_str(self.description()),
            Some(ref message) => f.write_fmt(format_args!("{}: {}", self.description(), message)),
        }
    }
}

impl Error for UriError {
    fn description(&self) -> &str {
        match self.error_kind {
            UriErrorKind::UnsupportedProtocol => "Unsupported protocol",
            UriErrorKind::BadUri => "Bad URI",
            UriErrorKind::BadState => "Bad State",
            UriErrorKind::BadReference => "Bad Reference",
        }
    }
}

pub type UriValidator = Fn(&Url) -> Result<(), UriError>;

#[derive(Debug)]
pub struct PanicError;

impl ToGError for PanicError {
    fn to_gerror(&self) -> (u32, i32) {
        (gst_library_error_domain(), 1)
    }
}

#[macro_export]
macro_rules! panic_to_error(
    ($wrap:expr, $ret:expr, $code:block) => {{
        if $wrap.panicked.load(Ordering::Relaxed) {
            error_msg!(PanicError, ["Panicked"]).post($wrap.raw);
            return $ret;
        }

        let result = panic::catch_unwind(AssertUnwindSafe(|| $code));

        match result {
            Ok(result) => result,
            Err(err) => {
                $wrap.panicked.store(true, Ordering::Relaxed);
                if let Some(cause) = err.downcast_ref::<&str>() {
                    error_msg!(PanicError, ["Panicked: {}", cause]).post($wrap.raw);
                } else if let Some(cause) = err.downcast_ref::<String>() {
                    error_msg!(PanicError, ["Panicked: {}", cause]).post($wrap.raw);
                } else {
                    error_msg!(PanicError, ["Panicked"]).post($wrap.raw);
                }
                $ret
            }
        }
    }}
);
<|endoftext|>


<commit_before>use clap::{App, Arg, ArgMatches, SubCommand};
use exercise::{
    cmd::{configure, fetch_configlet, generate, update},
    errors::Result,
};
use failure::format_err;

// Creates a new CLI app with appropriate matches
// and returns the initialized matches.
fn init_app<'a>() -> ArgMatches<'a> {
    App::new(env!("CARGO_PKG_NAME"))
        .version(env!("CARGO_PKG_VERSION"))
        .about(env!("CARGO_PKG_DESCRIPTION"))
        .subcommand(
            SubCommand::with_name("generate")
                .about("Generates new exercise")
                .arg(Arg::with_name("exercise_name").required(true).help("The name of the generated exercise"))
                .arg(Arg::with_name("configure").long("configure").short("c").help(
                    "If set, the command will edit the config.json file after generating the exercise",
                ))
                .arg(Arg::with_name("use_maplit").long("use-maplit").short("m").help("Use the maplit crate to improve the readability of the generated test suite")),
        )
        .subcommand(
            SubCommand::with_name("update")
                .about("Updates the specified exercise")
                .arg(Arg::with_name("exercise_name").help("The name of the updated exercise"))
                .arg(Arg::with_name("use_maplit").long("use-maplit").short("m").help("Use the maplit crate to improve the readability of the updated test suite"))
                .arg(Arg::with_name("dont_update_readme").long("dont-update-readme").short("r").help("If set, the README of the exercise would not be updated"))
                .arg(Arg::with_name("configure").long("configure").short("c").help(
                    "If set, the command will edit the config.json file after updating the exercise",
                ))
        )
        .subcommand(
            SubCommand::with_name("configure")
                .about("Edits config.json for the specified exercise")
                .arg(Arg::with_name("exercise_name").required(true).help("The name of the configured exercise")),
        )
        .subcommand(
            SubCommand::with_name("fetch_configlet")
                .about("Downloads and extracts configlet utility into the repo's /bin directory")
        )
        .get_matches()
}

// Determine which subcommand was used
// and call the appropriate function.
fn process_matches(matches: &ArgMatches<'_>) -> Result<()> {
    match matches.subcommand() {
        ("generate", Some(generate_matches)) => {
            let exercise_name = generate_matches
                .value_of("exercise_name")
                .ok_or_else(|| format_err!("exercise name not present in args"))?;
            let run_configure = generate_matches.is_present("configure");
            let use_maplit = generate_matches.is_present("use_maplit");

            generate::generate_exercise(exercise_name, use_maplit)?;

            if run_configure {
                configure::configure_exercise(exercise_name)?;
            }
        }

        ("update", Some(update_matches)) => {
            let exercise_name = update_matches
                .value_of("exercise_name")
                .ok_or_else(|| format_err!("exercise name not present in args"))?;

            let run_configure = update_matches.is_present("configure");

            let use_maplit = update_matches.is_present("use_maplit");

            let update_readme = !update_matches.is_present("dont_update_readme");

            update::update_exercise(exercise_name, use_maplit)?;

            if run_configure {
                configure::configure_exercise(exercise_name)?;
            }

            if update_readme {
                exercise::run_configlet_command("generate", &[".", "-o", exercise_name])?;
            }
        }

        ("configure", Some(configure_matches)) => {
            configure::configure_exercise(
                configure_matches
                    .value_of("exercise_name")
                    .ok_or_else(|| format_err!("exercise name not present in args"))?,
            )?;
        }

        ("fetch_configlet", Some(_fetch_configlet_matches)) => {
            if let Ok(fetch_path) = fetch_configlet::download() {
                println!(
                    "Downloaded and moved the configlet utility to the {:?} path",
                    fetch_path
                );
            } else {
                println!("Failed to fetch the configlet utility");
            }
        }

        ("", None) => {
            println!("No subcommand was used.\nUse init_exercise --help to learn about the possible subcommands.");
        }

        _ => unreachable!(),
    };

    Ok(())
}

fn main() -> Result<()> {
    let matches = init_app();

    process_matches(&matches)?;
    Ok(())
}
<commit_msg>fix a small typo in the exercise utility help (#1175)<commit_after>use clap::{App, Arg, ArgMatches, SubCommand};
use exercise::{
    cmd::{configure, fetch_configlet, generate, update},
    errors::Result,
};
use failure::format_err;

// Creates a new CLI app with appropriate matches
// and returns the initialized matches.
fn init_app<'a>() -> ArgMatches<'a> {
    App::new(env!("CARGO_PKG_NAME"))
        .version(env!("CARGO_PKG_VERSION"))
        .about(env!("CARGO_PKG_DESCRIPTION"))
        .subcommand(
            SubCommand::with_name("generate")
                .about("Generates new exercise")
                .arg(Arg::with_name("exercise_name").required(true).help("The name of the generated exercise"))
                .arg(Arg::with_name("configure").long("configure").short("c").help(
                    "If set, the command will edit the config.json file after generating the exercise",
                ))
                .arg(Arg::with_name("use_maplit").long("use-maplit").short("m").help("Use the maplit crate to improve the readability of the generated test suite")),
        )
        .subcommand(
            SubCommand::with_name("update")
                .about("Updates the specified exercise")
                .arg(Arg::with_name("exercise_name").help("The name of the updated exercise"))
                .arg(Arg::with_name("use_maplit").long("use-maplit").short("m").help("Use the maplit crate to improve the readability of the updated test suite"))
                .arg(Arg::with_name("dont_update_readme").long("dont-update-readme").short("r").help("If set, the README of the exercise would not be updated"))
                .arg(Arg::with_name("configure").long("configure").short("c").help(
                    "If set, the command will edit the config.json file after updating the exercise",
                ))
        )
        .subcommand(
            SubCommand::with_name("configure")
                .about("Edits config.json for the specified exercise")
                .arg(Arg::with_name("exercise_name").required(true).help("The name of the configured exercise")),
        )
        .subcommand(
            SubCommand::with_name("fetch_configlet")
                .about("Downloads and extracts configlet utility into the repo's /bin directory")
        )
        .get_matches()
}

// Determine which subcommand was used
// and call the appropriate function.
fn process_matches(matches: &ArgMatches<'_>) -> Result<()> {
    match matches.subcommand() {
        ("generate", Some(generate_matches)) => {
            let exercise_name = generate_matches
                .value_of("exercise_name")
                .ok_or_else(|| format_err!("exercise name not present in args"))?;
            let run_configure = generate_matches.is_present("configure");
            let use_maplit = generate_matches.is_present("use_maplit");

            generate::generate_exercise(exercise_name, use_maplit)?;

            if run_configure {
                configure::configure_exercise(exercise_name)?;
            }
        }

        ("update", Some(update_matches)) => {
            let exercise_name = update_matches
                .value_of("exercise_name")
                .ok_or_else(|| format_err!("exercise name not present in args"))?;

            let run_configure = update_matches.is_present("configure");

            let use_maplit = update_matches.is_present("use_maplit");

            let update_readme = !update_matches.is_present("dont_update_readme");

            update::update_exercise(exercise_name, use_maplit)?;

            if run_configure {
                configure::configure_exercise(exercise_name)?;
            }

            if update_readme {
                exercise::run_configlet_command("generate", &[".", "-o", exercise_name])?;
            }
        }

        ("configure", Some(configure_matches)) => {
            configure::configure_exercise(
                configure_matches
                    .value_of("exercise_name")
                    .ok_or_else(|| format_err!("exercise name not present in args"))?,
            )?;
        }

        ("fetch_configlet", Some(_fetch_configlet_matches)) => {
            if let Ok(fetch_path) = fetch_configlet::download() {
                println!(
                    "Downloaded and moved the configlet utility to the {:?} path",
                    fetch_path
                );
            } else {
                println!("Failed to fetch the configlet utility");
            }
        }

        ("", None) => {
            println!("No subcommand was used.\nUse exercise --help to learn about the possible subcommands.");
        }

        _ => unreachable!(),
    };

    Ok(())
}

fn main() -> Result<()> {
    let matches = init_app();

    process_matches(&matches)?;
    Ok(())
}
<|endoftext|>


<commit_before>/// Deserialization

use byteorder::{BigEndian, ReadBytesExt};

use std;
use std::fmt;
use std::fmt::Display;
use std::io;
use std::io::Read;
use std::vec;
use serde::de;
use serde::de::Visitor;

enum OscArg {
    /// 32-bit signed integer
    i(i32),
    /// 32-bit float
    f(f32),
    /// String; specified as null-terminated ascii.
    /// This might also represent the message address pattern (aka path)
    s(String),
    /// 'blob' (binary) data
    b(Vec<u8>),
}

struct OscDeserializer<R> {
    read: R,
    state: State,
}

/// Which part of the OSC message is being parsed
enum State {
    /// Deserializing the address pattern.
    Address,
    /// Deserializing the typestring.
    Typestring,
    /// Deserializing the argument data.
    /// Each entry in the Vec is the typecode we parsed earlier
    /// We store this as an iterator to avoid tracking the index of the current arg.
    Arguments(vec::IntoIter<u8>),
}

#[derive(Debug)]
enum Error {
    /// User provided error message (via serde::de::Error::custom)
    Message(String),
    /// Unknown argument type (i.e. not a 'f'=f32, 'i'=i32, etc)
    UnknownType(u8),
    /// Attempt to read more arguments than were in the typestring
    ArgMiscount,
    /// OSC expects all data to be aligned to 4 bytes lengths.
    /// Likely violators of this are strings, especially those at the end of a packet.
    BadPadding,
    /// Error encountered due to std::io::Read
    Io(io::Error),
    /// We store ascii strings as UTF-8.
    /// Technically, this is safe, but if we received non-ascii data, we could have invalid UTF-8
    StrParseError(std::string::FromUtf8Error),
}

/// Alias for a 'Result' with the error type 'serde_osc::de::Error'
type ResultE<T> = Result<T, Error>;

impl Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "serde_osc::de::Error")
    }
}

impl std::error::Error for Error {
    fn description(&self) -> &str {
        match *self {
            Error::Message(ref msg) => msg,
            _ => "Unknown serde_osc::de::Error",
        }
    }
    fn cause(&self) -> Option<&std::error::Error> {
        None
    }
}

impl de::Error for Error {
    fn custom<T: Display>(msg: T) -> Self {
        Error::Message(msg.to_string())
    }
}

impl<R> OscDeserializer<R>
    where R: Read
{
    pub fn new(read: R) -> Self {
        Self {
            read: read,
            state: State::Address,
        }
    }
    /// Strings in OSC are ascii and null-terminated.
    /// Strict specification is 1-4 null terminators, to make them end on a 4-byte boundary.
    fn read_0term_bytes(&mut self) -> ResultE<Vec<u8>> {
        let mut data = Vec::new();
        // Because of the 4-byte required padding, we can process 4 characters at a time
        let mut buf: [u8; 4] = [0, 0, 0, 0];
        while true {
            match self.read.read_exact(&mut buf) {
                Err(err) => return Err(Error::Io(err)),
                Ok(_) => {
                    // Copy the NON-NULL characters to the buffer.
                    let num_zeros = buf.iter().filter(|c| **c == 0).count();
                    if buf[4-num_zeros..4].iter().any(|c| *c != 0) {
                        // We had data after the null terminator.
                        return Err(Error::BadPadding);
                    }
                    data.extend_from_slice(&buf[0..4-num_zeros]);
                },
            }
        }
        Ok(data)
    }
    fn parse_str(&mut self) -> ResultE<String> {
        // Note: although OSC specifies ascii only, we may have data >= 128 in the vector.
        // We can safely assume a UTF-8 encoding, because no byte of any multibyte UTF-8
        // contains a zero; the only zero possible in a UTF-8 string is the ASCII zero.
        // See the UTF-8 table here: https://en.wikipedia.org/wiki/UTF-8#History
        let bytes = self.read_0term_bytes()?;
        String::from_utf8(bytes).map_err(|err| {
            Error::StrParseError(err)
        })
    }
    fn parse_typetag(&mut self) -> ResultE<vec::IntoIter<u8>> {
        // The type tag is a string type, with 4-byte null padding.
        self.read_0term_bytes().map(|bytes| bytes.into_iter())
    }

    fn parse_next(&mut self) -> ResultE<OscArg> {
        let typetag = match self.state {
            State::Address => {
                let address = self.parse_str()?;
                // Successfully parsed the address component; advance to the typestring.
                self.state = State::Typestring;
                return Ok(OscArg::s(address));
            },
            State::Typestring => {
                // parse the type tag
                let mut tags = self.parse_typetag()?;
                let parsed = self.parse_arg(tags.next())?;
                self.state = State::Arguments(tags);
                return Ok(parsed);
            },
            State::Arguments(ref mut tags) => {
                // Because parse_arg borrows self as mut, we need to do this weird
                // thing where we pop the typetag here, and then call parse_arg OUTSIDE
                tags.next()
            },
            _ => panic!("Invalid OscDeserializer state"),
        };
        let parsed = self.parse_arg(typetag)?;
        return Ok(parsed);
    }
    fn parse_arg(&mut self, typecode: Option<u8>) -> ResultE<OscArg> {
        match typecode {
            Some(b'i') => self.parse_i32().map(|i| { OscArg::i(i) }),
            Some(b'f') => self.parse_f32().map(|f| { OscArg::f(f) }),
            Some(b's') => self.parse_str().map(|s| { OscArg::s(s) }),
            Some(b'b') => self.parse_blob().map(|b| { OscArg::b(b) }),
            Some(c) => Err(Error::UnknownType(c)),
            None => Err(Error::ArgMiscount),
        }
    }
    fn parse_i32(&mut self) -> ResultE<i32> {
        self.read.read_i32::<BigEndian>().map_err(|err| {
            Error::Io(err)
        })
    }
    fn parse_f32(&mut self) -> ResultE<f32> {
        self.read.read_f32::<BigEndian>().map_err(|err| {
            Error::Io(err)
        })
    }
    fn parse_blob(&mut self) -> ResultE<Vec<u8>> {
        unimplemented!()
    }
}

impl<'a, R> de::Deserializer for &'a mut OscDeserializer<R>
    where R: Read
{
    type Error = Error;
    fn deserialize<V>(self, visitor: V) -> ResultE<V::Value>
    where
        V: Visitor
    {
        let value = self.parse_next()?;
        match value {
            _ => unimplemented!()
        }
    }
    fn deserialize_bool<V>(self, visitor: V) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_u8<V>(self, visitor: V) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_u16<V>(self, visitor: V) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_u32<V>(self, visitor: V) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_u64<V>(self, visitor: V) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_i8<V>(self, visitor: V) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_i16<V>(self, visitor: V) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_i32<V>(self, visitor: V) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_i64<V>(self, visitor: V) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_f32<V>(self, visitor: V) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_f64<V>(self, visitor: V) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_char<V>(self, visitor: V) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_str<V>(self, visitor: V) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_string<V>(self, visitor: V) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_bytes<V>(self, visitor: V) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_byte_buf<V>(
        self,
        visitor: V
    ) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_option<V>(self, visitor: V) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_unit<V>(self, visitor: V) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_unit_struct<V>(
        self,
        name: &'static str,
        visitor: V
    ) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_newtype_struct<V>(
        self,
        name: &'static str,
        visitor: V
    ) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_seq<V>(self, visitor: V) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_seq_fixed_size<V>(
        self,
        len: usize,
        visitor: V
    ) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_tuple<V>(
        self,
        len: usize,
        visitor: V
    ) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_tuple_struct<V>(
        self,
        name: &'static str,
        len: usize,
        visitor: V
    ) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_map<V>(self, visitor: V) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_struct<V>(
        self,
        name: &'static str,
        fields: &'static [&'static str],
        visitor: V
    ) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_struct_field<V>(
        self,
        visitor: V
    ) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_enum<V>(
        self,
        name: &'static str,
        variants: &'static [&'static str],
        visitor: V
    ) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_ignored_any<V>(
        self,
        visitor: V
    ) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
}
<commit_msg>Implement OscDeserializer::deserialize<commit_after>/// Deserialization

use byteorder::{BigEndian, ReadBytesExt};

use std;
use std::fmt;
use std::fmt::Display;
use std::io;
use std::io::Read;
use std::vec;
use serde::de;
use serde::de::Visitor;

enum OscArg {
    /// 32-bit signed integer
    i(i32),
    /// 32-bit float
    f(f32),
    /// String; specified as null-terminated ascii.
    /// This might also represent the message address pattern (aka path)
    s(String),
    /// 'blob' (binary) data
    b(Vec<u8>),
}

struct OscDeserializer<R> {
    read: R,
    state: State,
}

/// Which part of the OSC message is being parsed
enum State {
    /// Deserializing the address pattern.
    Address,
    /// Deserializing the typestring.
    Typestring,
    /// Deserializing the argument data.
    /// Each entry in the Vec is the typecode we parsed earlier
    /// We store this as an iterator to avoid tracking the index of the current arg.
    Arguments(vec::IntoIter<u8>),
}

#[derive(Debug)]
enum Error {
    /// User provided error message (via serde::de::Error::custom)
    Message(String),
    /// Unknown argument type (i.e. not a 'f'=f32, 'i'=i32, etc)
    UnknownType(u8),
    /// Attempt to read more arguments than were in the typestring
    ArgMiscount,
    /// OSC expects all data to be aligned to 4 bytes lengths.
    /// Likely violators of this are strings, especially those at the end of a packet.
    BadPadding,
    /// Error encountered due to std::io::Read
    Io(io::Error),
    /// We store ascii strings as UTF-8.
    /// Technically, this is safe, but if we received non-ascii data, we could have invalid UTF-8
    StrParseError(std::string::FromUtf8Error),
}

/// Alias for a 'Result' with the error type 'serde_osc::de::Error'
type ResultE<T> = Result<T, Error>;

impl Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "serde_osc::de::Error")
    }
}

impl std::error::Error for Error {
    fn description(&self) -> &str {
        match *self {
            Error::Message(ref msg) => msg,
            _ => "Unknown serde_osc::de::Error",
        }
    }
    fn cause(&self) -> Option<&std::error::Error> {
        None
    }
}

impl de::Error for Error {
    fn custom<T: Display>(msg: T) -> Self {
        Error::Message(msg.to_string())
    }
}

impl<R> OscDeserializer<R>
    where R: Read
{
    pub fn new(read: R) -> Self {
        Self {
            read: read,
            state: State::Address,
        }
    }
    /// Strings in OSC are ascii and null-terminated.
    /// Strict specification is 1-4 null terminators, to make them end on a 4-byte boundary.
    fn read_0term_bytes(&mut self) -> ResultE<Vec<u8>> {
        let mut data = Vec::new();
        // Because of the 4-byte required padding, we can process 4 characters at a time
        let mut buf: [u8; 4] = [0, 0, 0, 0];
        while true {
            match self.read.read_exact(&mut buf) {
                Err(err) => return Err(Error::Io(err)),
                Ok(_) => {
                    // Copy the NON-NULL characters to the buffer.
                    let num_zeros = buf.iter().filter(|c| **c == 0).count();
                    if buf[4-num_zeros..4].iter().any(|c| *c != 0) {
                        // We had data after the null terminator.
                        return Err(Error::BadPadding);
                    }
                    data.extend_from_slice(&buf[0..4-num_zeros]);
                },
            }
        }
        Ok(data)
    }
    fn parse_str(&mut self) -> ResultE<String> {
        // Note: although OSC specifies ascii only, we may have data >= 128 in the vector.
        // We can safely assume a UTF-8 encoding, because no byte of any multibyte UTF-8
        // contains a zero; the only zero possible in a UTF-8 string is the ASCII zero.
        // See the UTF-8 table here: https://en.wikipedia.org/wiki/UTF-8#History
        let bytes = self.read_0term_bytes()?;
        String::from_utf8(bytes).map_err(|err| {
            Error::StrParseError(err)
        })
    }
    fn parse_typetag(&mut self) -> ResultE<vec::IntoIter<u8>> {
        // The type tag is a string type, with 4-byte null padding.
        self.read_0term_bytes().map(|bytes| bytes.into_iter())
    }

    fn parse_next(&mut self) -> ResultE<OscArg> {
        let typetag = match self.state {
            State::Address => {
                let address = self.parse_str()?;
                // Successfully parsed the address component; advance to the typestring.
                self.state = State::Typestring;
                return Ok(OscArg::s(address));
            },
            State::Typestring => {
                // parse the type tag
                let mut tags = self.parse_typetag()?;
                let parsed = self.parse_arg(tags.next())?;
                self.state = State::Arguments(tags);
                return Ok(parsed);
            },
            State::Arguments(ref mut tags) => {
                // Because parse_arg borrows self as mut, we need to do this weird
                // thing where we pop the typetag here, and then call parse_arg OUTSIDE
                tags.next()
            },
        };
        let parsed = self.parse_arg(typetag)?;
        return Ok(parsed);
    }
    fn parse_arg(&mut self, typecode: Option<u8>) -> ResultE<OscArg> {
        match typecode {
            Some(b'i') => self.parse_i32().map(|i| { OscArg::i(i) }),
            Some(b'f') => self.parse_f32().map(|f| { OscArg::f(f) }),
            Some(b's') => self.parse_str().map(|s| { OscArg::s(s) }),
            Some(b'b') => self.parse_blob().map(|b| { OscArg::b(b) }),
            Some(c) => Err(Error::UnknownType(c)),
            None => Err(Error::ArgMiscount),
        }
    }
    fn parse_i32(&mut self) -> ResultE<i32> {
        self.read.read_i32::<BigEndian>().map_err(|err| {
            Error::Io(err)
        })
    }
    fn parse_f32(&mut self) -> ResultE<f32> {
        self.read.read_f32::<BigEndian>().map_err(|err| {
            Error::Io(err)
        })
    }
    fn parse_blob(&mut self) -> ResultE<Vec<u8>> {
        unimplemented!()
    }
}

impl<'a, R> de::Deserializer for &'a mut OscDeserializer<R>
    where R: Read
{
    type Error = Error;
    fn deserialize<V>(self, visitor: V) -> ResultE<V::Value>
    where
        V: Visitor
    {
        let value = self.parse_next()?;
        match value {
            OscArg::i(i) => visitor.visit_i32(i),
            OscArg::f(f) => visitor.visit_f32(f),
            OscArg::s(s) => visitor.visit_string(s),
            OscArg::b(b) => unimplemented!(),
        }
    }
    fn deserialize_bool<V>(self, visitor: V) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_u8<V>(self, visitor: V) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_u16<V>(self, visitor: V) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_u32<V>(self, visitor: V) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_u64<V>(self, visitor: V) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_i8<V>(self, visitor: V) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_i16<V>(self, visitor: V) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_i32<V>(self, visitor: V) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_i64<V>(self, visitor: V) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_f32<V>(self, visitor: V) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_f64<V>(self, visitor: V) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_char<V>(self, visitor: V) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_str<V>(self, visitor: V) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_string<V>(self, visitor: V) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_bytes<V>(self, visitor: V) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_byte_buf<V>(
        self,
        visitor: V
    ) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_option<V>(self, visitor: V) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_unit<V>(self, visitor: V) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_unit_struct<V>(
        self,
        name: &'static str,
        visitor: V
    ) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_newtype_struct<V>(
        self,
        name: &'static str,
        visitor: V
    ) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_seq<V>(self, visitor: V) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_seq_fixed_size<V>(
        self,
        len: usize,
        visitor: V
    ) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_tuple<V>(
        self,
        len: usize,
        visitor: V
    ) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_tuple_struct<V>(
        self,
        name: &'static str,
        len: usize,
        visitor: V
    ) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_map<V>(self, visitor: V) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_struct<V>(
        self,
        name: &'static str,
        fields: &'static [&'static str],
        visitor: V
    ) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_struct_field<V>(
        self,
        visitor: V
    ) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_enum<V>(
        self,
        name: &'static str,
        variants: &'static [&'static str],
        visitor: V
    ) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
    fn deserialize_ignored_any<V>(
        self,
        visitor: V
    ) -> ResultE<V::Value>
    where
        V: Visitor { unimplemented!() }
}
<|endoftext|>


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

//! The context within which CSS code is parsed.

#![deny(missing_docs)]

use cssparser::{Parser, SourcePosition, UnicodeRange};
use error_reporting::ParseErrorReporter;
use style_traits::OneOrMoreCommaSeparated;
use stylesheets::{Origin, UrlExtraData};

/// The data that the parser needs from outside in order to parse a stylesheet.
pub struct ParserContext<'a> {
    /// The `Origin` of the stylesheet, whether it's a user, author or
    /// user-agent stylesheet.
    pub stylesheet_origin: Origin,
    /// The extra data we need for resolving url values.
    pub url_data: &'a UrlExtraData,
    /// An error reporter to report syntax errors.
    pub error_reporter: &'a ParseErrorReporter,
}

impl<'a> ParserContext<'a> {
    /// Create a parser context.
    pub fn new(stylesheet_origin: Origin,
               url_data: &'a UrlExtraData,
               error_reporter: &'a ParseErrorReporter)
               -> ParserContext<'a> {
        ParserContext {
            stylesheet_origin: stylesheet_origin,
            url_data: url_data,
            error_reporter: error_reporter,
        }
    }

    /// Create a parser context for on-the-fly parsing in CSSOM
    pub fn new_for_cssom(url_data: &'a UrlExtraData,
                         error_reporter: &'a ParseErrorReporter)
                         -> ParserContext<'a> {
        Self::new(Origin::User, url_data, error_reporter)
    }
}

/// Defaults to a no-op.
/// Set a `RUST_LOG=style::errors` environment variable
/// to log CSS parse errors to stderr.
pub fn log_css_error(input: &mut Parser,
                     position: SourcePosition,
                     message: &str,
                     parsercontext: &ParserContext) {
    let url_data = parsercontext.url_data;
    parsercontext.error_reporter.report_error(input, position, message, url_data);
}

// XXXManishearth Replace all specified value parse impls with impls of this
// trait. This will make it easy to write more generic values in the future.
/// A trait to abstract parsing of a specified value given a `ParserContext` and
/// CSS input.
pub trait Parse : Sized {
    /// Parse a value of this type.
    ///
    /// Returns an error on failure.
    fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()>;
}

impl<T> Parse for Vec<T> where T: Parse + OneOrMoreCommaSeparated {
    fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
        input.parse_comma_separated(|input| T::parse(context, input))
    }
}

/// Parse a non-empty space-separated or comma-separated list of objects parsed by parse_one
pub fn parse_space_or_comma_separated<F, T>(input: &mut Parser, mut parse_one: F)
        -> Result<Vec<T>, ()>
        where F: FnMut(&mut Parser) -> Result<T, ()> {
    let first = parse_one(input)?;
    let mut vec = vec![first];
    loop {
        let _ = input.try(|i| i.expect_comma());
        if let Ok(val) = input.try(|i| parse_one(i)) {
            vec.push(val)
        } else {
            break
        }
    }
    Ok(vec)
}
impl Parse for UnicodeRange {
    fn parse(_context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
        UnicodeRange::parse(input)
    }
}
<commit_msg>ParserContext::new_for_cssom is used for author origin, not user.<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/. */

//! The context within which CSS code is parsed.

#![deny(missing_docs)]

use cssparser::{Parser, SourcePosition, UnicodeRange};
use error_reporting::ParseErrorReporter;
use style_traits::OneOrMoreCommaSeparated;
use stylesheets::{Origin, UrlExtraData};

/// The data that the parser needs from outside in order to parse a stylesheet.
pub struct ParserContext<'a> {
    /// The `Origin` of the stylesheet, whether it's a user, author or
    /// user-agent stylesheet.
    pub stylesheet_origin: Origin,
    /// The extra data we need for resolving url values.
    pub url_data: &'a UrlExtraData,
    /// An error reporter to report syntax errors.
    pub error_reporter: &'a ParseErrorReporter,
}

impl<'a> ParserContext<'a> {
    /// Create a parser context.
    pub fn new(stylesheet_origin: Origin,
               url_data: &'a UrlExtraData,
               error_reporter: &'a ParseErrorReporter)
               -> ParserContext<'a> {
        ParserContext {
            stylesheet_origin: stylesheet_origin,
            url_data: url_data,
            error_reporter: error_reporter,
        }
    }

    /// Create a parser context for on-the-fly parsing in CSSOM
    pub fn new_for_cssom(url_data: &'a UrlExtraData,
                         error_reporter: &'a ParseErrorReporter)
                         -> ParserContext<'a> {
        Self::new(Origin::Author, url_data, error_reporter)
    }
}

/// Defaults to a no-op.
/// Set a `RUST_LOG=style::errors` environment variable
/// to log CSS parse errors to stderr.
pub fn log_css_error(input: &mut Parser,
                     position: SourcePosition,
                     message: &str,
                     parsercontext: &ParserContext) {
    let url_data = parsercontext.url_data;
    parsercontext.error_reporter.report_error(input, position, message, url_data);
}

// XXXManishearth Replace all specified value parse impls with impls of this
// trait. This will make it easy to write more generic values in the future.
/// A trait to abstract parsing of a specified value given a `ParserContext` and
/// CSS input.
pub trait Parse : Sized {
    /// Parse a value of this type.
    ///
    /// Returns an error on failure.
    fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()>;
}

impl<T> Parse for Vec<T> where T: Parse + OneOrMoreCommaSeparated {
    fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
        input.parse_comma_separated(|input| T::parse(context, input))
    }
}

/// Parse a non-empty space-separated or comma-separated list of objects parsed by parse_one
pub fn parse_space_or_comma_separated<F, T>(input: &mut Parser, mut parse_one: F)
        -> Result<Vec<T>, ()>
        where F: FnMut(&mut Parser) -> Result<T, ()> {
    let first = parse_one(input)?;
    let mut vec = vec![first];
    loop {
        let _ = input.try(|i| i.expect_comma());
        if let Ok(val) = input.try(|i| parse_one(i)) {
            vec.push(val)
        } else {
            break
        }
    }
    Ok(vec)
}
impl Parse for UnicodeRange {
    fn parse(_context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
        UnicodeRange::parse(input)
    }
}
<|endoftext|>


<commit_before>//! Methods to construct flow-controlled sources.

use ::Data;
use order::{PartialOrder, TotalOrder};
use dataflow::operators::generic::operator::source;
use dataflow::operators::probe::Handle;
use dataflow::{Stream, Scope};

/// Output of the input reading function for iterator_source.
pub struct IteratorSourceInput<T: Clone, D: Data, DI: IntoIterator<Item=D>, I: IntoIterator<Item=(T, DI)>> {
    /// Lower bound on timestamps that can be emitted by this input in the future.
    pub lower_bound: T,
    /// Any `T: IntoIterator` of new input data in the form (time, data): time must be
    /// monotonically increasing.
    pub data: I,
    /// A timestamp that represents the frontier that the probe should have
    /// reached before the function is invoked again to ingest additional input.
    pub target: T,
}

/// Construct a source that repeatedly calls the provided function to ingest input.
/// - The function can return None to signal the end of the input;
/// - otherwise, it should return a `IteratorSourceInput`, where:
///   * `lower_bound` is a lower bound on timestamps that can be emitted by this input in the future,
///   `Default::default()` can be used if this isn't needed (the source will assume that
///   the timestamps in `data` are monotonically increasing and will release capabilities
///   accordingly);
///   * `data` is any `T: IntoIterator` of new input data in the form (time, data): time must be
///   monotonically increasing;
///   * `target` is a timestamp that represents the frontier that the probe should have
///   reached before the function is invoked again to ingest additional input.
/// The function will receive the current lower bound of timestamps that can be inserted,
/// `lower_bound`.
///
/// # Example
/// ```rust
/// extern crate timely;
///
/// use timely::dataflow::operators::flow_controlled::{iterator_source, IteratorSourceInput};
/// use timely::dataflow::operators::{probe, Probe, Inspect};
///
/// use timely::progress::timestamp::RootTimestamp;
///
/// fn main() {
///     timely::execute_from_args(std::env::args(), |worker| {
///         let mut input = (0u64..100000).peekable();
///         worker.dataflow(|scope| {
///             let mut probe_handle = probe::Handle::new();
///             let probe_handle_2 = probe_handle.clone();
///
///             let mut next_t: u64 = 0;
///             iterator_source(
///                 scope,
///                 "Source",
///                 move |prev_t| {
///                     if let Some(first_x) = input.peek().cloned() {
///                         next_t = first_x / 100 * 100;
///                         Some(IteratorSourceInput {
///                             lower_bound: Default::default(),
///                             data: vec![
///                                 (RootTimestamp::new(next_t),
///                                  input.by_ref().take(10).map(|x| (/* "timestamp" */ x, x)).collect::<Vec<_>>())],
///                             target: *prev_t,
///                         })
///                     } else {
///                         None
///                     }
///                 },
///                 probe_handle_2)
///             .inspect_time(|t, d| eprintln!("@ {:?}: {:?}", t, d))
///             .probe_with(&mut probe_handle);
///         });
///     }).unwrap();
/// }
/// ```
pub fn iterator_source<
    G: Scope,
    D: Data,
    DI: IntoIterator<Item=D>,
    I: IntoIterator<Item=(G::Timestamp, DI)>,
    F: FnMut(&G::Timestamp)->Option<IteratorSourceInput<G::Timestamp, D, DI, I>>+'static>(
        scope: &G,
        name: &str,
        mut input_f: F,
        probe: Handle<G::Timestamp>,
        ) -> Stream<G, D> where G::Timestamp: TotalOrder {

    let mut target = Default::default();
    source(scope, name, |cap| {
        let mut cap = Some(cap);
        move |output| {
            cap = cap.take().and_then(|mut cap| {
                if !probe.less_than(&target) {
                    loop {
                        if let Some(IteratorSourceInput {
                             lower_bound,
                             data,
                             target: new_target,
                         }) = input_f(cap.time()) {
                            target = new_target;
                            let mut has_data = false;
                            for (t, ds) in data.into_iter() {
                                cap = if cap.time() != &t { cap.delayed(&t) } else { cap };
                                let mut session = output.session(&cap);
                                session.give_iterator(ds.into_iter());
                                has_data = true;
                            }

                            cap = if cap.time().less_than(&lower_bound) { cap.delayed(&lower_bound) } else { cap };
                            if !has_data {
                                break Some(cap);
                            }
                        } else {
                            break None;
                        }
                    }
                } else {
                    Some(cap)
                }
            });
        }
    })
}
<commit_msg>Oops<commit_after>//! Methods to construct flow-controlled sources.

use ::Data;
use order::{PartialOrder, TotalOrder};
use dataflow::operators::generic::operator::source;
use dataflow::operators::probe::Handle;
use dataflow::{Stream, Scope};

/// Output of the input reading function for iterator_source.
pub struct IteratorSourceInput<T: Clone, D: Data, DI: IntoIterator<Item=D>, I: IntoIterator<Item=(T, DI)>> {
    /// Lower bound on timestamps that can be emitted by this input in the future.
    pub lower_bound: T,
    /// Any `T: IntoIterator` of new input data in the form (time, data): time must be
    /// monotonically increasing.
    pub data: I,
    /// A timestamp that represents the frontier that the probe should have
    /// reached before the function is invoked again to ingest additional input.
    pub target: T,
}

/// Construct a source that repeatedly calls the provided function to ingest input.
/// - The function can return None to signal the end of the input;
/// - otherwise, it should return a `IteratorSourceInput`, where:
///   * `lower_bound` is a lower bound on timestamps that can be emitted by this input in the future,
///   `Default::default()` can be used if this isn't needed (the source will assume that
///   the timestamps in `data` are monotonically increasing and will release capabilities
///   accordingly);
///   * `data` is any `T: IntoIterator` of new input data in the form (time, data): time must be
///   monotonically increasing;
///   * `target` is a timestamp that represents the frontier that the probe should have
///   reached before the function is invoked again to ingest additional input.
/// The function will receive the current lower bound of timestamps that can be inserted,
/// `lower_bound`.
///
/// # Example
/// ```rust
/// extern crate timely;
///
/// use timely::dataflow::operators::flow_controlled::{iterator_source, IteratorSourceInput};
/// use timely::dataflow::operators::{probe, Probe, Inspect};
///
/// use timely::progress::timestamp::RootTimestamp;
///
/// fn main() {
///     timely::execute_from_args(std::env::args(), |worker| {
///         let mut input = (0u64..100000).peekable();
///         worker.dataflow(|scope| {
///             let mut probe_handle = probe::Handle::new();
///             let probe_handle_2 = probe_handle.clone();
///
///             let mut next_t: u64 = 0;
///             iterator_source(
///                 scope,
///                 "Source",
///                 move |prev_t| {
///                     if let Some(first_x) = input.peek().cloned() {
///                         next_t = first_x / 100 * 100;
///                         Some(IteratorSourceInput {
///                             lower_bound: Default::default(),
///                             data: vec![
///                                 (RootTimestamp::new(next_t),
///                                  input.by_ref().take(10).map(|x| (/* "timestamp" */ x, x)).collect::<Vec<_>>())],
///                             target: *prev_t,
///                         })
///                     } else {
///                         None
///                     }
///                 },
///                 probe_handle_2)
///             .inspect_time(|t, d| eprintln!("@ {:?}: {:?}", t, d))
///             .probe_with(&mut probe_handle);
///         });
///     }).unwrap();
/// }
/// ```
pub fn iterator_source<
    G: Scope,
    D: Data,
    DI: IntoIterator<Item=D>,
    I: IntoIterator<Item=(G::Timestamp, DI)>,
    F: FnMut(&G::Timestamp)->Option<IteratorSourceInput<G::Timestamp, D, DI, I>>+'static>(
        scope: &G,
        name: &str,
        mut input_f: F,
        probe: Handle<G::Timestamp>,
        ) -> Stream<G, D> where G::Timestamp: TotalOrder {

    let mut target = Default::default();
    source(scope, name, |cap| {
        let mut cap = Some(cap);
        move |output| {
            cap = cap.take().and_then(|mut cap| {
                loop {
                    if !probe.less_than(&target) {
                        if let Some(IteratorSourceInput {
                             lower_bound,
                             data,
                             target: new_target,
                         }) = input_f(cap.time()) {
                            target = new_target;
                            let mut has_data = false;
                            for (t, ds) in data.into_iter() {
                                cap = if cap.time() != &t { cap.delayed(&t) } else { cap };
                                let mut session = output.session(&cap);
                                session.give_iterator(ds.into_iter());
                                has_data = true;
                            }

                            cap = if cap.time().less_than(&lower_bound) { cap.delayed(&lower_bound) } else { cap };
                            if !has_data {
                                break Some(cap);
                            }
                        } else {
                            break None;
                        }
                    } else {
                        break Some(cap);
                    }
                }
            });
        }
    })
}
<|endoftext|>


<commit_before>

// intellij-rust flags this anyway
// #![feature(field_init_shorthand)]

#![allow(unused_features)]
#![allow(unused_imports)]
#![allow(dead_code)]
#![allow(unused_variables)]

extern crate petgraph;
extern crate daggy;
extern crate imageflow_types;
extern crate imageflow_c_components;
extern crate imageflow_helpers;
extern crate imageflow_riapi;
extern crate num;

#[macro_use]
extern crate lazy_static;

#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate lcms2;
extern crate libc;
extern crate rustc_serialize;
extern crate uuid;
extern crate imagequant;
extern crate gif;
extern crate smallvec;
extern crate chashmap;
extern crate rgb;
extern crate imgref;
extern crate lodepng;
extern crate mozjpeg;
extern crate mozjpeg_sys;
extern crate evalchroma;
extern crate twox_hash;
extern crate libwebp_sys;

#[macro_use]
pub mod errors;
pub use crate::errors::*;

mod json;
mod flow;
mod context_methods;
mod context;
mod codecs;
mod io;
pub mod graphics;
pub mod imaging;

pub use crate::context::{Context};
pub use crate::io::IoProxy;
pub use crate::ffi::{IoDirection};
pub use crate::flow::definitions::Graph;
pub use crate::json::JsonResponse;
pub use crate::json::MethodRouter;
pub use crate::codecs::NamedDecoders;
// use std::ops::DerefMut;
pub mod clients;
pub mod ffi;
pub mod parsing;
pub mod test_helpers;
use std::fmt;
use std::borrow::Cow;
use petgraph::graph::NodeIndex;

#[doc(hidden)]
mod internal_prelude {
    #[doc(hidden)]
    pub mod external_without_std {
        pub extern crate imageflow_helpers;

        pub use imageflow_helpers::preludes::from_std::*;
        pub use daggy::{Dag, EdgeIndex, NodeIndex};
        pub use libc::{c_void, c_float, size_t};
        pub extern crate daggy;
        pub extern crate petgraph;
        pub extern crate serde;
        pub extern crate serde_json;
        pub extern crate time;
        pub extern crate libc;
        pub extern crate imageflow_types as s;

    }
    #[doc(hidden)]
    pub mod imageflow_core_all {
        #[doc(no_inline)]
        pub use crate::{Graph, Context, JsonResponse,
                   MethodRouter};
        #[doc(no_inline)]
        pub use crate::{CError, clients, FlowError, Result, ErrorKind};
        #[doc(no_inline)]
        pub use crate::clients::fluent;
    }
    #[doc(hidden)]
    pub mod external {
        #[doc(no_inline)]
        pub use crate::internal_prelude::external_without_std::*;
        pub extern crate std;
    }
    #[doc(hidden)]
    pub mod works_everywhere {
        #[doc(no_inline)]
        pub use crate::{CError, clients, FlowError, Result, ErrorKind};
        #[doc(no_inline)]
        pub use crate::internal_prelude::external::*;
    }
    #[doc(hidden)]
    pub mod default {
        #[doc(no_inline)]
        pub use crate::{Graph, Context, JsonResponse,
                   MethodRouter};
        #[doc(no_inline)]
        pub use crate::internal_prelude::works_everywhere::*;
    }
    #[doc(hidden)]
    pub mod c_components {}
}
#[doc(hidden)]
pub mod for_other_imageflow_crates {
    #[doc(hidden)]
    pub mod preludes {
        #[doc(hidden)]
        pub mod external_without_std {
            #[doc(no_inline)]
            pub use crate::internal_prelude::external_without_std::*;
        }
        #[doc(hidden)]
        pub mod default {
            #[doc(no_inline)]
            pub use crate::internal_prelude::external_without_std::*;
            #[doc(no_inline)]
            pub use crate::internal_prelude::imageflow_core_all::*;
        }
    }
}
<commit_msg>Remove imaging module<commit_after>

// intellij-rust flags this anyway
// #![feature(field_init_shorthand)]

#![allow(unused_features)]
#![allow(unused_imports)]
#![allow(dead_code)]
#![allow(unused_variables)]

extern crate petgraph;
extern crate daggy;
extern crate imageflow_types;
extern crate imageflow_c_components;
extern crate imageflow_helpers;
extern crate imageflow_riapi;
extern crate num;

#[macro_use]
extern crate lazy_static;

#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate lcms2;
extern crate libc;
extern crate rustc_serialize;
extern crate uuid;
extern crate imagequant;
extern crate gif;
extern crate smallvec;
extern crate chashmap;
extern crate rgb;
extern crate imgref;
extern crate lodepng;
extern crate mozjpeg;
extern crate mozjpeg_sys;
extern crate evalchroma;
extern crate twox_hash;
extern crate libwebp_sys;

#[macro_use]
pub mod errors;
pub use crate::errors::*;

mod json;
mod flow;
mod context_methods;
mod context;
mod codecs;
mod io;
pub mod graphics;

pub use crate::context::{Context};
pub use crate::io::IoProxy;
pub use crate::ffi::{IoDirection};
pub use crate::flow::definitions::Graph;
pub use crate::json::JsonResponse;
pub use crate::json::MethodRouter;
pub use crate::codecs::NamedDecoders;
// use std::ops::DerefMut;
pub mod clients;
pub mod ffi;
pub mod parsing;
pub mod test_helpers;
use std::fmt;
use std::borrow::Cow;
use petgraph::graph::NodeIndex;

#[doc(hidden)]
mod internal_prelude {
    #[doc(hidden)]
    pub mod external_without_std {
        pub extern crate imageflow_helpers;

        pub use imageflow_helpers::preludes::from_std::*;
        pub use daggy::{Dag, EdgeIndex, NodeIndex};
        pub use libc::{c_void, c_float, size_t};
        pub extern crate daggy;
        pub extern crate petgraph;
        pub extern crate serde;
        pub extern crate serde_json;
        pub extern crate time;
        pub extern crate libc;
        pub extern crate imageflow_types as s;

    }
    #[doc(hidden)]
    pub mod imageflow_core_all {
        #[doc(no_inline)]
        pub use crate::{Graph, Context, JsonResponse,
                   MethodRouter};
        #[doc(no_inline)]
        pub use crate::{CError, clients, FlowError, Result, ErrorKind};
        #[doc(no_inline)]
        pub use crate::clients::fluent;
    }
    #[doc(hidden)]
    pub mod external {
        #[doc(no_inline)]
        pub use crate::internal_prelude::external_without_std::*;
        pub extern crate std;
    }
    #[doc(hidden)]
    pub mod works_everywhere {
        #[doc(no_inline)]
        pub use crate::{CError, clients, FlowError, Result, ErrorKind};
        #[doc(no_inline)]
        pub use crate::internal_prelude::external::*;
    }
    #[doc(hidden)]
    pub mod default {
        #[doc(no_inline)]
        pub use crate::{Graph, Context, JsonResponse,
                   MethodRouter};
        #[doc(no_inline)]
        pub use crate::internal_prelude::works_everywhere::*;
    }
    #[doc(hidden)]
    pub mod c_components {}
}
#[doc(hidden)]
pub mod for_other_imageflow_crates {
    #[doc(hidden)]
    pub mod preludes {
        #[doc(hidden)]
        pub mod external_without_std {
            #[doc(no_inline)]
            pub use crate::internal_prelude::external_without_std::*;
        }
        #[doc(hidden)]
        pub mod default {
            #[doc(no_inline)]
            pub use crate::internal_prelude::external_without_std::*;
            #[doc(no_inline)]
            pub use crate::internal_prelude::imageflow_core_all::*;
        }
    }
}
<|endoftext|>


<commit_before>extern crate rand;

use std::io;
use std::cmp::Ordering;
use rand::Rng;

fn main() {
    println!("Hello in my guessing game!");

    let secret_number = rand::thread_rng().gen_range(1, 101);

    println!("The secret number is: {}", secret_number);
    loop {
        println!("Input your guess, please:");

        let mut guess = String::new();

        io::stdin().read_line(&mut guess)
            .expect("Failed to read line!");

        let guess: u32 = guess.trim().parse()
            .expect("It's not a valid number :(");

        println!("Your guess is: {}", guess);

        match guess.cmp(&secret_number) {
            Ordering::Less => println!("Too low!"),
            Ordering::Greater => println!("Too big!"),
            Ordering::Equal => println!("Great guess! You win!")
        }
    }
}
<commit_msg>Finish program after correct guess<commit_after>extern crate rand;

use std::io;
use std::cmp::Ordering;
use rand::Rng;

fn main() {
    println!("Hello in my guessing game!");

    let secret_number = rand::thread_rng().gen_range(1, 101);

    println!("The secret number is: {}", secret_number);
    loop {
        println!("Input your guess, please:");

        let mut guess = String::new();

        io::stdin().read_line(&mut guess)
            .expect("Failed to read line!");

        let guess: u32 = guess.trim().parse()
            .expect("It's not a valid number :(");

        println!("Your guess is: {}", guess);

        match guess.cmp(&secret_number) {
            Ordering::Less => println!("Too low!"),
            Ordering::Greater => println!("Too big!"),
            Ordering::Equal => {
                println!("Great guess! You win!");
                break;
            }
        }
    }
}
<|endoftext|>