<commit_before>//! Abstractions for the replies passed back from i3.

use std::collections::HashMap;

/// The outcome of a single command.
#[derive(Debug)]
pub struct CommandOutcome {
    /// Whether the command was successful.
    pub success: bool,
    /// A human-readable error message.
    pub error: Option<String>
}

/// The reply to the `command` request.
#[derive(Debug)]
pub struct Command {
    /// A list of `CommandOutcome` structs; one for each command that was parsed.
    pub outcomes: Vec<CommandOutcome>
}

/// A single workspace.
#[derive(Debug)]
pub struct Workspace {
    /// The logical number of the workspace. Corresponds to the command to switch to this
    /// workspace. For named workspaces, this will be -1.
    pub num: i32,
    /// The name of this workspace (by default num+1), as changed by the user.
    pub name: String,
    /// Whether this workspace is currently visible on an output (multiple workspaces can be
    /// visible at the same time).
    pub visible: bool,
    /// Whether this workspace currently has the focus (only one workspace can have the focus
    /// at the same time).
    pub focused: bool,
    /// Whether a window on this workspace has the "urgent" flag set.
    pub urgent: bool,
    /// The rectangle of this workspace (equals the rect of the output it is on), consists of
    /// x, y, width, height.
    pub rect: (i32, i32, i32, i32),
    /// The video output this workspace is on (LVDS1, VGA1, …).
    pub output: String
}

/// The reply to the `get_workspaces` request.
#[derive(Debug)]
pub struct Workspaces {
    /// A list of workspaces.
    pub workspaces: Vec<Workspace>,
}

/// The reply to the `subscribe` request.
#[derive(Debug)]
pub struct Subscribe {
    /// Indicates whether the subscription was successful (the default) or whether a JSON
    /// parse error occurred.
    pub success: bool,
}

/// A single output (display)
#[derive(Debug)]
pub struct Output {
    /// The name of this output (as seen in xrandr).
    pub name: String,
    /// Whether the output is currently active (has a valid mode).
    pub active: bool,
    /// Whether the output is currently the primary output.
    pub primary: bool,
    /// The name of the current workspace that is visible on this output. None if the output is
    /// not active.
    pub current_workspace: Option<String>,
    /// The rectangle of this output (equals the rect of the output it is on), consists of
    /// x, y, width, height.
    pub rect: (i32, i32, i32, i32)
}

/// The reply to the `get_outputs` request.
#[derive(Debug)]
pub struct Outputs {
    /// A list of outputs (displays)
    pub outputs: Vec<Output>
}

#[derive(Debug)]
pub enum NodeType {
    Root,
    Output,
    Con,
    FloatingCon,
    Workspace,
    DockArea,
    /// A NodeType we don't support yet.
    Unknown,
}

#[derive(Debug)]
pub enum NodeBorder {
    Normal,
    None,
    Pixel,
    /// A NodeBorder we don't support yet.
    Unknown,
}

#[derive(Debug)]
pub enum NodeLayout {
    SplitH,
    SplitV,
    Stacked,
    Tabbed,
    DockArea,
    Output,
    /// A NodeLayout we don't support yet.
    Unknown,
}

/// The reply to the `get_tree` request.
#[derive(Debug)]
pub struct Node {
    /// The child nodes of this container.
    pub nodes: Vec<Node>,

    /// The child floating nodes of this container.
    pub floating_nodes: Vec<Node>,

    /// The internal ID (actually a C pointer value) of this container. Do not make any
    /// assumptions about it. You can use it to (re-)identify and address containers when
    /// talking to i3.
    pub id: i64,

    /// The internal name of this container. For all containers which are part of the tree
    /// structure down to the workspace contents, this is set to a nice human-readable name of
    /// the container. For containers that have an X11 window, the content is the title
    /// (_NET_WM_NAME property) of that window. For all other containers, the content is not
    /// defined (yet).
    pub name: Option<String>,

    /// Type of this container. Can be one of "root", "output", "con", "floating_con",
    /// "workspace" or "dockarea".
    pub nodetype: NodeType,

    /// Can be either "normal", "none" or "1pixel", dependending on the container’s border
    /// style.
    pub border: NodeBorder,

    /// Number of pixels of the border width.
    pub current_border_width: i32,

    /// Can be either "splith", "splitv", "stacked", "tabbed", "dockarea" or "output". Other values
    /// might be possible in the future, should we add new layouts.
    pub layout: NodeLayout,

    /// The percentage which this container takes in its parent. A value of null means that the
    /// percent property does not make sense for this container, for example for the root
    /// container.
    pub percent: Option<f64>,

    /// The (x, y, width, height) absolute display coordinates for this container. Display
    /// coordinates means that when you have two 1600x1200 monitors on a single X11 Display
    /// (the standard way), the coordinates of the first window on the second monitor are
    /// (1600, 0, 1600, 1200).
    pub rect: (i32, i32, i32, i32),

    /// The (x, y, width, height) coordinates of the actual client window inside its container.
    /// These coordinates are  relative to the container and do not include the window
    /// decoration (which is actually rendered on the parent container). So for example, when
    /// using the default layout, you will have a 2 pixel border on each side, making the
    /// window_rect (2, 0, 632, 366).
    pub window_rect: (i32, i32, i32, i32),

    /// The (x, y, width, height) coordinates of the window decoration inside its container.
    /// These coordinates are relative to the container and do not include the actual client
    /// window.
    pub deco_rect: (i32, i32, i32, i32),

    /// The original geometry the window specified when i3 mapped it. Used when switching a
    /// window to floating mode, for example.
    pub geometry: (i32, i32, i32, i32),

    /// The X11 window ID of the actual client window inside this container. This field is set
    /// to null for split containers or otherwise empty containers. This ID corresponds to what
    /// xwininfo(1) and other X11-related tools display (usually in hex).
    pub window: Option<i32>,

    /// Whether this container (window or workspace) has the urgency hint set.
    pub urgent: bool,

    /// Whether this container is currently focused.
    pub focused: bool,
}

/// The reply to the `get_marks` request.
///
/// Consists of a single vector of strings for each container that has a mark. A mark can only
/// be set on one container, so the vector is unique. The order of that vector is undefined. If
/// no window has a mark the response will be an empty vector.
#[derive(Debug)]
pub struct Marks {
    pub marks: Vec<String>
}

/// The reply to the `get_bar_ids` request.
///
/// This can be used by third-party workspace bars (especially i3bar, but others are free to
/// implement compatible alternatives) to get the bar block configuration from i3.
#[derive(Debug)]
pub struct BarIds {
    /// A vector of configured bar IDs.
    pub ids: Vec<String>
}

#[derive(Hash, Eq, PartialEq, Debug)]
pub enum ColorableBarPart {
    /// Background color of the bar.
    Background,

    /// Text color to be used for the statusline.
    Statusline,

    /// Text color to be used for the separator.
    Separator,

    /// Background color of the bar on the currently focused monitor output.
    #[cfg(feature = "i3-4-12")]
    #[cfg_attr(feature = "dox", doc(cfg(feature = "i3-4-12")))]
    FocusedBackground,

    /// Text color to be used for the statusline on the currently focused
    /// monitor output.
    #[cfg(feature = "i3-4-12")]
    #[cfg_attr(feature = "dox", doc(cfg(feature = "i3-4-12")))]
    FocusedStatusline,

    /// Text color to be used for the separator on the currently focused
    /// monitor output.
    #[cfg(feature = "i3-4-12")]
    #[cfg_attr(feature = "dox", doc(cfg(feature = "i3-4-12")))]
    FocusedSeparator,

    /// Text color for a workspace button when the workspace has focus.
    FocusedWorkspaceText,

    /// Background color for a workspace button when the workspace has focus.
    FocusedWorkspaceBg,

    /// Border color for a workspace button when the workspace has focus.
    FocusedWorkspaceBorder,

    /// Text color for a workspace button when the workspace is active (visible) on some
    /// output, but the focus is on another one. You can only tell this apart from the
    /// focused workspace when you are using multiple monitors.
    ActiveWorkspaceText,

    /// Background color for a workspace button when the workspace is active (visible) on some
    /// output, but the focus is on another one. You can only tell this apart from the
    /// focused workspace when you are using multiple monitors.
    ActiveWorkspaceBg,

    /// Border color for a workspace button when the workspace is active (visible) on some
    /// output, but the focus is on another one. You can only tell this apart from the
    /// focused workspace when you are using multiple monitors.
    ActiveWorkspaceBorder,

    /// Text color for a workspace button when the workspace does not have focus and is not
    /// active (visible) on any output. This will be the case for most workspaces.
    InactiveWorkspaceText,

    /// Background color for a workspace button when the workspace does not have focus and is
    /// not active (visible) on any output. This will be the case for most workspaces.
    InactiveWorkspaceBg,

    /// Border color for a workspace button when the workspace does not have focus and is
    /// not active (visible) on any output. This will be the case for most workspaces.
    InactiveWorkspaceBorder,

    /// Text color for workspaces which contain at least one window with the urgency hint set.
    UrgentWorkspaceText,

    /// Background color for workspaces which contain at least one window with the urgency hint
    /// set.
    UrgentWorkspaceBg,

    /// Border color for workspaces which contain at least one window with the urgency hint set.
    UrgentWorkspaceBorder,

    /// Text color for the binding mode indicator.
    BindingModeText,

    /// Background color for the binding mode indicator.
    BindingModeBg,

    /// Border color for the binding mode indicator.
    BindingModeBorder,

    /// A ColorableBarPart we don't support yet.
    Unknown,
}

/// The reply to the `get_bar_config` request.
///
/// This can be used by third-party workspace bars (especially i3bar, but others are free to
/// implement compatible alternatives) to get the bar block configuration from i3.
#[derive(Debug)]
pub struct BarConfig {
    /// The ID for this bar. Included in case you request multiple configurations and want to
    /// differentiate the different replies.
    pub id: String,

    /// Either dock (the bar sets the dock window type) or hide (the bar does not show unless a
    /// specific key is pressed).
    pub mode: String,

    /// Either bottom or top at the moment.
    pub position: String,

    /// Command which will be run to generate a statusline. Each line on stdout of this command
    /// will be displayed in the bar. At the moment, no formatting is supported.
    pub status_command: String,

