<commit_before>#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Debug)]
pub enum Chain<A,B> {
    Args(A),
    Ret(B),
}

impl <A,B> Chain<A,B> {
    pub fn map<F: FnOnce(A) -> Chain<A,B>>(self, f: F) -> Chain<A, B> {
        match self {
            Chain::Args(a) => f(a),
            Chain::Ret(b) => Chain::Ret(b),
        }
    }

    pub fn is_done(self) -> bool {
        match self {
            Chain::Args(_) => false,
            Chain::Ret(_) => true,
        }
    }

    pub fn unwrap(self) -> B {
        match self {
            Chain::Args(_) => panic!("Called unwrap on Chain::Args."),
            Chain::Ret(b) => b,
        }
    }

    pub fn unwrap_or<F: FnOnce(A) -> B>(self, f: F) -> B {
        match self {
            Chain::Args(a) => f(a),
            Chain::Ret(b) => b,
        }
    }

    pub fn unwrap_or_else(self, b: B) -> B {
        match self {
            Chain::Args(_) => b,
            Chain::Ret(d) => d,
        }
    }
}

#[test]
fn test_chain() {
    assert!(Chain::Args("yo").map( |_| {
        Chain::Args("hey")
    }).map( |_| {
        Chain::Ret("the deed is done")
    }).map( |_| {
        Chain::Ret("wha??")
    }).unwrap() == "the deed is done");

    assert!(Chain::Args("yo").map( |_| {
        Chain::Args("hey")
    }).unwrap_or( |_| {
        "use this instead"
    }) == "use this instead");

    assert!(Chain::Args("yo").map( |_| {
        Chain::Args("hey")
    }).unwrap_or_else(
        "use this instead"
    ) == "use this instead");
}
<commit_msg>unfinished filter_map checkpoint<commit_after>#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Debug)]
pub enum Chain<A,B> {
    Args(A),
    Ret(B),
}

impl <A,B> Chain<A,B> {
    pub fn map<F: FnOnce(A) -> Chain<A,B>>(self, f: F) -> Chain<A, B> {
        match self {
            Chain::Args(a) => f(a),
            Chain::Ret(b) => Chain::Ret(b),
        }
    }

    /*
    pub fn filter_map<F: FnOnce(&A) -> bool, G: FnOnce(A) -> Chain<A,B>>
        (&self, f: F, g: G) -> Chain<A, B> {
        match self {
            Chain::Args(a) => match f(&a) {
                true => g(a),
                false => self,
            },
            Chain::Ret(b) => Chain::Ret(b),
        }
    }
    */

    pub fn is_done(self) -> bool {
        match self {
            Chain::Args(_) => false,
            Chain::Ret(_) => true,
        }
    }

    pub fn unwrap(self) -> B {
        match self {
            Chain::Args(_) => panic!("Called unwrap on Chain::Args."),
            Chain::Ret(b) => b,
        }
    }

    pub fn unwrap_or<F: FnOnce(A) -> B>(self, f: F) -> B {
        match self {
            Chain::Args(a) => f(a),
            Chain::Ret(b) => b,
        }
    }

    pub fn unwrap_or_else(self, b: B) -> B {
        match self {
            Chain::Args(_) => b,
            Chain::Ret(d) => d,
        }
    }
}

#[test]
fn test_chain() {
    assert!(Chain::Args("yo").map( |_| {
        Chain::Args("hey")
    }).map( |_| {
        Chain::Ret("the deed is done")
    }).map( |_| {
        Chain::Ret("wha??")
    }).unwrap() == "the deed is done");

    assert!(Chain::Args("yo").map( |_| {
        Chain::Args("hey")
    }).unwrap_or( |_| {
        "use this instead"
    }) == "use this instead");

    assert!(Chain::Args("yo").map( |_| {
        Chain::Args("hey")
    }).unwrap_or_else(
        "use this instead"
    ) == "use this instead");
}
<|endoftext|>


<commit_before>macro_rules! commands {
    ($($cmd:ident),* $(,)*) => {
        $(
            mod $cmd;
            pub use self::$cmd::*;
        )*
    }
}

