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

/// Connect events to sending a message.
///
/// ## Rules
/// 1. Send `$msg` to `$other_component` when the GTK+ `$event` is emitted on `$widget`.
///
/// 2. Optionally send `$msg.0` when the GTK+ `$event` is emitted on `$widget`.
/// Return `$msg.1` in the GTK+ callback.
/// This variant gives more control to the caller since it expects a `$msg` returning `(Option<MSG>,
/// ReturnValue)` where the `ReturnValue` is the value to return in the GTK+ callback.
/// Option<MSG> can be None if no message needs to be emitted.
///
/// 3. Send `$msg` when the GTK+ `$event` is emitted on `$widget`.
///
/// 4. Send `$msg` to `$widget` when the `$message` is received on `$stream`.
#[macro_export]
macro_rules! connect {
    // Connect to a GTK+ widget event, sending a message to another widget.
    ($widget:expr, $event:ident($($args:pat),*), $other_component:expr, $msg:expr) => {
        connect_stream!($widget, $event($($args),*), $other_component.stream(), $msg);
    };

    // Connect to a GTK+ widget event.
    // This variant gives more control to the caller since it expects a `$msg` returning (Option<MSG>,
    // ReturnValue) where the ReturnValue is the value to return in the GTK+ callback.
    // Option<MSG> can be None if no message needs to be emitted.
    ($relm:expr, $widget:expr, $event:ident($($args:pat),*), return $msg:expr) => {{
        connect_stream!(return $relm.stream(), $widget, $event($($args),*), $msg);
    }};

    // Connect to a GTK+ widget event.
    ($relm:expr, $widget:expr, $event:ident($($args:pat),*), $msg:expr) => {{
        let stream = $relm.stream().clone();
        let _ = $widget.$event(move |$($args),*| {
            let msg: Option<_> = $crate::IntoOption::into_option($msg);
            if let Some(msg) = msg {
                stream.emit(msg);
            }
        });
    }};

    // Connect to a message reception.
    // TODO: create another macro rule accepting multiple patterns.
    ($src_component:ident @ $message:pat, $dst_component:expr, $msg:expr) => {
        let stream = $src_component.stream().clone();
        connect_stream!(stream@$message, $dst_component.stream(), $msg);
    };
}

/// Connect events to sending a message.
/// Similar to `connect!` but wants a stream instead of a component.
///
/// ## Rules
/// 1. Send `$msg` to `$other_stream` when the GTK+ `$event` is emitted on `$widget`.
///
/// 2. Send `$msg` to `$widget` when the `$message` is received on `$stream`.
#[macro_export]
macro_rules! connect_stream {
    // Connect to a GTK+ widget event.
    // This variant gives more control to the caller since it expects a `$msg` returning (Option<MSG>,
    // ReturnValue) where the ReturnValue is the value to return in the GTK+ callback.
    // Option<MSG> can be None if no message needs to be emitted.
    (return $stream:expr, $widget:expr, $event:ident($($args:pat),*), $msg:expr) => {{
        let stream = $stream.clone();
        let _ = $widget.$event(move |$($args),*| {
            let (msg, return_value) = $crate::IntoPair::into_pair($msg);
            let msg: Option<_> = $crate::IntoOption::into_option(msg);
            if let Some(msg) = msg {
                stream.emit(msg);
            }
            return_value
        });
    }};

    // Connect to a GTK+ widget event, sending a message to another widget.
    ($widget:expr, $event:ident($($args:pat),*), $other_stream:expr, $msg:expr) => {
        let stream = $other_stream.clone();
        let _ = $widget.$event(move |$($args),*| {
            let msg: Option<_> = $crate::IntoOption::into_option($msg);
            if let Some(msg) = msg {
                stream.emit(msg);
            }
        });
    };

    // Connect to a message reception.
    // TODO: create another macro rule accepting multiple patterns.
    ($src_stream:ident @ $message:pat, $dst_stream:expr, $msg:expr) => {
        let stream = $dst_stream.clone();
        $src_stream.observe(move |msg| {
            #[allow(unreachable_patterns)]
            match msg {
                &$message =>  {
                    let msg: Option<_> = $crate::IntoOption::into_option($msg);
                    if let Some(msg) = msg {
                        stream.emit(msg);
                    }
                },
                _ => (),
            }
        });
    };
}

/// Connect an asynchronous method call to send a message.
/// The variants with `$fail_msg` will send this message when there's an error.
/// Those without this argument will ignore the error.
#[macro_export]
macro_rules! connect_async {
    ($object:expr, $async_method:ident, $relm:expr, $msg:ident) => {
        connect_async!($object, $async_method(), $relm, $msg)
    };
    ($object:expr, $async_method:ident ( $($args:expr),* ), $relm:expr, $msg:ident) => {{
        use ::futures::Sink;
        let (tx, rx) = ::futures::sync::mpsc::unbounded();
        let tx = ::std::sync::Mutex::new(tx);
        $object.$async_method($($args,)* None, move |result| {
            if let Ok(result) = result {
                let mut tx = tx.lock().unwrap();
                if let Ok(::futures::AsyncSink::Ready) = tx.start_send(result) {
                    tx.poll_complete().unwrap();
                } else {
                    eprintln!("Unable to send message to sender");
                }
            }
        });
        $relm.connect_exec_ignore_err(rx, $msg);
    }};
    ($object:expr, $async_method:ident, $relm:expr, $msg:ident, $fail_msg:ident) => {
        connect_async!($object, $async_method(), $relm, $msg, $fail_msg)
    };
    ($object:expr, $async_method:ident ( $($args:expr),* ), $relm:expr, $msg:ident, $fail_msg:ident) => {{
        use ::futures::{Sink, Stream};
        let (tx, rx) = ::futures::sync::mpsc::unbounded();
        let tx = ::std::sync::Mutex::new(tx);
        $object.$async_method($($args,)* None, move |result| {
            let mut tx = tx.lock().unwrap();
            if let Ok(::futures::AsyncSink::Ready) = tx.start_send(result) {
                tx.poll_complete().unwrap();
            } else {
                eprintln!("Unable to send message to sender");
            }
        });

        let event_stream = $relm.stream().clone();
        let fail_event_stream = $relm.stream().clone();
        let future =
            rx.for_each(move |result| {
                match result {
                    Ok(value) => event_stream.emit($msg(value)),
                    Err(error) => fail_event_stream.emit($fail_msg(error)),
                }
                Ok(())
            });
        $relm.exec(future);
    }};
}

/// Connect an asynchronous function call to send a message.
/// The variants with `$fail_msg` will send this message when there's an error.
/// Those without this argument will ignore the error.
#[macro_export]
macro_rules! connect_async_func {
    ($class:ident :: $async_function:ident, $relm:expr, $msg:ident) => {
        connect_async!($async_func(), $relm, $msg)
    };
    ($class:ident :: $async_func:ident ( $($args:expr),* ), $relm:expr, $msg:ident) => {{
        use ::futures::Sink;
        let (tx, rx) = ::futures::sync::mpsc::unbounded();
        let tx = ::std::sync::Mutex::new(tx);
        $class::$async_func($($args,)* None, move |result| {
            if let Ok(result) = result {
                let mut tx = tx.lock().unwrap();
                if let Ok(::futures::AsyncSink::Ready) = tx.start_send(result) {
                    tx.poll_complete().unwrap();
                } else {
                    eprintln!("Unable to send message to sender");
                }
            }
        });
        $relm.connect_exec_ignore_err(rx, $msg);
    }};
    ($class:ident :: $async_func:ident, $relm:expr, $msg:ident, $fail_msg:ident) => {
        connect_async!($async_func(), $relm, $msg, $fail_msg)
    };
    ($class:ident :: $async_func:ident ( $($args:expr),* ), $relm:expr, $msg:ident, $fail_msg:ident) => {{
        use ::futures::{Sink, Stream};
        let (tx, rx) = ::futures::sync::mpsc::unbounded();
        let tx = ::std::sync::Mutex::new(tx);
        $class::$async_func($($args,)* None, move |result| {
            let mut tx = tx.lock().unwrap();
            if let Ok(::futures::AsyncSink::Ready) = tx.start_send(result) {
                tx.poll_complete().unwrap();
            } else {
                eprintln!("Unable to send message to sender");
            }
        });

        let event_stream = $relm.stream().clone();
        let fail_event_stream = $relm.stream().clone();
        let future =
            rx.for_each(move |result| {
                match result {
                    Ok(value) => event_stream.emit($msg(value)),
                    Err(error) => fail_event_stream.emit($fail_msg(error)),
                }
                Ok(())
            });
        $relm.exec(future);
    }};
}