    /// The font to use for text on the bar.
    pub font: String,

    /// Display workspace buttons or not? Defaults to true.
    pub workspace_buttons: bool,

    /// Display the mode indicator or not? Defaults to true.
    pub binding_mode_indicator: bool,

    /// Should the bar enable verbose output for debugging? Defaults to false.
    pub verbose: bool,

    /// Contains key/value pairs of colors. Each value is a color code in hex, formatted
    /// \#rrggbb (like in HTML).
    pub colors: HashMap<ColorableBarPart, String>,
}

/// The reply to the `get_version` request.
#[derive(Debug)]
pub struct Version {
    /// The major version of i3, such as 4.
    pub major: i32,

    /// The minor version of i3, such as 2. Changes in the IPC interface (new features) will
    /// only occur with new minor (or major) releases. However, bugfixes might be introduced in
    /// patch releases, too.
    pub minor: i32,

    /// The patch version of i3, such as 1 (when the complete version is 4.2.1). For versions
    /// such as 4.2, patch will be set to 0.
    pub patch: i32,

    /// A human-readable version of i3 containing the precise git version, build date and
    /// branch name. When you need to display the i3 version to your users, use the
    /// human-readable version whenever possible (since this is what i3 --version displays,
    /// too).
    pub human_readable: String,

    /// The current config path.
    pub loaded_config_file_name: String
}

/// The reply to the `get_binding_modes` request.
#[cfg(feature = "i3-4-13")]
#[cfg_attr(feature = "dox", doc(cfg(feature = "i3-4-13")))]
#[derive(Debug)]
pub struct BindingModes {
    /// A vector of all currently configured binding modes.
    pub modes: Vec<String>,
}
<commit_msg>Update Node::urgent docs<commit_after>//! Abstractions for the replies passed back from i3.

use std::collections::HashMap;

/// The outcome of a single command.
#[derive(Debug)]
pub struct CommandOutcome {
    /// Whether the command was successful.
    pub success: bool,
    /// A human-readable error message.
    pub error: Option<String>
}

/// The reply to the `command` request.
#[derive(Debug)]
pub struct Command {
    /// A list of `CommandOutcome` structs; one for each command that was parsed.
    pub outcomes: Vec<CommandOutcome>
}

/// A single workspace.
#[derive(Debug)]
pub struct Workspace {
    /// The logical number of the workspace. Corresponds to the command to switch to this
    /// workspace. For named workspaces, this will be -1.
    pub num: i32,
    /// The name of this workspace (by default num+1), as changed by the user.
    pub name: String,
    /// Whether this workspace is currently visible on an output (multiple workspaces can be
    /// visible at the same time).
    pub visible: bool,
    /// Whether this workspace currently has the focus (only one workspace can have the focus
    /// at the same time).
    pub focused: bool,
    /// Whether a window on this workspace has the "urgent" flag set.
    pub urgent: bool,
    /// The rectangle of this workspace (equals the rect of the output it is on), consists of
    /// x, y, width, height.
    pub rect: (i32, i32, i32, i32),
    /// The video output this workspace is on (LVDS1, VGA1, …).
    pub output: String
}

/// The reply to the `get_workspaces` request.
#[derive(Debug)]
pub struct Workspaces {
    /// A list of workspaces.
    pub workspaces: Vec<Workspace>,
}

/// The reply to the `subscribe` request.
#[derive(Debug)]
pub struct Subscribe {
    /// Indicates whether the subscription was successful (the default) or whether a JSON
    /// parse error occurred.
    pub success: bool,
}

/// A single output (display)
#[derive(Debug)]
pub struct Output {
    /// The name of this output (as seen in xrandr).
    pub name: String,
    /// Whether the output is currently active (has a valid mode).
    pub active: bool,
    /// Whether the output is currently the primary output.
    pub primary: bool,
    /// The name of the current workspace that is visible on this output. None if the output is
    /// not active.
    pub current_workspace: Option<String>,
    /// The rectangle of this output (equals the rect of the output it is on), consists of
    /// x, y, width, height.
    pub rect: (i32, i32, i32, i32)
}

/// The reply to the `get_outputs` request.
#[derive(Debug)]
pub struct Outputs {
    /// A list of outputs (displays)
    pub outputs: Vec<Output>
}

#[derive(Debug)]
pub enum NodeType {
    Root,
    Output,
    Con,
    FloatingCon,
    Workspace,
    DockArea,
    /// A NodeType we don't support yet.
    Unknown,
}

#[derive(Debug)]
pub enum NodeBorder {
    Normal,
    None,
    Pixel,
    /// A NodeBorder we don't support yet.
    Unknown,
}

#[derive(Debug)]
pub enum NodeLayout {
    SplitH,
    SplitV,
    Stacked,
    Tabbed,
    DockArea,
    Output,
    /// A NodeLayout we don't support yet.
    Unknown,
}

/// The reply to the `get_tree` request.
#[derive(Debug)]
pub struct Node {
    /// The child nodes of this container.
    pub nodes: Vec<Node>,

    /// The child floating nodes of this container.
    pub floating_nodes: Vec<Node>,

    /// The internal ID (actually a C pointer value) of this container. Do not make any
    /// assumptions about it. You can use it to (re-)identify and address containers when
    /// talking to i3.
    pub id: i64,

    /// The internal name of this container. For all containers which are part of the tree
    /// structure down to the workspace contents, this is set to a nice human-readable name of
    /// the container. For containers that have an X11 window, the content is the title
    /// (_NET_WM_NAME property) of that window. For all other containers, the content is not
    /// defined (yet).
    pub name: Option<String>,

    /// Type of this container. Can be one of "root", "output", "con", "floating_con",
    /// "workspace" or "dockarea".
    pub nodetype: NodeType,

    /// Can be either "normal", "none" or "1pixel", dependending on the container’s border
    /// style.
    pub border: NodeBorder,

    /// Number of pixels of the border width.
    pub current_border_width: i32,

    /// Can be either "splith", "splitv", "stacked", "tabbed", "dockarea" or "output". Other values
    /// might be possible in the future, should we add new layouts.
    pub layout: NodeLayout,

    /// The percentage which this container takes in its parent. A value of null means that the
    /// percent property does not make sense for this container, for example for the root
    /// container.
    pub percent: Option<f64>,

    /// The (x, y, width, height) absolute display coordinates for this container. Display
    /// coordinates means that when you have two 1600x1200 monitors on a single X11 Display
    /// (the standard way), the coordinates of the first window on the second monitor are
    /// (1600, 0, 1600, 1200).
    pub rect: (i32, i32, i32, i32),

    /// The (x, y, width, height) coordinates of the actual client window inside its container.
    /// These coordinates are  relative to the container and do not include the window
    /// decoration (which is actually rendered on the parent container). So for example, when
    /// using the default layout, you will have a 2 pixel border on each side, making the
    /// window_rect (2, 0, 632, 366).
    pub window_rect: (i32, i32, i32, i32),

    /// The (x, y, width, height) coordinates of the window decoration inside its container.
    /// These coordinates are relative to the container and do not include the actual client
    /// window.
    pub deco_rect: (i32, i32, i32, i32),

    /// The original geometry the window specified when i3 mapped it. Used when switching a
    /// window to floating mode, for example.
    pub geometry: (i32, i32, i32, i32),

    /// The X11 window ID of the actual client window inside this container. This field is set
    /// to null for split containers or otherwise empty containers. This ID corresponds to what
    /// xwininfo(1) and other X11-related tools display (usually in hex).
    pub window: Option<i32>,

    /// Whether this container (window, split container, floating container or workspace) has the
    /// urgency hint set, directly or indirectly. All parent containers up until the workspace
    /// container will be marked urgent if they have at least one urgent child.
    pub urgent: bool,

    /// Whether this container is currently focused.
    pub focused: bool,
}

/// The reply to the `get_marks` request.
///
/// Consists of a single vector of strings for each container that has a mark. A mark can only
/// be set on one container, so the vector is unique. The order of that vector is undefined. If
/// no window has a mark the response will be an empty vector.
#[derive(Debug)]
pub struct Marks {
    pub marks: Vec<String>
}

/// The reply to the `get_bar_ids` request.
///
/// This can be used by third-party workspace bars (especially i3bar, but others are free to
/// implement compatible alternatives) to get the bar block configuration from i3.
#[derive(Debug)]
pub struct BarIds {
    /// A vector of configured bar IDs.
    pub ids: Vec<String>
}

#[derive(Hash, Eq, PartialEq, Debug)]
pub enum ColorableBarPart {
    /// Background color of the bar.
    Background,

    /// Text color to be used for the statusline.
    Statusline,

    /// Text color to be used for the separator.
    Separator,

    /// Background color of the bar on the currently focused monitor output.
    #[cfg(feature = "i3-4-12")]
    #[cfg_attr(feature = "dox", doc(cfg(feature = "i3-4-12")))]
    FocusedBackground,

    /// Text color to be used for the statusline on the currently focused
    /// monitor output.
    #[cfg(feature = "i3-4-12")]
    #[cfg_attr(feature = "dox", doc(cfg(feature = "i3-4-12")))]
    FocusedStatusline,

    /// Text color to be used for the separator on the currently focused
    /// monitor output.
    #[cfg(feature = "i3-4-12")]
    #[cfg_attr(feature = "dox", doc(cfg(feature = "i3-4-12")))]
    FocusedSeparator,

    /// Text color for a workspace button when the workspace has focus.
    FocusedWorkspaceText,

    /// Background color for a workspace button when the workspace has focus.
    FocusedWorkspaceBg,

    /// Border color for a workspace button when the workspace has focus.
    FocusedWorkspaceBorder,

    /// Text color for a workspace button when the workspace is active (visible) on some
    /// output, but the focus is on another one. You can only tell this apart from the
    /// focused workspace when you are using multiple monitors.
    ActiveWorkspaceText,

    /// Background color for a workspace button when the workspace is active (visible) on some
    /// output, but the focus is on another one. You can only tell this apart from the
    /// focused workspace when you are using multiple monitors.
    ActiveWorkspaceBg,

    /// Border color for a workspace button when the workspace is active (visible) on some
    /// output, but the focus is on another one. You can only tell this apart from the
    /// focused workspace when you are using multiple monitors.
    ActiveWorkspaceBorder,