macro_rules! command {
    ( $(#[$attr:meta])* ) => {
        #[derive(Command)]
        $(#[$attr])*
        struct _DummyCommand;
    }
}

/// Splice an array of arguments into another term
///
/// `args` is a macro that’s used to splice a number of arguments into another term. This is
/// useful when you want to call a variadic term such as [branch](commands/trait.Branch.html) with a set of arguments produced at
/// runtime.
///
/// *Note* that args evaluates all its arguments before passing them into the parent term, even if
/// the parent term otherwise allows lazy evaluation.
///
/// # Example
///
/// Get Alice and Bob from the table `people`.
///
/// ```
/// # #[macro_use] extern crate reql;
/// # use reql::commands::*;
/// # use reql::commands::run::Dummy;
/// # fn main() {
/// # let r = Command::new();
/// let x = 10;
/// r.branch(args!(r.expr(x).gt(5), "big", "small")).run::<String>();
/// # }
/// ```
#[macro_export]
macro_rules! args {
    ( $($arg:tt)* ) => {{
        use $crate::Term;
        use $crate::commands::Command;

        let mut term = Term::new();
        __process_args!(term, $($arg)*);
        let mut cmd = Command::new();
        cmd.set_term(term);
        cmd
    }};
}

#[doc(hidden)]
#[macro_export]
macro_rules! __process_args {
    ( $term:ident, ) => { };

    ( $term:ident,  $(,)* { $($key:ident: $val:tt),* $(,)* } $(,)* ) => {{
        $(
            let key = stringify!($key);
            let mut val = Term::new();
            __process_args!(val, $val);
            let temp_pair = Command::create_term_pair(key, val);
            $term.mut_optargs().push(temp_pair);
         )*
    }};

    ( $term:ident,  $(,)* { $($key:ident: $val:tt),* $(,)* } $($tail:tt)* ) => {{
        let mut arg = Term::new();
        $(
            let key = stringify!($key);
            let mut val = Term::new();
            __process_args!(val, $val);
            let temp_pair = Command::create_term_pair(key, val);
            arg.mut_optargs().push(temp_pair);
         )*
        $term.mut_args().push(arg);
        __process_args!($term, $($tail)*);
    }};

    ( $term:ident,  $(,)* [ $($val:expr),* ] $($tail:tt)* ) => {{
        let mut arg = Term::new();
        $(
            let mut val = Term::new();
            __process_args!(val, $val);
            arg.mut_args().push(val);
        )*
        $term.mut_args().push(arg);
        __process_args!($term, $($tail)*);
    }};

    ( $term:ident,  $(,)* | $($arg:ident),* $(,)* | $body:tt $($tail:tt)* ) => {{
        unimplemented!();
        __process_args!($term, $($tail)*);
    }};

    ( $term:ident,  $(,)* $arg:expr, $($tail:tt)+ ) => {{
        #[allow(unused_imports)]
        use $crate::ToArg;
        $term.mut_args().push($arg.to_arg());
        __process_args!($term, $($tail)+);
    }};

    ( $term:ident,  $(,)* $arg:expr $(,)* ) => {{
        #[allow(unused_imports)]
        use $crate::ToArg;
        $term.mut_args().push($arg.to_arg());
    }};
}
<commit_msg>Fix nested objects<commit_after>macro_rules! commands {
    ($($cmd:ident),* $(,)*) => {
        $(
            mod $cmd;
            pub use self::$cmd::*;
        )*
    }
}

macro_rules! command {
    ( $(#[$attr:meta])* ) => {
        #[derive(Command)]
        $(#[$attr])*
        struct _DummyCommand;
    }
}

/// Splice an array of arguments into another term
///
/// `args` is a macro that’s used to splice a number of arguments into another term. This is
/// useful when you want to call a variadic term such as [branch](commands/trait.Branch.html) with a set of arguments produced at
/// runtime.
///
/// *Note* that args evaluates all its arguments before passing them into the parent term, even if
/// the parent term otherwise allows lazy evaluation.
///
/// # Example
///
/// Get Alice and Bob from the table `people`.
///
/// ```
/// # #[macro_use] extern crate reql;
/// # use reql::commands::*;
/// # use reql::commands::run::Dummy;
/// # fn main() {
/// # let r = Command::new();
/// let x = 10;
/// r.branch(args!(r.expr(x).gt(5), "big", "small")).run::<String>();
/// # }
/// ```
#[macro_export]
macro_rules! args {
    ( $($arg:tt)* ) => {{
        use $crate::Term;
        use $crate::commands::Command;

        let mut term = Term::new();
        __process_args!(term, $($arg)*);
        let mut cmd = Command::new();
        cmd.set_term(term);
        cmd
    }};
}

#[doc(hidden)]
#[macro_export]
macro_rules! __process_args {
    ( $term:ident, ) => { };

    ( $term:ident,  $(,)* { $($key:ident: $val:tt),* $(,)* } $(,)* ) => {{
        $(
            let key = stringify!($key);
            let mut val = Term::new();
            __process_args!(val, $val);
            let temp_pair = Command::create_term_pair(key, val);
            $term.mut_optargs().push(temp_pair);
         )*
    }};

    ( $term:ident,  $(,)* { $($key:ident: $val:tt),* $(,)* } $($tail:tt)* ) => {{
        let mut arg = Term::new();
        $(
            let key = stringify!($key);
            let mut val = Term::new();
            __process_args!(val, $val);
            let temp_pair = Command::create_term_pair(key, val);
            arg.mut_optargs().push(temp_pair);
         )*
        $term.mut_args().push(arg);
        __process_args!($term, $($tail)*);
    }};

    ( $term:ident,  $(,)* [ $($val:tt),* ] $($tail:tt)* ) => {{
        let mut arg = Term::new();
        $(
            let mut val = Term::new();
            __process_args!(val, $val);
            arg.mut_args().push(val);
        )*
        $term.mut_args().push(arg);
        __process_args!($term, $($tail)*);
    }};

    ( $term:ident,  $(,)* | $($arg:ident),* $(,)* | $body:tt $($tail:tt)* ) => {{
        unimplemented!();
        __process_args!($term, $($tail)*);
    }};

    ( $term:ident,  $(,)* $arg:expr, $($tail:tt)+ ) => {{
        #[allow(unused_imports)]
        use $crate::ToArg;
        $term.mut_args().push($arg.to_arg());
        __process_args!($term, $($tail)+);
    }};

    ( $term:ident,  $(,)* $arg:expr $(,)* ) => {{
        #[allow(unused_imports)]
        use $crate::ToArg;
        $term.mut_args().push($arg.to_arg());
    }};
}
<|endoftext|>


<commit_before>const HEAP_START: usize = 0xC0_00_00_00;
const HEAP_END: usize = 0xD0_00_00_00;

use core;
use notex::Notex;
use rlibc;

static HEAP_PTR_NOTEX: Notex<usize> = notex!(HEAP_START);

#[no_mangle]
pub extern fn rust_allocate(size: usize, align: usize) -> *mut u8 {
    let mut heap_ptr = HEAP_PTR_NOTEX.lock();
    let new_heap_ptr  = *heap_ptr & !(align - 1);

    if new_heap_ptr + size >= HEAP_END {
        core::ptr::null_mut()
    }
    else {
        *heap_ptr = new_heap_ptr + size;
        new_heap_ptr as *mut u8
    }
}

#[no_mangle]
pub extern fn rust_reallocate(ptr: *mut u8, old_size: usize, size: usize, align: usize) -> *mut u8 {
    let new_ptr = rust_allocate(size, align);
    if !ptr.is_null() {
        unsafe {
            rlibc::memcpy(new_ptr, ptr, old_size);
        }
    }
    ptr
}

#[allow(unused_variables)]
#[no_mangle]
pub extern fn rust_reallocate_inplace(ptr: *mut u8, old_size: usize, size: usize, align: usize) -> usize {
    old_size
}

#[allow(unused_variables)]
#[no_mangle]
pub extern fn rust_deallocate(ptr: *mut u8, old_size: usize, align: usize) {}

#[allow(unused_variables)]
#[no_mangle]
pub extern fn rust_usable_size(size: usize, align: usize) -> usize {
    size
}

#[no_mangle]
pub extern fn rust_stats_print() {}
<commit_msg>More mutexes<commit_after>const HEAP_START: usize = 0xC0_00_00_00;
const HEAP_END: usize = 0xD0_00_00_00;

use core;
use mutex::Mutex;
use rlibc;

static HEAP_PTR_NOTEX: Mutex<usize> = mutex!(HEAP_START);

#[no_mangle]
pub extern fn rust_allocate(size: usize, align: usize) -> *mut u8 {
    let mut heap_ptr = HEAP_PTR_NOTEX.lock();
    let new_heap_ptr  = *heap_ptr & !(align - 1);

    if new_heap_ptr + size >= HEAP_END {
        core::ptr::null_mut()
    }
    else {
        *heap_ptr = new_heap_ptr + size;
        new_heap_ptr as *mut u8
    }
}

#[no_mangle]
pub extern fn rust_reallocate(ptr: *mut u8, old_size: usize, size: usize, align: usize) -> *mut u8 {
    let new_ptr = rust_allocate(size, align);
    if !ptr.is_null() {
        unsafe {
            rlibc::memcpy(new_ptr, ptr, old_size);
        }
    }
    ptr
}

#[allow(unused_variables)]
#[no_mangle]
pub extern fn rust_reallocate_inplace(ptr: *mut u8, old_size: usize, size: usize, align: usize) -> usize {
    old_size
}

#[allow(unused_variables)]
#[no_mangle]
pub extern fn rust_deallocate(ptr: *mut u8, old_size: usize, align: usize) {}

#[allow(unused_variables)]
#[no_mangle]
pub extern fn rust_usable_size(size: usize, align: usize) -> usize {
    size
}

#[no_mangle]
pub extern fn rust_stats_print() {}
<|endoftext|>


<commit_before>// Copyright 2014 Michael Yang. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

use types::{
    CLPK_integer,
};

pub trait Matrix<T> {
    fn rows(&self) -> CLPK_integer;
    fn cols(&self) -> CLPK_integer;
    fn as_ptr(&self) -> *const T;
    fn as_mut_ptr(&mut self) -> *mut T;
}

#[cfg(test)]
pub mod tests {
    use matrix::Matrix;
    use types::CLPK_integer;

    impl<T> Matrix<T> for (CLPK_integer, CLPK_integer, Vec<T>) {
        fn rows(&self) -> CLPK_integer {
            let &(rows, _, _) = self;
            rows
        }

        fn cols(&self) -> CLPK_integer {
            let &(_, cols, _) = self;
            cols
        }

        fn as_ptr(&self) -> *const T {
            let &(_, _, ref v) = self;
            v.as_slice().as_ptr()
        }

        fn as_mut_ptr(&mut self) -> *mut T {
            let &(_, _, ref mut v) = self;
            v.as_mut_slice().as_mut_ptr()
        }
    }
}
<commit_msg>Add BandMatrix trait<commit_after>// Copyright 2014 Michael Yang. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

use types::{
    CLPK_integer,
};

pub trait Matrix<T> {
    fn rows(&self) -> CLPK_integer;
    fn cols(&self) -> CLPK_integer;
    fn as_ptr(&self) -> *const T;
    fn as_mut_ptr(&mut self) -> *mut T;
}

pub trait BandMatrix<T>: Matrix<T> {
    fn sub_diagonals(&self) -> CLPK_integer;
    fn sup_diagonals(&self) -> CLPK_integer;
}

#[cfg(test)]
pub mod tests {
    use matrix::Matrix;
    use types::CLPK_integer;

    impl<T> Matrix<T> for (CLPK_integer, CLPK_integer, Vec<T>) {
        fn rows(&self) -> CLPK_integer {
            let &(rows, _, _) = self;
            rows
        }

        fn cols(&self) -> CLPK_integer {
            let &(_, cols, _) = self;
            cols
        }

        fn as_ptr(&self) -> *const T {
            let &(_, _, ref v) = self;
            v.as_slice().as_ptr()
        }

        fn as_mut_ptr(&mut self) -> *mut T {
            let &(_, _, ref mut v) = self;
            v.as_mut_slice().as_mut_ptr()
        }
    }
}
<|endoftext|>


<commit_before>use super::vector3::Vector3;
use std::ops;

///Implements a matrix 3 x 3
#[derive(Clone, PartialEq, Debug)]
pub struct Matrix3x3 {
    pub r1: Vector3,
    pub r2: Vector3,
    pub r3: Vector3,
}

impl Matrix3x3 {

    ///Creates a new Matrix3x3 from 3 vector3 rows
    pub fn new(r1: Vector3, r2: Vector3, r3: Vector3) -> Matrix3x3 {
        Matrix3x3 {r1: r1, r2: r2, r3: r3}
    }

    ///Creates a new Matrix3x3 from 9 indexed floats
    pub fn new_idx(n1: f32, n2: f32, n3: f32, n4: f32, n5: f32, n6: f32, n7: f32, n8: f32, n9: f32)
                                                                                -> Matrix3x3 {

        Matrix3x3 {r1: Vector3::new(n1, n2, n3),
                   r2: Vector3::new(n4, n5, n6),
                   r3: Vector3::new(n7, n8, n9)}
    }
}

impl ops::Mul<Vector3> for Matrix3x3 {
    type Output = Vector3;

    ///Implements the transform matrix of a vector 3 into another vector 3.
    fn mul(self, vec: Vector3) -> Vector3 {
        Vector3 {x: self.r1.x * vec.x + self.r1.y * vec.y + self.r1.z * vec.z,
            y: self.r2.x * vec.x + self.r2.y * vec.y + self.r2.z * vec.z,
            z: self.r3.x * vec.x + self.r3.y * vec.y + self.r3.z * vec.z}
    }
}

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

    #[test]
    fn matrix_created_new_from_3_vector3() {
        let actual = Matrix3x3::new(Vector3::new(1f32, 2f32, 3f32),
                                        Vector3::new(1f32, 2f32, 3f32),
                                        Vector3::new(1f32, 2f32, 3f32));
        let expected = Matrix3x3 {r1: Vector3::new(1f32, 2f32, 3f32),
                                        r2: Vector3::new(1f32, 2f32, 3f32),
                                        r3: Vector3::new(1f32, 2f32, 3f32)};
        assert_eq!(expected, actual);
    }

    #[test]
    fn matrix_created_new_from_9_floats() {
        let actual = Matrix3x3::new_idx(1f32, 1f32, 1f32, 1f32, 1f32, 1f32,
                                    1f32, 1f32, 1f32);
        let expected = Matrix3x3 {r1: Vector3::new(1f32, 1f32, 1f32),
                                            r2: Vector3::new(1f32, 1f32, 1f32),
                                            r3: Vector3::new(1f32, 1f32, 1f32)};
        assert_eq!(expected, actual);
    }

    #[test]
    fn vector_transform_by_matrix() {
        let vec = Vector3::new(1f32, 2f32, 3f32);
        let matrix = Matrix3x3::new_idx(1f32, 2f32, 3f32,
                                        4f32, 5f32, 6f32, 7f32, 8f32, 9f32);
        let actual = matrix * vec;
        let expected = Vector3::new(14f32, 32f32, 50f32);
        assert_eq!(expected, actual);
    }
}<commit_msg>det matrix 3x3<commit_after>use super::vector3::Vector3;
use std::ops;

///Implements a matrix 3 x 3
#[derive(Clone, PartialEq, Debug)]
pub struct Matrix3x3 {
    pub r1: Vector3,
    pub r2: Vector3,
    pub r3: Vector3,
}

impl Matrix3x3 {

    ///Creates a new Matrix3x3 from 3 vector3 rows
    pub fn new(r1: Vector3, r2: Vector3, r3: Vector3) -> Matrix3x3 {
        Matrix3x3 {r1: r1, r2: r2, r3: r3}
    }

    ///Creates a new Matrix3x3 from 9 indexed floats
    pub fn new_idx(n1: f32, n2: f32, n3: f32, n4: f32, n5: f32, n6: f32, n7: f32, n8: f32, n9: f32)
                                                                                -> Matrix3x3 {

        Matrix3x3 {r1: Vector3::new(n1, n2, n3),
                   r2: Vector3::new(n4, n5, n6),
                   r3: Vector3::new(n7, n8, n9)}
    }

    pub fn det(self) -> f32 {
        (self.r1.x * self.r2.y * self.r3.z +
            self.r1.y * self.r2.z * self.r3.x +
            self.r1.z * self.r2.x * self.r3.y)
        - (self.r1.z * self.r2.y * self.r3.x +
            self.r1.y * self.r2.x * self.r3.z +
            self.r1.x * self.r2.z * self.r3.y)
    }
}

impl ops::Mul<Vector3> for Matrix3x3 {
    type Output = Vector3;

    ///Implements the transform matrix of a vector 3 into another vector 3.
    fn mul(self, vec: Vector3) -> Vector3 {
        Vector3 {x: self.r1 * vec.clone(),
            y: self.r2 * vec.clone(),
            z: self.r3 * vec.clone()}
    }
}

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

    #[test]
    fn matrix_created_new_from_3_vector3() {
        let actual = Matrix3x3::new(Vector3::new(1f32, 2f32, 3f32),
                                        Vector3::new(1f32, 2f32, 3f32),
                                        Vector3::new(1f32, 2f32, 3f32));
        let expected = Matrix3x3 {r1: Vector3::new(1f32, 2f32, 3f32),
                                        r2: Vector3::new(1f32, 2f32, 3f32),
                                        r3: Vector3::new(1f32, 2f32, 3f32)};
        assert_eq!(expected, actual);
    }

    #[test]
    fn matrix_created_new_from_9_floats() {
        let actual = Matrix3x3::new_idx(1f32, 1f32, 1f32, 1f32, 1f32, 1f32,
                                    1f32, 1f32, 1f32);
        let expected = Matrix3x3 {r1: Vector3::new(1f32, 1f32, 1f32),
                                            r2: Vector3::new(1f32, 1f32, 1f32),
                                            r3: Vector3::new(1f32, 1f32, 1f32)};
        assert_eq!(expected, actual);
    }

    #[test]
    fn vector_transform_by_matrix() {
        let vec = Vector3::new(1f32, 2f32, 3f32);
        let matrix = Matrix3x3::new_idx(1f32, 2f32, 3f32,
                                        4f32, 5f32, 6f32, 7f32, 8f32, 9f32);
        let actual = matrix * vec;
        let expected = Vector3::new(14f32, 32f32, 50f32);
        assert_eq!(expected, actual);
    }

    #[test]
    fn seq_maxtrix_det() {
        let matrix = Matrix3x3::new_idx(1f32, 2f32, 3f32,
                                        4f32, 5f32, 6f32, 7f32, 8f32, 5f32);
        let actual = matrix.det();
        let expected = 12f32;
        assert_eq!(expected, actual);
    }
}<|endoftext|>


<commit_before>const DATA: &'static str = include_str!("../data/input_6.txt");

pub fn main() -> Vec<String> {
    let s1 = light_show(DATA);
    let s2 = bright_show(DATA);
    vec![s1.to_string(), s2.to_string()]
}

fn doit<F, L>(f: F, state: &mut [[L; 1000]; 1000], a: (usize, usize), b: (usize, usize))
    where F: Fn(&mut L)
{
    for x in a.0..(b.0 + 1) {
        for y in a.1..(b.1 + 1) {
            f(&mut state[x][y]);
        }
    }
}

enum Cmnd {
    On((usize, usize), (usize, usize)),
    Off((usize, usize), (usize, usize)),
    Toggle((usize, usize), (usize, usize)),
}

fn parse_coords(line: &str) -> ((usize, usize), (usize, usize)) {
    if let (Some(a), Some(b), Some(c), Some(d)) = scan_fmt!(&line,
                                                            "{d},{d} through {d},{d}",
                                                            usize,
                                                            usize,
                                                            usize,
                                                            usize) {
        ((a, b), (c, d))
    } else {
        panic!("bad input");
    }
}

fn parse_cmnd(line: &str) -> Cmnd {
    let mut words = line.split_whitespace();

    match words.next() {
        Some("turn") => {
            match words.next() {
                Some("on") => {
                    let c = parse_coords(&words.collect::<String>());
                    Cmnd::On(c.0, c.1)
                }
                Some("off") => {
                    let c = parse_coords(&words.collect::<String>());
                    Cmnd::Off(c.0, c.1)
                }
                _ => panic!("bad input"),
            }
        }
        Some("toggle") => {
            let c = parse_coords(&words.collect::<String>());
            Cmnd::Toggle(c.0, c.1)
        }
        _ => panic!("bad input"),
    }
}

fn light_show(input: &str) -> usize {
    let mut state = box [[false; 1000]; 1000];

    for line in input.lines() {
        let cmnd = parse_cmnd(line);
        match cmnd {
            Cmnd::On(a, b) => doit(|light: &mut bool| *light = true, &mut state, a, b),
            Cmnd::Off(a, b) => doit(|light: &mut bool| *light = false, &mut state, a, b),
            Cmnd::Toggle(a, b) => doit(|light: &mut bool| *light = !*light, &mut state, a, b),
        }
    }
    state.iter()
         .flat_map(|inner| inner.iter())
         .filter(|&&on| on == true)
         .count()
}

fn bright_show(input: &str) -> u32 {
    let mut state = box [[0u32; 1000]; 1000];

    let on = |light: &mut u32| *light += 1;
    let off = |light: &mut u32| {
        if *light > 0 {
            *light -= 1
        }
    };
    let toggle = |light: &mut u32| *light += 2;

    for line in input.lines() {
        let cmnd = parse_cmnd(line);
        match cmnd {
            Cmnd::On(a, b) => doit(&on, &mut state, a, b),
            Cmnd::Off(a, b) => doit(&off, &mut state, a, b),
            Cmnd::Toggle(a, b) => doit(&toggle, &mut state, a, b),
        }
    }
    state.iter()
         .flat_map(|inner| inner.iter())
         .sum()
}

#[cfg(test)]
mod test {
    use super::{light_show, bright_show};

    #[test]
    fn test_light_show() {
        assert_eq!(light_show("turn on 0,0 through 999,999"), 1000 * 1000);
        assert_eq!(light_show("toggle 0,0 through 999,0"), 1000);
        assert_eq!(light_show("turn off 499,499 through 500,500"), 0);
    }

    #[test]
    fn test_bright_show() {
        assert_eq!(bright_show("turn on 0,0 through 0,0"), 1);
        assert_eq!(bright_show("toggle 0,0 through 999,999"), 2 * 1000 * 1000);
    }
}
<commit_msg>day06: real error handling/propogation instead of panic!<commit_after>const DATA: &'static str = include_str!("../data/input_6.txt");

pub fn main() -> Vec<String> {
    let s1 = light_show(DATA);
    let s2 = bright_show(DATA);
    vec![s1.to_string(), s2.to_string()]
}

fn doit<F, L>(f: F, state: &mut [[L; 1000]; 1000], a: (usize, usize), b: (usize, usize))
    where F: Fn(&mut L)
{
    for x in a.0..(b.0 + 1) {
        for y in a.1..(b.1 + 1) {
            f(&mut state[x][y]);
        }
    }
}

enum Cmnd {
    On((usize, usize), (usize, usize)),
    Off((usize, usize), (usize, usize)),
    Toggle((usize, usize), (usize, usize)),
}

fn parse_coords(line: &str) -> Result<((usize, usize), (usize, usize)), &'static str> {
    if let (Some(a), Some(b), Some(c), Some(d)) = scan_fmt!(&line,
                                                            "{d},{d} through {d},{d}",
                                                            usize,
                                                            usize,
                                                            usize,
                                                            usize) {
        Ok(((a, b), (c, d)))
    } else {
        Err("error parsing coordinates")
    }
}

fn parse_cmnd(line: &str) -> Result<Cmnd, &'static str> {
    let mut words = line.split_whitespace();

    match words.next() {
        Some("turn") => {
            match words.next() {
                Some("on") => {
                    let c = parse_coords(&words.collect::<String>());
                    c.map(|c| Cmnd::On(c.0, c.1))
                }
                Some("off") => {
                    let c = parse_coords(&words.collect::<String>());
                    c.map(|c| Cmnd::Off(c.0, c.1))
                }
                _ => Err("error parsing command"),
            }
        }
        Some("toggle") => {
            let c = parse_coords(&words.collect::<String>());
            c.map(|c| Cmnd::Toggle(c.0, c.1))
        }
        _ => Err("error parsing command"),
    }
}