/// Like `connect_async!`, but also return a `Cancellable` to control the asynchronous request.
#[macro_export]
macro_rules! connect_async_full {
    ($object:expr, $async_method:ident, $relm:expr, $msg:ident) => {
        connect_async_full!($object, $async_method(), $relm, $msg)
    };
    ($object:expr, $async_method:ident ( $($args:expr),* ), $relm:expr, $msg:ident) => {{
        let cancellable = ::gio::Cancellable::new();
        use ::futures::Sink;
        let (tx, rx) = ::futures::sync::mpsc::unbounded();
        let tx = ::std::sync::Mutex::new(tx);
        $object.$async_method($($args,)* Some(&cancellable), move |result| {
            if let Ok(result) = result {
                let mut tx = tx.lock().unwrap();
                if let Ok(::futures::AsyncSink::Ready) = tx.start_send(result) {
                    tx.poll_complete().unwrap();
                } else {
                    eprintln!("Unable to send message to sender");
                }
            }
        });
        $relm.connect_exec_ignore_err(rx, $msg);
        cancellable
    }};
    ($object:expr, $async_method:ident, $relm:expr, $msg:ident, $fail_msg:ident) => {
        connect_async_full!($object, $async_method(), $relm, $msg, $fail_msg)
    };
    ($object:expr, $async_method:ident ( $($args:expr),* ), $relm:expr, $msg:ident, $fail_msg:ident) => {{
        let cancellable = ::gio::Cancellable::new();
        use ::futures::{Sink, Stream};
        let (tx, rx) = ::futures::sync::mpsc::unbounded();
        let tx = ::std::sync::Mutex::new(tx);
        $object.$async_method($($args,)* Some(&cancellable), move |result| {
            let mut tx = tx.lock().unwrap();
            if let Ok(::futures::AsyncSink::Ready) = tx.start_send(result) {
                tx.poll_complete().unwrap();
            } else {
                eprintln!("Unable to send message to sender");
            }
        });

        let event_stream = $relm.stream().clone();
        let fail_event_stream = $relm.stream().clone();
        let future =
            rx.for_each(move |result| {
                match result {
                    Ok(value) => event_stream.emit($msg(value)),
                    Err(error) => fail_event_stream.emit($fail_msg(error)),
                }
                Ok(())
            });
        $relm.exec(future);
        cancellable
    }};
}