    /// Text color for a workspace button when the workspace does not have focus and is not
    /// active (visible) on any output. This will be the case for most workspaces.
    InactiveWorkspaceText,

    /// Background color for a workspace button when the workspace does not have focus and is
    /// not active (visible) on any output. This will be the case for most workspaces.
    InactiveWorkspaceBg,

    /// Border color for a workspace button when the workspace does not have focus and is
    /// not active (visible) on any output. This will be the case for most workspaces.
    InactiveWorkspaceBorder,

    /// Text color for workspaces which contain at least one window with the urgency hint set.
    UrgentWorkspaceText,

    /// Background color for workspaces which contain at least one window with the urgency hint
    /// set.
    UrgentWorkspaceBg,

    /// Border color for workspaces which contain at least one window with the urgency hint set.
    UrgentWorkspaceBorder,

    /// Text color for the binding mode indicator.
    BindingModeText,

    /// Background color for the binding mode indicator.
    BindingModeBg,

    /// Border color for the binding mode indicator.
    BindingModeBorder,

    /// A ColorableBarPart we don't support yet.
    Unknown,
}

/// The reply to the `get_bar_config` request.
///
/// This can be used by third-party workspace bars (especially i3bar, but others are free to
/// implement compatible alternatives) to get the bar block configuration from i3.
#[derive(Debug)]
pub struct BarConfig {
    /// The ID for this bar. Included in case you request multiple configurations and want to
    /// differentiate the different replies.
    pub id: String,

    /// Either dock (the bar sets the dock window type) or hide (the bar does not show unless a
    /// specific key is pressed).
    pub mode: String,

    /// Either bottom or top at the moment.
    pub position: String,

    /// Command which will be run to generate a statusline. Each line on stdout of this command
    /// will be displayed in the bar. At the moment, no formatting is supported.
    pub status_command: String,

    /// The font to use for text on the bar.
    pub font: String,

    /// Display workspace buttons or not? Defaults to true.
    pub workspace_buttons: bool,

    /// Display the mode indicator or not? Defaults to true.
    pub binding_mode_indicator: bool,

    /// Should the bar enable verbose output for debugging? Defaults to false.
    pub verbose: bool,

    /// Contains key/value pairs of colors. Each value is a color code in hex, formatted
    /// \#rrggbb (like in HTML).
    pub colors: HashMap<ColorableBarPart, String>,
}

/// The reply to the `get_version` request.
#[derive(Debug)]
pub struct Version {
    /// The major version of i3, such as 4.
    pub major: i32,

    /// The minor version of i3, such as 2. Changes in the IPC interface (new features) will
    /// only occur with new minor (or major) releases. However, bugfixes might be introduced in
    /// patch releases, too.
    pub minor: i32,

    /// The patch version of i3, such as 1 (when the complete version is 4.2.1). For versions
    /// such as 4.2, patch will be set to 0.
    pub patch: i32,

    /// A human-readable version of i3 containing the precise git version, build date and
    /// branch name. When you need to display the i3 version to your users, use the
    /// human-readable version whenever possible (since this is what i3 --version displays,
    /// too).
    pub human_readable: String,

    /// The current config path.
    pub loaded_config_file_name: String
}

/// The reply to the `get_binding_modes` request.
#[cfg(feature = "i3-4-13")]
#[cfg_attr(feature = "dox", doc(cfg(feature = "i3-4-13")))]
#[derive(Debug)]
pub struct BindingModes {
    /// A vector of all currently configured binding modes.
    pub modes: Vec<String>,
}
<|endoftext|>


<commit_before>use cql_bindgen::CassLogMessage;

#[repr(C)]
pub enum CassLogLevel {
    DISABLED = 0,
    CRITICAL = 1,
    ERROR = 2,
    WARN = 3,
    INFO = 4,
    DEBUG = 5,
    TRACE = 6,
    LAST_ENTRY = 7,
}

pub type CassLogCallback =
    ::std::option::Option<extern "C" fn (
        message: *const CassLogMessage,
        data: *mut ::libc::c_void
    )>;
<commit_msg>log level<commit_after>use cql_bindgen::CassLogMessage;

#[repr(C)]
pub enum LogLevel {
    DISABLED = 0,
    CRITICAL = 1,
    ERROR = 2,
    WARN = 3,
    INFO = 4,
    DEBUG = 5,
    TRACE = 6,
    LAST_ENTRY = 7,
}

pub type CassLogCallback =
    ::std::option::Option<extern "C" fn (
        message: *const CassLogMessage,
        data: *mut ::libc::c_void
    )>;
<|endoftext|>