fn light_show(input: &str) -> usize {
    let mut state = box [[false; 1000]; 1000];

    for line in input.lines() {
        let cmnd = parse_cmnd(line);
        let _ = cmnd.map(|c| {
            match c {
                Cmnd::On(a, b) => doit(|light: &mut bool| *light = true, &mut state, a, b),
                Cmnd::Off(a, b) => doit(|light: &mut bool| *light = false, &mut state, a, b),
                Cmnd::Toggle(a, b) => doit(|light: &mut bool| *light = !*light, &mut state, a, b),
            }
        });
    }
    state.iter()
         .flat_map(|inner| inner.iter())
         .filter(|&&on| on == true)
         .count()
}

fn bright_show(input: &str) -> u32 {
    let mut state = box [[0u32; 1000]; 1000];

    let on = |light: &mut u32| *light += 1;
    let off = |light: &mut u32| {
        if *light > 0 {
            *light -= 1
        }
    };
    let toggle = |light: &mut u32| *light += 2;

    for line in input.lines() {
        let cmnd = parse_cmnd(line);
        let _ = cmnd.map(|c| {
            match c {
                Cmnd::On(a, b) => doit(&on, &mut state, a, b),
                Cmnd::Off(a, b) => doit(&off, &mut state, a, b),
                Cmnd::Toggle(a, b) => doit(&toggle, &mut state, a, b),
            }
        });
    }
    state.iter()
         .flat_map(|inner| inner.iter())
         .sum()
}

#[cfg(test)]
mod test {
    use super::{light_show, bright_show};

    #[test]
    fn test_light_show() {
        assert_eq!(light_show("turn on 0,0 through 999,999"), 1000 * 1000);
        assert_eq!(light_show("toggle 0,0 through 999,0"), 1000);
        assert_eq!(light_show("turn off 499,499 through 500,500"), 0);
    }

    #[test]
    fn test_bright_show() {
        assert_eq!(bright_show("turn on 0,0 through 0,0"), 1);
        assert_eq!(bright_show("toggle 0,0 through 999,999"), 2 * 1000 * 1000);
    }
}
<|endoftext|>


<commit_before>//! C API extensions to experiment with eager execution of kernels.
//!
//! WARNING: The underlying C-API for the eager execution is not guaranteed to be
//! stable and can be changed without notice, which could result in breaking.

mod context;
pub use context::*;

mod readonly_tensor;
pub use readonly_tensor::*;

mod tensor_handle;
pub use tensor_handle::*;

mod op;

pub use op::raw_ops;

use crate::{Result, Tensor, TensorType};

impl<T: TensorType> Tensor<T> {
    /// Convert a Tensor to a readonly Tensor for use in eager execution.
    pub fn freeze(self) -> ReadonlyTensor<T> {
        ReadonlyTensor {
            inner: self.inner,
            dims: self.dims,
        }
    }

    /// Convert a Tensor to a TensorHandle for use in eager execution.
    pub fn into_handle<'a>(self, ctx: &'a Context) -> Result<TensorHandle<'a>> {
        self.freeze().to_handle(ctx)
    }
}

/// A helper trait to convert a Tensor or some other types into a TensorHandle
/// for use in eager execution.
pub trait ToTensorHandle<'a> {
    /// Convert a Tensor or values into a new TensorHandle.
    fn to_handle(&self, ctx: &'a Context) -> Result<TensorHandle<'a>>;
}

impl<'a, T> ToTensorHandle<'a> for ReadonlyTensor<T>
where
    T: TensorType,
{
    fn to_handle(&self, ctx: &'a Context) -> Result<TensorHandle<'a>> {
        TensorHandle::new(ctx, self)
    }
}

impl<'a> ToTensorHandle<'a> for TensorHandle<'a> {
    fn to_handle(&self, _: &'a Context) -> Result<TensorHandle<'a>> {
        self.copy_sharing_tensor()
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::eager::{Context, ContextOptions};
    use crate::Tensor;

    #[test]
    fn tensor_to_handle() {
        let ctx = Context::new(ContextOptions::new()).unwrap();

        // Create a read-only tensor.
        let tensor = Tensor::<i32>::new(&[1, 2, 3, 4]).freeze();
        let handle = tensor.to_handle(&ctx).unwrap();
        assert_eq!(handle.num_dims().unwrap(), 4);
        assert_eq!(handle.dim(0).unwrap(), 1);
        assert_eq!(handle.dim(1).unwrap(), 2);
        assert_eq!(handle.dim(2).unwrap(), 3);
        assert_eq!(handle.dim(3).unwrap(), 4);

        // Create a TensorHandle directly from a Tensor.
        // It takes ownership of the Tensor.
        let tensor = Tensor::<i32>::new(&[1, 2, 3, 4]);
        let handle = tensor.into_handle(&ctx).unwrap();
        assert_eq!(handle.num_dims().unwrap(), 4);
        assert_eq!(handle.dim(0).unwrap(), 1);
        assert_eq!(handle.dim(1).unwrap(), 2);
        assert_eq!(handle.dim(2).unwrap(), 3);
        assert_eq!(handle.dim(3).unwrap(), 4);
    }

    #[test]
    fn handle_to_handle() {
        let ctx = Context::new(ContextOptions::new()).unwrap();
        let tensor = Tensor::<i32>::new(&[1, 2, 3, 4]).freeze();
        let handle = tensor.to_handle(&ctx).unwrap();
        let handle2 = handle.to_handle(&ctx).unwrap();
        let tensor2 = handle2.resolve::<i32>().unwrap();
        assert_eq!(tensor, tensor2);
    }

    #[test]
    fn handle_to_handle_unsafe() {
        let ctx = Context::new(ContextOptions::new()).unwrap();
        let tensor = Tensor::<i32>::new(&[1, 2, 3, 4]).freeze();
        let handle = tensor.to_handle(&ctx).unwrap();
        let handle2 = handle.to_handle(&ctx).unwrap();
        let tensor2 = handle2.resolve::<i32>().unwrap();
        let mut tensor2 = unsafe {tensor2.into_tensor()};
        assert_eq!(tensor, tensor2);

        // Check that tensor and tensro2 share the same underlying data.
        // This is why we need to use unsafe.
        tensor2[0] = 5;
        assert_eq!(tensor[0], 5);
    }
}
<commit_msg>apply fmt<commit_after>//! C API extensions to experiment with eager execution of kernels.
//!
//! WARNING: The underlying C-API for the eager execution is not guaranteed to be
//! stable and can be changed without notice, which could result in breaking.

mod context;
pub use context::*;

mod readonly_tensor;
pub use readonly_tensor::*;

mod tensor_handle;
pub use tensor_handle::*;

mod op;

pub use op::raw_ops;

use crate::{Result, Tensor, TensorType};

impl<T: TensorType> Tensor<T> {
    /// Convert a Tensor to a readonly Tensor for use in eager execution.
    pub fn freeze(self) -> ReadonlyTensor<T> {
        ReadonlyTensor {
            inner: self.inner,
            dims: self.dims,
        }
    }

    /// Convert a Tensor to a TensorHandle for use in eager execution.
    pub fn into_handle<'a>(self, ctx: &'a Context) -> Result<TensorHandle<'a>> {
        self.freeze().to_handle(ctx)
    }
}

/// A helper trait to convert a Tensor or some other types into a TensorHandle
/// for use in eager execution.
pub trait ToTensorHandle<'a> {
    /// Convert a Tensor or values into a new TensorHandle.
    fn to_handle(&self, ctx: &'a Context) -> Result<TensorHandle<'a>>;
}