/// Like `connect_async_func!`, but also return a `Cancellable` to control the asynchronous request.
#[macro_export]
macro_rules! connect_async_func_full {
    ($class:ident :: $async_function:ident, $relm:expr, $msg:ident) => {
        connect_async!($async_func(), $relm, $msg)
    };
    ($class:ident :: $async_func:ident ( $($args:expr),* ), $relm:expr, $msg:ident) => {{
        let cancellable = ::gio::Cancellable::new();
        use ::futures::Sink;
        let (tx, rx) = ::futures::sync::mpsc::unbounded();
        let tx = ::std::sync::Mutex::new(tx);
        $class::$async_func($($args,)* Some(&cancellable), move |result| {
            if let Ok(result) = result {
                let mut tx = tx.lock().unwrap();
                if let Ok(::futures::AsyncSink::Ready) = tx.start_send(result) {
                    tx.poll_complete().unwrap();
                } else {
                    eprintln!("Unable to send message to sender");
                }
            }
        });
        $relm.connect_exec_ignore_err(rx, $msg);
        cancellable
    }};
    ($class:ident :: $async_func:ident, $relm:expr, $msg:ident, $fail_msg:ident) => {
        connect_async!($async_func(), $relm, $msg, $fail_msg)
    };
    ($class:ident :: $async_func:ident ( $($args:expr),* ), $relm:expr, $msg:ident, $fail_msg:ident) => {{
        let cancellable = ::gio::Cancellable::new();
        use ::futures::{Sink, Stream};
        let (tx, rx) = ::futures::sync::mpsc::unbounded();
        let tx = ::std::sync::Mutex::new(tx);
        $class::$async_func($($args,)* Some(&cancellable), move |result| {
            let mut tx = tx.lock().unwrap();
            if let Ok(::futures::AsyncSink::Ready) = tx.start_send(result) {
                tx.poll_complete().unwrap();
            } else {
                eprintln!("Unable to send message to sender");
            }
        });

        let event_stream = $relm.stream().clone();
        let fail_event_stream = $relm.stream().clone();
        let future =
            rx.for_each(move |result| {
                match result {
                    Ok(value) => event_stream.emit($msg(value)),
                    Err(error) => fail_event_stream.emit($fail_msg(error)),
                }
                Ok(())
            });
        $relm.exec(future);
        cancellable
    }};
}
<commit_msg>Revert "Temporary fix to publish the crate"<commit_after>/*
 * Copyright (c) 2017 Boucher, Antoni <bouanto@zoho.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

include!("../relm-state/src/macros.rs");
<|endoftext|>


<commit_before>/// Gets the offset of a field. Used by container_of!
macro_rules! offset_of(
    ($ty:ty, $field:ident) => {
        &(*(0 as *const $ty)).$field as *const _ as usize
    }
);

/// Gets the parent struct from a pointer.
/// VERY unsafe. The parent struct _must_ be repr(C), and the
/// type passed to this macro _must_ match the type of the parent.
macro_rules! container_of (
    ($ptr: expr, $container: ty, $field: ident) => {
        ($ptr as *mut u8).offset(-(offset_of!($container, $field) as isize)) as *mut $container
    }
);

/// Iterates over a wl_list.
///
/// # Safety
/// It is not safe to delete an element while iterating over the list,
/// so don't do it!
macro_rules! wl_list_for_each {
    ($ptr: expr, $field: ident, ($pos: ident : $container: ty) => $body: block) => {
        let mut $pos: *mut $container;
        $pos = container_of!($ptr.next, $container, $field);
        loop {
            if &(*$pos).$field as *const _ == &$ptr as *const _ {
                break
            }
            { $body }
            $pos = container_of!((*$pos).$field.next, $container, $field);
        }
    }
}

/// Convert a literal string to a C string.
/// Note: Does not check for internal nulls, nor does it do any conversions on
/// the grapheme clustors. Just passes the bytes as is.
/// So probably only works on ASCII.
#[macro_export]
macro_rules! c_str {
    ($s:expr) => {
        concat!($s, "\0").as_ptr() as *const i8
    }
}

/// Logs a message using wlroots' logging capability.
///
/// Possible values for `verb`:
///
/// * L_SILENT
/// * L_INFO
/// * L_DEBUG
/// * L_ERROR
#[macro_export]
macro_rules! wlr_log {
    ($verb: expr, $($msg:tt)*) => {{
        use $crate::wlroots_sys::_wlr_log;
        use $crate::wlroots_sys::log_importance_t::*;
        use ::std::ffi::CString;
        unsafe {
            let fmt = CString::new(format!($($msg)*))
                .expect("Could not convert log message to C string");
            let raw = fmt.into_raw();
            _wlr_log($verb, c_str!("[%s:%lu] %s"),
                    c_str!(file!()), line!(), raw);
            // Deallocate string
            CString::from_raw(raw);
        }
    }}
}

/// Defines a new struct that contains a variable number of listeners that
/// will trigger unsafe user-defined callbacks.
///
/// The structure that is defined is repr(C), has one `data` field with the
/// given user type, and a field for each `$listener`.
///
/// Each `$listener` has a getter method that lets you get the pointer to the
/// listener. This method is unsafe, since it returns a raw pointer.
/// To use it correctly, you need to ensure that the data it refers to never
/// moves (e.g keep it in a box). The primary purpose of this method is to pass
/// the listener pointer to other methods to register it for a Wayland event.
/// **A listener can only be registered to one event at a time**.
///
/// Finally, it also takes in a body for each `$listener` that is called
/// every time the event that is later hooked up to it is fired.
/// This method is inherently unsafe, because the user data hasn't been cast
/// from the void pointer yet. It is the user's job to write this safely.
/// To highlight this fact, the body of the function must be prefixed with
/// `unsafe`.
///
/// # Example
/// ```rust,no_run,ignore
/// #[macro_use] extern crate wlroots;
/// extern crate wlroots_sys;
/// #[macro_use] extern crate wayland_sys;
/// extern crate libc;
///
/// use wlroots::InputDevice;
/// use wlroots_sys::wlr_input_device;
///
/// // Handles input addition and removal.
/// pub trait InputManagerHandler {
///     // Callback triggered when an input device is added.
///     fn input_added(&mut self, InputDevice);
/// }
///
/// wayland_listener!(
///     // The name of the structure that will be defined.
///     InputManager,
///     // The type that's stored in the `data` field.
///     // Note that we use a Box here to achieve dynamic dispatch,
///     // it's not required for this type to be in a box.
///     Box<InputManagerHandler>,
///     [
///         // Adds a new listener called `add_listener`.
///         // Adds an unsafe function called `add_notify` that is triggered
///         // whenever add_listener is activated from a Wayland event.
///         add_listener => add_notify: |this: &mut InputManager, data: *mut libc::c_void,| unsafe {
///             let ref mut manager = this.data;
///             // Call the method defined above, wrapping it in a safe interface.
///             // It is your job to ensure that the code in here doesn't trigger UB!
///             manager.input_added(InputDevice::from_ptr(data as *mut wlr_input_device))
///         };
///     ]
/// );
/// # fn main() {}
/// ```
///
/// # Unsafety
/// Note that the purpose of this macro is to make it easy to generate unsafe
/// boiler plate for using listeners with Rust data.
///
/// However, there are a few things this macro doesn't protect against.
///
/// First and foremost, the data cannot move. The listeners assume that the
/// structure will never move, so in order to defend against this the generated
/// `new` method returns a Box version. **Do not move out of the box**.
///
/// Second, this macro doesn't protect against the stored data being unsized.
/// Passing a pointer of unsized data to C is UB, don't do it.
macro_rules! wayland_listener {
    ($struct_name: ident, $data: ty, $([
        $($listener: ident => $listener_func: ident :
          |$($func_arg:ident: $func_type:ty,)*| unsafe $body: block;)*])+) => {
        #[repr(C)]
        pub struct $struct_name {
            data: $data,
            $($($listener: $crate::wlroots_sys::wl_listener),*)*
        }

        impl $struct_name {
            pub(crate) fn new(data: $data) -> Box<$struct_name> {
                use $crate::wayland_sys::server::WAYLAND_SERVER_HANDLE;
                Box::new($struct_name {
                    data,
                    $($($listener: unsafe {
                        // NOTE Rationale for zeroed memory:
                        // * Need to pass a pointer to wl_list_init
                        // * The list is initialized by Wayland, which doesn't "drop"
                        // * The listener is written to without dropping any of the data
                        let mut listener: $crate::wlroots_sys::wl_listener = ::std::mem::zeroed();
                        ffi_dispatch!(WAYLAND_SERVER_HANDLE,
                                      wl_list_init,
                                      &mut listener.link as *mut _ as _);
                        ::std::ptr::write(&mut listener.notify, Some($struct_name::$listener_func));
                        listener
                    }),*)*
                })
            }

            $($(pub(crate) unsafe extern "C" fn $listener(&mut self)
                                                   -> *mut $crate::wlroots_sys::wl_listener {
                &mut self.$listener as *mut _
            })*)*

            $($(pub(crate) unsafe extern "C" fn $listener_func(listener:
                                                        *mut $crate::wlroots_sys::wl_listener,
                                                        data: *mut libc::c_void) {
                let manager: &mut $struct_name = &mut (*container_of!(listener,
                                                                      $struct_name,
                                                                      $listener));
                $crate::utils::handle_unwind(
                    ::std::panic::catch_unwind(
                        ::std::panic::AssertUnwindSafe(|| {
                            (|$($func_arg: $func_type,)*| { $body })(manager, data)
                        })));
            })*)*
        }
    }
}

/// Used to indicate what data is global compositor data.
/// It will automatically implement the CompositorData trait for the struct,
/// and also add a method to `Compositor` to unwrap the data from the fat
/// pointer.
#[macro_export]
macro_rules! compositor_data {
    ($struct_name: ty) => {
        impl<'a>::std::convert::From<&'a mut $crate::Compositor> for &'a mut $struct_name {
            fn from(compositor: &'a mut $crate::Compositor) -> &'a mut $struct_name {
                &mut *compositor.data.downcast_mut::<$struct_name>()
                    .unwrap_or_else(|| {
                        wlr_log!(L_ERROR, "Could not cast compositor state to {:#?}",
                                 stringify!($struct_name));
                        panic!("Could not cast compositor state to correct value")
                    })
            }
        }
    }
}

/// A convenience macro designed for use with Handle types.
///
/// This allows you to avoid the rightward drift of death that is often found
/// with heavily nested callback systems.
///
/// Any `HandleResult`s are flattened and the first one encountered is immediately
/// returned before any of the `$body` code is executed.
///
/// Order of evaluation is from left to right. It is possible to refer to the previous
/// result, as commonly found in Lisp's `let*` macro.
///
/// An example of simple use:
///
/// ```rust,ignore
/// with_handles!([(compositor: {compositor}),
///    (output: {&mut result.output_handle})] => {
///    ...
/// })
/// ```
///
/// A more complex use:
///
/// ```rust,ignore
/// with_handles!([(shell: {shell_handle}),
///    // Notice how we use the previous result to get the surface.
///    (surface: {shell.surface_handle})] => {
///    ...
/// })
/// ```
///
#[macro_export]
macro_rules! with_handles {
    ([($handle_name: ident: $unhandle_name: block)] => $body: block) => {
        $unhandle_name.run(|$handle_name| {
            $body
        })
    };
    ([($handle_name1: ident: $unhandle_name1: block),
      ($handle_name2: ident: $unhandle_name2: block),
      $($rest: tt)*] => $body: block) => {
        $unhandle_name1.run(|$handle_name1| {
            with_handles!([($handle_name2: $unhandle_name2), $($rest)*] => $body)
        }).and_then(|n: $crate::HandleResult<_>| n)
    };
    ([($handle_name: ident: $unhandle_name: block), $($rest: tt)*] => $body: block) => {
        $unhandle_name.run(|$handle_name| {
            with_handles!([$($rest)*] => $body)
        }).and_then(|n: $crate::HandleResult<_>| n)
    };
}

/// An even more convenient macro for use with Handle types.
///
/// This allows you to avoid rightward drift from having handles nested inside
/// each other.
///
/// Any `HandleResult`s are flattened and the first one encountered is immediantly
/// returned.
///
/// Note that unlike `with_handles` it is possible for some of the code to execute
/// before a `HandleErr` is returned. At each @ line there's the possibility
/// it will return an Error early.
///
/// To make this more clear, it is mandated that a ? is appended to each of these lines.
///
/// Here is some code using `with_handles`:
///
/// ```no_run,no_run,ignore
/// with_handles!([(compositor: {compositor})] => {
///     let state: &mut State = compositor.into();
///     with_handles!([(shell: {&state.shell_handle})] => {
///         // Do stuff with shell
///     }).unwrap();
/// }).unwrap();
/// ```
///
/// Here is that some code using `dehandle!`
/// ```no_run,no_run,ignore
///dehandle!(
///    @compositor = {compositor_handle}?;
///    let state: &mut State = compositor.into()
///    @shell = {&state.shell_handle}?;
///    // do stuff with shell
///).unwrap().unwrap();
///```
///
///
/// Now here is that same code in dehandle! but this time without the ? error handling:
/// ```no_run,no_run,ignore
///dehandle!(
///    @compositor = {compositor_handle};
///    let state: &mut State = compositor.into()
///    @shell = {&state.shell_handle};
///    // do stuff with shell
///);
///```
///
/// If an error occurs in the `@` lines with out the `?` it will panic with
/// an ok-ish stacktrace and an error message pointing out exactly which one
/// failed (e.g. it would say unwrapping `{&state.shell_handle}` and
/// placing the result in `shell` failed)
#[macro_export]
macro_rules! dehandle {
    // Handles going into an extra scope
    ({$($b: tt)*}) => {
        #[allow(unused_must_use)]
        {dehandle!($($b)*)}
    };
    // Handles going into an extra scope with more things after it
    ({$($b: tt)*} $($rest: tt)*) => {{
        #[allow(unused_must_use)]
        {dehandle!($($b)*)};
        dehandle!($($rest)*)
    }};
    // While loop, nothing after it
    (while $_: expr => {$($b: tt)*}) => {{
        #[allow(unused_must_use)]
        while $_ {
            dehandle!($($b)*);
        }
    }};
    // While loop, more stuff after it
    (while $_: expr => {$($b: tt)*} $($rest: tt)*) => {{
        #[allow(unused_must_use)]
        while $_ {
            dehandle!($($b)*);
        }
        dehandle!($($rest)*)
    }};

    // For loop, nothing after it
    (for $_: pat in $__: expr => {$($b: tt)*}) => {{
        #[allow(unused_must_use)]
        for $_ in $__ {
            dehandle!($($b)*);
        }
    }};
    // For loop, more stuff after it
    (for $_: pat in $__: expr => {$($b: tt)*} $($rest: tt)*) => {{
        #[allow(unused_must_use)]
        for $_ in $__ {
            dehandle!($($b)*);
        }
        dehandle!($($rest)*)
    }};
    // @unhandle = {handle};
    // This one will automatically unwrap the result.
    (@$handle_name: ident = $unhandle_name: block; $($rest: tt)+) => {
        with_handles!([($handle_name: $unhandle_name)] => {
            dehandle!($($rest)+)
        }).expect(concat!("Could not upgrade ", stringify!(unhandle_name), " and set the result to ", stringify!(handle_name)));
    };
    // @unhandle = {handle}?;
    (@$handle_name: ident = $unhandle_name: block?; $($rest: tt)+) => {
        with_handles!([($handle_name: $unhandle_name)] => {
            dehandle!($($rest)+)
        })
    };
    // General expressions
    ($line: expr; $($rest: tt)*) => {
        {
            $line;
            dehandle!($($rest)*)
        }
    };
    // General lines
    ($line: stmt; $($rest: tt)*) => {
        {
            $line;
            dehandle!($($rest)*)
        }
    };
    // Result of the dehandle block
    ($line: expr) => {
        $line
    };
}
<commit_msg>Fixed the error message string for dehandle wo/ ?<commit_after>/// Gets the offset of a field. Used by container_of!
macro_rules! offset_of(
    ($ty:ty, $field:ident) => {
        &(*(0 as *const $ty)).$field as *const _ as usize
    }
);

/// Gets the parent struct from a pointer.
/// VERY unsafe. The parent struct _must_ be repr(C), and the
/// type passed to this macro _must_ match the type of the parent.
macro_rules! container_of (
    ($ptr: expr, $container: ty, $field: ident) => {
        ($ptr as *mut u8).offset(-(offset_of!($container, $field) as isize)) as *mut $container
    }
);

/// Iterates over a wl_list.
///
/// # Safety
/// It is not safe to delete an element while iterating over the list,
/// so don't do it!
macro_rules! wl_list_for_each {
    ($ptr: expr, $field: ident, ($pos: ident : $container: ty) => $body: block) => {
        let mut $pos: *mut $container;
        $pos = container_of!($ptr.next, $container, $field);
        loop {
            if &(*$pos).$field as *const _ == &$ptr as *const _ {
                break
            }
            { $body }
            $pos = container_of!((*$pos).$field.next, $container, $field);
        }
    }
}

/// Convert a literal string to a C string.
/// Note: Does not check for internal nulls, nor does it do any conversions on
/// the grapheme clustors. Just passes the bytes as is.
/// So probably only works on ASCII.
#[macro_export]
macro_rules! c_str {
    ($s:expr) => {
        concat!($s, "\0").as_ptr() as *const i8
    }
}

/// Logs a message using wlroots' logging capability.
///
/// Possible values for `verb`:
///
/// * L_SILENT
/// * L_INFO
/// * L_DEBUG
/// * L_ERROR
#[macro_export]
macro_rules! wlr_log {
    ($verb: expr, $($msg:tt)*) => {{
        use $crate::wlroots_sys::_wlr_log;
        use $crate::wlroots_sys::log_importance_t::*;
        use ::std::ffi::CString;
        unsafe {
            let fmt = CString::new(format!($($msg)*))
                .expect("Could not convert log message to C string");
            let raw = fmt.into_raw();
            _wlr_log($verb, c_str!("[%s:%lu] %s"),
                    c_str!(file!()), line!(), raw);
            // Deallocate string
            CString::from_raw(raw);
        }
    }}
}

/// Defines a new struct that contains a variable number of listeners that
/// will trigger unsafe user-defined callbacks.
///
/// The structure that is defined is repr(C), has one `data` field with the
/// given user type, and a field for each `$listener`.
///
/// Each `$listener` has a getter method that lets you get the pointer to the
/// listener. This method is unsafe, since it returns a raw pointer.
/// To use it correctly, you need to ensure that the data it refers to never
/// moves (e.g keep it in a box). The primary purpose of this method is to pass
/// the listener pointer to other methods to register it for a Wayland event.
/// **A listener can only be registered to one event at a time**.
///
/// Finally, it also takes in a body for each `$listener` that is called
/// every time the event that is later hooked up to it is fired.
/// This method is inherently unsafe, because the user data hasn't been cast
/// from the void pointer yet. It is the user's job to write this safely.
/// To highlight this fact, the body of the function must be prefixed with
/// `unsafe`.
///
/// # Example
/// ```rust,no_run,ignore
/// #[macro_use] extern crate wlroots;
/// extern crate wlroots_sys;
/// #[macro_use] extern crate wayland_sys;
/// extern crate libc;
///
/// use wlroots::InputDevice;
/// use wlroots_sys::wlr_input_device;
///
/// // Handles input addition and removal.
/// pub trait InputManagerHandler {
///     // Callback triggered when an input device is added.
///     fn input_added(&mut self, InputDevice);
/// }
///
/// wayland_listener!(
///     // The name of the structure that will be defined.
///     InputManager,
///     // The type that's stored in the `data` field.
///     // Note that we use a Box here to achieve dynamic dispatch,
///     // it's not required for this type to be in a box.
///     Box<InputManagerHandler>,
///     [
///         // Adds a new listener called `add_listener`.
///         // Adds an unsafe function called `add_notify` that is triggered
///         // whenever add_listener is activated from a Wayland event.
///         add_listener => add_notify: |this: &mut InputManager, data: *mut libc::c_void,| unsafe {
///             let ref mut manager = this.data;
///             // Call the method defined above, wrapping it in a safe interface.
///             // It is your job to ensure that the code in here doesn't trigger UB!
///             manager.input_added(InputDevice::from_ptr(data as *mut wlr_input_device))
///         };
///     ]
/// );
/// # fn main() {}
/// ```
///
/// # Unsafety
/// Note that the purpose of this macro is to make it easy to generate unsafe
/// boiler plate for using listeners with Rust data.
///
/// However, there are a few things this macro doesn't protect against.
///
/// First and foremost, the data cannot move. The listeners assume that the
/// structure will never move, so in order to defend against this the generated
/// `new` method returns a Box version. **Do not move out of the box**.
///
/// Second, this macro doesn't protect against the stored data being unsized.
/// Passing a pointer of unsized data to C is UB, don't do it.
macro_rules! wayland_listener {
    ($struct_name: ident, $data: ty, $([
        $($listener: ident => $listener_func: ident :
          |$($func_arg:ident: $func_type:ty,)*| unsafe $body: block;)*])+) => {
        #[repr(C)]
        pub struct $struct_name {
            data: $data,
            $($($listener: $crate::wlroots_sys::wl_listener),*)*
        }

        impl $struct_name {
            pub(crate) fn new(data: $data) -> Box<$struct_name> {
                use $crate::wayland_sys::server::WAYLAND_SERVER_HANDLE;
                Box::new($struct_name {
                    data,
                    $($($listener: unsafe {
                        // NOTE Rationale for zeroed memory:
                        // * Need to pass a pointer to wl_list_init
                        // * The list is initialized by Wayland, which doesn't "drop"
                        // * The listener is written to without dropping any of the data
                        let mut listener: $crate::wlroots_sys::wl_listener = ::std::mem::zeroed();
                        ffi_dispatch!(WAYLAND_SERVER_HANDLE,
                                      wl_list_init,
                                      &mut listener.link as *mut _ as _);
                        ::std::ptr::write(&mut listener.notify, Some($struct_name::$listener_func));
                        listener
                    }),*)*
                })
            }

            $($(pub(crate) unsafe extern "C" fn $listener(&mut self)
                                                   -> *mut $crate::wlroots_sys::wl_listener {
                &mut self.$listener as *mut _
            })*)*

            $($(pub(crate) unsafe extern "C" fn $listener_func(listener:
                                                        *mut $crate::wlroots_sys::wl_listener,
                                                        data: *mut libc::c_void) {
                let manager: &mut $struct_name = &mut (*container_of!(listener,
                                                                      $struct_name,
                                                                      $listener));
                $crate::utils::handle_unwind(
                    ::std::panic::catch_unwind(
                        ::std::panic::AssertUnwindSafe(|| {
                            (|$($func_arg: $func_type,)*| { $body })(manager, data)
                        })));
            })*)*
        }
    }
}

/// Used to indicate what data is global compositor data.
/// It will automatically implement the CompositorData trait for the struct,
/// and also add a method to `Compositor` to unwrap the data from the fat
/// pointer.
#[macro_export]
macro_rules! compositor_data {
    ($struct_name: ty) => {
        impl<'a>::std::convert::From<&'a mut $crate::Compositor> for &'a mut $struct_name {
            fn from(compositor: &'a mut $crate::Compositor) -> &'a mut $struct_name {
                &mut *compositor.data.downcast_mut::<$struct_name>()
                    .unwrap_or_else(|| {
                        wlr_log!(L_ERROR, "Could not cast compositor state to {:#?}",
                                 stringify!($struct_name));
                        panic!("Could not cast compositor state to correct value")
                    })
            }
        }
    }
}

/// A convenience macro designed for use with Handle types.
///
/// This allows you to avoid the rightward drift of death that is often found
/// with heavily nested callback systems.
///
/// Any `HandleResult`s are flattened and the first one encountered is immediately
/// returned before any of the `$body` code is executed.
///
/// Order of evaluation is from left to right. It is possible to refer to the previous
/// result, as commonly found in Lisp's `let*` macro.
///
/// An example of simple use:
///
/// ```rust,ignore
/// with_handles!([(compositor: {compositor}),
///    (output: {&mut result.output_handle})] => {
///    ...
/// })
/// ```
///
/// A more complex use:
///
/// ```rust,ignore
/// with_handles!([(shell: {shell_handle}),
///    // Notice how we use the previous result to get the surface.
///    (surface: {shell.surface_handle})] => {
///    ...
/// })
/// ```
///
#[macro_export]
macro_rules! with_handles {
    ([($handle_name: ident: $unhandle_name: block)] => $body: block) => {
        $unhandle_name.run(|$handle_name| {
            $body
        })
    };
    ([($handle_name1: ident: $unhandle_name1: block),
      ($handle_name2: ident: $unhandle_name2: block),
      $($rest: tt)*] => $body: block) => {
        $unhandle_name1.run(|$handle_name1| {
            with_handles!([($handle_name2: $unhandle_name2), $($rest)*] => $body)
        }).and_then(|n: $crate::HandleResult<_>| n)
    };
    ([($handle_name: ident: $unhandle_name: block), $($rest: tt)*] => $body: block) => {
        $unhandle_name.run(|$handle_name| {
            with_handles!([$($rest)*] => $body)
        }).and_then(|n: $crate::HandleResult<_>| n)
    };
}

/// An even more convenient macro for use with Handle types.
///
/// This allows you to avoid rightward drift from having handles nested inside
/// each other.
///
/// Any `HandleResult`s are flattened and the first one encountered is immediantly
/// returned.
///
/// Note that unlike `with_handles` it is possible for some of the code to execute
/// before a `HandleErr` is returned. At each @ line there's the possibility
/// it will return an Error early.
///
/// To make this more clear, it is mandated that a ? is appended to each of these lines.
///
/// Here is some code using `with_handles`:
///
/// ```no_run,no_run,ignore
/// with_handles!([(compositor: {compositor})] => {
///     let state: &mut State = compositor.into();
///     with_handles!([(shell: {&state.shell_handle})] => {
///         // Do stuff with shell
///     }).unwrap();
/// }).unwrap();
/// ```
///
/// Here is that some code using `dehandle!`
/// ```no_run,no_run,ignore
///dehandle!(
///    @compositor = {compositor_handle}?;
///    let state: &mut State = compositor.into()
///    @shell = {&state.shell_handle}?;
///    // do stuff with shell
///).unwrap().unwrap();
///```
///
///
/// Now here is that same code in dehandle! but this time without the ? error handling:
/// ```no_run,no_run,ignore
///dehandle!(
///    @compositor = {compositor_handle};
///    let state: &mut State = compositor.into()
///    @shell = {&state.shell_handle};
///    // do stuff with shell
///);
///```
///
/// If an error occurs in the `@` lines with out the `?` it will panic with
/// an ok-ish stacktrace and an error message pointing out exactly which one
/// failed (e.g. it would say unwrapping `{&state.shell_handle}` and
/// placing the result in `shell` failed)
#[macro_export]
macro_rules! dehandle {
    // Handles going into an extra scope
    ({$($b: tt)*}) => {
        #[allow(unused_must_use)]
        {dehandle!($($b)*)}
    };
    // Handles going into an extra scope with more things after it
    ({$($b: tt)*} $($rest: tt)*) => {{
        #[allow(unused_must_use)]
        {dehandle!($($b)*)};
        dehandle!($($rest)*)
    }};
    // While loop, nothing after it
    (while $_: expr => {$($b: tt)*}) => {{
        #[allow(unused_must_use)]
        while $_ {
            dehandle!($($b)*);
        }
    }};
    // While loop, more stuff after it
    (while $_: expr => {$($b: tt)*} $($rest: tt)*) => {{
        #[allow(unused_must_use)]
        while $_ {
            dehandle!($($b)*);
        }
        dehandle!($($rest)*)
    }};

    // For loop, nothing after it
    (for $_: pat in $__: expr => {$($b: tt)*}) => {{
        #[allow(unused_must_use)]
        for $_ in $__ {
            dehandle!($($b)*);
        }
    }};
    // For loop, more stuff after it
    (for $_: pat in $__: expr => {$($b: tt)*} $($rest: tt)*) => {{
        #[allow(unused_must_use)]
        for $_ in $__ {
            dehandle!($($b)*);
        }
        dehandle!($($rest)*)
    }};
    // @unhandle = {handle};
    // This one will automatically unwrap the result.
    (@$handle_name: ident = $unhandle_name: block; $($rest: tt)+) => {
        with_handles!([($handle_name: $unhandle_name)] => {
            dehandle!($($rest)+)
        }).expect(concat!("Could not upgrade ", stringify!($unhandle_name), " and set the result to ", stringify!($handle_name)));
    };
    // @unhandle = {handle}?;
    (@$handle_name: ident = $unhandle_name: block?; $($rest: tt)+) => {
        with_handles!([($handle_name: $unhandle_name)] => {
            dehandle!($($rest)+)
        })
    };
    // General expressions
    ($line: expr; $($rest: tt)*) => {
        {
            $line;
            dehandle!($($rest)*)
        }
    };
    // General lines
    ($line: stmt; $($rest: tt)*) => {
        {
            $line;
            dehandle!($($rest)*)
        }
    };
    // Result of the dehandle block
    ($line: expr) => {
        $line
    };
}
<|endoftext|>


<commit_before>/// Macro emulating `do`-notation for the parser monad, automatically threading the linear type.
///
/// ```ignore
/// parse!{input;
///                 parser("parameter");
///     let value = other_parser();
///
///     ret do_something(value);
/// }
/// // equivalent to:
/// parser(input, "parameter").bind(|i, _|
///     other_parser(i).bind(|i, value|
///         i.ret(do_something(value))))
/// ```
///
/// # Example
///
/// ```
/// # #[macro_use] extern crate chomp;
/// # fn main() {
/// use chomp::{Input, ParseResult, Error};
/// use chomp::{take_while1, token};
///
/// let i = Input::new("martin wernstål\n".as_bytes());
///
/// #[derive(Debug, Eq, PartialEq)]
/// struct Name<'a> {
///     first: &'a [u8],
///     last:  &'a [u8],
/// }
///
/// let r = parse!{i;
///     let first = take_while1(|c| c != b' ');
///                 token(b' ');
///     let last  = take_while1(|c| c != b'\n');
///
///     ret @ _, Error<_>: Name{
///         first: first,
///         last:  last,
///     }
/// };
///
/// assert_eq!(r.unwrap(), Name{first: b"martin", last: "wernstål".as_bytes()});
/// # }
/// ```
///
/// ## Grammar
///
/// EBNF using `$ty`, `$expr`, `$ident` and `$pat` for the equivalent Rust macro patterns.
///
/// ```text
/// RET_TYPED     = '@' $ty ',' $ty ':' $expr
/// RET_PLAIN     = $expr
///
/// ERR_TYPED     = '@' $ty ',' $ty ':' $expr
/// ERR_PLAIN     = $expr
///
/// VAR           = $ident ':' $ty | $pat
/// ACTION        = INLINE_ACTION | NAMED_ACTION
/// INLINE_ACTION = $ident '->' $expr
/// NAMED_ACTION  = $ident '(' ($expr ',')* ','? ')'
///
/// BIND          = 'let' VAR '=' ACTION
/// THEN          = ACTION
///
/// RET           = 'ret' ( RET_TYPED | RET_PLAIN )
/// ERR           = 'err' ( ERR_TYPED | ERR_PLAIN )
///
/// EXPR          = ( BIND ';' | THEN ';' )* (RET | ERR | THEN)
/// ```
#[macro_export]
macro_rules! parse {
    ( $($t:tt)* ) => { __parse_internal!{ $($t)* } };
}

/// Actual implementation of the parse macro, hidden to make the documentation easier to read.
#[macro_export]
#[doc(hidden)]
macro_rules! __parse_internal {
    // RET_TYPED     = '@' $ty ',' $ty ':' $expr
    ( @RET($i:expr); @ $t_ty:ty , $e_ty:ty : $e:expr ) => { $i.ret::<$t_ty, $e_ty>($e) };

    // RET_PLAIN     = $expr
    ( @RET($i:expr); $e:expr ) => { $i.ret($e) };

    // ERR_TYPED     = '@' $ty ',' $ty ':' $expr
    ( @ERR($i:expr); @ $t_ty:ty , $e_ty:ty : $e:expr ) => { $i.err::<$t_ty, $e_ty>($e) };

    // ERR_PLAIN     = $expr
    ( @ERR($i:expr); $e:expr ) => { $i.err($e) };

    // VAR           = $ident ':' $ty | $pat
    // pattern must be before ident
    ( @BIND($i:expr); $v:pat              = $($t:tt)* ) => { __parse_internal!{ @ACTION($i, $v      ); $($t)* } };
    ( @BIND($i:expr); $v:ident : $v_ty:ty = $($t:tt)* ) => { __parse_internal!{ @ACTION($i, $v:$v_ty); $($t)* } };

    // ACTION        = INLINE_ACTION | NAMED_ACTION

    // INLINE_ACTION = $ident '->' $expr
    // version with expression following, nonterminal:
    ( @ACTION($i:expr, $($v:tt)*); $m:ident -> $e:expr ; $($t:tt)*) => { __parse_internal!{ @CONCAT({ let $m = $i; $e }, $($v)*); $($t)* } };
    // terminal:
    ( @ACTION($i:expr, $($v:tt)*); $m:ident -> $e:expr )            => { { let $m = $i; $e } };

    // NAMED_ACTION  = $ident '(' ($expr ',')* ','? ')'
    // version with expression following, nonterminal:
    ( @ACTION($i:expr, $($v:tt)*); $f:ident ( $($p:expr),* $(,)*) ; $($t:tt)* ) => { __parse_internal!{ @CONCAT($f($i, $($p),*), $($v)*); $($t)*} };
    // terminal:
    ( @ACTION($i:expr, $($v:tt)*); $f:ident ( $($p:expr),* $(,)*) )             => { $f($i, $($p),*) };

    // Ties an expression together with the next, using the bind operator
    // invoked from @ACTION and @BIND (via @ACTION)
    // three variants are needed to coerce the tt-list into a parameter token
    // an additional three variants are needed to handle tailing semicolons, if there is nothing
    // else to expand, do not use bind
    ( @CONCAT($i:expr, _                  );              ) => { $i };
    ( @CONCAT($i:expr, _                  ); $($tail:tt)+ ) => { $i.bind(|i, _|        __parse_internal!{ i; $($tail)* }) };
    ( @CONCAT($i:expr, $v:pat             );              ) => { $i };
    ( @CONCAT($i:expr, $v:pat             ); $($tail:tt)+ ) => { $i.bind(|i, $v|       __parse_internal!{ i; $($tail)* }) };
    ( @CONCAT($i:expr, $v:ident : $v_ty:ty);              ) => { $i };
    ( @CONCAT($i:expr, $v:ident : $v_ty:ty); $($tail:tt)+ ) => { $i.bind(|i, $v:$v_ty| __parse_internal!{ i; $($tail)* }) };

    // EXPR          = ( BIND ';' | THEN ';' )* (RET | ERR | THEN)
    // TODO: Any way to prevent BIND from being the last?

    // BIND          = 'let' VAR '=' ACTION
    ( $i:expr ; let $($tail:tt)* ) => { __parse_internal!{ @BIND($i); $($tail)+ } };
    // RET           = 'ret' ( RET_TYPED | RET_PLAIN )
    ( $i:expr ; ret $($tail:tt)+ ) => { __parse_internal!{ @RET($i); $($tail)+ } };
    // ERR           = 'err' ( ERR_TYPED | ERR_PLAIN )
    ( $i:expr ; err $($tail:tt)+ ) => { __parse_internal!{ @ERR($i); $($tail)+ } };
    // THEN          = ACTION
    // needs to be last since it is the most general
    ( $i:expr ; $($tail:tt)+ )     => { __parse_internal!{ @ACTION($i, _); $($tail)+ } };

    // Terminals:
    ( $i:expr ; ) => { $i };
    ( $i:expr )   => { $i };
}

#[cfg(test)]
mod test {
    /// Simplified implementation of the emulated monad using linear types.
    #[derive(Debug, Eq, PartialEq)]
    struct Input(i64);
    /// Simplified implementation of the emulated monad using linear types.
    #[derive(Debug, Eq, PartialEq)]
    enum Data<T, E> {
        Value(i64, T),
        Error(i64, E),
    }

    impl Input {
        fn ret<T, E>(self, t: T) -> Data<T, E> {
            Data::Value(self.0, t)
        }

        fn err<T, E>(self, e: E) -> Data<T, E> {
            Data::Error(self.0, e)
        }
    }

    impl<T, E> Data<T, E> {
        fn bind<F, U, V = E>(self, f: F) -> Data<U, V>
          where F: FnOnce(Input, T) -> Data<U, V>,
                V: From<E> {
            match self {
                Data::Value(i, t) => f(Input(i), t).map_err(From::from),
                Data::Error(i, e) => Data::Error(i, From::from(e)),
            }
        }

        fn map_err<F, V>(self, f: F) -> Data<T, V>
          where F: FnOnce(E) -> V {
            match self {
                Data::Value(i, t) => Data::Value(i, t),
                Data::Error(i, e) => Data::Error(i, f(e)),
            }
        }
    }

    #[test]
    fn empty() {
        let i = 123;

        let r = parse!{i};

        assert_eq!(r, 123);
    }

    #[test]
    fn empty_expr() {
        let r = parse!{1 + 2};

        assert_eq!(r, 3);
    }

    #[test]
    fn ret() {
        let i = Input(123);

        // Type annotation necessary since ret leaves E free
        let r: Data<_, ()> = parse!{i; ret "foo"};

        assert_eq!(r, Data::Value(123, "foo"));
    }

    #[test]
    fn ret_typed() {
        let i = Input(123);

        let r = parse!{i; ret @ _, (): "foo"};

        assert_eq!(r, Data::Value(123, "foo"));
    }

    #[test]
    fn ret_typed2() {
        let i = Input(123);

        let r = parse!{i; ret @ &str, (): "foo"};

        assert_eq!(r, Data::Value(123, "foo"));
    }

    #[test]
    fn err() {
        let i = Input(123);

        // Type annotation necessary since err leaves T free
        let r: Data<(), _> = parse!{i; err "foo"};

        assert_eq!(r, Data::Error(123, "foo"));
    }

    #[test]
    fn err_typed() {
        let i = Input(123);

        let r = parse!{i; err @(), _: "foo"};

        assert_eq!(r, Data::Error(123, "foo"));
    }

    #[test]
    fn err_typed2() {
        let i = Input(123);

        let r = parse!{i; err @(), &str: "foo"};

        assert_eq!(r, Data::Error(123, "foo"));
    }

    #[test]
    fn action() {
        fn doit(i: Input) -> Data<&'static str, ()> {
            Data::Value(i.0, "doit")
        }

        let i = Input(123);

        let r = parse!(i; doit());

        assert_eq!(r, Data::Value(123, "doit"));
    }

    #[test]
    fn action2() {
        fn doit(i: Input, p: &str) -> Data<&str, ()> {
            Data::Value(i.0, p)
        }

        let i = Input(123);

        let r = parse!(i; doit("doit"));

        assert_eq!(r, Data::Value(123, "doit"));
    }

    #[test]
    fn action3() {
        fn doit(i: Input, p: &str, u: u32) -> Data<(&str, u32), ()> {
            Data::Value(i.0, (p, u))
        }

        let i = Input(123);

        let r = parse!(i; doit("doit", 1337));

        assert_eq!(r, Data::Value(123, ("doit", 1337)));
    }

    #[test]
    fn two_actions() {
        fn doit(i: Input) -> Data<u32, ()> {
            assert_eq!(i.0, 123);

            Data::Value(321, 1)
        }
        fn something(i: Input) -> Data<u32, ()> {
            assert_eq!(i.0, 321);

            Data::Value(123, 2)
        }

        let i = Input(123);

        let r = parse!(i; doit(); something());

        assert_eq!(r, Data::Value(123, 2));
    }

    #[test]
    fn two_actions2() {
        fn doit(i: Input, n: u32) -> Data<u32, ()> {
            assert_eq!(i.0, 123);

            Data::Value(321, n)
        }
        fn something(i: Input, n: u32) -> Data<u32, ()> {
            assert_eq!(i.0, 321);

            Data::Value(123, n)
        }

        let i = Input(123);

        let r = parse!(i; doit(22); something(33));

        assert_eq!(r, Data::Value(123, 33));
    }

    #[test]
    fn two_actions3() {
        fn doit(i: Input, n: u32, x: i32) -> Data<(u32, i32), ()> {
            assert_eq!(i.0, 123);

            Data::Value(321, (n, x))
        }
        fn something(i: Input, n: u32, x: i32) -> Data<(u32, i32), ()> {
            assert_eq!(i.0, 321);

            Data::Value(123, (n, x))
        }

        let i = Input(123);

        let r = parse!(i; doit(22, 1); something(33, 2));

        assert_eq!(r, Data::Value(123, (33, 2)));
    }

    #[test]
    fn tailing_semicolon() {
        fn f(n: u32) -> u32 {
            n + 3
        }

        let r = parse!{123; f(); };

        assert_eq!(r, 126);
    }
}
<commit_msg>Rustdoc: Changed an ignore example to text<commit_after>/// Macro emulating `do`-notation for the parser monad, automatically threading the linear type.
///
/// ```text
/// parse!{input;
///                 parser("parameter");
///     let value = other_parser();
///
///     ret do_something(value);
/// }
/// // is equivalent to:
/// parser(input, "parameter").bind(|i, _|
///     other_parser(i).bind(|i, value|
///         i.ret(do_something(value))))
/// ```
///
/// # Example
///
/// ```
/// # #[macro_use] extern crate chomp;
/// # fn main() {
/// use chomp::{Input, ParseResult, Error};
/// use chomp::{take_while1, token};
///
/// let i = Input::new("martin wernstål\n".as_bytes());
///
/// #[derive(Debug, Eq, PartialEq)]
/// struct Name<'a> {
///     first: &'a [u8],
///     last:  &'a [u8],
/// }
///
/// let r = parse!{i;
///     let first = take_while1(|c| c != b' ');
///                 token(b' ');
///     let last  = take_while1(|c| c != b'\n');
///
///     ret @ _, Error<_>: Name{
///         first: first,
///         last:  last,
///     }
/// };
///
/// assert_eq!(r.unwrap(), Name{first: b"martin", last: "wernstål".as_bytes()});
/// # }
/// ```
///
/// ## Grammar
///
/// EBNF using `$ty`, `$expr`, `$ident` and `$pat` for the equivalent Rust macro patterns.
///
/// ```text
/// RET_TYPED     = '@' $ty ',' $ty ':' $expr
/// RET_PLAIN     = $expr
///
/// ERR_TYPED     = '@' $ty ',' $ty ':' $expr
/// ERR_PLAIN     = $expr
///
/// VAR           = $ident ':' $ty | $pat
/// ACTION        = INLINE_ACTION | NAMED_ACTION
/// INLINE_ACTION = $ident '->' $expr
/// NAMED_ACTION  = $ident '(' ($expr ',')* ','? ')'
///
/// BIND          = 'let' VAR '=' ACTION
/// THEN          = ACTION
///
/// RET           = 'ret' ( RET_TYPED | RET_PLAIN )
/// ERR           = 'err' ( ERR_TYPED | ERR_PLAIN )
///
/// EXPR          = ( BIND ';' | THEN ';' )* (RET | ERR | THEN)
/// ```
#[macro_export]
macro_rules! parse {
    ( $($t:tt)* ) => { __parse_internal!{ $($t)* } };
}

/// Actual implementation of the parse macro, hidden to make the documentation easier to read.
#[macro_export]
#[doc(hidden)]
macro_rules! __parse_internal {
    // RET_TYPED     = '@' $ty ',' $ty ':' $expr
    ( @RET($i:expr); @ $t_ty:ty , $e_ty:ty : $e:expr ) => { $i.ret::<$t_ty, $e_ty>($e) };

    // RET_PLAIN     = $expr
    ( @RET($i:expr); $e:expr ) => { $i.ret($e) };

    // ERR_TYPED     = '@' $ty ',' $ty ':' $expr
    ( @ERR($i:expr); @ $t_ty:ty , $e_ty:ty : $e:expr ) => { $i.err::<$t_ty, $e_ty>($e) };

    // ERR_PLAIN     = $expr
    ( @ERR($i:expr); $e:expr ) => { $i.err($e) };

    // VAR           = $ident ':' $ty | $pat
    // pattern must be before ident
    ( @BIND($i:expr); $v:pat              = $($t:tt)* ) => { __parse_internal!{ @ACTION($i, $v      ); $($t)* } };
    ( @BIND($i:expr); $v:ident : $v_ty:ty = $($t:tt)* ) => { __parse_internal!{ @ACTION($i, $v:$v_ty); $($t)* } };

    // ACTION        = INLINE_ACTION | NAMED_ACTION

    // INLINE_ACTION = $ident '->' $expr
    // version with expression following, nonterminal:
    ( @ACTION($i:expr, $($v:tt)*); $m:ident -> $e:expr ; $($t:tt)*) => { __parse_internal!{ @CONCAT({ let $m = $i; $e }, $($v)*); $($t)* } };
    // terminal:
    ( @ACTION($i:expr, $($v:tt)*); $m:ident -> $e:expr )            => { { let $m = $i; $e } };

    // NAMED_ACTION  = $ident '(' ($expr ',')* ','? ')'
    // version with expression following, nonterminal:
    ( @ACTION($i:expr, $($v:tt)*); $f:ident ( $($p:expr),* $(,)*) ; $($t:tt)* ) => { __parse_internal!{ @CONCAT($f($i, $($p),*), $($v)*); $($t)*} };
    // terminal:
    ( @ACTION($i:expr, $($v:tt)*); $f:ident ( $($p:expr),* $(,)*) )             => { $f($i, $($p),*) };

    // Ties an expression together with the next, using the bind operator
    // invoked from @ACTION and @BIND (via @ACTION)
    // three variants are needed to coerce the tt-list into a parameter token
    // an additional three variants are needed to handle tailing semicolons, if there is nothing
    // else to expand, do not use bind
    ( @CONCAT($i:expr, _                  );              ) => { $i };
    ( @CONCAT($i:expr, _                  ); $($tail:tt)+ ) => { $i.bind(|i, _|        __parse_internal!{ i; $($tail)* }) };
    ( @CONCAT($i:expr, $v:pat             );              ) => { $i };
    ( @CONCAT($i:expr, $v:pat             ); $($tail:tt)+ ) => { $i.bind(|i, $v|       __parse_internal!{ i; $($tail)* }) };
    ( @CONCAT($i:expr, $v:ident : $v_ty:ty);              ) => { $i };
    ( @CONCAT($i:expr, $v:ident : $v_ty:ty); $($tail:tt)+ ) => { $i.bind(|i, $v:$v_ty| __parse_internal!{ i; $($tail)* }) };

    // EXPR          = ( BIND ';' | THEN ';' )* (RET | ERR | THEN)
    // TODO: Any way to prevent BIND from being the last?

    // BIND          = 'let' VAR '=' ACTION
    ( $i:expr ; let $($tail:tt)* ) => { __parse_internal!{ @BIND($i); $($tail)+ } };
    // RET           = 'ret' ( RET_TYPED | RET_PLAIN )
    ( $i:expr ; ret $($tail:tt)+ ) => { __parse_internal!{ @RET($i); $($tail)+ } };
    // ERR           = 'err' ( ERR_TYPED | ERR_PLAIN )
    ( $i:expr ; err $($tail:tt)+ ) => { __parse_internal!{ @ERR($i); $($tail)+ } };
    // THEN          = ACTION
    // needs to be last since it is the most general
    ( $i:expr ; $($tail:tt)+ )     => { __parse_internal!{ @ACTION($i, _); $($tail)+ } };

    // Terminals:
    ( $i:expr ; ) => { $i };
    ( $i:expr )   => { $i };
}

#[cfg(test)]
mod test {
    /// Simplified implementation of the emulated monad using linear types.
    #[derive(Debug, Eq, PartialEq)]
    struct Input(i64);
    /// Simplified implementation of the emulated monad using linear types.
    #[derive(Debug, Eq, PartialEq)]
    enum Data<T, E> {
        Value(i64, T),
        Error(i64, E),
    }

    impl Input {
        fn ret<T, E>(self, t: T) -> Data<T, E> {
            Data::Value(self.0, t)
        }

        fn err<T, E>(self, e: E) -> Data<T, E> {
            Data::Error(self.0, e)
        }
    }

    impl<T, E> Data<T, E> {
        fn bind<F, U, V = E>(self, f: F) -> Data<U, V>
          where F: FnOnce(Input, T) -> Data<U, V>,
                V: From<E> {
            match self {
                Data::Value(i, t) => f(Input(i), t).map_err(From::from),
                Data::Error(i, e) => Data::Error(i, From::from(e)),
            }
        }

        fn map_err<F, V>(self, f: F) -> Data<T, V>
          where F: FnOnce(E) -> V {
            match self {
                Data::Value(i, t) => Data::Value(i, t),
                Data::Error(i, e) => Data::Error(i, f(e)),
            }
        }
    }

    #[test]
    fn empty() {
        let i = 123;

        let r = parse!{i};

        assert_eq!(r, 123);
    }

    #[test]
    fn empty_expr() {
        let r = parse!{1 + 2};

        assert_eq!(r, 3);
    }

    #[test]
    fn ret() {
        let i = Input(123);

        // Type annotation necessary since ret leaves E free
        let r: Data<_, ()> = parse!{i; ret "foo"};

        assert_eq!(r, Data::Value(123, "foo"));
    }

    #[test]
    fn ret_typed() {
        let i = Input(123);

        let r = parse!{i; ret @ _, (): "foo"};

        assert_eq!(r, Data::Value(123, "foo"));
    }

    #[test]
    fn ret_typed2() {
        let i = Input(123);

        let r = parse!{i; ret @ &str, (): "foo"};

        assert_eq!(r, Data::Value(123, "foo"));
    }

    #[test]
    fn err() {
        let i = Input(123);

        // Type annotation necessary since err leaves T free
        let r: Data<(), _> = parse!{i; err "foo"};

        assert_eq!(r, Data::Error(123, "foo"));
    }

    #[test]
    fn err_typed() {
        let i = Input(123);

        let r = parse!{i; err @(), _: "foo"};

        assert_eq!(r, Data::Error(123, "foo"));
    }

    #[test]
    fn err_typed2() {
        let i = Input(123);

        let r = parse!{i; err @(), &str: "foo"};

        assert_eq!(r, Data::Error(123, "foo"));
    }

    #[test]
    fn action() {
        fn doit(i: Input) -> Data<&'static str, ()> {
            Data::Value(i.0, "doit")
        }

        let i = Input(123);

        let r = parse!(i; doit());

        assert_eq!(r, Data::Value(123, "doit"));
    }

    #[test]
    fn action2() {
        fn doit(i: Input, p: &str) -> Data<&str, ()> {
            Data::Value(i.0, p)
        }

        let i = Input(123);

        let r = parse!(i; doit("doit"));

        assert_eq!(r, Data::Value(123, "doit"));
    }

    #[test]
    fn action3() {
        fn doit(i: Input, p: &str, u: u32) -> Data<(&str, u32), ()> {
            Data::Value(i.0, (p, u))
        }

        let i = Input(123);

        let r = parse!(i; doit("doit", 1337));

        assert_eq!(r, Data::Value(123, ("doit", 1337)));
    }

    #[test]
    fn two_actions() {
        fn doit(i: Input) -> Data<u32, ()> {
            assert_eq!(i.0, 123);

            Data::Value(321, 1)
        }
        fn something(i: Input) -> Data<u32, ()> {
            assert_eq!(i.0, 321);

            Data::Value(123, 2)
        }

        let i = Input(123);

        let r = parse!(i; doit(); something());

        assert_eq!(r, Data::Value(123, 2));
    }

    #[test]
    fn two_actions2() {
        fn doit(i: Input, n: u32) -> Data<u32, ()> {
            assert_eq!(i.0, 123);

            Data::Value(321, n)
        }
        fn something(i: Input, n: u32) -> Data<u32, ()> {
            assert_eq!(i.0, 321);

            Data::Value(123, n)
        }

        let i = Input(123);

        let r = parse!(i; doit(22); something(33));

        assert_eq!(r, Data::Value(123, 33));
    }

    #[test]
    fn two_actions3() {
        fn doit(i: Input, n: u32, x: i32) -> Data<(u32, i32), ()> {
            assert_eq!(i.0, 123);

            Data::Value(321, (n, x))
        }
        fn something(i: Input, n: u32, x: i32) -> Data<(u32, i32), ()> {
            assert_eq!(i.0, 321);

            Data::Value(123, (n, x))
        }

        let i = Input(123);

        let r = parse!(i; doit(22, 1); something(33, 2));

        assert_eq!(r, Data::Value(123, (33, 2)));
    }

    #[test]
    fn tailing_semicolon() {
        fn f(n: u32) -> u32 {
            n + 3
        }

        let r = parse!{123; f(); };

        assert_eq!(r, 126);
    }
}
<|endoftext|>


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

/// Approximate equality of using the absolute difference.
#[macro_export]
macro_rules! abs_diff_eq {
    ($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*) => {
        $crate::AbsDiff::default()$(.$opt($val))*.eq(&$lhs, &$rhs)
    };
    ($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*,) => {
        $crate::AbsDiff::default()$(.$opt($val))*.eq(&$lhs, &$rhs)
    };
}

/// Approximate inequality of using the absolute difference.
#[macro_export]
macro_rules! abs_diff_ne {
    ($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*) => {
        $crate::AbsDiff::default()$(.$opt($val))*.ne(&$lhs, &$rhs)
    };
    ($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*,) => {
        $crate::AbsDiff::default()$(.$opt($val))*.ne(&$lhs, &$rhs)
    };
}

/// Approximate equality using both the absolute difference and relative based comparisons.
#[macro_export]
macro_rules! relative_eq {
    ($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*) => {
        $crate::Relative::default()$(.$opt($val))*.eq(&$lhs, &$rhs)
    };
    ($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*,) => {
        $crate::Relative::default()$(.$opt($val))*.eq(&$lhs, &$rhs)
    };
}

/// Approximate inequality using both the absolute difference and relative based comparisons.
#[macro_export]
macro_rules! relative_ne {
    ($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*) => {
        $crate::Relative::default()$(.$opt($val))*.ne(&$lhs, &$rhs)
    };
    ($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*,) => {
        $crate::Relative::default()$(.$opt($val))*.ne(&$lhs, &$rhs)
    };
}

/// Approximate equality using both the absolute difference and ULPs (Units in Last Place).
#[macro_export]
macro_rules! ulps_eq {
    ($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*) => {
        $crate::Ulps::default()$(.$opt($val))*.eq(&$lhs, &$rhs)
    };
    ($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*,) => {
        $crate::Ulps::default()$(.$opt($val))*.eq(&$lhs, &$rhs)
    };
}

/// Approximate inequality using both the absolute difference and ULPs (Units in Last Place).
#[macro_export]
macro_rules! ulps_ne {
    ($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*) => {
        $crate::Ulps::default()$(.$opt($val))*.ne(&$lhs, &$rhs)
    };
    ($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*,) => {
        $crate::Ulps::default()$(.$opt($val))*.ne(&$lhs, &$rhs)
    };
}

#[doc(hidden)]
#[macro_export]
macro_rules! __assert_approx {
    ($eq:ident, $given:expr, $expected:expr) => {{
        let (given, expected) = (&($given), &($expected));

        if !$eq!(*given, *expected) {
            panic!(
"assert_{}!({}, {})

    left  = {:?}
    right = {:?}

",
                stringify!($eq),
                stringify!($given),
                stringify!($expected),
                given, expected,
            );
        }
    }};
    ($eq:ident, $given:expr, $expected:expr, $($opt:ident = $val:expr),+) => {{
        let (given, expected) = (&($given), &($expected));

        if !$eq!(*given, *expected, $($opt = $val),+) {
            panic!(
"assert_{}!({}, {}, {})

    left  = {:?}
    right = {:?}

",
                stringify!($eq),
                stringify!($given),
                stringify!($expected),
                stringify!($($opt = $val),+),
                given, expected,
            );
        }
    }};
}

/// An assertion that delegates to `abs_diff_eq!`, and panics with a helpful error on failure.
#[macro_export]
macro_rules! assert_abs_diff_eq {
    ($given:expr, $expected:expr $(, $opt:ident = $val:expr)*) => {
        __assert_approx!(abs_diff_eq, $given, $expected $(, $opt = $val)*)
    };
    ($given:expr, $expected:expr $(, $opt:ident = $val:expr)*,) => {
        __assert_approx!(abs_diff_eq, $given, $expected $(, $opt = $val)*)
    };
}

/// An assertion that delegates to `abs_diff_ne!`, and panics with a helpful error on failure.
#[macro_export]
macro_rules! assert_abs_diff_ne {
    ($given:expr, $expected:expr $(, $opt:ident = $val:expr)*) => {
        __assert_approx!(abs_diff_ne, $given, $expected $(, $opt = $val)*)
    };
    ($given:expr, $expected:expr $(, $opt:ident = $val:expr)*,) => {
        __assert_approx!(abs_diff_ne, $given, $expected $(, $opt = $val)*)
    };
}

/// An assertion that delegates to `relative_eq!`, and panics with a helpful error on failure.
#[macro_export]
macro_rules! assert_relative_eq {
    ($given:expr, $expected:expr $(, $opt:ident = $val:expr)*) => {
        __assert_approx!(relative_eq, $given, $expected $(, $opt = $val)*)
    };
    ($given:expr, $expected:expr $(, $opt:ident = $val:expr)*,) => {
        __assert_approx!(relative_eq, $given, $expected $(, $opt = $val)*)
    };
}

/// An assertion that delegates to `relative_ne!`, and panics with a helpful error on failure.
#[macro_export]
macro_rules! assert_relative_ne {
    ($given:expr, $expected:expr $(, $opt:ident = $val:expr)*) => {
        __assert_approx!(relative_ne, $given, $expected $(, $opt = $val)*)
    };
    ($given:expr, $expected:expr $(, $opt:ident = $val:expr)*,) => {
        __assert_approx!(relative_ne, $given, $expected $(, $opt = $val)*)
    };
}

/// An assertion that delegates to `ulps_eq!`, and panics with a helpful error on failure.
#[macro_export]
macro_rules! assert_ulps_eq {
    ($given:expr, $expected:expr $(, $opt:ident = $val:expr)*) => {
        __assert_approx!(ulps_eq, $given, $expected $(, $opt = $val)*)
    };
    ($given:expr, $expected:expr $(, $opt:ident = $val:expr)*,) => {
        __assert_approx!(ulps_eq, $given, $expected $(, $opt = $val)*)
    };
}

/// An assertion that delegates to `ulps_ne!`, and panics with a helpful error on failure.
#[macro_export]
macro_rules! assert_ulps_ne {
    ($given:expr, $expected:expr $(, $opt:ident = $val:expr)*) => {
        __assert_approx!(ulps_ne, $given, $expected $(, $opt = $val)*)
    };
    ($given:expr, $expected:expr $(, $opt:ident = $val:expr)*,) => {
        __assert_approx!(ulps_ne, $given, $expected $(, $opt = $val)*)
    };
}
<commit_msg>Export macros that call other macros with `local_inner_macros` attribute<commit_after>// Copyright 2015 Brendan Zabarauskas
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/// Approximate equality of using the absolute difference.
#[macro_export]
macro_rules! abs_diff_eq {
    ($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*) => {
        $crate::AbsDiff::default()$(.$opt($val))*.eq(&$lhs, &$rhs)
    };
    ($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*,) => {
        $crate::AbsDiff::default()$(.$opt($val))*.eq(&$lhs, &$rhs)
    };
}

/// Approximate inequality of using the absolute difference.
#[macro_export]
macro_rules! abs_diff_ne {
    ($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*) => {
        $crate::AbsDiff::default()$(.$opt($val))*.ne(&$lhs, &$rhs)
    };
    ($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*,) => {
        $crate::AbsDiff::default()$(.$opt($val))*.ne(&$lhs, &$rhs)
    };
}

/// Approximate equality using both the absolute difference and relative based comparisons.
#[macro_export]
macro_rules! relative_eq {
    ($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*) => {
        $crate::Relative::default()$(.$opt($val))*.eq(&$lhs, &$rhs)
    };
    ($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*,) => {
        $crate::Relative::default()$(.$opt($val))*.eq(&$lhs, &$rhs)
    };
}

/// Approximate inequality using both the absolute difference and relative based comparisons.
#[macro_export]
macro_rules! relative_ne {
    ($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*) => {
        $crate::Relative::default()$(.$opt($val))*.ne(&$lhs, &$rhs)
    };
    ($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*,) => {
        $crate::Relative::default()$(.$opt($val))*.ne(&$lhs, &$rhs)
    };
}

/// Approximate equality using both the absolute difference and ULPs (Units in Last Place).
#[macro_export]
macro_rules! ulps_eq {
    ($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*) => {
        $crate::Ulps::default()$(.$opt($val))*.eq(&$lhs, &$rhs)
    };
    ($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*,) => {
        $crate::Ulps::default()$(.$opt($val))*.eq(&$lhs, &$rhs)
    };
}

/// Approximate inequality using both the absolute difference and ULPs (Units in Last Place).
#[macro_export]
macro_rules! ulps_ne {
    ($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*) => {
        $crate::Ulps::default()$(.$opt($val))*.ne(&$lhs, &$rhs)
    };
    ($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*,) => {
        $crate::Ulps::default()$(.$opt($val))*.ne(&$lhs, &$rhs)
    };
}

#[doc(hidden)]
#[macro_export]
macro_rules! __assert_approx {
    ($eq:ident, $given:expr, $expected:expr) => {{
        let (given, expected) = (&($given), &($expected));

        if !$eq!(*given, *expected) {
            panic!(
"assert_{}!({}, {})

    left  = {:?}
    right = {:?}

",
                stringify!($eq),
                stringify!($given),
                stringify!($expected),
                given, expected,
            );
        }
    }};
    ($eq:ident, $given:expr, $expected:expr, $($opt:ident = $val:expr),+) => {{
        let (given, expected) = (&($given), &($expected));

        if !$eq!(*given, *expected, $($opt = $val),+) {
            panic!(
"assert_{}!({}, {}, {})

    left  = {:?}
    right = {:?}

",
                stringify!($eq),
                stringify!($given),
                stringify!($expected),
                stringify!($($opt = $val),+),
                given, expected,
            );
        }
    }};
}

/// An assertion that delegates to `abs_diff_eq!`, and panics with a helpful error on failure.
#[macro_export(local_inner_macros)]
macro_rules! assert_abs_diff_eq {
    ($given:expr, $expected:expr $(, $opt:ident = $val:expr)*) => {
        __assert_approx!(abs_diff_eq, $given, $expected $(, $opt = $val)*)
    };
    ($given:expr, $expected:expr $(, $opt:ident = $val:expr)*,) => {
        __assert_approx!(abs_diff_eq, $given, $expected $(, $opt = $val)*)
    };
}

/// An assertion that delegates to `abs_diff_ne!`, and panics with a helpful error on failure.
#[macro_export(local_inner_macros)]
macro_rules! assert_abs_diff_ne {
    ($given:expr, $expected:expr $(, $opt:ident = $val:expr)*) => {
        __assert_approx!(abs_diff_ne, $given, $expected $(, $opt = $val)*)
    };
    ($given:expr, $expected:expr $(, $opt:ident = $val:expr)*,) => {
        __assert_approx!(abs_diff_ne, $given, $expected $(, $opt = $val)*)
    };
}

/// An assertion that delegates to `relative_eq!`, and panics with a helpful error on failure.
#[macro_export(local_inner_macros)]
macro_rules! assert_relative_eq {
    ($given:expr, $expected:expr $(, $opt:ident = $val:expr)*) => {
        __assert_approx!(relative_eq, $given, $expected $(, $opt = $val)*)
    };
    ($given:expr, $expected:expr $(, $opt:ident = $val:expr)*,) => {
        __assert_approx!(relative_eq, $given, $expected $(, $opt = $val)*)
    };
}

/// An assertion that delegates to `relative_ne!`, and panics with a helpful error on failure.
#[macro_export(local_inner_macros)]
macro_rules! assert_relative_ne {
    ($given:expr, $expected:expr $(, $opt:ident = $val:expr)*) => {
        __assert_approx!(relative_ne, $given, $expected $(, $opt = $val)*)
    };
    ($given:expr, $expected:expr $(, $opt:ident = $val:expr)*,) => {
        __assert_approx!(relative_ne, $given, $expected $(, $opt = $val)*)
    };
}

/// An assertion that delegates to `ulps_eq!`, and panics with a helpful error on failure.
#[macro_export(local_inner_macros)]
macro_rules! assert_ulps_eq {
    ($given:expr, $expected:expr $(, $opt:ident = $val:expr)*) => {
        __assert_approx!(ulps_eq, $given, $expected $(, $opt = $val)*)
    };
    ($given:expr, $expected:expr $(, $opt:ident = $val:expr)*,) => {
        __assert_approx!(ulps_eq, $given, $expected $(, $opt = $val)*)
    };
}

/// An assertion that delegates to `ulps_ne!`, and panics with a helpful error on failure.
#[macro_export(local_inner_macros)]
macro_rules! assert_ulps_ne {
    ($given:expr, $expected:expr $(, $opt:ident = $val:expr)*) => {
        __assert_approx!(ulps_ne, $given, $expected $(, $opt = $val)*)
    };
    ($given:expr, $expected:expr $(, $opt:ident = $val:expr)*,) => {
        __assert_approx!(ulps_ne, $given, $expected $(, $opt = $val)*)
    };
}
<|endoftext|>