<commit_before>#[cfg(not(syn_can_match_ident_after_attrs))]
macro_rules! ast_struct {
    (
        $(#[$attr:meta])*
        pub struct $name:ident #full $($rest:tt)*
    ) => {
        #[cfg(feature = "full")]
        $(#[$attr])*
        #[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
        #[cfg_attr(feature = "clone-impls", derive(Clone))]
        pub struct $name $($rest)*

        #[cfg(not(feature = "full"))]
        $(#[$attr])*
        #[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
        #[cfg_attr(feature = "clone-impls", derive(Clone))]
        pub struct $name {
            _noconstruct: (),
        }
    };

    (
        $(#[$attr:meta])*
        pub struct $name:ident #manual_extra_traits $($rest:tt)*
    ) => {
        $(#[$attr])*
        #[cfg_attr(feature = "extra-traits", derive(Debug))]
        #[cfg_attr(feature = "clone-impls", derive(Clone))]
        pub struct $name $($rest)*
    };

    (
        $(#[$attr:meta])*
        pub struct $name:ident $($rest:tt)*
    ) => {
        $(#[$attr])*
        #[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
        #[cfg_attr(feature = "clone-impls", derive(Clone))]
        pub struct $name $($rest)*
    };
}

#[cfg(syn_can_match_ident_after_attrs)]
macro_rules! ast_struct {
    (
        $(#[$attr:meta])*
        $pub:ident $struct:ident $name:ident #full $($rest:tt)*
    ) => {
        check_keyword_matches!(pub $pub);
        check_keyword_matches!(struct $struct);

        #[cfg(feature = "full")]
        $(#[$attr])*
        #[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
        #[cfg_attr(feature = "clone-impls", derive(Clone))]
        $pub $struct $name $($rest)*

        #[cfg(not(feature = "full"))]
        $(#[$attr])*
        #[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
        #[cfg_attr(feature = "clone-impls", derive(Clone))]
        $pub $struct $name {
            _noconstruct: (),
        }
    };

    (
        $(#[$attr:meta])*
        $pub:ident $struct:ident $name:ident #manual_extra_traits $($rest:tt)*
    ) => {
        check_keyword_matches!(pub $pub);
        check_keyword_matches!(struct $struct);

        $(#[$attr])*
        #[cfg_attr(feature = "extra-traits", derive(Debug))]
        #[cfg_attr(feature = "clone-impls", derive(Clone))]
        $pub $struct $name $($rest)*
    };

    (
        $(#[$attr:meta])*
        $pub:ident $struct:ident $name:ident $($rest:tt)*
    ) => {
        check_keyword_matches!(pub $pub);
        check_keyword_matches!(struct $struct);

        $(#[$attr])*
        #[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
        #[cfg_attr(feature = "clone-impls", derive(Clone))]
        $pub $struct $name $($rest)*
    };
}

#[cfg(not(syn_can_match_ident_after_attrs))]
macro_rules! ast_enum {
    // Drop the `#no_visit` attribute, if present.
    (
        $(#[$enum_attr:meta])*
        pub enum $name:ident #no_visit $($rest:tt)*
    ) => (
        ast_enum! { $(#[$enum_attr])* pub enum $name $($rest)* }
    );

    (
        $(#[$enum_attr:meta])*
        pub enum $name:ident $($rest:tt)*
    ) => (
        $(#[$enum_attr])*
        #[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
        #[cfg_attr(feature = "clone-impls", derive(Clone))]
        pub enum $name $($rest)*
    );
}

#[cfg(syn_can_match_ident_after_attrs)]
macro_rules! ast_enum {
    // Drop the `#no_visit` attribute, if present.
    (
        $(#[$enum_attr:meta])*
        $pub:ident $enum:ident $name:ident #no_visit $($rest:tt)*
    ) => (
        ast_enum! { $(#[$enum_attr])* $pub $enum $name $($rest)* }
    );

    (
        $(#[$enum_attr:meta])*
        $pub:ident $enum:ident $name:ident $($rest:tt)*
    ) => (
        check_keyword_matches!(pub $pub);
        check_keyword_matches!(enum $enum);

        $(#[$enum_attr])*
        #[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
        #[cfg_attr(feature = "clone-impls", derive(Clone))]
        $pub $enum $name $($rest)*
    );
}

#[cfg(not(syn_can_match_ident_after_attrs))]
macro_rules! ast_enum_of_structs {
    (
        $(#[$enum_attr:meta])*
        pub enum $name:ident {
            $(
                $(#[$variant_attr:meta])*
                pub $variant:ident $( ($member:ident $($rest:tt)*) )*,
            )*
        }

        $($remaining:tt)*
    ) => (
        ast_enum! {
            $(#[$enum_attr])*
            pub enum $name {
                $(
                    $(#[$variant_attr])*
                    $variant $( ($member) )*,
                )*
            }
        }

        $(
            maybe_ast_struct! {
                $(#[$variant_attr])*
                $(
                    pub struct $member $($rest)*
                )*
            }

            $(
                impl From<$member> for $name {
                    fn from(e: $member) -> $name {
                        $name::$variant(e)
                    }
                }
            )*
        )*

        #[cfg(feature = "printing")]
        generate_to_tokens! {
            $($remaining)*
            ()
            tokens
            $name { $($variant $( [$($rest)*] )*,)* }
        }
    )
}

#[cfg(syn_can_match_ident_after_attrs)]
macro_rules! ast_enum_of_structs {
    (
        $(#[$enum_attr:meta])*
        $pub:ident $enum:ident $name:ident {
            $(
                $(#[$variant_attr:meta])*
                $vpub:ident $variant:ident $( ($member:ident $($rest:tt)*) )*,
            )*
        }

        $($remaining:tt)*
    ) => (
        check_keyword_matches!(pub $pub);
        check_keyword_matches!(enum $enum);

        ast_enum! {
            $(#[$enum_attr])*
            $pub $enum $name {
                $(
                    $(#[$variant_attr])*
                    $variant $( ($member) )*,
                )*
            }
        }

        $(
            check_keyword_matches!(pub $vpub);
            maybe_ast_struct! {
                $(#[$variant_attr])*
                $(
                    $vpub struct $member $($rest)*
                )*
            }

            $(
                impl From<$member> for $name {
                    fn from(e: $member) -> $name {
                        $name::$variant(e)
                    }
                }
            )*
        )*

        #[cfg(feature = "printing")]
        generate_to_tokens! {
            $($remaining)*
            ()
            tokens
            $name { $($variant $( [$($rest)*] )*,)* }
        }
    )
}

#[cfg(feature = "printing")]
macro_rules! generate_to_tokens {
    (do_not_generate_to_tokens $($foo:tt)*) => ();

    (($($arms:tt)*) $tokens:ident $name:ident { $variant:ident, $($next:tt)*}) => {
        generate_to_tokens!(
            ($($arms)* $name::$variant => {})
            $tokens $name { $($next)* }
        );
    };

    (($($arms:tt)*) $tokens:ident $name:ident { $variant:ident [$($rest:tt)*], $($next:tt)*}) => {
        generate_to_tokens!(
            ($($arms)* $name::$variant(ref _e) => to_tokens_call!(_e, $tokens, $($rest)*),)
            $tokens $name { $($next)* }
        );
    };

    (($($arms:tt)*) $tokens:ident $name:ident {}) => {
        impl ::quote::ToTokens for $name {
            fn to_tokens(&self, $tokens: &mut ::proc_macro2::TokenStream) {
                match *self {
                    $($arms)*
                }
            }
        }
    };
}

#[cfg(all(feature = "printing", feature = "full"))]
macro_rules! to_tokens_call {
    ($e:ident, $tokens:ident, $($rest:tt)*) => {
        $e.to_tokens($tokens)
    };
}

#[cfg(all(feature = "printing", feature = "derive", not(feature = "full")))]
macro_rules! to_tokens_call {
    // If the variant is marked as #full, don't auto-generate to-tokens for it.
    ($e:ident, $tokens:ident, #full $($rest:tt)*) => {
        unreachable!()
    };
    ($e:ident, $tokens:ident, $($rest:tt)*) => {
        $e.to_tokens($tokens)
    };
}

macro_rules! maybe_ast_struct {
    (
        $(#[$attr:meta])*
        $(
            pub struct $name:ident
        )*
    ) => ();

    ($($rest:tt)*) => (ast_struct! { $($rest)* });
}

#[cfg(syn_can_match_ident_after_attrs)]
macro_rules! check_keyword_matches {
    (struct struct) => {};
    (enum enum) => {};
    (pub pub) => {};
}
<commit_msg>Add a comment explaining why `ast_enum_of_structs` generates bad spans for the outer enum<commit_after>#[cfg(not(syn_can_match_ident_after_attrs))]
macro_rules! ast_struct {
    (
        $(#[$attr:meta])*
        pub struct $name:ident #full $($rest:tt)*
    ) => {
        #[cfg(feature = "full")]
        $(#[$attr])*
        #[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
        #[cfg_attr(feature = "clone-impls", derive(Clone))]
        pub struct $name $($rest)*

        #[cfg(not(feature = "full"))]
        $(#[$attr])*
        #[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
        #[cfg_attr(feature = "clone-impls", derive(Clone))]
        pub struct $name {
            _noconstruct: (),
        }
    };

    (
        $(#[$attr:meta])*
        pub struct $name:ident #manual_extra_traits $($rest:tt)*
    ) => {
        $(#[$attr])*
        #[cfg_attr(feature = "extra-traits", derive(Debug))]
        #[cfg_attr(feature = "clone-impls", derive(Clone))]
        pub struct $name $($rest)*
    };

    (
        $(#[$attr:meta])*
        pub struct $name:ident $($rest:tt)*
    ) => {
        $(#[$attr])*
        #[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
        #[cfg_attr(feature = "clone-impls", derive(Clone))]
        pub struct $name $($rest)*
    };
}

#[cfg(syn_can_match_ident_after_attrs)]
macro_rules! ast_struct {
    (
        $(#[$attr:meta])*
        $pub:ident $struct:ident $name:ident #full $($rest:tt)*
    ) => {
        check_keyword_matches!(pub $pub);
        check_keyword_matches!(struct $struct);

        #[cfg(feature = "full")]
        $(#[$attr])*
        #[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
        #[cfg_attr(feature = "clone-impls", derive(Clone))]
        $pub $struct $name $($rest)*

        #[cfg(not(feature = "full"))]
        $(#[$attr])*
        #[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
        #[cfg_attr(feature = "clone-impls", derive(Clone))]
        $pub $struct $name {
            _noconstruct: (),
        }
    };

    (
        $(#[$attr:meta])*
        $pub:ident $struct:ident $name:ident #manual_extra_traits $($rest:tt)*
    ) => {
        check_keyword_matches!(pub $pub);
        check_keyword_matches!(struct $struct);

        $(#[$attr])*
        #[cfg_attr(feature = "extra-traits", derive(Debug))]
        #[cfg_attr(feature = "clone-impls", derive(Clone))]
        $pub $struct $name $($rest)*
    };

    (
        $(#[$attr:meta])*
        $pub:ident $struct:ident $name:ident $($rest:tt)*
    ) => {
        check_keyword_matches!(pub $pub);
        check_keyword_matches!(struct $struct);

        $(#[$attr])*
        #[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
        #[cfg_attr(feature = "clone-impls", derive(Clone))]
        $pub $struct $name $($rest)*
    };
}

#[cfg(not(syn_can_match_ident_after_attrs))]
macro_rules! ast_enum {
    // Drop the `#no_visit` attribute, if present.
    (
        $(#[$enum_attr:meta])*
        pub enum $name:ident #no_visit $($rest:tt)*
    ) => (
        ast_enum! { $(#[$enum_attr])* pub enum $name $($rest)* }
    );

    (
        $(#[$enum_attr:meta])*
        pub enum $name:ident $($rest:tt)*
    ) => (
        $(#[$enum_attr])*
        #[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
        #[cfg_attr(feature = "clone-impls", derive(Clone))]
        pub enum $name $($rest)*
    );
}

#[cfg(syn_can_match_ident_after_attrs)]
macro_rules! ast_enum {
    // Drop the `#no_visit` attribute, if present.
    (
        $(#[$enum_attr:meta])*
        $pub:ident $enum:ident $name:ident #no_visit $($rest:tt)*
    ) => (
        ast_enum! { $(#[$enum_attr])* $pub $enum $name $($rest)* }
    );

    (
        $(#[$enum_attr:meta])*
        $pub:ident $enum:ident $name:ident $($rest:tt)*
    ) => (
        check_keyword_matches!(pub $pub);
        check_keyword_matches!(enum $enum);

        $(#[$enum_attr])*
        #[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
        #[cfg_attr(feature = "clone-impls", derive(Clone))]
        $pub $enum $name $($rest)*
    );
}

#[cfg(not(syn_can_match_ident_after_attrs))]
macro_rules! ast_enum_of_structs {
    (
        $(#[$enum_attr:meta])*
        pub enum $name:ident {
            $(
                $(#[$variant_attr:meta])*
                pub $variant:ident $( ($member:ident $($rest:tt)*) )*,
            )*
        }

        $($remaining:tt)*
    ) => (
        ast_enum! {
            $(#[$enum_attr])*
            pub enum $name {
                $(
                    $(#[$variant_attr])*
                    $variant $( ($member) )*,
                )*
            }
        }

        $(
            maybe_ast_struct! {
                $(#[$variant_attr])*
                $(
                    pub struct $member $($rest)*
                )*
            }

            $(
                impl From<$member> for $name {
                    fn from(e: $member) -> $name {
                        $name::$variant(e)
                    }
                }
            )*
        )*

        #[cfg(feature = "printing")]
        generate_to_tokens! {
            $($remaining)*
            ()
            tokens
            $name { $($variant $( [$($rest)*] )*,)* }
        }
    )
}

// Unfortunately, at this time, we can't make the generated enum here have the
// correct span. The way that the span for the overall enum decl is calculated
// is using `lo.to(prev_span)` [1].
//
// If the beginning and ending spans of the enum item don't have the same macro
// context, fallback code is run [2]. This code chooses the span within the
// macro context to avoid firing spurious diagnostics [3].
//
// This means `[src]` links in rustdoc will point to the macro, instead of the
// actual declaration, if either the first or last token of our declaration has
// a span from the macro. With `macro_rules!` there is no way to preserve the
// span of a `{}` block while changing its contents, so we're forced to have the
// span of our final token point to our macro.
//
// [1]: https://github.com/rust-lang/rust/blob/9a90d03ad171856dc016c2dcc19292ec49a8a26f/src/libsyntax/parse/parser.rs#L7377
// [2]: https://github.com/rust-lang/rust/blob/9a90d03ad171856dc016c2dcc19292ec49a8a26f/src/libsyntax_pos/lib.rs#L467-L478
// [3]: https://github.com/rust-lang/rust/pull/47942
#[cfg(syn_can_match_ident_after_attrs)]
macro_rules! ast_enum_of_structs {
    (
        $(#[$enum_attr:meta])*
        $pub:ident $enum:ident $name:ident {
            $(
                $(#[$variant_attr:meta])*
                $vpub:ident $variant:ident $( ($member:ident $($rest:tt)*) )*,
            )*
        }

        $($remaining:tt)*
    ) => (
        check_keyword_matches!(pub $pub);
        check_keyword_matches!(enum $enum);

        ast_enum! {
            $(#[$enum_attr])*
            $pub $enum $name {
                $(
                    $(#[$variant_attr])*
                    $variant $( ($member) )*,
                )*
            }
        }

        $(
            check_keyword_matches!(pub $vpub);
            maybe_ast_struct! {
                $(#[$variant_attr])*
                $(
                    $vpub struct $member $($rest)*
                )*
            }

            $(
                impl From<$member> for $name {
                    fn from(e: $member) -> $name {
                        $name::$variant(e)
                    }
                }
            )*
        )*

        #[cfg(feature = "printing")]
        generate_to_tokens! {
            $($remaining)*
            ()
            tokens
            $name { $($variant $( [$($rest)*] )*,)* }
        }
    )
}

#[cfg(feature = "printing")]
macro_rules! generate_to_tokens {
    (do_not_generate_to_tokens $($foo:tt)*) => ();

    (($($arms:tt)*) $tokens:ident $name:ident { $variant:ident, $($next:tt)*}) => {
        generate_to_tokens!(
            ($($arms)* $name::$variant => {})
            $tokens $name { $($next)* }
        );
    };

    (($($arms:tt)*) $tokens:ident $name:ident { $variant:ident [$($rest:tt)*], $($next:tt)*}) => {
        generate_to_tokens!(
            ($($arms)* $name::$variant(ref _e) => to_tokens_call!(_e, $tokens, $($rest)*),)
            $tokens $name { $($next)* }
        );
    };

    (($($arms:tt)*) $tokens:ident $name:ident {}) => {
        impl ::quote::ToTokens for $name {
            fn to_tokens(&self, $tokens: &mut ::proc_macro2::TokenStream) {
                match *self {
                    $($arms)*
                }
            }
        }
    };
}

#[cfg(all(feature = "printing", feature = "full"))]
macro_rules! to_tokens_call {
    ($e:ident, $tokens:ident, $($rest:tt)*) => {
        $e.to_tokens($tokens)
    };
}

#[cfg(all(feature = "printing", feature = "derive", not(feature = "full")))]
macro_rules! to_tokens_call {
    // If the variant is marked as #full, don't auto-generate to-tokens for it.
    ($e:ident, $tokens:ident, #full $($rest:tt)*) => {
        unreachable!()
    };
    ($e:ident, $tokens:ident, $($rest:tt)*) => {
        $e.to_tokens($tokens)
    };
}

macro_rules! maybe_ast_struct {
    (
        $(#[$attr:meta])*
        $(
            pub struct $name:ident
        )*
    ) => ();

    ($($rest:tt)*) => (ast_struct! { $($rest)* });
}

#[cfg(syn_can_match_ident_after_attrs)]
macro_rules! check_keyword_matches {
    (struct struct) => {};
    (enum enum) => {};
    (pub pub) => {};
}
<|endoftext|>


<commit_before>/**
Gets a reference to a `Class`.

Panics if no class with the given name can be found.
To check for a class that may not exist, use `Class::get`.

# Example
``` no_run
# #[macro_use] extern crate objc;
# fn main() {
let cls = class!(NSObject);
# }
```
*/
#[macro_export]
macro_rules! class {
    ($name:ident) => ({
        #[allow(deprecated)]
        #[inline(always)]
        fn get_class(name: &str) -> Option<&'static $crate::runtime::Class> {
            unsafe {
                #[cfg_attr(feature = "cargo-clippy", allow(replace_consts))]
                static CLASS: ::std::sync::atomic::AtomicUsize = ::std::sync::atomic::ATOMIC_USIZE_INIT;
                // `Relaxed` should be fine since `objc_getClass` is thread-safe.
                let ptr = CLASS.load(::std::sync::atomic::Ordering::Relaxed) as *const $crate::runtime::Class;
                if ptr.is_null() {
                    let cls = $crate::runtime::objc_getClass(name.as_ptr() as *const _);
                    CLASS.store(cls as usize, ::std::sync::atomic::Ordering::Relaxed);
                    if cls.is_null() { None } else { Some(&*cls) }
                } else {
                    Some(&*ptr)
                }
            }
        }
        match get_class(concat!(stringify!($name), '\0')) {
            Some(cls) => cls,
            None => panic!("Class with name {} could not be found", stringify!($name)),
        }
    })
}

#[doc(hidden)]
#[macro_export]
macro_rules! sel_impl {
    // Declare a function to hide unsafety, otherwise we can trigger the
    // unused_unsafe lint; see rust-lang/rust#8472
    ($name:expr) => ({
        #[allow(deprecated)]
        #[inline(always)]
        fn register_sel(name: &str) -> $crate::runtime::Sel {
            unsafe {
                #[cfg_attr(feature = "cargo-clippy", allow(replace_consts))]
                static SEL: ::std::sync::atomic::AtomicUsize = ::std::sync::atomic::ATOMIC_USIZE_INIT;
                let ptr = SEL.load(::std::sync::atomic::Ordering::Relaxed) as *const ::std::os::raw::c_void;
                // It should be fine to use `Relaxed` ordering here because `sel_registerName` is
                // thread-safe.
                if ptr.is_null() {
                    let sel = $crate::runtime::sel_registerName(name.as_ptr() as *const _);
                    SEL.store(sel.as_ptr() as usize, ::std::sync::atomic::Ordering::Relaxed);
                    sel
                } else {
                    $crate::runtime::Sel::from_ptr(ptr)
                }
            }
        }
        register_sel($name)
    })
}

/**
Registers a selector, returning a `Sel`.

# Example
```
# #[macro_use] extern crate objc;
# fn main() {
let sel = sel!(description);
let sel = sel!(setObject:forKey:);
# }
```
*/
#[macro_export]
macro_rules! sel {
    ($name:ident) => ({sel_impl!(concat!(stringify!($name), '\0'))});
    ($($name:ident :)+) => ({sel_impl!(concat!($(stringify!($name), ':'),+, '\0'))});
}

/**
Sends a message to an object.

The first argument can be any type that dereferences to a type that implements
`Message`, like a reference, pointer, or an `Id`.
The syntax is similar to the message syntax in Objective-C.
Variadic arguments are not currently supported.

# Example
``` no_run
# #[macro_use] extern crate objc;
# use objc::runtime::Object;
# fn main() {
# unsafe {
let obj: *mut Object;
# let obj: *mut Object = 0 as *mut Object;
let description: *const Object = msg_send![obj, description];
let _: () = msg_send![obj, setArg1:1 arg2:2];
# }
# }
```
*/
#[macro_export]
macro_rules! msg_send {
    (super($obj:expr, $superclass:expr), $name:ident) => ({
        let sel = sel!($name);
        match $crate::__send_super_message(&*$obj, $superclass, sel, ()) {
            Err(s) => panic!("{}", s),
            Ok(r) => r,
        }
    });
    (super($obj:expr, $superclass:expr), $($name:ident : $arg:expr)+) => ({
        let sel = sel!($($name:)+);
        match $crate::__send_super_message(&*$obj, $superclass, sel, ($($arg,)*)) {
            Err(s) => panic!("{}", s),
            Ok(r) => r,
        }
    });
    ($obj:expr, $name:ident) => ({
        let sel = sel!($name);
        match $crate::__send_message(&*$obj, sel, ()) {
            Err(s) => panic!("{}", s),
            Ok(r) => r,
        }
    });
    ($obj:expr, $($name:ident : $arg:expr)+) => ({
        let sel = sel!($($name:)+);
        match $crate::__send_message(&*$obj, sel, ($($arg,)*)) {
            Err(s) => panic!("{}", s),
            Ok(r) => r,
        }
    });
}
<commit_msg>Remove usages of deprecated ATOMIC_USIZE_INIT (#75)<commit_after>/**
Gets a reference to a `Class`.

Panics if no class with the given name can be found.
To check for a class that may not exist, use `Class::get`.

# Example
``` no_run
# #[macro_use] extern crate objc;
# fn main() {
let cls = class!(NSObject);
# }
```
*/
#[macro_export]
macro_rules! class {
    ($name:ident) => ({
        #[allow(deprecated)]
        #[inline(always)]
        fn get_class(name: &str) -> Option<&'static $crate::runtime::Class> {
            unsafe {
                static CLASS: ::std::sync::atomic::AtomicUsize = ::std::sync::atomic::AtomicUsize::new(0);
                // `Relaxed` should be fine since `objc_getClass` is thread-safe.
                let ptr = CLASS.load(::std::sync::atomic::Ordering::Relaxed) as *const $crate::runtime::Class;
                if ptr.is_null() {
                    let cls = $crate::runtime::objc_getClass(name.as_ptr() as *const _);
                    CLASS.store(cls as usize, ::std::sync::atomic::Ordering::Relaxed);
                    if cls.is_null() { None } else { Some(&*cls) }
                } else {
                    Some(&*ptr)
                }
            }
        }
        match get_class(concat!(stringify!($name), '\0')) {
            Some(cls) => cls,
            None => panic!("Class with name {} could not be found", stringify!($name)),
        }
    })
}

#[doc(hidden)]
#[macro_export]
macro_rules! sel_impl {
    // Declare a function to hide unsafety, otherwise we can trigger the
    // unused_unsafe lint; see rust-lang/rust#8472
    ($name:expr) => ({
        #[allow(deprecated)]
        #[inline(always)]
        fn register_sel(name: &str) -> $crate::runtime::Sel {
            unsafe {
                static SEL: ::std::sync::atomic::AtomicUsize = ::std::sync::atomic::AtomicUsize::new(0);
                let ptr = SEL.load(::std::sync::atomic::Ordering::Relaxed) as *const ::std::os::raw::c_void;
                // It should be fine to use `Relaxed` ordering here because `sel_registerName` is
                // thread-safe.
                if ptr.is_null() {
                    let sel = $crate::runtime::sel_registerName(name.as_ptr() as *const _);
                    SEL.store(sel.as_ptr() as usize, ::std::sync::atomic::Ordering::Relaxed);
                    sel
                } else {
                    $crate::runtime::Sel::from_ptr(ptr)
                }
            }
        }
        register_sel($name)
    })
}

/**
Registers a selector, returning a `Sel`.

# Example
```
# #[macro_use] extern crate objc;
# fn main() {
let sel = sel!(description);
let sel = sel!(setObject:forKey:);
# }
```
*/
#[macro_export]
macro_rules! sel {
    ($name:ident) => ({sel_impl!(concat!(stringify!($name), '\0'))});
    ($($name:ident :)+) => ({sel_impl!(concat!($(stringify!($name), ':'),+, '\0'))});
}

/**
Sends a message to an object.

The first argument can be any type that dereferences to a type that implements
`Message`, like a reference, pointer, or an `Id`.
The syntax is similar to the message syntax in Objective-C.
Variadic arguments are not currently supported.

# Example
``` no_run
# #[macro_use] extern crate objc;
# use objc::runtime::Object;
# fn main() {
# unsafe {
let obj: *mut Object;
# let obj: *mut Object = 0 as *mut Object;
let description: *const Object = msg_send![obj, description];
let _: () = msg_send![obj, setArg1:1 arg2:2];
# }
# }
```
*/
#[macro_export]
macro_rules! msg_send {
    (super($obj:expr, $superclass:expr), $name:ident) => ({
        let sel = sel!($name);
        match $crate::__send_super_message(&*$obj, $superclass, sel, ()) {
            Err(s) => panic!("{}", s),
            Ok(r) => r,
        }
    });
    (super($obj:expr, $superclass:expr), $($name:ident : $arg:expr)+) => ({
        let sel = sel!($($name:)+);
        match $crate::__send_super_message(&*$obj, $superclass, sel, ($($arg,)*)) {
            Err(s) => panic!("{}", s),
            Ok(r) => r,
        }
    });
    ($obj:expr, $name:ident) => ({
        let sel = sel!($name);
        match $crate::__send_message(&*$obj, sel, ()) {
            Err(s) => panic!("{}", s),
            Ok(r) => r,
        }
    });
    ($obj:expr, $($name:ident : $arg:expr)+) => ({
        let sel = sel!($($name:)+);
        match $crate::__send_message(&*$obj, sel, ($($arg,)*)) {
            Err(s) => panic!("{}", s),
            Ok(r) => r,
        }
    });
}
<|endoftext|>


<commit_before>
/// Forward a method to an inherent method or a base trait method.
macro_rules! forward {
    ($( Self :: $method:ident ( self $( , $arg:ident : $ty:ty )* ) -> $ret:ty ; )*)
        => {$(
            #[inline]
            fn $method(self $( , $arg : $ty )* ) -> $ret {
                Self::$method(self $( , $arg )* )
            }
        )*};
    ($( $base:ident :: $method:ident ( self $( , $arg:ident : $ty:ty )* ) -> $ret:ty ; )*)
        => {$(
            #[inline]
            fn $method(self $( , $arg : $ty )* ) -> $ret {
                <Self as $base>::$method(self $( , $arg )* )
            }
        )*};
    ($( $base:ident :: $method:ident ( $( $arg:ident : $ty:ty ),* ) -> $ret:ty ; )*)
        => {$(
            #[inline]
            fn $method( $( $arg : $ty ),* ) -> $ret {
                <Self as $base>::$method( $( $arg ),* )
            }
        )*}
}

macro_rules! constant {
    ($( $method:ident () -> $ret:expr ; )*)
        => {$(
            #[inline]
            fn $method() -> Self {
                $ret
            }
        )*};
}
<commit_msg>allow unused macros<commit_after>// not all are used in all features configurations
#![allow(unused)]

/// Forward a method to an inherent method or a base trait method.
macro_rules! forward {
    ($( Self :: $method:ident ( self $( , $arg:ident : $ty:ty )* ) -> $ret:ty ; )*)
        => {$(
            #[inline]
            fn $method(self $( , $arg : $ty )* ) -> $ret {
                Self::$method(self $( , $arg )* )
            }
        )*};
    ($( $base:ident :: $method:ident ( self $( , $arg:ident : $ty:ty )* ) -> $ret:ty ; )*)
        => {$(
            #[inline]
            fn $method(self $( , $arg : $ty )* ) -> $ret {
                <Self as $base>::$method(self $( , $arg )* )
            }
        )*};
    ($( $base:ident :: $method:ident ( $( $arg:ident : $ty:ty ),* ) -> $ret:ty ; )*)
        => {$(
            #[inline]
            fn $method( $( $arg : $ty ),* ) -> $ret {
                <Self as $base>::$method( $( $arg ),* )
            }
        )*}
}

macro_rules! constant {
    ($( $method:ident () -> $ret:expr ; )*)
        => {$(
            #[inline]
            fn $method() -> Self {
                $ret
            }
        )*};
}
<|endoftext|>


<commit_before>//!Some helpful macros.

///The `insert_routes!` macro generates routes from the provided handlers and routing tree and
///adds them to the provided router. The router is then returned.
///
///This can be useful to lower the risk of typing errors, among other things.
///
///##Example 1
///
///```rust
///#[macro_use]
///extern crate rustful;
///use rustful::Method::Get;
///# use rustful::{Handler, Context, Response, TreeRouter};
///
///# #[derive(Copy)]
///# struct DummyHandler;
///# impl Handler for DummyHandler {
///#     type Cache = ();
///#     fn handle_request(&self, _: Context, _: Response){}
///# }
///# fn main() {
///# let about_us = DummyHandler;
///# let show_user = DummyHandler;
///# let show_product = DummyHandler;
///# let show_error = DummyHandler;
///# let show_welcome = DummyHandler;
///let router = insert_routes! {
///    TreeRouter::new() => {
///        "/about" => Get: about_us,
///        "/user/:user" => Get: show_user,
///        "/product/:name" => Get: show_product,
///        "/*" => Get: show_error,
///        "/" => Get: show_welcome
///    }
///};
///# }
///```
///
///##Example 2
///
///```rust
///#[macro_use]
///extern crate rustful;
///use rustful::Method::{Get, Post, Delete};
///# use rustful::{Handler, Context, Response, TreeRouter};
///
///# #[derive(Copy)]
///# struct DummyHandler;
///# impl Handler for DummyHandler {
///#     type Cache = ();
///#     fn handle_request(&self, _: Context, _: Response){}
///# }
///# fn main() {
///# let show_home = DummyHandler;
///# let show_user = DummyHandler;
///# let save_user = DummyHandler;
///# let show_all_products = DummyHandler;
///# let send_all_product_data = DummyHandler;
///# let show_product = DummyHandler;
///# let edit_product = DummyHandler;
///# let send_product_data = DummyHandler;
///
///let mut router = TreeRouter::new();
///
///insert_routes! {
///    &mut router => {
///        "/" => Get: show_home,
///        "home" => Get: show_home,
///        "user/:username" => {
///            "/" => Get: show_user,
///            "/" => Post: save_user
///        },
///        "product" => {
///            "/" => Get: show_all_products,
///
///            "json" => Get: send_all_product_data,
///            ":id" => {
///                "/" => Get: show_product,
///                "/" => Post: edit_product,
///                "/" => Delete: edit_product,
///
///                "json" => Get: send_product_data
///            }
///        }
///    }
///};
///# }
///```
#[macro_export]
macro_rules! insert_routes {
    ($router:expr => {$($paths:tt)+}) => {
        {
            use $crate::Router;
            let mut router = $router;
            __insert_internal!(router, [], $($paths)+);
            router
        }
    }
}

//Internal stuff. Only meant to be used through `insert_routes!`.
#[doc(hidden)]
#[macro_export]
macro_rules! __insert_internal {
    ($router:ident, [$($steps:expr),*], $path:expr => {$($paths:tt)+}, $($next:tt)*) => {
        {
            __insert_internal!($router, [$($steps,)* $path], $($paths)*);
            __insert_internal!($router, [$($steps),*], $($next)*);
        }
    };
    ($router:ident, [$($steps:expr),*], $path:expr => {$($paths:tt)+}) => {
        {
            __insert_internal!($router, [$($steps,)* $path], $($paths)*);
        }
    };
    ($router:ident, [$($steps:expr),*], $path:expr => $method:path: $handler:expr, $($next:tt)*) => {
        {
            $router.insert($method, &[$($steps,)* $path][..], $handler);
            __insert_internal!($router, [$($steps),*], $($next)*)
        }
    };
    ($router:ident, [$($steps:expr),*], $path:expr => $method:path: $handler:expr) => {
        {
            $router.insert($method, &[$($steps,)* $path][..], $handler);
        }
    };
}

/**
A macro for assigning content types.

It takes a main type, a sub type and a parameter list. Instead of this:

```rust
use rustful::header::ContentType;
use rustful::mime::Mime;

ContentType(
    Mime (
        std::str::FromStr::from_str("text").unwrap(),
        std::str::FromStr::from_str("html").unwrap(),
        vec![(std::str::FromStr::from_str("charset").unwrap(), std::str::FromStr::from_str("UTF-8").unwrap())]
    )
);
```

it can be written like this:

```
#[macro_use]
extern crate rustful;
use rustful::header::ContentType;

# fn main() {
ContentType(content_type!("text", "html", ("charset", "UTF-8")));
# }
```

The `"charset": "UTF-8"` part defines the parameter list for the content type.
It may contain more than one parameter, or be omitted:

```
#[macro_use]
extern crate rustful;
use rustful::header::ContentType;

# fn main() {
ContentType(content_type!("application", "octet-stream", ("type", "image/gif"), ("padding", "4")));
# }
```

```
#[macro_use]
extern crate rustful;
use rustful::header::ContentType;

# fn main() {
ContentType(content_type!("image", "png"));
# }
```
**/
#[macro_export]
macro_rules! content_type {
    ($main_type:expr, $sub_type:expr) => ({
        $crate::mime::Mime (
            std::str::FromStr::from_str($main_type).unwrap(),
            std::str::FromStr::from_str($sub_type).unwrap(),
            Vec::new()
        )
    });

    ($main_type:expr, $sub_type:expr, $(($param:expr, $value:expr)),+) => ({
        $crate::mime::Mime (
            std::str::FromStr::from_str($main_type).unwrap(),
            std::str::FromStr::from_str($sub_type).unwrap(),
            vec!( $( (std::str::FromStr::from_str($param).unwrap(), std::str::FromStr::from_str($value).unwrap()) ),+ )
        )
    });
}
<commit_msg>Use global paths in content_type!<commit_after>//!Some helpful macros.

///The `insert_routes!` macro generates routes from the provided handlers and routing tree and
///adds them to the provided router. The router is then returned.
///
///This can be useful to lower the risk of typing errors, among other things.
///
///##Example 1
///
///```rust
///#[macro_use]
///extern crate rustful;
///use rustful::Method::Get;
///# use rustful::{Handler, Context, Response, TreeRouter};
///
///# #[derive(Copy)]
///# struct DummyHandler;
///# impl Handler for DummyHandler {
///#     type Cache = ();
///#     fn handle_request(&self, _: Context, _: Response){}
///# }
///# fn main() {
///# let about_us = DummyHandler;
///# let show_user = DummyHandler;
///# let show_product = DummyHandler;
///# let show_error = DummyHandler;
///# let show_welcome = DummyHandler;
///let router = insert_routes! {
///    TreeRouter::new() => {
///        "/about" => Get: about_us,
///        "/user/:user" => Get: show_user,
///        "/product/:name" => Get: show_product,
///        "/*" => Get: show_error,
///        "/" => Get: show_welcome
///    }
///};
///# }
///```
///
///##Example 2
///
///```rust
///#[macro_use]
///extern crate rustful;
///use rustful::Method::{Get, Post, Delete};
///# use rustful::{Handler, Context, Response, TreeRouter};
///
///# #[derive(Copy)]
///# struct DummyHandler;
///# impl Handler for DummyHandler {
///#     type Cache = ();
///#     fn handle_request(&self, _: Context, _: Response){}
///# }
///# fn main() {
///# let show_home = DummyHandler;
///# let show_user = DummyHandler;
///# let save_user = DummyHandler;
///# let show_all_products = DummyHandler;
///# let send_all_product_data = DummyHandler;
///# let show_product = DummyHandler;
///# let edit_product = DummyHandler;
///# let send_product_data = DummyHandler;
///
///let mut router = TreeRouter::new();
///
///insert_routes! {
///    &mut router => {
///        "/" => Get: show_home,
///        "home" => Get: show_home,
///        "user/:username" => {
///            "/" => Get: show_user,
///            "/" => Post: save_user
///        },
///        "product" => {
///            "/" => Get: show_all_products,
///
///            "json" => Get: send_all_product_data,
///            ":id" => {
///                "/" => Get: show_product,
///                "/" => Post: edit_product,
///                "/" => Delete: edit_product,
///
///                "json" => Get: send_product_data
///            }
///        }
///    }
///};
///# }
///```
#[macro_export]
macro_rules! insert_routes {
    ($router:expr => {$($paths:tt)+}) => {
        {
            use $crate::Router;
            let mut router = $router;
            __insert_internal!(router, [], $($paths)+);
            router
        }
    }
}

//Internal stuff. Only meant to be used through `insert_routes!`.
#[doc(hidden)]
#[macro_export]
macro_rules! __insert_internal {
    ($router:ident, [$($steps:expr),*], $path:expr => {$($paths:tt)+}, $($next:tt)*) => {
        {
            __insert_internal!($router, [$($steps,)* $path], $($paths)*);
            __insert_internal!($router, [$($steps),*], $($next)*);
        }
    };
    ($router:ident, [$($steps:expr),*], $path:expr => {$($paths:tt)+}) => {
        {
            __insert_internal!($router, [$($steps,)* $path], $($paths)*);
        }
    };
    ($router:ident, [$($steps:expr),*], $path:expr => $method:path: $handler:expr, $($next:tt)*) => {
        {
            $router.insert($method, &[$($steps,)* $path][..], $handler);
            __insert_internal!($router, [$($steps),*], $($next)*)
        }
    };
    ($router:ident, [$($steps:expr),*], $path:expr => $method:path: $handler:expr) => {
        {
            $router.insert($method, &[$($steps,)* $path][..], $handler);
        }
    };
}

/**
A macro for assigning content types.

It takes a main type, a sub type and a parameter list. Instead of this:

```rust
use rustful::header::ContentType;
use rustful::mime::Mime;

ContentType(
    Mime (
        std::str::FromStr::from_str("text").unwrap(),
        std::str::FromStr::from_str("html").unwrap(),
        vec![(std::str::FromStr::from_str("charset").unwrap(), std::str::FromStr::from_str("UTF-8").unwrap())]
    )
);
```

it can be written like this:

```
#[macro_use]
extern crate rustful;
use rustful::header::ContentType;

# fn main() {
ContentType(content_type!("text", "html", ("charset", "UTF-8")));
# }
```

The `"charset": "UTF-8"` part defines the parameter list for the content type.
It may contain more than one parameter, or be omitted:

```
#[macro_use]
extern crate rustful;
use rustful::header::ContentType;

# fn main() {
ContentType(content_type!("application", "octet-stream", ("type", "image/gif"), ("padding", "4")));
# }
```

```
#[macro_use]
extern crate rustful;
use rustful::header::ContentType;

# fn main() {
ContentType(content_type!("image", "png"));
# }
```
**/
#[macro_export]
macro_rules! content_type {
    ($main_type:expr, $sub_type:expr) => ({
        $crate::mime::Mime (
            ::std::str::FromStr::from_str($main_type).unwrap(),
            ::std::str::FromStr::from_str($sub_type).unwrap(),
            Vec::new()
        )
    });

    ($main_type:expr, $sub_type:expr, $(($param:expr, $value:expr)),+) => ({
        $crate::mime::Mime (
            ::std::str::FromStr::from_str($main_type).unwrap(),
            ::std::str::FromStr::from_str($sub_type).unwrap(),
            vec!( $( (::std::str::FromStr::from_str($param).unwrap(), ::std::str::FromStr::from_str($value).unwrap()) ),+ )
        )
    });
}
<|endoftext|>


<commit_before>//! The Scene system is basically for transitioning between
//! *completely* different states that have entirely different game
//! loops and but which all share a state.  It operates as a stack, with new
//! scenes getting pushed to the stack (while the old ones stay in
//! memory unchanged).  Apparently this is basically a push-down automata.
//!
//! Also there's no reason you can't have a Scene contain its own
//! Scene subsystem to do its own indirection.  With a different state
//! type, as well!  What fun!  Though whether you want to go that deep
//! down the rabbit-hole is up to you.  I haven't found it necessary
//! yet.
//!
//! This is basically identical in concept to the Amethyst engine's scene
//! system, the only difference is the details of how the pieces are put
//! together.

use ggez;

/// A command to change to a new scene, either by pushign a new one,
/// popping one or replacing the current scene (pop and then push).
pub enum SceneSwitch<C, Ev> {
    None,
    Push(Box<Scene<C, Ev>>),
    Replace(Box<Scene<C, Ev>>),
    Pop,
}

/// A trait for you to implement on a scene.
/// Defines the callbacks the scene uses:
/// a common context type `C`, and an input event type `Ev`.
pub trait Scene<C, Ev> {
    fn update(&mut self, gameworld: &mut C) -> SceneSwitch<C, Ev>;
    fn draw(&mut self, gameworld: &mut C, ctx: &mut ggez::Context) -> ggez::GameResult<()>;
    fn input(&mut self, gameworld: &mut C, event: Ev, started: bool);
    /// Only used for human-readable convenience (or not at all, tbh)
    fn name(&self) -> &str;
    /// This returns whether or not to draw the next scene down on the
    /// stack as well; this is useful for layers or GUI stuff that
    /// only partially covers the screen.
    fn draw_previous(&self) -> bool {
        false
    }
}

impl<C, Ev> SceneSwitch<C, Ev> {
    /// Convenient shortcut function for boxing scenes.
    ///
    /// Slightly nicer than writing
    /// `SceneSwitch::Replace(Box::new(x))` all the damn time.
    pub fn replace<S>(scene: S) -> Self
    where
        S: Scene<C, Ev> + 'static,
    {
        SceneSwitch::Replace(Box::new(scene))
    }

    /// Same as `replace()` but returns SceneSwitch::Push
    pub fn push<S>(scene: S) -> Self
    where
        S: Scene<C, Ev> + 'static,
    {
        SceneSwitch::Push(Box::new(scene))
    }
}

/// A stack of `Scene`'s, together with a context object.
pub struct SceneStack<C, Ev> {
    pub world: C,
    scenes: Vec<Box<Scene<C, Ev>>>,
}

impl<C, Ev> SceneStack<C, Ev> {
    pub fn new(ctx: &mut ggez::Context, global_state: C) -> Self {
        Self {
            world: global_state,
            scenes: Vec::new(),
        }
    }

    /// Add a new scene to the top of the stack.
    pub fn push(&mut self, scene: Box<Scene<C, Ev>>) {
        self.scenes.push(scene)
    }

    /// Remove the top scene from the stack and returns it;
    /// panics if there is none.
    pub fn pop(&mut self) -> Box<Scene<C, Ev>> {
        self.scenes
            .pop()
            .expect("ERROR: Popped an empty scene stack.")
    }

    /// Returns the current scene; panics if there is none.
    pub fn current(&self) -> &Scene<C, Ev> {
        &**self.scenes
            .last()
            .expect("ERROR: Tried to get current scene of an empty scene stack.")
    }

    /// Executes the given SceneSwitch command; if it is a pop or replace
    /// it returns `Some(old_scene)`, otherwise `None`
    pub fn switch(&mut self, next_scene: SceneSwitch<C, Ev>) -> Option<Box<Scene<C, Ev>>> {
        match next_scene {
            SceneSwitch::None => None,
            SceneSwitch::Pop => {
                let s = self.pop();
                Some(s)
            }
            SceneSwitch::Push(s) => {
                self.push(s);
                None
            }
            SceneSwitch::Replace(s) => {
                let old_scene = self.pop();
                self.push(s);
                Some(old_scene)
            }
        }
    }

    // These functions must be on the SceneStack because otherwise
    // if you try to get the current scene and the world to call
    // update() on the current scene it causes a double-borrow.  :/
    pub fn update(&mut self) {
        let next_scene = {
            let current_scene = &mut **self.scenes
                .last_mut()
                .expect("Tried to update empty scene stack");
            current_scene.update(&mut self.world)
        };
        self.switch(next_scene);
    }

    /// We walk down the scene stack until we find a scene where we aren't
    /// supposed to draw the previous one, then draw them from the bottom up.
    ///
    /// This allows for layering GUI's and such.
    fn draw_scenes(scenes: &mut [Box<Scene<C, Ev>>], world: &mut C, ctx: &mut ggez::Context) {
        assert!(scenes.len() > 0);
        if let Some((current, rest)) = scenes.split_last_mut() {
            if current.draw_previous() {
                SceneStack::draw_scenes(rest, world, ctx);
            }
            current
                .draw(world, ctx)
                .expect("I would hope drawing a scene never fails!");
        }
    }

    /// Draw the current scene.
    pub fn draw(&mut self, ctx: &mut ggez::Context) {
        SceneStack::draw_scenes(&mut self.scenes, &mut self.world, ctx)
    }

    /// Feeds the given input event to the current scene.
    pub fn input(&mut self, event: Ev, started: bool) {
        let current_scene = &mut **self.scenes
            .last_mut()
            .expect("Tried to do input for empty scene stack");
        current_scene.input(&mut self.world, event, started);
    }
}

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

    struct Thing {
        scenes: Vec<SceneStack<u32, u32>>,
    }

    #[test]
    fn test1() {
        let x = Thing { scenes: vec![] };
    }
}
<commit_msg>pass ctx to `update`<commit_after>//! The Scene system is basically for transitioning between
//! *completely* different states that have entirely different game
//! loops and but which all share a state.  It operates as a stack, with new
//! scenes getting pushed to the stack (while the old ones stay in
//! memory unchanged).  Apparently this is basically a push-down automata.
//!
//! Also there's no reason you can't have a Scene contain its own
//! Scene subsystem to do its own indirection.  With a different state
//! type, as well!  What fun!  Though whether you want to go that deep
//! down the rabbit-hole is up to you.  I haven't found it necessary
//! yet.
//!
//! This is basically identical in concept to the Amethyst engine's scene
//! system, the only difference is the details of how the pieces are put
//! together.

use ggez;

/// A command to change to a new scene, either by pushign a new one,
/// popping one or replacing the current scene (pop and then push).
pub enum SceneSwitch<C, Ev> {
    None,
    Push(Box<Scene<C, Ev>>),
    Replace(Box<Scene<C, Ev>>),
    Pop,
}

/// A trait for you to implement on a scene.
/// Defines the callbacks the scene uses:
/// a common context type `C`, and an input event type `Ev`.
pub trait Scene<C, Ev> {
    fn update(&mut self, gameworld: &mut C, ctx: &mut ggez::Context) -> SceneSwitch<C, Ev>;
    fn draw(&mut self, gameworld: &mut C, ctx: &mut ggez::Context) -> ggez::GameResult<()>;
    fn input(&mut self, gameworld: &mut C, event: Ev, started: bool);
    /// Only used for human-readable convenience (or not at all, tbh)
    fn name(&self) -> &str;
    /// This returns whether or not to draw the next scene down on the
    /// stack as well; this is useful for layers or GUI stuff that
    /// only partially covers the screen.
    fn draw_previous(&self) -> bool {
        false
    }
}

impl<C, Ev> SceneSwitch<C, Ev> {
    /// Convenient shortcut function for boxing scenes.
    ///
    /// Slightly nicer than writing
    /// `SceneSwitch::Replace(Box::new(x))` all the damn time.
    pub fn replace<S>(scene: S) -> Self
    where
        S: Scene<C, Ev> + 'static,
    {
        SceneSwitch::Replace(Box::new(scene))
    }

    /// Same as `replace()` but returns SceneSwitch::Push
    pub fn push<S>(scene: S) -> Self
    where
        S: Scene<C, Ev> + 'static,
    {
        SceneSwitch::Push(Box::new(scene))
    }
}

/// A stack of `Scene`'s, together with a context object.
pub struct SceneStack<C, Ev> {
    pub world: C,
    scenes: Vec<Box<Scene<C, Ev>>>,
}

impl<C, Ev> SceneStack<C, Ev> {
    pub fn new(ctx: &mut ggez::Context, global_state: C) -> Self {
        Self {
            world: global_state,
            scenes: Vec::new(),
        }
    }

    /// Add a new scene to the top of the stack.
    pub fn push(&mut self, scene: Box<Scene<C, Ev>>) {
        self.scenes.push(scene)
    }

    /// Remove the top scene from the stack and returns it;
    /// panics if there is none.
    pub fn pop(&mut self) -> Box<Scene<C, Ev>> {
        self.scenes
            .pop()
            .expect("ERROR: Popped an empty scene stack.")
    }

    /// Returns the current scene; panics if there is none.
    pub fn current(&self) -> &Scene<C, Ev> {
        &**self.scenes
            .last()
            .expect("ERROR: Tried to get current scene of an empty scene stack.")
    }

    /// Executes the given SceneSwitch command; if it is a pop or replace
    /// it returns `Some(old_scene)`, otherwise `None`
    pub fn switch(&mut self, next_scene: SceneSwitch<C, Ev>) -> Option<Box<Scene<C, Ev>>> {
        match next_scene {
            SceneSwitch::None => None,
            SceneSwitch::Pop => {
                let s = self.pop();
                Some(s)
            }
            SceneSwitch::Push(s) => {
                self.push(s);
                None
            }
            SceneSwitch::Replace(s) => {
                let old_scene = self.pop();
                self.push(s);
                Some(old_scene)
            }
        }
    }

    // These functions must be on the SceneStack because otherwise
    // if you try to get the current scene and the world to call
    // update() on the current scene it causes a double-borrow.  :/
    pub fn update(&mut self, ctx: &mut ggez::Context) {
        let next_scene = {
            let current_scene = &mut **self.scenes
                .last_mut()
                .expect("Tried to update empty scene stack");
            current_scene.update(&mut self.world, ctx)
        };
        self.switch(next_scene);
    }

    /// We walk down the scene stack until we find a scene where we aren't
    /// supposed to draw the previous one, then draw them from the bottom up.
    ///
    /// This allows for layering GUI's and such.
    fn draw_scenes(scenes: &mut [Box<Scene<C, Ev>>], world: &mut C, ctx: &mut ggez::Context) {
        assert!(scenes.len() > 0);
        if let Some((current, rest)) = scenes.split_last_mut() {
            if current.draw_previous() {
                SceneStack::draw_scenes(rest, world, ctx);
            }
            current
                .draw(world, ctx)
                .expect("I would hope drawing a scene never fails!");
        }
    }

    /// Draw the current scene.
    pub fn draw(&mut self, ctx: &mut ggez::Context) {
        SceneStack::draw_scenes(&mut self.scenes, &mut self.world, ctx)
    }

    /// Feeds the given input event to the current scene.
    pub fn input(&mut self, event: Ev, started: bool) {
        let current_scene = &mut **self.scenes
            .last_mut()
            .expect("Tried to do input for empty scene stack");
        current_scene.input(&mut self.world, event, started);
    }
}

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

    struct Thing {
        scenes: Vec<SceneStack<u32, u32>>,
    }

    #[test]
    fn test1() {
        let x = Thing { scenes: vec![] };
    }
}
<|endoftext|>


<commit_before>use lexer::{LexicalError, Token};
use lalrpop_util::ParseError;

pub fn print_diagnostic(input: &str, error: ParseError<usize, Token, LexicalError>) {
    let mut error_lines = Vec::new();

    match error {
        ParseError::InvalidToken { location } => {
            error_lines.extend(get_lines(input, (location, location + 1)));
            println!("Invalid token.");
        },
        ParseError::UnrecognizedToken { token, expected } => {
            if let Some((start, tok, end)) = token {
                error_lines.extend(get_lines(input, (start, end)));
                println!("Unrecognized token: {:?}.", tok);
            } else {
                println!("Unexpected eof.");
            }
            println!("Expected one of: {}", expected.join(", "));
        },
        ParseError::ExtraToken { token: (start, tok, end) } => {
            error_lines.extend(get_lines(input, (start, end)));
            println!("Extra token: {:?}.", tok);
        },
        ParseError::User { error: LexicalError { msg, pos } } => {
            error_lines.extend(get_lines(input, (pos, pos + 1)));
            println!("{}", msg);
        }
    }

    for (i, (line, arrow)) in error_lines {
        println!("{:<5}: {}", i+1, line);
        println!("       {}", arrow);
    }
}

fn get_lines<'a>(input: &'a str, span: (usize, usize)) -> Vec<(usize, (&'a str, String))> {
    let mut arrow = String::with_capacity(input.len());

    for (i, c) in input.chars().enumerate() {
        arrow.push(match c {
            '\n' => '\n',
            _ if span.0 <= i && i < span.1 => '^',
            _ => ' ',
        });
    }

    input.lines()
        .zip(arrow.lines().map(String::from))
        .enumerate()
        .filter(|&(_, (_, ref arrow))| {
            arrow.contains('^')
        })
        .collect()
}
<commit_msg>Small change<commit_after>use lexer::{LexicalError, Token};
use lalrpop_util::ParseError;

pub fn print_diagnostic(input: &str, error: ParseError<usize, Token, LexicalError>) {
    let error_lines = match error {
        ParseError::InvalidToken { location } => {
            println!("Invalid token.");
            get_lines(input, (location, location + 1))
        },
        ParseError::UnrecognizedToken { token, expected } => {
            let lines = if let Some((start, tok, end)) = token {
                println!("Unrecognized token: {:?}.", tok);
                get_lines(input, (start, end))
            } else {
                println!("Unexpected eof.");
                Vec::new()
            };
            if expected.len() != 0 {
                println!("Expected one of: {}", expected.join(", "));
            }
            lines
        },
        ParseError::ExtraToken { token: (start, tok, end) } => {
            println!("Extra token: {:?}.", tok);
            get_lines(input, (start, end))
        },
        ParseError::User { error: LexicalError { msg, pos } } => {
            println!("{}", msg);
            get_lines(input, (pos, pos + 1))
        }
    };

    for (i, (line, arrow)) in error_lines {
        println!("{:<5}: {}", i+1, line);
        println!("       {}", arrow);
    }
}

fn get_lines<'a>(input: &'a str, span: (usize, usize)) -> Vec<(usize, (&'a str, String))> {
    let mut arrow = String::with_capacity(input.len());

    for (i, c) in input.chars().enumerate() {
        arrow.push(match c {
            '\n' => '\n',
            _ if span.0 <= i && i < span.1 => '^',
            _ => ' ',
        });
    }

    input.lines()
        .zip(arrow.lines().map(String::from))
        .enumerate()
        .filter(|&(_, (_, ref arrow))| {
            arrow.contains('^')
        })
        .collect()
}
<|endoftext|>