impl<'a, T> ToTensorHandle<'a> for ReadonlyTensor<T>
where
    T: TensorType,
{
    fn to_handle(&self, ctx: &'a Context) -> Result<TensorHandle<'a>> {
        TensorHandle::new(ctx, self)
    }
}

impl<'a> ToTensorHandle<'a> for TensorHandle<'a> {
    fn to_handle(&self, _: &'a Context) -> Result<TensorHandle<'a>> {
        self.copy_sharing_tensor()
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::eager::{Context, ContextOptions};
    use crate::Tensor;

    #[test]
    fn tensor_to_handle() {
        let ctx = Context::new(ContextOptions::new()).unwrap();

        // Create a read-only tensor.
        let tensor = Tensor::<i32>::new(&[1, 2, 3, 4]).freeze();
        let handle = tensor.to_handle(&ctx).unwrap();
        assert_eq!(handle.num_dims().unwrap(), 4);
        assert_eq!(handle.dim(0).unwrap(), 1);
        assert_eq!(handle.dim(1).unwrap(), 2);
        assert_eq!(handle.dim(2).unwrap(), 3);
        assert_eq!(handle.dim(3).unwrap(), 4);

        // Create a TensorHandle directly from a Tensor.
        // It takes ownership of the Tensor.
        let tensor = Tensor::<i32>::new(&[1, 2, 3, 4]);
        let handle = tensor.into_handle(&ctx).unwrap();
        assert_eq!(handle.num_dims().unwrap(), 4);
        assert_eq!(handle.dim(0).unwrap(), 1);
        assert_eq!(handle.dim(1).unwrap(), 2);
        assert_eq!(handle.dim(2).unwrap(), 3);
        assert_eq!(handle.dim(3).unwrap(), 4);
    }

    #[test]
    fn handle_to_handle() {
        let ctx = Context::new(ContextOptions::new()).unwrap();
        let tensor = Tensor::<i32>::new(&[1, 2, 3, 4]).freeze();
        let handle = tensor.to_handle(&ctx).unwrap();
        let handle2 = handle.to_handle(&ctx).unwrap();
        let tensor2 = handle2.resolve::<i32>().unwrap();
        assert_eq!(tensor, tensor2);
    }

    #[test]
    fn handle_to_handle_unsafe() {
        let ctx = Context::new(ContextOptions::new()).unwrap();
        let tensor = Tensor::<i32>::new(&[1, 2, 3, 4]).freeze();
        let handle = tensor.to_handle(&ctx).unwrap();
        let handle2 = handle.to_handle(&ctx).unwrap();
        let tensor2 = handle2.resolve::<i32>().unwrap();
        let mut tensor2 = unsafe { tensor2.into_tensor() };
        assert_eq!(tensor, tensor2);

        // Check that tensor and tensro2 share the same underlying data.
        // This is why we need to use unsafe.
        tensor2[0] = 5;
        assert_eq!(tensor[0], 5);
    }
}
<|endoftext|>


<commit_before>//! Error manipulations.

use std::{error, ffi, fmt};

use rdkafka_sys as rdsys;
use rdkafka_sys::types::*;

// Re-export rdkafka error code
pub use rdsys::types::RDKafkaErrorCode;

/// Kafka result.
pub type KafkaResult<T> = Result<T, KafkaError>;

/// Verify if the value represents an error condition.
///
/// Some librdkafka codes are informational, rather than true errors.
pub trait IsError {
    /// Reports whether the value represents an error.
    fn is_error(self) -> bool;
}

impl IsError for RDKafkaRespErr {
    fn is_error(self) -> bool {
        self as i32 != RDKafkaRespErr::RD_KAFKA_RESP_ERR_NO_ERROR as i32
    }
}

impl IsError for RDKafkaConfRes {
    fn is_error(self) -> bool {
        self as i32 != RDKafkaConfRes::RD_KAFKA_CONF_OK as i32
    }
}

// TODO: consider using macro

/// Represents all possible Kafka errors.
///
/// If applicable, check the underlying [`RDKafkaErrorCode`] to get details.
#[derive(Clone, PartialEq, Eq)]
pub enum KafkaError {
    /// Creation of admin operation failed.
    AdminOpCreation(String),
    /// The admin operation itself failed.
    AdminOp(RDKafkaErrorCode),
    /// The client was dropped before the operation completed.
    Canceled,
    /// Invalid client configuration.
    ClientConfig(RDKafkaConfRes, String, String, String),
    /// Client creation failed.
    ClientCreation(String),
    /// Consumer commit failed.
    ConsumerCommit(RDKafkaErrorCode),
    /// Global error.
    Global(RDKafkaErrorCode),
    /// Group list fetch failed.
    GroupListFetch(RDKafkaErrorCode),
    /// Message consumption failed.
    MessageConsumption(RDKafkaErrorCode),
    /// Message production error.
    MessageProduction(RDKafkaErrorCode),
    /// Metadata fetch error.
    MetadataFetch(RDKafkaErrorCode),
    /// No message was received.
    NoMessageReceived,
    /// Unexpected null pointer
    Nul(ffi::NulError),
    /// Offset fetch failed.
    OffsetFetch(RDKafkaErrorCode),
    /// End of partition reached.
    PartitionEOF(i32),
    /// Pause/Resume failed.
    PauseResume(String),
    /// Seeking a partition failed.
    Seek(String),
    /// Setting partition offset failed.
    SetPartitionOffset(RDKafkaErrorCode),
    /// Offset store failed.
    StoreOffset(RDKafkaErrorCode),
    /// Subscription creation failed.
    Subscription(String),
}

impl fmt::Debug for KafkaError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match *self {
            KafkaError::AdminOp(err) => write!(f, "KafkaError (Admin operation error: {})", err),
            KafkaError::AdminOpCreation(ref err) => {
                write!(f, "KafkaError (Admin operation creation error: {})", err)
            }
            KafkaError::Canceled => write!(f, "KafkaError (Client dropped)"),
            KafkaError::ClientConfig(_, ref desc, ref key, ref value) => write!(
                f,
                "KafkaError (Client config error: {} {} {})",
                desc, key, value
            ),
            KafkaError::ClientCreation(ref err) => {
                write!(f, "KafkaError (Client creation error: {})", err)
            }
            KafkaError::ConsumerCommit(err) => {
                write!(f, "KafkaError (Consumer commit error: {})", err)
            }
            KafkaError::Global(err) => write!(f, "KafkaError (Global error: {})", err),
            KafkaError::GroupListFetch(err) => {
                write!(f, "KafkaError (Group list fetch error: {})", err)
            }
            KafkaError::MessageConsumption(err) => {
                write!(f, "KafkaError (Message consumption error: {})", err)
            }
            KafkaError::MessageProduction(err) => {
                write!(f, "KafkaError (Message production error: {})", err)
            }
            KafkaError::MetadataFetch(err) => {
                write!(f, "KafkaError (Metadata fetch error: {})", err)
            }
            KafkaError::NoMessageReceived => {
                write!(f, "No message received within the given poll interval")
            }
            KafkaError::Nul(_) => write!(f, "FFI null error"),
            KafkaError::OffsetFetch(err) => write!(f, "KafkaError (Offset fetch error: {})", err),
            KafkaError::PartitionEOF(part_n) => write!(f, "KafkaError (Partition EOF: {})", part_n),
            KafkaError::PauseResume(ref err) => {
                write!(f, "KafkaError (Pause/resume error: {})", err)
            }
            KafkaError::Seek(ref err) => write!(f, "KafkaError (Seek error: {})", err),
            KafkaError::SetPartitionOffset(err) => {
                write!(f, "KafkaError (Set partition offset error: {})", err)
            }
            KafkaError::StoreOffset(err) => write!(f, "KafkaError (Store offset error: {})", err),
            KafkaError::Subscription(ref err) => {
                write!(f, "KafkaError (Subscription error: {})", err)
            }
        }
    }
}

impl fmt::Display for KafkaError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match *self {
            KafkaError::AdminOp(err) => write!(f, "Admin operation error: {}", err),
            KafkaError::AdminOpCreation(ref err) => {
                write!(f, "Admin operation creation error: {}", err)
            }
            KafkaError::Canceled => write!(f, "KafkaError (Client dropped)"),
            KafkaError::ClientConfig(_, ref desc, ref key, ref value) => {
                write!(f, "Client config error: {} {} {}", desc, key, value)
            }
            KafkaError::ClientCreation(ref err) => write!(f, "Client creation error: {}", err),
            KafkaError::ConsumerCommit(err) => write!(f, "Consumer commit error: {}", err),
            KafkaError::Global(err) => write!(f, "Global error: {}", err),
            KafkaError::GroupListFetch(err) => write!(f, "Group list fetch error: {}", err),
            KafkaError::MessageConsumption(err) => write!(f, "Message consumption error: {}", err),
            KafkaError::MessageProduction(err) => write!(f, "Message production error: {}", err),
            KafkaError::MetadataFetch(err) => write!(f, "Meta data fetch error: {}", err),
            KafkaError::NoMessageReceived => {
                write!(f, "No message received within the given poll interval")
            }
            KafkaError::Nul(_) => write!(f, "FFI nul error"),
            KafkaError::OffsetFetch(err) => write!(f, "Offset fetch error: {}", err),
            KafkaError::PartitionEOF(part_n) => write!(f, "Partition EOF: {}", part_n),
            KafkaError::PauseResume(ref err) => write!(f, "Pause/resume error: {}", err),
            KafkaError::Seek(ref err) => write!(f, "Seek error: {}", err),
            KafkaError::SetPartitionOffset(err) => write!(f, "Set partition offset error: {}", err),
            KafkaError::StoreOffset(err) => write!(f, "Store offset error: {}", err),
            KafkaError::Subscription(ref err) => write!(f, "Subscription error: {}", err),
        }
    }
}

impl error::Error for KafkaError {
    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
        self.rdkafka_error_code()
            .map(|e| e as &(dyn error::Error + 'static))
    }
}

impl From<ffi::NulError> for KafkaError {
    fn from(err: ffi::NulError) -> KafkaError {
        KafkaError::Nul(err)
    }
}

impl KafkaError {
    /// Returns if an error is `Fatal` and requires reinitialisation.
    /// for details see https://docs.confluent.io/5.5.0/clients/librdkafka/rdkafka_8h.html
    pub fn is_fatal(&self) -> bool {
        match self.rdkafka_error_code() {
            Some(RDKafkaErrorCode::Fatal) => true,
            _ => false,
        }
    }

    /// Returns the [`RDKafkaErrorCode`] underlying this error, if any.
    #[allow(clippy::match_same_arms)]
    pub fn rdkafka_error_code(&self) -> Option<&RDKafkaErrorCode> {
        match self {
            KafkaError::AdminOp(_) => None,
            KafkaError::AdminOpCreation(_) => None,
            KafkaError::Canceled => None,
            KafkaError::ClientConfig(_, _, _, _) => None,
            KafkaError::ClientCreation(_) => None,
            KafkaError::ConsumerCommit(err) => Some(err),
            KafkaError::Global(err) => Some(err),
            KafkaError::GroupListFetch(err) => Some(err),
            KafkaError::MessageConsumption(err) => Some(err),
            KafkaError::MessageProduction(err) => Some(err),
            KafkaError::MetadataFetch(err) => Some(err),
            KafkaError::NoMessageReceived => None,
            KafkaError::Nul(_) => None,
            KafkaError::OffsetFetch(err) => Some(err),
            KafkaError::PartitionEOF(_) => None,
            KafkaError::PauseResume(_) => None,
            KafkaError::Seek(_) => None,
            KafkaError::SetPartitionOffset(err) => Some(err),
            KafkaError::StoreOffset(err) => Some(err),
            KafkaError::Subscription(_) => None,
        }
    }
}
<commit_msg>Remove is_fatal method<commit_after>//! Error manipulations.

use std::{error, ffi, fmt};

use rdkafka_sys as rdsys;
use rdkafka_sys::types::*;

// Re-export rdkafka error code
pub use rdsys::types::RDKafkaErrorCode;

/// Kafka result.
pub type KafkaResult<T> = Result<T, KafkaError>;

/// Verify if the value represents an error condition.
///
/// Some librdkafka codes are informational, rather than true errors.
pub trait IsError {
    /// Reports whether the value represents an error.
    fn is_error(self) -> bool;
}

impl IsError for RDKafkaRespErr {
    fn is_error(self) -> bool {
        self as i32 != RDKafkaRespErr::RD_KAFKA_RESP_ERR_NO_ERROR as i32
    }
}

impl IsError for RDKafkaConfRes {
    fn is_error(self) -> bool {
        self as i32 != RDKafkaConfRes::RD_KAFKA_CONF_OK as i32
    }
}

// TODO: consider using macro

/// Represents all possible Kafka errors.
///
/// If applicable, check the underlying [`RDKafkaErrorCode`] to get details.
#[derive(Clone, PartialEq, Eq)]
pub enum KafkaError {
    /// Creation of admin operation failed.
    AdminOpCreation(String),
    /// The admin operation itself failed.
    AdminOp(RDKafkaErrorCode),
    /// The client was dropped before the operation completed.
    Canceled,
    /// Invalid client configuration.
    ClientConfig(RDKafkaConfRes, String, String, String),
    /// Client creation failed.
    ClientCreation(String),
    /// Consumer commit failed.
    ConsumerCommit(RDKafkaErrorCode),
    /// Global error.
    Global(RDKafkaErrorCode),
    /// Group list fetch failed.
    GroupListFetch(RDKafkaErrorCode),
    /// Message consumption failed.
    MessageConsumption(RDKafkaErrorCode),
    /// Message production error.
    MessageProduction(RDKafkaErrorCode),
    /// Metadata fetch error.
    MetadataFetch(RDKafkaErrorCode),
    /// No message was received.
    NoMessageReceived,
    /// Unexpected null pointer
    Nul(ffi::NulError),
    /// Offset fetch failed.
    OffsetFetch(RDKafkaErrorCode),
    /// End of partition reached.
    PartitionEOF(i32),
    /// Pause/Resume failed.
    PauseResume(String),
    /// Seeking a partition failed.
    Seek(String),
    /// Setting partition offset failed.
    SetPartitionOffset(RDKafkaErrorCode),
    /// Offset store failed.
    StoreOffset(RDKafkaErrorCode),
    /// Subscription creation failed.
    Subscription(String),
}

impl fmt::Debug for KafkaError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match *self {
            KafkaError::AdminOp(err) => write!(f, "KafkaError (Admin operation error: {})", err),
            KafkaError::AdminOpCreation(ref err) => {
                write!(f, "KafkaError (Admin operation creation error: {})", err)
            }
            KafkaError::Canceled => write!(f, "KafkaError (Client dropped)"),
            KafkaError::ClientConfig(_, ref desc, ref key, ref value) => write!(
                f,
                "KafkaError (Client config error: {} {} {})",
                desc, key, value
            ),
            KafkaError::ClientCreation(ref err) => {
                write!(f, "KafkaError (Client creation error: {})", err)
            }
            KafkaError::ConsumerCommit(err) => {
                write!(f, "KafkaError (Consumer commit error: {})", err)
            }
            KafkaError::Global(err) => write!(f, "KafkaError (Global error: {})", err),
            KafkaError::GroupListFetch(err) => {
                write!(f, "KafkaError (Group list fetch error: {})", err)
            }
            KafkaError::MessageConsumption(err) => {
                write!(f, "KafkaError (Message consumption error: {})", err)
            }
            KafkaError::MessageProduction(err) => {
                write!(f, "KafkaError (Message production error: {})", err)
            }
            KafkaError::MetadataFetch(err) => {
                write!(f, "KafkaError (Metadata fetch error: {})", err)
            }
            KafkaError::NoMessageReceived => {
                write!(f, "No message received within the given poll interval")
            }
            KafkaError::Nul(_) => write!(f, "FFI null error"),
            KafkaError::OffsetFetch(err) => write!(f, "KafkaError (Offset fetch error: {})", err),
            KafkaError::PartitionEOF(part_n) => write!(f, "KafkaError (Partition EOF: {})", part_n),
            KafkaError::PauseResume(ref err) => {
                write!(f, "KafkaError (Pause/resume error: {})", err)
            }
            KafkaError::Seek(ref err) => write!(f, "KafkaError (Seek error: {})", err),
            KafkaError::SetPartitionOffset(err) => {
                write!(f, "KafkaError (Set partition offset error: {})", err)
            }
            KafkaError::StoreOffset(err) => write!(f, "KafkaError (Store offset error: {})", err),
            KafkaError::Subscription(ref err) => {
                write!(f, "KafkaError (Subscription error: {})", err)
            }
        }
    }
}

impl fmt::Display for KafkaError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match *self {
            KafkaError::AdminOp(err) => write!(f, "Admin operation error: {}", err),
            KafkaError::AdminOpCreation(ref err) => {
                write!(f, "Admin operation creation error: {}", err)
            }
            KafkaError::Canceled => write!(f, "KafkaError (Client dropped)"),
            KafkaError::ClientConfig(_, ref desc, ref key, ref value) => {
                write!(f, "Client config error: {} {} {}", desc, key, value)
            }
            KafkaError::ClientCreation(ref err) => write!(f, "Client creation error: {}", err),
            KafkaError::ConsumerCommit(err) => write!(f, "Consumer commit error: {}", err),
            KafkaError::Global(err) => write!(f, "Global error: {}", err),
            KafkaError::GroupListFetch(err) => write!(f, "Group list fetch error: {}", err),
            KafkaError::MessageConsumption(err) => write!(f, "Message consumption error: {}", err),
            KafkaError::MessageProduction(err) => write!(f, "Message production error: {}", err),
            KafkaError::MetadataFetch(err) => write!(f, "Meta data fetch error: {}", err),
            KafkaError::NoMessageReceived => {
                write!(f, "No message received within the given poll interval")
            }
            KafkaError::Nul(_) => write!(f, "FFI nul error"),
            KafkaError::OffsetFetch(err) => write!(f, "Offset fetch error: {}", err),
            KafkaError::PartitionEOF(part_n) => write!(f, "Partition EOF: {}", part_n),
            KafkaError::PauseResume(ref err) => write!(f, "Pause/resume error: {}", err),
            KafkaError::Seek(ref err) => write!(f, "Seek error: {}", err),
            KafkaError::SetPartitionOffset(err) => write!(f, "Set partition offset error: {}", err),
            KafkaError::StoreOffset(err) => write!(f, "Store offset error: {}", err),
            KafkaError::Subscription(ref err) => write!(f, "Subscription error: {}", err),
        }
    }
}

impl error::Error for KafkaError {
    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
        self.rdkafka_error_code()
            .map(|e| e as &(dyn error::Error + 'static))
    }
}

impl From<ffi::NulError> for KafkaError {
    fn from(err: ffi::NulError) -> KafkaError {
        KafkaError::Nul(err)
    }
}

impl KafkaError {
    /// Returns the [`RDKafkaErrorCode`] underlying this error, if any.
    #[allow(clippy::match_same_arms)]
    pub fn rdkafka_error_code(&self) -> Option<&RDKafkaErrorCode> {
        match self {
            KafkaError::AdminOp(_) => None,
            KafkaError::AdminOpCreation(_) => None,
            KafkaError::Canceled => None,
            KafkaError::ClientConfig(_, _, _, _) => None,
            KafkaError::ClientCreation(_) => None,
            KafkaError::ConsumerCommit(err) => Some(err),
            KafkaError::Global(err) => Some(err),
            KafkaError::GroupListFetch(err) => Some(err),
            KafkaError::MessageConsumption(err) => Some(err),
            KafkaError::MessageProduction(err) => Some(err),
            KafkaError::MetadataFetch(err) => Some(err),
            KafkaError::NoMessageReceived => None,
            KafkaError::Nul(_) => None,
            KafkaError::OffsetFetch(err) => Some(err),
            KafkaError::PartitionEOF(_) => None,
            KafkaError::PauseResume(_) => None,
            KafkaError::Seek(_) => None,
            KafkaError::SetPartitionOffset(err) => Some(err),
            KafkaError::StoreOffset(err) => Some(err),
            KafkaError::Subscription(_) => None,
        }
    }
}
<|endoftext|>


<commit_before>//! This module defines different errors occurring during communication with MPD.
//!
//! There're following kinds of possible errors:
//!
//!   - IO errors (due to network communication failures),
//!   - parsing errors (because of bugs in parsing server response),
//!   - protocol errors (happen when we get unexpected data from server,
//!     mostly because protocol version mismatch, network data corruption
//!     or just bugs in the client),
//!   - server errors (run-time errors coming from MPD due to some MPD
//!     errors, like database failures or sound problems)
//!
//! This module defines all necessary infrastructure to represent these kinds or errors.

use std::convert::From;
use std::error::Error as StdError;
use std::fmt;
use std::io::Error as IoError;
use std::num::{ParseFloatError, ParseIntError};
use std::result;
use std::str::FromStr;
use std::string::ParseError as StringParseError;
use time::ParseError as TimeParseError;

// Server errors {{{
/// Server error codes, as defined in [libmpdclient](http://www.musicpd.org/doc/libmpdclient/protocol_8h_source.html)
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
pub enum ErrorCode {
    /// not a list
    NotList = 1,
    /// bad command arguments
    Argument = 2,
    /// invalid password
    Password = 3,
    /// insufficient permissions
    Permission = 4,
    /// unknown command
    UnknownCmd = 5,
    /// object doesn't exist
    NoExist = 50,
    /// maximum playlist size exceeded
    PlaylistMax = 51,
    /// general system error
    System = 52,
    /// error loading playlist
    PlaylistLoad = 53,
    /// update database is already in progress
    UpdateAlready = 54,
    /// player synchronization error
    PlayerSync = 55,
    /// object already exists
    Exist = 56,
}

impl FromStr for ErrorCode {
    type Err = ParseError;
    fn from_str(s: &str) -> result::Result<ErrorCode, ParseError> {
        use self::ErrorCode::*;
        match s.parse()? {
            1 => Ok(NotList),
            2 => Ok(Argument),
            3 => Ok(Password),
            4 => Ok(Permission),
            5 => Ok(UnknownCmd),

            50 => Ok(NoExist),
            51 => Ok(PlaylistMax),
            52 => Ok(System),
            53 => Ok(PlaylistLoad),
            54 => Ok(UpdateAlready),
            55 => Ok(PlayerSync),
            56 => Ok(Exist),

            v => Err(ParseError::BadErrorCode(v)),
        }
    }
}

impl StdError for ErrorCode {
    fn description(&self) -> &str {
        use self::ErrorCode::*;
        match *self {
            NotList => "not a list",
            Argument => "invalid argument",
            Password => "invalid password",
            Permission => "permission",
            UnknownCmd => "unknown command",

            NoExist => "item not found",
            PlaylistMax => "playlist overflow",
            System => "system",
            PlaylistLoad => "playload load",
            UpdateAlready => "already updating",
            PlayerSync => "player syncing",
            Exist => "already exists",
        }
    }
}

impl fmt::Display for ErrorCode {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str(self.description())
    }
}

/// Server error
#[derive(Debug, Clone, PartialEq)]
pub struct ServerError {
    /// server error code
    pub code: ErrorCode,
    /// command position in command list
    pub pos: u16,
    /// command name, which caused the error
    pub command: String,
    /// detailed error description
    pub detail: String,
}

impl fmt::Display for ServerError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{} error (`{}') at {}", self.code, self.detail, self.pos)
    }
}

impl StdError for ServerError {
    fn description(&self) -> &str {
        self.code.description()
    }
}

impl FromStr for ServerError {
    type Err = ParseError;
    fn from_str(s: &str) -> result::Result<ServerError, ParseError> {
        // ACK [<code>@<index>] {<command>} <description>
        if s.starts_with("ACK [") {
            let s = &s[5..];
            if let (Some(atsign), Some(right_bracket)) = (s.find('@'), s.find(']')) {
                match (s[..atsign].parse(), s[atsign + 1..right_bracket].parse()) {
                    (Ok(code), Ok(pos)) => {
                        let s = &s[right_bracket + 1..];
                        if let (Some(left_brace), Some(right_brace)) = (s.find('{'), s.find('}')) {
                            let command = s[left_brace + 1..right_brace].to_string();
                            let detail = s[right_brace + 1..].trim().to_string();
                            Ok(ServerError {
                                   code: code,
                                   pos: pos,
                                   command: command,
                                   detail: detail,
                               })
                        } else {
                            Err(ParseError::NoMessage)
                        }
                    }
                    (Err(_), _) => Err(ParseError::BadCode),
                    (_, Err(_)) => Err(ParseError::BadPos),
                }
            } else {
                Err(ParseError::NoCodePos)
            }
        } else {
            Err(ParseError::NotAck)
        }
    }
}
// }}}

// Error {{{
/// Main error type, describing all possible error classes for the crate
#[derive(Debug)]
pub enum Error {
    /// IO errors (low-level network communication failures)
    Io(IoError),
    /// parsing errors (unknown data came from server)
    Parse(ParseError),
    /// protocol errors (e.g. missing required fields in server response, no handshake message etc.)
    Proto(ProtoError),
    /// server errors (a.k.a. `ACK` responses from server)
    Server(ServerError),
}

/// Shortcut type for MPD results
pub type Result<T> = result::Result<T, Error>;

impl StdError for Error {
    fn cause(&self) -> Option<&dyn StdError> {
        match *self {
            Error::Io(ref err) => Some(err),
            Error::Parse(ref err) => Some(err),
            Error::Proto(ref err) => Some(err),
            Error::Server(ref err) => Some(err),
        }
    }
    fn description(&self) -> &str {
        match *self {
            Error::Io(ref err) => err.description(),
            Error::Parse(ref err) => err.description(),
            Error::Proto(ref err) => err.description(),
            Error::Server(ref err) => err.description(),
        }
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Error::Io(ref err) => err.fmt(f),
            Error::Parse(ref err) => err.fmt(f),
            Error::Proto(ref err) => err.fmt(f),
            Error::Server(ref err) => err.fmt(f),
        }
    }
}

impl From<IoError> for Error {
    fn from(e: IoError) -> Error {
        Error::Io(e)
    }
}
impl From<ParseError> for Error {
    fn from(e: ParseError) -> Error {
        Error::Parse(e)
    }
}
impl From<ProtoError> for Error {
    fn from(e: ProtoError) -> Error {
        Error::Proto(e)
    }
}
impl From<ParseIntError> for Error {
    fn from(e: ParseIntError) -> Error {
        Error::Parse(ParseError::BadInteger(e))
    }
}
impl From<ParseFloatError> for Error {
    fn from(e: ParseFloatError) -> Error {
        Error::Parse(ParseError::BadFloat(e))
    }
}
impl From<TimeParseError> for Error {
    fn from(e: TimeParseError) -> Error {
        Error::Parse(ParseError::BadTime(e))
    }
}

impl From<ServerError> for Error {
    fn from(e: ServerError) -> Error {
        Error::Server(e)
    }
}
// }}}

// Parse errors {{{
/// Parsing error kinds
#[derive(Debug, Clone, PartialEq)]
pub enum ParseError {
    /// invalid integer
    BadInteger(ParseIntError),
    /// invalid float
    BadFloat(ParseFloatError),
    /// some other invalid value
    BadValue(String),
    /// date/time parsing error
    BadTime(TimeParseError),
    /// invalid version format (should be x.y.z)
    BadVersion,
    /// the response is not an `ACK` (not an error)
    /// (this is not actually an error, just a marker
    /// to try to parse the response as some other type,
    /// like a pair)
    NotAck,
    /// invalid pair
    BadPair,
    /// invalid error code in `ACK` response
    BadCode,
    /// invalid command position in `ACK` response
    BadPos,
    /// missing command position and/or error code in `ACK` response
    NoCodePos,
    /// missing error message in `ACK` response
    NoMessage,
    /// missing bitrate in audio format field
    NoRate,
    /// missing bits in audio format field
    NoBits,
    /// missing channels in audio format field
    NoChans,
    /// invalid bitrate in audio format field
    BadRate(ParseIntError),
    /// invalid bits in audio format field
    BadBits(ParseIntError),
    /// invalid channels in audio format field
    BadChans(ParseIntError),
    /// unknown state in state status field
    BadState(String),
    /// unknown error code in `ACK` response
    BadErrorCode(usize),
}

impl fmt::Display for ParseError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.description())
    }
}

impl StdError for ParseError {
    fn description(&self) -> &str {
        use self::ParseError::*;
        match *self {
            BadInteger(_) => "invalid integer",
            BadFloat(_) => "invalid float",
            BadValue(_) => "invalid value",
            BadTime(_) => "invalid date/time",
            BadVersion => "invalid version",
            NotAck => "not an ACK",
            BadPair => "invalid pair",
            BadCode => "invalid code",
            BadPos => "invalid position",
            NoCodePos => "missing code and position",
            NoMessage => "missing position",
            NoRate => "missing audio format rate",
            NoBits => "missing audio format bits",
            NoChans => "missing audio format channels",
            BadRate(_) => "invalid audio format rate",
            BadBits(_) => "invalid audio format bits",
            BadChans(_) => "invalid audio format channels",
            BadState(_) => "invalid playing state",
            BadErrorCode(_) => "unknown error code",
        }
    }
}

impl From<TimeParseError> for ParseError {
    fn from(e: TimeParseError) -> ParseError {
        ParseError::BadTime(e)
    }
}

impl From<ParseIntError> for ParseError {
    fn from(e: ParseIntError) -> ParseError {
        ParseError::BadInteger(e)
    }
}

impl From<ParseFloatError> for ParseError {
    fn from(e: ParseFloatError) -> ParseError {
        ParseError::BadFloat(e)
    }
}

impl From<StringParseError> for ParseError {
    fn from(e: StringParseError) -> ParseError {
        match e {}
    }
}
// }}}

// Protocol errors {{{
/// Protocol errors
///
/// They usually occur when server violate expected command response format,
/// like missing fields in answer to some command, missing closing `OK`
/// line after data stream etc.
#[derive(Debug, Clone, PartialEq)]
pub enum ProtoError {
    /// `OK` was expected, but it was missing
    NotOk,
    /// a data pair was expected
    NotPair,
    /// invalid handshake banner received
    BadBanner,
    /// expected some field, but it was missing
    NoField(&'static str),
    /// expected sticker value, but didn't find it
    BadSticker,
}

impl fmt::Display for ProtoError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.description())
    }
}

impl StdError for ProtoError {
    fn description(&self) -> &str {
        match *self {
            ProtoError::NotOk => "OK expected",
            ProtoError::NotPair => "pair expected",
            ProtoError::BadBanner => "banner error",
            ProtoError::NoField(_) => "missing field",
            ProtoError::BadSticker => "sticker error",
        }
    }
}
// }}}
<commit_msg>Adapt types implementing std::error::Error<commit_after>//! This module defines different errors occurring during communication with MPD.
//!
//! There're following kinds of possible errors:
//!
//!   - IO errors (due to network communication failures),
//!   - parsing errors (because of bugs in parsing server response),
//!   - protocol errors (happen when we get unexpected data from server,
//!     mostly because protocol version mismatch, network data corruption
//!     or just bugs in the client),
//!   - server errors (run-time errors coming from MPD due to some MPD
//!     errors, like database failures or sound problems)
//!
//! This module defines all necessary infrastructure to represent these kinds or errors.

use std::convert::From;
use std::error::Error as StdError;
use std::fmt;
use std::io::Error as IoError;
use std::num::{ParseFloatError, ParseIntError};
use std::result;
use std::str::FromStr;
use std::string::ParseError as StringParseError;
use time::ParseError as TimeParseError;

// Server errors {{{
/// Server error codes, as defined in [libmpdclient](http://www.musicpd.org/doc/libmpdclient/protocol_8h_source.html)
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
pub enum ErrorCode {
    /// not a list
    NotList = 1,
    /// bad command arguments
    Argument = 2,
    /// invalid password
    Password = 3,
    /// insufficient permissions
    Permission = 4,
    /// unknown command
    UnknownCmd = 5,
    /// object doesn't exist
    NoExist = 50,
    /// maximum playlist size exceeded
    PlaylistMax = 51,
    /// general system error
    System = 52,
    /// error loading playlist
    PlaylistLoad = 53,
    /// update database is already in progress
    UpdateAlready = 54,
    /// player synchronization error
    PlayerSync = 55,
    /// object already exists
    Exist = 56,
}

impl FromStr for ErrorCode {
    type Err = ParseError;
    fn from_str(s: &str) -> result::Result<ErrorCode, ParseError> {
        use self::ErrorCode::*;
        match s.parse()? {
            1 => Ok(NotList),
            2 => Ok(Argument),
            3 => Ok(Password),
            4 => Ok(Permission),
            5 => Ok(UnknownCmd),

            50 => Ok(NoExist),
            51 => Ok(PlaylistMax),
            52 => Ok(System),
            53 => Ok(PlaylistLoad),
            54 => Ok(UpdateAlready),
            55 => Ok(PlayerSync),
            56 => Ok(Exist),

            v => Err(ParseError::BadErrorCode(v)),
        }
    }
}

impl StdError for ErrorCode { }

impl fmt::Display for ErrorCode {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use self::ErrorCode::*;

        let desc = match *self {
            NotList => "not a list",
            Argument => "invalid argument",
            Password => "invalid password",
            Permission => "permission",
            UnknownCmd => "unknown command",

            NoExist => "item not found",
            PlaylistMax => "playlist overflow",
            System => "system",
            PlaylistLoad => "playload load",
            UpdateAlready => "already updating",
            PlayerSync => "player syncing",
            Exist => "already exists",
        };

        f.write_str(desc)
    }
}

/// Server error
#[derive(Debug, Clone, PartialEq)]
pub struct ServerError {
    /// server error code
    pub code: ErrorCode,
    /// command position in command list
    pub pos: u16,
    /// command name, which caused the error
    pub command: String,
    /// detailed error description
    pub detail: String,
}

impl StdError for ServerError { }

impl fmt::Display for ServerError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{} error (`{}') at {}", self.code, self.detail, self.pos)
    }
}

impl FromStr for ServerError {
    type Err = ParseError;
    fn from_str(s: &str) -> result::Result<ServerError, ParseError> {
        // ACK [<code>@<index>] {<command>} <description>
        if s.starts_with("ACK [") {
            let s = &s[5..];
            if let (Some(atsign), Some(right_bracket)) = (s.find('@'), s.find(']')) {
                match (s[..atsign].parse(), s[atsign + 1..right_bracket].parse()) {
                    (Ok(code), Ok(pos)) => {
                        let s = &s[right_bracket + 1..];
                        if let (Some(left_brace), Some(right_brace)) = (s.find('{'), s.find('}')) {
                            let command = s[left_brace + 1..right_brace].to_string();
                            let detail = s[right_brace + 1..].trim().to_string();
                            Ok(ServerError {
                                   code: code,
                                   pos: pos,
                                   command: command,
                                   detail: detail,
                               })
                        } else {
                            Err(ParseError::NoMessage)
                        }
                    }
                    (Err(_), _) => Err(ParseError::BadCode),
                    (_, Err(_)) => Err(ParseError::BadPos),
                }
            } else {
                Err(ParseError::NoCodePos)
            }
        } else {
            Err(ParseError::NotAck)
        }
    }
}
// }}}

// Error {{{
/// Main error type, describing all possible error classes for the crate
#[derive(Debug)]
pub enum Error {
    /// IO errors (low-level network communication failures)
    Io(IoError),
    /// parsing errors (unknown data came from server)
    Parse(ParseError),
    /// protocol errors (e.g. missing required fields in server response, no handshake message etc.)
    Proto(ProtoError),
    /// server errors (a.k.a. `ACK` responses from server)
    Server(ServerError),
}

/// Shortcut type for MPD results
pub type Result<T> = result::Result<T, Error>;

impl StdError for Error {
    fn source(&self) -> Option<&(dyn StdError + 'static)> {
        match *self {
            Error::Io(ref err) => Some(err),
            Error::Parse(ref err) => Some(err),
            Error::Proto(ref err) => Some(err),
            Error::Server(ref err) => Some(err),
        }
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Error::Io(ref err) => err.fmt(f),
            Error::Parse(ref err) => err.fmt(f),
            Error::Proto(ref err) => err.fmt(f),
            Error::Server(ref err) => err.fmt(f),
        }
    }
}

impl From<IoError> for Error {
    fn from(e: IoError) -> Error {
        Error::Io(e)
    }
}
impl From<ParseError> for Error {
    fn from(e: ParseError) -> Error {
        Error::Parse(e)
    }
}
impl From<ProtoError> for Error {
    fn from(e: ProtoError) -> Error {
        Error::Proto(e)
    }
}
impl From<ParseIntError> for Error {
    fn from(e: ParseIntError) -> Error {
        Error::Parse(ParseError::BadInteger(e))
    }
}
impl From<ParseFloatError> for Error {
    fn from(e: ParseFloatError) -> Error {
        Error::Parse(ParseError::BadFloat(e))
    }
}
impl From<TimeParseError> for Error {
    fn from(e: TimeParseError) -> Error {
        Error::Parse(ParseError::BadTime(e))
    }
}

impl From<ServerError> for Error {
    fn from(e: ServerError) -> Error {
        Error::Server(e)
    }
}
// }}}

// Parse errors {{{
/// Parsing error kinds
#[derive(Debug, Clone, PartialEq)]
pub enum ParseError {
    /// invalid integer
    BadInteger(ParseIntError),
    /// invalid float
    BadFloat(ParseFloatError),
    /// some other invalid value
    BadValue(String),
    /// date/time parsing error
    BadTime(TimeParseError),
    /// invalid version format (should be x.y.z)
    BadVersion,
    /// the response is not an `ACK` (not an error)
    /// (this is not actually an error, just a marker
    /// to try to parse the response as some other type,
    /// like a pair)
    NotAck,
    /// invalid pair
    BadPair,
    /// invalid error code in `ACK` response
    BadCode,
    /// invalid command position in `ACK` response
    BadPos,
    /// missing command position and/or error code in `ACK` response
    NoCodePos,
    /// missing error message in `ACK` response
    NoMessage,
    /// missing bitrate in audio format field
    NoRate,
    /// missing bits in audio format field
    NoBits,
    /// missing channels in audio format field
    NoChans,
    /// invalid bitrate in audio format field
    BadRate(ParseIntError),
    /// invalid bits in audio format field
    BadBits(ParseIntError),
    /// invalid channels in audio format field
    BadChans(ParseIntError),
    /// unknown state in state status field
    BadState(String),
    /// unknown error code in `ACK` response
    BadErrorCode(usize),
}

impl StdError for ParseError { }

impl fmt::Display for ParseError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use self::ParseError::*;

        let desc = match *self {
            BadInteger(_) => "invalid integer",
            BadFloat(_) => "invalid float",
            BadValue(_) => "invalid value",
            BadTime(_) => "invalid date/time",
            BadVersion => "invalid version",
            NotAck => "not an ACK",
            BadPair => "invalid pair",
            BadCode => "invalid code",
            BadPos => "invalid position",
            NoCodePos => "missing code and position",
            NoMessage => "missing position",
            NoRate => "missing audio format rate",
            NoBits => "missing audio format bits",
            NoChans => "missing audio format channels",
            BadRate(_) => "invalid audio format rate",
            BadBits(_) => "invalid audio format bits",
            BadChans(_) => "invalid audio format channels",
            BadState(_) => "invalid playing state",
            BadErrorCode(_) => "unknown error code",
        };

        write!(f, "{}", desc)
    }
}

impl From<TimeParseError> for ParseError {
    fn from(e: TimeParseError) -> ParseError {
        ParseError::BadTime(e)
    }
}

impl From<ParseIntError> for ParseError {
    fn from(e: ParseIntError) -> ParseError {
        ParseError::BadInteger(e)
    }
}

impl From<ParseFloatError> for ParseError {
    fn from(e: ParseFloatError) -> ParseError {
        ParseError::BadFloat(e)
    }
}

impl From<StringParseError> for ParseError {
    fn from(e: StringParseError) -> ParseError {
        match e {}
    }
}
// }}}

// Protocol errors {{{
/// Protocol errors
///
/// They usually occur when server violate expected command response format,
/// like missing fields in answer to some command, missing closing `OK`
/// line after data stream etc.
#[derive(Debug, Clone, PartialEq)]
pub enum ProtoError {
    /// `OK` was expected, but it was missing
    NotOk,
    /// a data pair was expected
    NotPair,
    /// invalid handshake banner received
    BadBanner,
    /// expected some field, but it was missing
    NoField(&'static str),
    /// expected sticker value, but didn't find it
    BadSticker,
}

impl StdError for ProtoError { }

impl fmt::Display for ProtoError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let desc = match *self {
            ProtoError::NotOk => "OK expected",
            ProtoError::NotPair => "pair expected",
            ProtoError::BadBanner => "banner error",
            ProtoError::NoField(_) => "missing field",
            ProtoError::BadSticker => "sticker error",
        };

        write!(f, "{}", desc)
    }
}
// }}}
<|endoftext|>


<commit_before>// This file was generated by gir (af5277e) from gir-files (11e0e6d)
// DO NOT EDIT

use Adjustment;
use CellEditable;
use Editable;
use Entry;
use Orientable;
use ScrollType;
use SpinButtonUpdatePolicy;
use SpinType;
use Widget;
use ffi;
use ffi::GtkScrollType;
use ffi::GtkSpinButton;
use glib::object::Downcast;
use glib::signal::connect;
use glib::translate::*;
use glib_ffi::gboolean;
use glib_ffi::gpointer;
use std::boxed::Box as Box_;
use std::mem;
use std::mem::transmute;

glib_wrapper! {
    pub struct SpinButton(Object<ffi::GtkSpinButton>): Entry, Widget, CellEditable, Editable, Orientable;

    match fn {
        get_type => || ffi::gtk_spin_button_get_type(),
    }
}

impl SpinButton {
    pub fn new(adjustment: Option<&Adjustment>, climb_rate: f64, digits: u32) -> SpinButton {
        assert_initialized_main_thread!();
        unsafe {
            Widget::from_glib_none(ffi::gtk_spin_button_new(adjustment.to_glib_none().0, climb_rate, digits)).downcast_unchecked()
        }
    }

    pub fn new_with_range(min: f64, max: f64, step: f64) -> SpinButton {
        assert_initialized_main_thread!();
        unsafe {
            Widget::from_glib_none(ffi::gtk_spin_button_new_with_range(min, max, step)).downcast_unchecked()
        }
    }

    pub fn configure(&self, adjustment: Option<&Adjustment>, climb_rate: f64, digits: u32) {
        unsafe {
            ffi::gtk_spin_button_configure(self.to_glib_none().0, adjustment.to_glib_none().0, climb_rate, digits);
        }
    }

    pub fn get_adjustment(&self) -> Adjustment {
        unsafe {
            from_glib_none(ffi::gtk_spin_button_get_adjustment(self.to_glib_none().0))
        }
    }

    pub fn get_digits(&self) -> u32 {
        unsafe {
            ffi::gtk_spin_button_get_digits(self.to_glib_none().0)
        }
    }

    pub fn get_increments(&self) -> (f64, f64) {
        unsafe {
            let mut step = mem::uninitialized();
            let mut page = mem::uninitialized();
            ffi::gtk_spin_button_get_increments(self.to_glib_none().0, &mut step, &mut page);
            (step, page)
        }
    }

    pub fn get_numeric(&self) -> bool {
        unsafe {
            from_glib(ffi::gtk_spin_button_get_numeric(self.to_glib_none().0))
        }
    }

    pub fn get_range(&self) -> (f64, f64) {
        unsafe {
            let mut min = mem::uninitialized();
            let mut max = mem::uninitialized();
            ffi::gtk_spin_button_get_range(self.to_glib_none().0, &mut min, &mut max);
            (min, max)
        }
    }

    pub fn get_snap_to_ticks(&self) -> bool {
        unsafe {
            from_glib(ffi::gtk_spin_button_get_snap_to_ticks(self.to_glib_none().0))
        }
    }

    pub fn get_update_policy(&self) -> SpinButtonUpdatePolicy {
        unsafe {
            from_glib(ffi::gtk_spin_button_get_update_policy(self.to_glib_none().0))
        }
    }

    pub fn get_value(&self) -> f64 {
        unsafe {
            ffi::gtk_spin_button_get_value(self.to_glib_none().0)
        }
    }

    pub fn get_value_as_int(&self) -> i32 {
        unsafe {
            ffi::gtk_spin_button_get_value_as_int(self.to_glib_none().0)
        }
    }

    pub fn get_wrap(&self) -> bool {
        unsafe {
            from_glib(ffi::gtk_spin_button_get_wrap(self.to_glib_none().0))
        }
    }

    pub fn set_adjustment(&self, adjustment: &Adjustment) {
        unsafe {
            ffi::gtk_spin_button_set_adjustment(self.to_glib_none().0, adjustment.to_glib_none().0);
        }
    }

    pub fn set_digits(&self, digits: u32) {
        unsafe {
            ffi::gtk_spin_button_set_digits(self.to_glib_none().0, digits);
        }
    }

    pub fn set_increments(&self, step: f64, page: f64) {
        unsafe {
            ffi::gtk_spin_button_set_increments(self.to_glib_none().0, step, page);
        }
    }

    pub fn set_numeric(&self, numeric: bool) {
        unsafe {
            ffi::gtk_spin_button_set_numeric(self.to_glib_none().0, numeric.to_glib());
        }
    }

    pub fn set_range(&self, min: f64, max: f64) {
        unsafe {
            ffi::gtk_spin_button_set_range(self.to_glib_none().0, min, max);
        }
    }

    pub fn set_snap_to_ticks(&self, snap_to_ticks: bool) {
        unsafe {
            ffi::gtk_spin_button_set_snap_to_ticks(self.to_glib_none().0, snap_to_ticks.to_glib());
        }
    }

    pub fn set_update_policy(&self, policy: SpinButtonUpdatePolicy) {
        unsafe {
            ffi::gtk_spin_button_set_update_policy(self.to_glib_none().0, policy.to_glib());
        }
    }

    pub fn set_value(&self, value: f64) {
        unsafe {
            ffi::gtk_spin_button_set_value(self.to_glib_none().0, value);
        }
    }

    pub fn set_wrap(&self, wrap: bool) {
        unsafe {
            ffi::gtk_spin_button_set_wrap(self.to_glib_none().0, wrap.to_glib());
        }
    }

    pub fn spin(&self, direction: SpinType, increment: f64) {
        unsafe {
            ffi::gtk_spin_button_spin(self.to_glib_none().0, direction.to_glib(), increment);
        }
    }

    pub fn update(&self) {
        unsafe {
            ffi::gtk_spin_button_update(self.to_glib_none().0);
        }
    }

    pub fn connect_change_value<F: Fn(&SpinButton, ScrollType) + 'static>(&self, f: F) -> u64 {
        unsafe {
            let f: Box_<Box_<Fn(&SpinButton, ScrollType) + 'static>> = Box_::new(Box_::new(f));
            connect(self.to_glib_none().0, "change-value",
                transmute(change_value_trampoline as usize), Box_::into_raw(f) as *mut _)
        }
    }

    //pub fn connect_input<Unsupported or ignored types>(&self, f: F) -> u64 {
    //    Out new_value: *.Double
    //}

    pub fn connect_output<F: Fn(&SpinButton) -> bool + 'static>(&self, f: F) -> u64 {
        unsafe {
            let f: Box_<Box_<Fn(&SpinButton) -> bool + 'static>> = Box_::new(Box_::new(f));
            connect(self.to_glib_none().0, "output",
                transmute(output_trampoline as usize), Box_::into_raw(f) as *mut _)
        }
    }

    pub fn connect_value_changed<F: Fn(&SpinButton) + 'static>(&self, f: F) -> u64 {
        unsafe {
            let f: Box_<Box_<Fn(&SpinButton) + 'static>> = Box_::new(Box_::new(f));
            connect(self.to_glib_none().0, "value-changed",
                transmute(value_changed_trampoline as usize), Box_::into_raw(f) as *mut _)
        }
    }

    pub fn connect_wrapped<F: Fn(&SpinButton) + 'static>(&self, f: F) -> u64 {
        unsafe {
            let f: Box_<Box_<Fn(&SpinButton) + 'static>> = Box_::new(Box_::new(f));
            connect(self.to_glib_none().0, "wrapped",
                transmute(wrapped_trampoline as usize), Box_::into_raw(f) as *mut _)
        }
    }
}

unsafe extern "C" fn change_value_trampoline(this: *mut GtkSpinButton, scroll: GtkScrollType, f: gpointer) {
    callback_guard!();
    let f: &Box_<Fn(&SpinButton, ScrollType) + 'static> = transmute(f);
    f(&from_glib_none(this), from_glib(scroll))
}

unsafe extern "C" fn output_trampoline(this: *mut GtkSpinButton, f: gpointer) -> gboolean {
    callback_guard!();
    let f: &Box_<Fn(&SpinButton) -> bool + 'static> = transmute(f);
    f(&from_glib_none(this)).to_glib()
}

unsafe extern "C" fn value_changed_trampoline(this: *mut GtkSpinButton, f: gpointer) {
    callback_guard!();
    let f: &Box_<Fn(&SpinButton) + 'static> = transmute(f);
    f(&from_glib_none(this))
}

unsafe extern "C" fn wrapped_trampoline(this: *mut GtkSpinButton, f: gpointer) {
    callback_guard!();
    let f: &Box_<Fn(&SpinButton) + 'static> = transmute(f);
    f(&from_glib_none(this))
}
<commit_msg>Regen<commit_after>// This file was generated by gir (af5277e) from gir-files (11e0e6d)
// DO NOT EDIT

use Adjustment;
use CellEditable;
use Editable;
use Entry;
use Orientable;
use SpinButtonUpdatePolicy;
use SpinType;
use Widget;
use ffi;
use glib::object::Downcast;
use glib::translate::*;
use std::mem;

glib_wrapper! {
    pub struct SpinButton(Object<ffi::GtkSpinButton>): Entry, Widget, CellEditable, Editable, Orientable;

    match fn {
        get_type => || ffi::gtk_spin_button_get_type(),
    }
}

impl SpinButton {
    pub fn new(adjustment: Option<&Adjustment>, climb_rate: f64, digits: u32) -> SpinButton {
        assert_initialized_main_thread!();
        unsafe {
            Widget::from_glib_none(ffi::gtk_spin_button_new(adjustment.to_glib_none().0, climb_rate, digits)).downcast_unchecked()
        }
    }

    pub fn new_with_range(min: f64, max: f64, step: f64) -> SpinButton {
        assert_initialized_main_thread!();
        unsafe {
            Widget::from_glib_none(ffi::gtk_spin_button_new_with_range(min, max, step)).downcast_unchecked()
        }
    }

    pub fn configure(&self, adjustment: Option<&Adjustment>, climb_rate: f64, digits: u32) {
        unsafe {
            ffi::gtk_spin_button_configure(self.to_glib_none().0, adjustment.to_glib_none().0, climb_rate, digits);
        }
    }

    pub fn get_adjustment(&self) -> Adjustment {
        unsafe {
            from_glib_none(ffi::gtk_spin_button_get_adjustment(self.to_glib_none().0))
        }
    }

    pub fn get_digits(&self) -> u32 {
        unsafe {
            ffi::gtk_spin_button_get_digits(self.to_glib_none().0)
        }
    }

    pub fn get_increments(&self) -> (f64, f64) {
        unsafe {
            let mut step = mem::uninitialized();
            let mut page = mem::uninitialized();
            ffi::gtk_spin_button_get_increments(self.to_glib_none().0, &mut step, &mut page);
            (step, page)
        }
    }

    pub fn get_numeric(&self) -> bool {
        unsafe {
            from_glib(ffi::gtk_spin_button_get_numeric(self.to_glib_none().0))
        }
    }

    pub fn get_range(&self) -> (f64, f64) {
        unsafe {
            let mut min = mem::uninitialized();
            let mut max = mem::uninitialized();
            ffi::gtk_spin_button_get_range(self.to_glib_none().0, &mut min, &mut max);
            (min, max)
        }
    }

    pub fn get_snap_to_ticks(&self) -> bool {
        unsafe {
            from_glib(ffi::gtk_spin_button_get_snap_to_ticks(self.to_glib_none().0))
        }
    }

    pub fn get_update_policy(&self) -> SpinButtonUpdatePolicy {
        unsafe {
            from_glib(ffi::gtk_spin_button_get_update_policy(self.to_glib_none().0))
        }
    }

    pub fn get_value(&self) -> f64 {
        unsafe {
            ffi::gtk_spin_button_get_value(self.to_glib_none().0)
        }
    }

    pub fn get_value_as_int(&self) -> i32 {
        unsafe {
            ffi::gtk_spin_button_get_value_as_int(self.to_glib_none().0)
        }
    }

    pub fn get_wrap(&self) -> bool {
        unsafe {
            from_glib(ffi::gtk_spin_button_get_wrap(self.to_glib_none().0))
        }
    }

    pub fn set_adjustment(&self, adjustment: &Adjustment) {
        unsafe {
            ffi::gtk_spin_button_set_adjustment(self.to_glib_none().0, adjustment.to_glib_none().0);
        }
    }

    pub fn set_digits(&self, digits: u32) {
        unsafe {
            ffi::gtk_spin_button_set_digits(self.to_glib_none().0, digits);
        }
    }

    pub fn set_increments(&self, step: f64, page: f64) {
        unsafe {
            ffi::gtk_spin_button_set_increments(self.to_glib_none().0, step, page);
        }
    }

    pub fn set_numeric(&self, numeric: bool) {
        unsafe {
            ffi::gtk_spin_button_set_numeric(self.to_glib_none().0, numeric.to_glib());
        }
    }

    pub fn set_range(&self, min: f64, max: f64) {
        unsafe {
            ffi::gtk_spin_button_set_range(self.to_glib_none().0, min, max);
        }
    }

    pub fn set_snap_to_ticks(&self, snap_to_ticks: bool) {
        unsafe {
            ffi::gtk_spin_button_set_snap_to_ticks(self.to_glib_none().0, snap_to_ticks.to_glib());
        }
    }

    pub fn set_update_policy(&self, policy: SpinButtonUpdatePolicy) {
        unsafe {
            ffi::gtk_spin_button_set_update_policy(self.to_glib_none().0, policy.to_glib());
        }
    }

    pub fn set_value(&self, value: f64) {
        unsafe {
            ffi::gtk_spin_button_set_value(self.to_glib_none().0, value);
        }
    }

    pub fn set_wrap(&self, wrap: bool) {
        unsafe {
            ffi::gtk_spin_button_set_wrap(self.to_glib_none().0, wrap.to_glib());
        }
    }

    pub fn spin(&self, direction: SpinType, increment: f64) {
        unsafe {
            ffi::gtk_spin_button_spin(self.to_glib_none().0, direction.to_glib(), increment);
        }
    }

    pub fn update(&self) {
        unsafe {
            ffi::gtk_spin_button_update(self.to_glib_none().0);
        }
    }
}
<|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.

#[macro_export]
macro_rules! plugin_define(
    ($name:expr, $description:expr, $plugin_init:ident,
     $version:expr, $license:expr, $source:expr,
     $package:expr, $origin:expr, $release_datetime:expr) => {
        pub mod plugin_desc {
            use $crate::glib::translate::{from_glib_borrow, ToGlib};

            // Not using c_char here because it requires the libc crate
            #[allow(non_camel_case_types)]
            type c_char = i8;

            #[repr(C)]
            pub struct GstPluginDesc($crate::gst_ffi::GstPluginDesc);
            unsafe impl Sync for GstPluginDesc {}

            #[no_mangle]
            #[allow(non_upper_case_globals)]
            pub static gst_plugin_desc: GstPluginDesc = GstPluginDesc($crate::gst_ffi::GstPluginDesc {
                major_version: 1,
                minor_version: 8,
                name: $name as *const u8 as *const c_char,
                description: $description as *const u8 as *const c_char,
                plugin_init: Some(plugin_init_trampoline),
                version: $version as *const u8 as *const c_char,
                license: $license as *const u8 as *const c_char,
                source: $source as *const u8 as *const c_char,
                package: $package as *const u8 as *const c_char,
                origin: $origin as *const u8 as *const c_char,
                release_datetime: $release_datetime as *const u8 as *const c_char,
                _gst_reserved: [0 as $crate::glib_ffi::gpointer; 4],
            });

            unsafe extern "C" fn plugin_init_trampoline(plugin: *mut $crate::gst_ffi::GstPlugin) -> $crate::glib_ffi::gboolean {
                use std::panic::{self, AssertUnwindSafe};

                let panic_result = panic::catch_unwind(AssertUnwindSafe(|| super::$plugin_init(&from_glib_borrow(plugin))));
                match panic_result {
                    Ok(register_result) => match register_result {
                        Ok(_) => $crate::glib_ffi::GTRUE,
                        Err(err) => {
                            let cat = $crate::gst::DebugCategory::get("GST_PLUGIN_LOADING").unwrap();
                            gst_error!(cat, "Failed to register plugin: {}", err);
                            $crate::glib_ffi::GFALSE
                        }
                    }
                    Err(err) => {
                        let cat = $crate::gst::DebugCategory::get("GST_PLUGIN_LOADING").unwrap();
                        if let Some(cause) = err.downcast_ref::<&str>() {
                            gst_error!(cat, "Failed to initialize plugin due to panic: {}", cause);
                        } else if let Some(cause) = err.downcast_ref::<String>() {
                            gst_error!(cat, "Failed to initialize plugin due to panic: {}", cause);
                        } else {
                            gst_error!(cat, "Failed to initialize plugin due to panic");
                        }

                        $crate::glib_ffi::GFALSE
                    }
                }
            }
        }
    };
);
<commit_msg>create plugin_register_static in plugin_define!<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.

#[macro_export]
macro_rules! plugin_define(
    ($name:expr, $description:expr, $plugin_init:ident,
     $version:expr, $license:expr, $source:expr,
     $package:expr, $origin:expr, $release_datetime:expr) => {
        pub mod plugin_desc {
            use $crate::glib::translate::{from_glib_borrow, ToGlib, from_glib};

            const MAJOR_VERSION: i32 = 1;
            const MINOR_VERSION: i32 = 8;

            // Not using c_char here because it requires the libc crate
            #[allow(non_camel_case_types)]
            type c_char = i8;

            #[repr(C)]
            pub struct GstPluginDesc($crate::gst_ffi::GstPluginDesc);
            unsafe impl Sync for GstPluginDesc {}

            #[no_mangle]
            #[allow(non_upper_case_globals)]
            pub static gst_plugin_desc: GstPluginDesc = GstPluginDesc($crate::gst_ffi::GstPluginDesc {
                major_version: MAJOR_VERSION,
                minor_version: MINOR_VERSION,
                name: $name as *const u8 as *const c_char,
                description: $description as *const u8 as *const c_char,
                plugin_init: Some(plugin_init_trampoline),
                version: $version as *const u8 as *const c_char,
                license: $license as *const u8 as *const c_char,
                source: $source as *const u8 as *const c_char,
                package: $package as *const u8 as *const c_char,
                origin: $origin as *const u8 as *const c_char,
                release_datetime: $release_datetime as *const u8 as *const c_char,
                _gst_reserved: [0 as $crate::glib_ffi::gpointer; 4],
            });

            pub fn plugin_register_static() -> bool {
                unsafe {
                    from_glib($crate::gst_ffi::gst_plugin_register_static(
                        MAJOR_VERSION,
                        MINOR_VERSION,
                        $name as *const u8 as *const c_char,
                        $description as *const u8 as *const c_char,
                        Some(plugin_init_trampoline),
                        $version as *const u8 as *const c_char,
                        $license as *const u8 as *const c_char,
                        $source as *const u8 as *const c_char,
                        $package as *const u8 as *const c_char,
                        $origin as *const u8 as *const c_char,
                    ))
                }
            }

            unsafe extern "C" fn plugin_init_trampoline(plugin: *mut $crate::gst_ffi::GstPlugin) -> $crate::glib_ffi::gboolean {
                use std::panic::{self, AssertUnwindSafe};

                let panic_result = panic::catch_unwind(AssertUnwindSafe(|| super::$plugin_init(&from_glib_borrow(plugin))));
                match panic_result {
                    Ok(register_result) => match register_result {
                        Ok(_) => $crate::glib_ffi::GTRUE,
                        Err(err) => {
                            let cat = $crate::gst::DebugCategory::get("GST_PLUGIN_LOADING").unwrap();
                            gst_error!(cat, "Failed to register plugin: {}", err);
                            $crate::glib_ffi::GFALSE
                        }
                    }
                    Err(err) => {
                        let cat = $crate::gst::DebugCategory::get("GST_PLUGIN_LOADING").unwrap();
                        if let Some(cause) = err.downcast_ref::<&str>() {
                            gst_error!(cat, "Failed to initialize plugin due to panic: {}", cause);
                        } else if let Some(cause) = err.downcast_ref::<String>() {
                            gst_error!(cat, "Failed to initialize plugin due to panic: {}", cause);
                        } else {
                            gst_error!(cat, "Failed to initialize plugin due to panic");
                        }

                        $crate::glib_ffi::GFALSE
                    }
                }
            }
        }
        pub use plugin_desc::plugin_register_static;
    };
);
<|endoftext|>