<commit_before>// Copyright 2016, The Gtk-rs Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>
use std::fmt::Debug;

use std::io;
use thiserror::Error;

#[derive(Error, Debug)]
#[non_exhaustive]
pub enum Error {
    #[error("No Memory")]
    NoMemory,
    #[error("Invalid Restore")]
    InvalidRestore,
    #[error("Invalid Pop Group")]
    InvalidPopGroup,
    #[error("No Current Point")]
    NoCurrentPoint,
    #[error("Invalid Matrix")]
    InvalidMatrix,
    #[error("Invalid Status")]
    InvalidStatus,
    #[error("Null Pointer")]
    NullPointer,
    #[error("Invalid String")]
    InvalidString,
    #[error("Invalid Path Data")]
    InvalidPathData,
    #[error("Cairo : Read Error")]
    ReadError,
    #[error("Write Error")]
    WriteError,
    #[error("Surface Finishied")]
    SurfaceFinished,
    #[error("Surface Type Mismatch")]
    SurfaceTypeMismatch,
    #[error("Pattern Type Mismatch")]
    PatternTypeMismatch,
    #[error("Invalid Content")]
    InvalidContent,
    #[error("Invalid Format")]
    InvalidFormat,
    #[error("Invalid Visual")]
    InvalidVisual,
    #[error("File Not Found")]
    FileNotFound,
    #[error("Invalid Dash")]
    InvalidDash,
    #[error("Invalid Dash Comment")]
    InvalidDscComment,
    #[error("Invalid Index")]
    InvalidIndex,
    #[error("Clip Not Representable")]
    ClipNotRepresentable,
    #[error("Temp File Error")]
    TempFileError,
    #[error("Invalid Stride")]
    InvalidStride,
    #[error("Font Type Mismatch")]
    FontTypeMismatch,
    #[error("User Font Immutable")]
    UserFontImmutable,
    #[error("User Font Error")]
    UserFontError,
    #[error("Negative Count")]
    NegativeCount,
    #[error("Invalid Clusters")]
    InvalidClusters,
    #[error("Invalid Slant")]
    InvalidSlant,
    #[error("Invalid Weight")]
    InvalidWeight,
    #[error("Ivalid Size")]
    InvalidSize,
    #[error("User Font Not Implemented")]
    UserFontNotImplemented,
    #[error("Device Type Mismatch")]
    DeviceTypeMismatch,
    #[error("Device Error")]
    DeviceError,
    #[error("Invalid Mesh Construction")]
    InvalidMeshConstruction,
    #[error("Device Finished")]
    DeviceFinished,
    #[error("JBig2Global Missing")]
    JBig2GlobalMissing,
    #[error("PNG Error")]
    PngError,
    #[error("Freetype Error")]
    FreetypeError,
    #[error("Win32Gdi Error")]
    Win32GdiError,
    #[error("LastStatus")]
    LastStatus,
    #[error("Unknown {0}")]
    #[doc(hidden)]
    __Unknown(i32),
}
#[doc(hidden)]
impl Into<ffi::cairo_status_t> for Error {
    fn into(self) -> ffi::cairo_status_t {
        match self {
            Error::NoMemory => ffi::STATUS_NO_MEMORY,
            Error::InvalidRestore => ffi::STATUS_INVALID_RESTORE,
            Error::InvalidPopGroup => ffi::STATUS_INVALID_POP_GROUP,
            Error::NoCurrentPoint => ffi::STATUS_NO_CURRENT_POINT,
            Error::InvalidMatrix => ffi::STATUS_INVALID_MATRIX,
            Error::InvalidStatus => ffi::STATUS_INVALID_STATUS,
            Error::NullPointer => ffi::STATUS_NULL_POINTER,
            Error::InvalidString => ffi::STATUS_INVALID_STRING,
            Error::InvalidPathData => ffi::STATUS_INVALID_PATH_DATA,
            Error::ReadError => ffi::STATUS_READ_ERROR,
            Error::WriteError => ffi::STATUS_WRITE_ERROR,
            Error::SurfaceFinished => ffi::STATUS_SURFACE_FINISHED,
            Error::SurfaceTypeMismatch => ffi::STATUS_SURFACE_TYPE_MISMATCH,
            Error::PatternTypeMismatch => ffi::STATUS_PATTERN_TYPE_MISMATCH,
            Error::InvalidContent => ffi::STATUS_INVALID_CONTENT,
            Error::InvalidFormat => ffi::STATUS_INVALID_FORMAT,
            Error::InvalidVisual => ffi::STATUS_INVALID_VISUAL,
            Error::FileNotFound => ffi::STATUS_FILE_NOT_FOUND,
            Error::InvalidDash => ffi::STATUS_INVALID_DASH,
            Error::InvalidDscComment => ffi::STATUS_INVALID_DSC_COMMENT,
            Error::InvalidIndex => ffi::STATUS_INVALID_INDEX,
            Error::ClipNotRepresentable => ffi::STATUS_CLIP_NOT_REPRESENTABLE,
            Error::TempFileError => ffi::STATUS_TEMP_FILE_ERROR,
            Error::InvalidStride => ffi::STATUS_INVALID_STRIDE,
            Error::FontTypeMismatch => ffi::STATUS_FONT_TYPE_MISMATCH,
            Error::UserFontImmutable => ffi::STATUS_USER_FONT_IMMUTABLE,
            Error::UserFontError => ffi::STATUS_USER_FONT_ERROR,
            Error::NegativeCount => ffi::STATUS_NEGATIVE_COUNT,
            Error::InvalidClusters => ffi::STATUS_INVALID_CLUSTERS,
            Error::InvalidSlant => ffi::STATUS_INVALID_SLANT,
            Error::InvalidWeight => ffi::STATUS_INVALID_WEIGHT,
            Error::InvalidSize => ffi::STATUS_INVALID_SIZE,
            Error::UserFontNotImplemented => ffi::STATUS_USER_FONT_NOT_IMPLEMENTED,
            Error::DeviceTypeMismatch => ffi::STATUS_DEVICE_TYPE_MISMATCH,
            Error::DeviceError => ffi::STATUS_DEVICE_ERROR,
            Error::InvalidMeshConstruction => ffi::STATUS_INVALID_MESH_CONSTRUCTION,
            Error::DeviceFinished => ffi::STATUS_DEVICE_FINISHED,
            Error::JBig2GlobalMissing => ffi::STATUS_J_BIG2_GLOBAL_MISSING,
            Error::PngError => ffi::STATUS_PNG_ERROR,
            Error::FreetypeError => ffi::STATUS_FREETYPE_ERROR,
            Error::Win32GdiError => ffi::STATUS_WIN32_GDI_ERROR,
            Error::LastStatus => ffi::STATUS_LAST_STATUS,
            Error::__Unknown(value) => value,
        }
    }
}

#[doc(hidden)]
impl From<ffi::cairo_status_t> for Error {
    fn from(value: ffi::cairo_status_t) -> Self {
        match value {
            ffi::STATUS_NO_MEMORY => Error::NoMemory,
            ffi::STATUS_INVALID_RESTORE => Error::InvalidRestore,
            ffi::STATUS_INVALID_POP_GROUP => Error::InvalidPopGroup,
            ffi::STATUS_NO_CURRENT_POINT => Error::NoCurrentPoint,
            ffi::STATUS_INVALID_MATRIX => Error::InvalidMatrix,
            ffi::STATUS_INVALID_STATUS => Error::InvalidStatus,
            ffi::STATUS_NULL_POINTER => Error::NullPointer,
            ffi::STATUS_INVALID_STRING => Error::InvalidString,
            ffi::STATUS_INVALID_PATH_DATA => Error::InvalidPathData,
            ffi::STATUS_READ_ERROR => Error::ReadError,
            ffi::STATUS_WRITE_ERROR => Error::WriteError,
            ffi::STATUS_SURFACE_FINISHED => Error::SurfaceFinished,
            ffi::STATUS_SURFACE_TYPE_MISMATCH => Error::SurfaceTypeMismatch,
            ffi::STATUS_PATTERN_TYPE_MISMATCH => Error::PatternTypeMismatch,
            ffi::STATUS_INVALID_CONTENT => Error::InvalidContent,
            ffi::STATUS_INVALID_FORMAT => Error::InvalidFormat,
            ffi::STATUS_INVALID_VISUAL => Error::InvalidVisual,
            ffi::STATUS_FILE_NOT_FOUND => Error::FileNotFound,
            ffi::STATUS_INVALID_DASH => Error::InvalidDash,
            ffi::STATUS_INVALID_DSC_COMMENT => Error::InvalidDscComment,
            ffi::STATUS_INVALID_INDEX => Error::InvalidIndex,
            ffi::STATUS_CLIP_NOT_REPRESENTABLE => Error::ClipNotRepresentable,
            ffi::STATUS_TEMP_FILE_ERROR => Error::TempFileError,
            ffi::STATUS_INVALID_STRIDE => Error::InvalidStride,
            ffi::STATUS_FONT_TYPE_MISMATCH => Error::FontTypeMismatch,
            ffi::STATUS_USER_FONT_IMMUTABLE => Error::UserFontImmutable,
            ffi::STATUS_USER_FONT_ERROR => Error::UserFontError,
            ffi::STATUS_NEGATIVE_COUNT => Error::NegativeCount,
            ffi::STATUS_INVALID_CLUSTERS => Error::InvalidClusters,
            ffi::STATUS_INVALID_SLANT => Error::InvalidSlant,
            ffi::STATUS_INVALID_WEIGHT => Error::InvalidWeight,
            ffi::STATUS_INVALID_SIZE => Error::InvalidSize,
            ffi::STATUS_USER_FONT_NOT_IMPLEMENTED => Error::UserFontNotImplemented,
            ffi::STATUS_DEVICE_TYPE_MISMATCH => Error::DeviceTypeMismatch,
            ffi::STATUS_DEVICE_ERROR => Error::DeviceError,
            ffi::STATUS_INVALID_MESH_CONSTRUCTION => Error::InvalidMeshConstruction,
            ffi::STATUS_DEVICE_FINISHED => Error::DeviceFinished,
            ffi::STATUS_J_BIG2_GLOBAL_MISSING => Error::JBig2GlobalMissing,
            ffi::STATUS_PNG_ERROR => Error::PngError,
            ffi::STATUS_FREETYPE_ERROR => Error::FreetypeError,
            ffi::STATUS_WIN32_GDI_ERROR => Error::Win32GdiError,
            ffi::STATUS_LAST_STATUS => Error::LastStatus,
            value => Error::__Unknown(value),
        }
    }
}

#[derive(Error, Debug)]
pub enum IoError {
    #[error("Cairo error: {0}")]
    Cairo(#[from] Error),
    #[error("IO error: {0}")]
    Io(#[from] io::Error),
}

#[derive(Error, Debug)]
pub enum BorrowError {
    #[error("Failed to borrow with Cairo error: {0}")]
    Cairo(#[from] ::Error),
    #[error("Can't get exclusive access")]
    NonExclusive,
}
<commit_msg>errors: derive Error from common enum traits<commit_after>// Copyright 2016, The Gtk-rs Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>
use std::fmt::Debug;

use std::io;
use thiserror::Error;

#[derive(Error, Debug, Clone, PartialEq, PartialOrd, Copy, Eq)]
#[non_exhaustive]
pub enum Error {
    #[error("No Memory")]
    NoMemory,
    #[error("Invalid Restore")]
    InvalidRestore,
    #[error("Invalid Pop Group")]
    InvalidPopGroup,
    #[error("No Current Point")]
    NoCurrentPoint,
    #[error("Invalid Matrix")]
    InvalidMatrix,
    #[error("Invalid Status")]
    InvalidStatus,
    #[error("Null Pointer")]
    NullPointer,
    #[error("Invalid String")]
    InvalidString,
    #[error("Invalid Path Data")]
    InvalidPathData,
    #[error("Cairo : Read Error")]
    ReadError,
    #[error("Write Error")]
    WriteError,
    #[error("Surface Finishied")]
    SurfaceFinished,
    #[error("Surface Type Mismatch")]
    SurfaceTypeMismatch,
    #[error("Pattern Type Mismatch")]
    PatternTypeMismatch,
    #[error("Invalid Content")]
    InvalidContent,
    #[error("Invalid Format")]
    InvalidFormat,
    #[error("Invalid Visual")]
    InvalidVisual,
    #[error("File Not Found")]
    FileNotFound,
    #[error("Invalid Dash")]
    InvalidDash,
    #[error("Invalid Dash Comment")]
    InvalidDscComment,
    #[error("Invalid Index")]
    InvalidIndex,
    #[error("Clip Not Representable")]
    ClipNotRepresentable,
    #[error("Temp File Error")]
    TempFileError,
    #[error("Invalid Stride")]
    InvalidStride,
    #[error("Font Type Mismatch")]
    FontTypeMismatch,
    #[error("User Font Immutable")]
    UserFontImmutable,
    #[error("User Font Error")]
    UserFontError,
    #[error("Negative Count")]
    NegativeCount,
    #[error("Invalid Clusters")]
    InvalidClusters,
    #[error("Invalid Slant")]
    InvalidSlant,
    #[error("Invalid Weight")]
    InvalidWeight,
    #[error("Ivalid Size")]
    InvalidSize,
    #[error("User Font Not Implemented")]
    UserFontNotImplemented,
    #[error("Device Type Mismatch")]
    DeviceTypeMismatch,
    #[error("Device Error")]
    DeviceError,
    #[error("Invalid Mesh Construction")]
    InvalidMeshConstruction,
    #[error("Device Finished")]
    DeviceFinished,
    #[error("JBig2Global Missing")]
    JBig2GlobalMissing,
    #[error("PNG Error")]
    PngError,
    #[error("Freetype Error")]
    FreetypeError,
    #[error("Win32Gdi Error")]
    Win32GdiError,
    #[error("LastStatus")]
    LastStatus,
    #[error("Unknown {0}")]
    #[doc(hidden)]
    __Unknown(i32),
}
#[doc(hidden)]
impl Into<ffi::cairo_status_t> for Error {
    fn into(self) -> ffi::cairo_status_t {
        match self {
            Error::NoMemory => ffi::STATUS_NO_MEMORY,
            Error::InvalidRestore => ffi::STATUS_INVALID_RESTORE,
            Error::InvalidPopGroup => ffi::STATUS_INVALID_POP_GROUP,
            Error::NoCurrentPoint => ffi::STATUS_NO_CURRENT_POINT,
            Error::InvalidMatrix => ffi::STATUS_INVALID_MATRIX,
            Error::InvalidStatus => ffi::STATUS_INVALID_STATUS,
            Error::NullPointer => ffi::STATUS_NULL_POINTER,
            Error::InvalidString => ffi::STATUS_INVALID_STRING,
            Error::InvalidPathData => ffi::STATUS_INVALID_PATH_DATA,
            Error::ReadError => ffi::STATUS_READ_ERROR,
            Error::WriteError => ffi::STATUS_WRITE_ERROR,
            Error::SurfaceFinished => ffi::STATUS_SURFACE_FINISHED,
            Error::SurfaceTypeMismatch => ffi::STATUS_SURFACE_TYPE_MISMATCH,
            Error::PatternTypeMismatch => ffi::STATUS_PATTERN_TYPE_MISMATCH,
            Error::InvalidContent => ffi::STATUS_INVALID_CONTENT,
            Error::InvalidFormat => ffi::STATUS_INVALID_FORMAT,
            Error::InvalidVisual => ffi::STATUS_INVALID_VISUAL,
            Error::FileNotFound => ffi::STATUS_FILE_NOT_FOUND,
            Error::InvalidDash => ffi::STATUS_INVALID_DASH,
            Error::InvalidDscComment => ffi::STATUS_INVALID_DSC_COMMENT,
            Error::InvalidIndex => ffi::STATUS_INVALID_INDEX,
            Error::ClipNotRepresentable => ffi::STATUS_CLIP_NOT_REPRESENTABLE,
            Error::TempFileError => ffi::STATUS_TEMP_FILE_ERROR,
            Error::InvalidStride => ffi::STATUS_INVALID_STRIDE,
            Error::FontTypeMismatch => ffi::STATUS_FONT_TYPE_MISMATCH,
            Error::UserFontImmutable => ffi::STATUS_USER_FONT_IMMUTABLE,
            Error::UserFontError => ffi::STATUS_USER_FONT_ERROR,
            Error::NegativeCount => ffi::STATUS_NEGATIVE_COUNT,
            Error::InvalidClusters => ffi::STATUS_INVALID_CLUSTERS,
            Error::InvalidSlant => ffi::STATUS_INVALID_SLANT,
            Error::InvalidWeight => ffi::STATUS_INVALID_WEIGHT,
            Error::InvalidSize => ffi::STATUS_INVALID_SIZE,
            Error::UserFontNotImplemented => ffi::STATUS_USER_FONT_NOT_IMPLEMENTED,
            Error::DeviceTypeMismatch => ffi::STATUS_DEVICE_TYPE_MISMATCH,
            Error::DeviceError => ffi::STATUS_DEVICE_ERROR,
            Error::InvalidMeshConstruction => ffi::STATUS_INVALID_MESH_CONSTRUCTION,
            Error::DeviceFinished => ffi::STATUS_DEVICE_FINISHED,
            Error::JBig2GlobalMissing => ffi::STATUS_J_BIG2_GLOBAL_MISSING,
            Error::PngError => ffi::STATUS_PNG_ERROR,
            Error::FreetypeError => ffi::STATUS_FREETYPE_ERROR,
            Error::Win32GdiError => ffi::STATUS_WIN32_GDI_ERROR,
            Error::LastStatus => ffi::STATUS_LAST_STATUS,
            Error::__Unknown(value) => value,
        }
    }
}

#[doc(hidden)]
impl From<ffi::cairo_status_t> for Error {
    fn from(value: ffi::cairo_status_t) -> Self {
        match value {
            ffi::STATUS_NO_MEMORY => Error::NoMemory,
            ffi::STATUS_INVALID_RESTORE => Error::InvalidRestore,
            ffi::STATUS_INVALID_POP_GROUP => Error::InvalidPopGroup,
            ffi::STATUS_NO_CURRENT_POINT => Error::NoCurrentPoint,
            ffi::STATUS_INVALID_MATRIX => Error::InvalidMatrix,
            ffi::STATUS_INVALID_STATUS => Error::InvalidStatus,
            ffi::STATUS_NULL_POINTER => Error::NullPointer,
            ffi::STATUS_INVALID_STRING => Error::InvalidString,
            ffi::STATUS_INVALID_PATH_DATA => Error::InvalidPathData,
            ffi::STATUS_READ_ERROR => Error::ReadError,
            ffi::STATUS_WRITE_ERROR => Error::WriteError,
            ffi::STATUS_SURFACE_FINISHED => Error::SurfaceFinished,
            ffi::STATUS_SURFACE_TYPE_MISMATCH => Error::SurfaceTypeMismatch,
            ffi::STATUS_PATTERN_TYPE_MISMATCH => Error::PatternTypeMismatch,
            ffi::STATUS_INVALID_CONTENT => Error::InvalidContent,
            ffi::STATUS_INVALID_FORMAT => Error::InvalidFormat,
            ffi::STATUS_INVALID_VISUAL => Error::InvalidVisual,
            ffi::STATUS_FILE_NOT_FOUND => Error::FileNotFound,
            ffi::STATUS_INVALID_DASH => Error::InvalidDash,
            ffi::STATUS_INVALID_DSC_COMMENT => Error::InvalidDscComment,
            ffi::STATUS_INVALID_INDEX => Error::InvalidIndex,
            ffi::STATUS_CLIP_NOT_REPRESENTABLE => Error::ClipNotRepresentable,
            ffi::STATUS_TEMP_FILE_ERROR => Error::TempFileError,
            ffi::STATUS_INVALID_STRIDE => Error::InvalidStride,
            ffi::STATUS_FONT_TYPE_MISMATCH => Error::FontTypeMismatch,
            ffi::STATUS_USER_FONT_IMMUTABLE => Error::UserFontImmutable,
            ffi::STATUS_USER_FONT_ERROR => Error::UserFontError,
            ffi::STATUS_NEGATIVE_COUNT => Error::NegativeCount,
            ffi::STATUS_INVALID_CLUSTERS => Error::InvalidClusters,
            ffi::STATUS_INVALID_SLANT => Error::InvalidSlant,
            ffi::STATUS_INVALID_WEIGHT => Error::InvalidWeight,
            ffi::STATUS_INVALID_SIZE => Error::InvalidSize,
            ffi::STATUS_USER_FONT_NOT_IMPLEMENTED => Error::UserFontNotImplemented,
            ffi::STATUS_DEVICE_TYPE_MISMATCH => Error::DeviceTypeMismatch,
            ffi::STATUS_DEVICE_ERROR => Error::DeviceError,
            ffi::STATUS_INVALID_MESH_CONSTRUCTION => Error::InvalidMeshConstruction,
            ffi::STATUS_DEVICE_FINISHED => Error::DeviceFinished,
            ffi::STATUS_J_BIG2_GLOBAL_MISSING => Error::JBig2GlobalMissing,
            ffi::STATUS_PNG_ERROR => Error::PngError,
            ffi::STATUS_FREETYPE_ERROR => Error::FreetypeError,
            ffi::STATUS_WIN32_GDI_ERROR => Error::Win32GdiError,
            ffi::STATUS_LAST_STATUS => Error::LastStatus,
            value => Error::__Unknown(value),
        }
    }
}

#[derive(Error, Debug)]
pub enum IoError {
    #[error("Cairo error: {0}")]
    Cairo(#[from] Error),
    #[error("IO error: {0}")]
    Io(#[from] io::Error),
}

#[derive(Error, Debug)]
pub enum BorrowError {
    #[error("Failed to borrow with Cairo error: {0}")]
    Cairo(#[from] ::Error),
    #[error("Can't get exclusive access")]
    NonExclusive,
}
<|endoftext|>


<commit_before>use backtrace::Backtrace;
use hyper::status::StatusCode;
use rustc_serialize::base64::FromBase64Error;
use rustc_serialize::json::{DecoderError, Json, ParserError, ToJson};
use std::borrow::Cow;
use std::collections::BTreeMap;
use std::convert::From;
use std::error::Error;
use std::fmt;
use std::io::Error as IoError;

#[derive(PartialEq, Debug)]
pub enum ErrorStatus {
    ElementClickIntercepted,
    ElementNotInteractable,
    ElementNotSelectable,
    InsecureCertificate,
    InvalidArgument,
    InvalidCookieDomain,
    InvalidCoordinates,
    InvalidElementState,
    InvalidSelector,
    InvalidSessionId,
    JavascriptError,
    MoveTargetOutOfBounds,
    NoSuchAlert,
    NoSuchCookie,
    NoSuchElement,
    NoSuchFrame,
    NoSuchWindow,
    ScriptTimeout,
    SessionNotCreated,
    StaleElementReference,
    Timeout,
    UnableToCaptureScreen,
    UnableToSetCookie,
    UnexpectedAlertOpen,
    UnknownCommand,
    UnknownError,
    UnknownMethod,
    UnknownPath,
    UnsupportedOperation,
}

impl ErrorStatus {
    pub fn error_code(&self) -> &'static str {
        match *self {
            ErrorStatus::ElementClickIntercepted => "element click intercepted",
            ErrorStatus::ElementNotInteractable => "element not interactable",
            ErrorStatus::ElementNotSelectable => "element not selectable",
            ErrorStatus::InsecureCertificate => "insecure certificate",
            ErrorStatus::InvalidArgument => "invalid argument",
            ErrorStatus::InvalidCookieDomain => "invalid cookie domain",
            ErrorStatus::InvalidCoordinates => "invalid coordinates",
            ErrorStatus::InvalidElementState => "invalid element state",
            ErrorStatus::InvalidSelector => "invalid selector",
            ErrorStatus::InvalidSessionId => "invalid session id",
            ErrorStatus::JavascriptError => "javascript error",
            ErrorStatus::MoveTargetOutOfBounds => "move target out of bounds",
            ErrorStatus::NoSuchAlert => "no such alert",
            ErrorStatus::NoSuchCookie => "no such cookie",
            ErrorStatus::NoSuchElement => "no such element",
            ErrorStatus::NoSuchFrame => "no such frame",
            ErrorStatus::NoSuchWindow => "no such window",
            ErrorStatus::ScriptTimeout => "script timeout",
            ErrorStatus::SessionNotCreated => "session not created",
            ErrorStatus::StaleElementReference => "stale element reference",
            ErrorStatus::Timeout => "timeout",
            ErrorStatus::UnableToCaptureScreen => "unable to capture screen",
            ErrorStatus::UnableToSetCookie => "unable to set cookie",
            ErrorStatus::UnexpectedAlertOpen => "unexpected alert open",
            ErrorStatus::UnknownCommand |
            ErrorStatus::UnknownError => "unknown error",
            ErrorStatus::UnknownMethod => "unknown method",
            ErrorStatus::UnknownPath => "unknown command",
            ErrorStatus::UnsupportedOperation => "unsupported operation",
        }
    }

    pub fn http_status(&self) -> StatusCode {
        match *self {
            ErrorStatus::ElementClickIntercepted => StatusCode::BadRequest,
            ErrorStatus::ElementNotInteractable => StatusCode::BadRequest,
            ErrorStatus::ElementNotSelectable => StatusCode::BadRequest,
            ErrorStatus::InsecureCertificate => StatusCode::BadRequest,
            ErrorStatus::InvalidArgument => StatusCode::BadRequest,
            ErrorStatus::InvalidCookieDomain => StatusCode::BadRequest,
            ErrorStatus::InvalidCoordinates => StatusCode::BadRequest,
            ErrorStatus::InvalidElementState => StatusCode::BadRequest,
            ErrorStatus::InvalidSelector => StatusCode::BadRequest,
            ErrorStatus::InvalidSessionId => StatusCode::NotFound,
            ErrorStatus::JavascriptError => StatusCode::InternalServerError,
            ErrorStatus::MoveTargetOutOfBounds => StatusCode::InternalServerError,
            ErrorStatus::NoSuchAlert => StatusCode::BadRequest,
            ErrorStatus::NoSuchCookie => StatusCode::NotFound,
            ErrorStatus::NoSuchElement => StatusCode::NotFound,
            ErrorStatus::NoSuchFrame => StatusCode::BadRequest,
            ErrorStatus::NoSuchWindow => StatusCode::BadRequest,
            ErrorStatus::ScriptTimeout => StatusCode::RequestTimeout,
            ErrorStatus::SessionNotCreated => StatusCode::InternalServerError,
            ErrorStatus::StaleElementReference => StatusCode::BadRequest,
            ErrorStatus::Timeout => StatusCode::RequestTimeout,
            ErrorStatus::UnableToCaptureScreen => StatusCode::BadRequest,
            ErrorStatus::UnableToSetCookie => StatusCode::InternalServerError,
            ErrorStatus::UnexpectedAlertOpen => StatusCode::InternalServerError,
            ErrorStatus::UnknownCommand => StatusCode::NotFound,
            ErrorStatus::UnknownError => StatusCode::InternalServerError,
            ErrorStatus::UnknownMethod => StatusCode::MethodNotAllowed,
            ErrorStatus::UnknownPath => StatusCode::NotFound,
            ErrorStatus::UnsupportedOperation => StatusCode::InternalServerError,
        }
    }
}

pub type WebDriverResult<T> = Result<T, WebDriverError>;

#[derive(Debug)]
pub struct WebDriverError {
    pub error: ErrorStatus,
    pub message: Cow<'static, str>,
    pub backtrace: Backtrace,
    pub delete_session: bool,
}

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

impl WebDriverError {
    pub fn new<S>(error: ErrorStatus, message: S) -> WebDriverError
        where S: Into<Cow<'static, str>>
    {
        WebDriverError {
            error: error,
            message: message.into(),
            backtrace: Backtrace::new(),
            delete_session: false,
        }
    }

    pub fn error_code(&self) -> &'static str {
        self.error.error_code()
    }

    pub fn http_status(&self) -> StatusCode {
        self.error.http_status()
    }

    pub fn to_json_string(&self) -> String {
        self.to_json().to_string()
    }
}

impl ToJson for WebDriverError {
    fn to_json(&self) -> Json {
        let mut data = BTreeMap::new();
        data.insert("error".into(), self.error_code().to_json());
        data.insert("message".into(), self.message.to_json());
        data.insert("stacktrace".into(),
                    format!("{:?}", self.backtrace).to_json());
        let mut wrapper = BTreeMap::new();
        wrapper.insert("value".into(), Json::Object(data));
        Json::Object(wrapper)
    }
}

impl Error for WebDriverError {
    fn description(&self) -> &str {
        self.error_code()
    }

    fn cause(&self) -> Option<&Error> {
        None
    }
}

impl From<ParserError> for WebDriverError {
    fn from(err: ParserError) -> WebDriverError {
        WebDriverError::new(ErrorStatus::UnknownError, err.description().to_string())
    }
}

impl From<IoError> for WebDriverError {
    fn from(err: IoError) -> WebDriverError {
        WebDriverError::new(ErrorStatus::UnknownError, err.description().to_string())
    }
}

impl From<DecoderError> for WebDriverError {
    fn from(err: DecoderError) -> WebDriverError {
        WebDriverError::new(ErrorStatus::UnknownError, err.description().to_string())
    }
}

impl From<FromBase64Error> for WebDriverError {
    fn from(err: FromBase64Error) -> WebDriverError {
        WebDriverError::new(ErrorStatus::UnknownError, err.description().to_string())
    }
}

impl From<Box<Error>> for WebDriverError {
    fn from(err: Box<Error>) -> WebDriverError {
        WebDriverError::new(ErrorStatus::UnknownError, err.description().to_string())
    }
}
<commit_msg>error: add documentation for ErrorStatus<commit_after>use backtrace::Backtrace;
use hyper::status::StatusCode;
use rustc_serialize::base64::FromBase64Error;
use rustc_serialize::json::{DecoderError, Json, ParserError, ToJson};
use std::borrow::Cow;
use std::collections::BTreeMap;
use std::convert::From;
use std::error::Error;
use std::fmt;
use std::io::Error as IoError;

#[derive(PartialEq, Debug)]
pub enum ErrorStatus {
    /// The [`ElementClick`] command could not be completed because the
    /// [element] receiving the events is obscuring the element that was
    /// requested clicked.
    ///
    /// [`ElementClick`]:
    /// ../command/enum.WebDriverCommand.html#variant.ElementClick
    /// [element]: ../common/struct.WebElement.html
    ElementClickIntercepted,

    /// A [command] could not be completed because the element is not pointer-
    /// or keyboard interactable.
    ///
    /// [command]: ../command/index.html
    ElementNotInteractable,

    /// An attempt was made to select an [element] that cannot be selected.
    ///
    /// [element]: ../common/struct.WebElement.html
    ElementNotSelectable,

    /// Navigation caused the user agent to hit a certificate warning, which is
    /// usually the result of an expired or invalid TLS certificate.
    InsecureCertificate,

    /// The arguments passed to a [command] are either invalid or malformed.
    ///
    /// [command]: ../command/index.html
    InvalidArgument,

    /// An illegal attempt was made to set a cookie under a different domain
    /// than the current page.
    InvalidCookieDomain,

    /// The coordinates provided to an interactions operation are invalid.
    InvalidCoordinates,

    /// A [command] could not be completed because the element is an invalid
    /// state, e.g. attempting to click an element that is no longer attached
    /// to the document.
    ///
    /// [command]: ../command/index.html
    InvalidElementState,

    /// Argument was an invalid selector.
    InvalidSelector,

    /// Occurs if the given session ID is not in the list of active sessions,
    /// meaning the session either does not exist or that it’s not active.
    InvalidSessionId,

    /// An error occurred while executing JavaScript supplied by the user.
    JavascriptError,

    /// The target for mouse interaction is not in the browser’s viewport and
    /// cannot be brought into that viewport.
    MoveTargetOutOfBounds,

    /// An attempt was made to operate on a modal dialogue when one was not
    /// open.
    NoSuchAlert,

    /// No cookie matching the given path name was found amongst the associated
    /// cookies of the current browsing context’s active document.
    NoSuchCookie,

    /// An [element] could not be located on the page using the given search
    /// parameters.
    ///
    /// [element]: ../common/struct.WebElement.html
    NoSuchElement,

    /// A [command] to switch to a frame could not be satisfied because the
    /// frame could not be found.
    ///
    /// [command]: ../command/index.html
    NoSuchFrame,

    /// A [command] to switch to a window could not be satisfied because the
    /// window could not be found.
    ///
    /// [command]: ../command/index.html
    NoSuchWindow,

    /// A script did not complete before its timeout expired.
    ScriptTimeout,

    /// A new session could not be created.
    SessionNotCreated,

    /// A [command] failed because the referenced [element] is no longer
    /// attached to the DOM.
    ///
    /// [command]: ../command/index.html
    /// [element]: ../common/struct.WebElement.html
    StaleElementReference,

    /// An operation did not complete before its timeout expired.
    Timeout,

    /// A screen capture was made impossible.
    UnableToCaptureScreen,

    /// Setting the cookie’s value could not be done.
    UnableToSetCookie,

    /// A modal dialogue was open, blocking this operation.
    UnexpectedAlertOpen,

    /// The requested command could not be executed because it does not exist.
    UnknownCommand,

    /// An unknown error occurred in the remote end whilst processing the
    /// [command].
    ///
    /// [command]: ../command/index.html
    UnknownError,

    /// The requested [command] matched a known endpoint, but did not match a
    /// method for that endpoint.
    ///
    /// [command]: ../command/index.html
    UnknownMethod,

    UnknownPath,

    /// Indicates that a [command] that should have executed properly is not
    /// currently supported.
    UnsupportedOperation,
}

impl ErrorStatus {
    pub fn error_code(&self) -> &'static str {
        match *self {
            ErrorStatus::ElementClickIntercepted => "element click intercepted",
            ErrorStatus::ElementNotInteractable => "element not interactable",
            ErrorStatus::ElementNotSelectable => "element not selectable",
            ErrorStatus::InsecureCertificate => "insecure certificate",
            ErrorStatus::InvalidArgument => "invalid argument",
            ErrorStatus::InvalidCookieDomain => "invalid cookie domain",
            ErrorStatus::InvalidCoordinates => "invalid coordinates",
            ErrorStatus::InvalidElementState => "invalid element state",
            ErrorStatus::InvalidSelector => "invalid selector",
            ErrorStatus::InvalidSessionId => "invalid session id",
            ErrorStatus::JavascriptError => "javascript error",
            ErrorStatus::MoveTargetOutOfBounds => "move target out of bounds",
            ErrorStatus::NoSuchAlert => "no such alert",
            ErrorStatus::NoSuchCookie => "no such cookie",
            ErrorStatus::NoSuchElement => "no such element",
            ErrorStatus::NoSuchFrame => "no such frame",
            ErrorStatus::NoSuchWindow => "no such window",
            ErrorStatus::ScriptTimeout => "script timeout",
            ErrorStatus::SessionNotCreated => "session not created",
            ErrorStatus::StaleElementReference => "stale element reference",
            ErrorStatus::Timeout => "timeout",
            ErrorStatus::UnableToCaptureScreen => "unable to capture screen",
            ErrorStatus::UnableToSetCookie => "unable to set cookie",
            ErrorStatus::UnexpectedAlertOpen => "unexpected alert open",
            ErrorStatus::UnknownCommand |
            ErrorStatus::UnknownError => "unknown error",
            ErrorStatus::UnknownMethod => "unknown method",
            ErrorStatus::UnknownPath => "unknown command",
            ErrorStatus::UnsupportedOperation => "unsupported operation",
        }
    }

    pub fn http_status(&self) -> StatusCode {
        match *self {
            ErrorStatus::ElementClickIntercepted => StatusCode::BadRequest,
            ErrorStatus::ElementNotInteractable => StatusCode::BadRequest,
            ErrorStatus::ElementNotSelectable => StatusCode::BadRequest,
            ErrorStatus::InsecureCertificate => StatusCode::BadRequest,
            ErrorStatus::InvalidArgument => StatusCode::BadRequest,
            ErrorStatus::InvalidCookieDomain => StatusCode::BadRequest,
            ErrorStatus::InvalidCoordinates => StatusCode::BadRequest,
            ErrorStatus::InvalidElementState => StatusCode::BadRequest,
            ErrorStatus::InvalidSelector => StatusCode::BadRequest,
            ErrorStatus::InvalidSessionId => StatusCode::NotFound,
            ErrorStatus::JavascriptError => StatusCode::InternalServerError,
            ErrorStatus::MoveTargetOutOfBounds => StatusCode::InternalServerError,
            ErrorStatus::NoSuchAlert => StatusCode::BadRequest,
            ErrorStatus::NoSuchCookie => StatusCode::NotFound,
            ErrorStatus::NoSuchElement => StatusCode::NotFound,
            ErrorStatus::NoSuchFrame => StatusCode::BadRequest,
            ErrorStatus::NoSuchWindow => StatusCode::BadRequest,
            ErrorStatus::ScriptTimeout => StatusCode::RequestTimeout,
            ErrorStatus::SessionNotCreated => StatusCode::InternalServerError,
            ErrorStatus::StaleElementReference => StatusCode::BadRequest,
            ErrorStatus::Timeout => StatusCode::RequestTimeout,
            ErrorStatus::UnableToCaptureScreen => StatusCode::BadRequest,
            ErrorStatus::UnableToSetCookie => StatusCode::InternalServerError,
            ErrorStatus::UnexpectedAlertOpen => StatusCode::InternalServerError,
            ErrorStatus::UnknownCommand => StatusCode::NotFound,
            ErrorStatus::UnknownError => StatusCode::InternalServerError,
            ErrorStatus::UnknownMethod => StatusCode::MethodNotAllowed,
            ErrorStatus::UnknownPath => StatusCode::NotFound,
            ErrorStatus::UnsupportedOperation => StatusCode::InternalServerError,
        }
    }
}

pub type WebDriverResult<T> = Result<T, WebDriverError>;

#[derive(Debug)]
pub struct WebDriverError {
    pub error: ErrorStatus,
    pub message: Cow<'static, str>,
    pub backtrace: Backtrace,
    pub delete_session: bool,
}

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

impl WebDriverError {
    pub fn new<S>(error: ErrorStatus, message: S) -> WebDriverError
        where S: Into<Cow<'static, str>>
    {
        WebDriverError {
            error: error,
            message: message.into(),
            backtrace: Backtrace::new(),
            delete_session: false,
        }
    }

    pub fn error_code(&self) -> &'static str {
        self.error.error_code()
    }

    pub fn http_status(&self) -> StatusCode {
        self.error.http_status()
    }

    pub fn to_json_string(&self) -> String {
        self.to_json().to_string()
    }
}

impl ToJson for WebDriverError {
    fn to_json(&self) -> Json {
        let mut data = BTreeMap::new();
        data.insert("error".into(), self.error_code().to_json());
        data.insert("message".into(), self.message.to_json());
        data.insert("stacktrace".into(),
                    format!("{:?}", self.backtrace).to_json());
        let mut wrapper = BTreeMap::new();
        wrapper.insert("value".into(), Json::Object(data));
        Json::Object(wrapper)
    }
}

impl Error for WebDriverError {
    fn description(&self) -> &str {
        self.error_code()
    }

    fn cause(&self) -> Option<&Error> {
        None
    }
}

impl From<ParserError> for WebDriverError {
    fn from(err: ParserError) -> WebDriverError {
        WebDriverError::new(ErrorStatus::UnknownError, err.description().to_string())
    }
}

impl From<IoError> for WebDriverError {
    fn from(err: IoError) -> WebDriverError {
        WebDriverError::new(ErrorStatus::UnknownError, err.description().to_string())
    }
}

impl From<DecoderError> for WebDriverError {
    fn from(err: DecoderError) -> WebDriverError {
        WebDriverError::new(ErrorStatus::UnknownError, err.description().to_string())
    }
}

impl From<FromBase64Error> for WebDriverError {
    fn from(err: FromBase64Error) -> WebDriverError {
        WebDriverError::new(ErrorStatus::UnknownError, err.description().to_string())
    }
}

impl From<Box<Error>> for WebDriverError {
    fn from(err: Box<Error>) -> WebDriverError {
        WebDriverError::new(ErrorStatus::UnknownError, err.description().to_string())
    }
}
<|endoftext|>


<commit_before>// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// Issue #7526: lowercase static constants in patterns look like bindings

// This is similar to compile-fail/match-static-const-lc, except it
// shows the expected usual workaround (choosing a different name for
// the static definition) and also demonstrates that one can work
// around this problem locally by renaming the constant in the `use`
// form to an uppercase identifier that placates the lint.

#[deny(non_uppercase_pattern_statics)];

pub static A : int = 97;

fn f() {
    let r = match (0,0) {
        (0, A) => 0,
        (x, y) => 1 + x + y,
    };
    assert!(r == 1);
}

mod m {
    pub static aha : int = 7;
}

fn g() {
    use AHA = m::aha;
    let r = match (0,0) {
        (0, AHA) => 0,
        (x, y)   => 1 + x + y,
    };
    assert!(r == 1);
}

fn h() {
    let r = match (0,0) {
        (0, m::aha) => 0,
        (x, y)      => 1 + x + y,
    };
    assert!(r == 1);
}

fn main () {
    f();
    g();
    h();
}
<commit_msg>Expanded test to clarify that the constants *are* matching when they should.<commit_after>// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// Issue #7526: lowercase static constants in patterns look like bindings

// This is similar to compile-fail/match-static-const-lc, except it
// shows the expected usual workaround (choosing a different name for
// the static definition) and also demonstrates that one can work
// around this problem locally by renaming the constant in the `use`
// form to an uppercase identifier that placates the lint.

#[deny(non_uppercase_pattern_statics)];

pub static A : int = 97;

fn f() {
    let r = match (0,0) {
        (0, A) => 0,
        (x, y) => 1 + x + y,
    };
    assert!(r == 1);
    let r = match (0,97) {
        (0, A) => 0,
        (x, y) => 1 + x + y,
    };
    assert!(r == 0);
}

mod m {
    pub static aha : int = 7;
}

fn g() {
    use AHA = m::aha;
    let r = match (0,0) {
        (0, AHA) => 0,
        (x, y)   => 1 + x + y,
    };
    assert!(r == 1);
    let r = match (0,7) {
        (0, AHA) => 0,
        (x, y)   => 1 + x + y,
    };
    assert!(r == 0);
}

fn h() {
    let r = match (0,0) {
        (0, m::aha) => 0,
        (x, y)      => 1 + x + y,
    };
    assert!(r == 1);
    let r = match (0,7) {
        (0, m::aha) => 0,
        (x, y)      => 1 + x + y,
    };
    assert!(r == 0);
}

fn main () {
    f();
    g();
    h();
}
<|endoftext|>


<commit_before>//! Libinput Events

use crate::{ffi, AsRaw, Context, Device, FromRaw, Libinput};

/// A libinput `Event`
#[derive(Debug, PartialEq, Eq, Hash)]
pub enum Event {
    /// A device related `Event`
    Device(DeviceEvent),
    /// A keyboard related `Event`
    Keyboard(KeyboardEvent),
    /// A pointer related `Event`
    Pointer(PointerEvent),
    /// A touch related `Event`
    Touch(TouchEvent),
    /// A tablet related `Event`
    Tablet(TabletToolEvent),
    /// A tabled pad related `Event`
    TabletPad(TabletPadEvent),
    /// A gesture related `Event`
    Gesture(GestureEvent),
    /// A switch related `Event`
    Switch(SwitchEvent),
}

/// Common functions all (Sub-)Events implement.
pub trait EventTrait: Context {
    #[doc(hidden)]
    fn as_raw_event(&self) -> *mut ffi::libinput_event;

    /// Convert into a general `Event` again
    fn into_event(self) -> Event
    where
        Self: Sized,
    {
        unsafe { Event::from_raw(self.as_raw_event(), self.context()) }
    }

    /// Return the device associated with this event.
    ///
    /// For device added/removed events this is the device added or removed.
    /// For all other device events, this is the device that generated the event.
    fn device(&self) -> Device {
        unsafe {
            Device::from_raw(
                ffi::libinput_event_get_device(self.as_raw_event()),
                self.context(),
            )
        }
    }
}

impl EventTrait for Event {
    fn as_raw_event(&self) -> *mut ffi::libinput_event {
        self.as_raw_mut()
    }
}

impl FromRaw<ffi::libinput_event> for Event {
    unsafe fn from_raw(event: *mut ffi::libinput_event, context: &Libinput) -> Self {
        match ffi::libinput_event_get_type(event) {
            ffi::libinput_event_type_LIBINPUT_EVENT_NONE => panic!("Trying to convert null event"),
            ffi::libinput_event_type_LIBINPUT_EVENT_DEVICE_ADDED
            | ffi::libinput_event_type_LIBINPUT_EVENT_DEVICE_REMOVED => Event::Device(
                DeviceEvent::from_raw(ffi::libinput_event_get_device_notify_event(event), context),
            ),
            ffi::libinput_event_type_LIBINPUT_EVENT_KEYBOARD_KEY => Event::Keyboard(
                KeyboardEvent::from_raw(ffi::libinput_event_get_keyboard_event(event), context),
            ),
            ffi::libinput_event_type_LIBINPUT_EVENT_POINTER_MOTION
            | ffi::libinput_event_type_LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE
            | ffi::libinput_event_type_LIBINPUT_EVENT_POINTER_BUTTON
            | ffi::libinput_event_type_LIBINPUT_EVENT_POINTER_AXIS => Event::Pointer(
                PointerEvent::from_raw(ffi::libinput_event_get_pointer_event(event), context),
            ),
            ffi::libinput_event_type_LIBINPUT_EVENT_TOUCH_DOWN
            | ffi::libinput_event_type_LIBINPUT_EVENT_TOUCH_UP
            | ffi::libinput_event_type_LIBINPUT_EVENT_TOUCH_MOTION
            | ffi::libinput_event_type_LIBINPUT_EVENT_TOUCH_CANCEL
            | ffi::libinput_event_type_LIBINPUT_EVENT_TOUCH_FRAME => Event::Touch(
                TouchEvent::from_raw(ffi::libinput_event_get_touch_event(event), context),
            ),
            ffi::libinput_event_type_LIBINPUT_EVENT_TABLET_TOOL_AXIS
            | ffi::libinput_event_type_LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY
            | ffi::libinput_event_type_LIBINPUT_EVENT_TABLET_TOOL_TIP
            | ffi::libinput_event_type_LIBINPUT_EVENT_TABLET_TOOL_BUTTON => {
                Event::Tablet(TabletToolEvent::from_raw(
                    ffi::libinput_event_get_tablet_tool_event(event),
                    context,
                ))
            }
            ffi::libinput_event_type_LIBINPUT_EVENT_TABLET_PAD_BUTTON
            | ffi::libinput_event_type_LIBINPUT_EVENT_TABLET_PAD_RING
            | ffi::libinput_event_type_LIBINPUT_EVENT_TABLET_PAD_STRIP => Event::TabletPad(
                TabletPadEvent::from_raw(ffi::libinput_event_get_tablet_pad_event(event), context),
            ),
            ffi::libinput_event_type_LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN
            | ffi::libinput_event_type_LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE
            | ffi::libinput_event_type_LIBINPUT_EVENT_GESTURE_SWIPE_END
            | ffi::libinput_event_type_LIBINPUT_EVENT_GESTURE_PINCH_BEGIN
            | ffi::libinput_event_type_LIBINPUT_EVENT_GESTURE_PINCH_UPDATE
            | ffi::libinput_event_type_LIBINPUT_EVENT_GESTURE_PINCH_END => Event::Gesture(
                GestureEvent::from_raw(ffi::libinput_event_get_gesture_event(event), context),
            ),
            ffi::libinput_event_type_LIBINPUT_EVENT_SWITCH_TOGGLE => Event::Switch(
                SwitchEvent::from_raw(ffi::libinput_event_get_switch_event(event), context),
            ),
            _ => panic!("libinput returned invalid 'libinput_event_type'"),
        }
    }
}

impl AsRaw<ffi::libinput_event> for Event {
    fn as_raw(&self) -> *const ffi::libinput_event {
        match self {
            Event::Device(event) => event.as_raw_event() as *const _,
            Event::Keyboard(event) => event.as_raw_event() as *const _,
            Event::Pointer(event) => event.as_raw_event() as *const _,
            Event::Touch(event) => event.as_raw_event() as *const _,
            Event::Tablet(event) => event.as_raw_event() as *const _,
            Event::TabletPad(event) => event.as_raw_event() as *const _,
            Event::Gesture(event) => event.as_raw_event() as *const _,
            Event::Switch(event) => event.as_raw_event() as *const _,
        }
    }
}

impl Context for Event {
    fn context(&self) -> &crate::Libinput {
        match self {
            Event::Device(event) => event.context(),
            Event::Keyboard(event) => event.context(),
            Event::Pointer(event) => event.context(),
            Event::Touch(event) => event.context(),
            Event::Tablet(event) => event.context(),
            Event::TabletPad(event) => event.context(),
            Event::Gesture(event) => event.context(),
            Event::Switch(event) => event.context(),
        }
    }
}

macro_rules! ffi_event_struct {
    ($(#[$attr:meta])* struct $struct_name:ident, $ffi_name:path, $get_base_fn:path) => (
        #[derive(Eq)]
        $(#[$attr])*
        pub struct $struct_name
        {
            ffi: *mut $ffi_name,
            context: $crate::context::Libinput,
        }

        impl std::fmt::Debug for $struct_name {
            fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
                write!(f, "$struct_name @{:p}", self.as_raw())
            }
        }

        impl FromRaw<$ffi_name> for $struct_name
        {
            unsafe fn from_raw(ffi: *mut $ffi_name, context: &$crate::context::Libinput) -> Self {
                $struct_name {
                    ffi,
                    context: context.clone(),
                }
            }
        }

        impl AsRaw<$ffi_name> for $struct_name
        {
            fn as_raw(&self) -> *const $ffi_name {
                self.ffi as *const _
            }
        }

        impl $crate::Context for $struct_name {
            fn context(&self) -> &$crate::context::Libinput {
                &self.context
            }
        }

        impl PartialEq for $struct_name {
            fn eq(&self, other: &Self) -> bool {
                self.as_raw() == other.as_raw()
            }
        }

        impl std::hash::Hash for $struct_name {
            fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
                self.as_raw().hash(state);
            }
        }

        impl EventTrait for $struct_name {
            #[doc(hidden)]
            fn as_raw_event(&self) -> *mut $crate::ffi::libinput_event {
                unsafe { $get_base_fn(self.as_raw_mut()) }
            }
        }

        impl Drop for $struct_name {
            fn drop(&mut self) {
                unsafe { $crate::ffi::libinput_event_destroy(self.as_raw_event()) }
            }
        }
    )
}

pub mod device;
pub mod gesture;
pub mod keyboard;
pub mod pointer;
pub mod switch;
pub mod tablet_pad;
pub mod tablet_tool;
pub mod touch;

pub use self::device::DeviceEvent;
pub use self::gesture::GestureEvent;
pub use self::keyboard::KeyboardEvent;
pub use self::pointer::PointerEvent;
pub use self::switch::SwitchEvent;
pub use self::tablet_pad::TabletPadEvent;
pub use self::tablet_tool::TabletToolEvent;
pub use self::touch::TouchEvent;
<commit_msg>Fix missing handling of TABLET_PAD_KEY event<commit_after>//! Libinput Events

use crate::{ffi, AsRaw, Context, Device, FromRaw, Libinput};

/// A libinput `Event`
#[derive(Debug, PartialEq, Eq, Hash)]
pub enum Event {
    /// A device related `Event`
    Device(DeviceEvent),
    /// A keyboard related `Event`
    Keyboard(KeyboardEvent),
    /// A pointer related `Event`
    Pointer(PointerEvent),
    /// A touch related `Event`
    Touch(TouchEvent),
    /// A tablet related `Event`
    Tablet(TabletToolEvent),
    /// A tabled pad related `Event`
    TabletPad(TabletPadEvent),
    /// A gesture related `Event`
    Gesture(GestureEvent),
    /// A switch related `Event`
    Switch(SwitchEvent),
}

/// Common functions all (Sub-)Events implement.
pub trait EventTrait: Context {
    #[doc(hidden)]
    fn as_raw_event(&self) -> *mut ffi::libinput_event;

    /// Convert into a general `Event` again
    fn into_event(self) -> Event
    where
        Self: Sized,
    {
        unsafe { Event::from_raw(self.as_raw_event(), self.context()) }
    }

    /// Return the device associated with this event.
    ///
    /// For device added/removed events this is the device added or removed.
    /// For all other device events, this is the device that generated the event.
    fn device(&self) -> Device {
        unsafe {
            Device::from_raw(
                ffi::libinput_event_get_device(self.as_raw_event()),
                self.context(),
            )
        }
    }
}

impl EventTrait for Event {
    fn as_raw_event(&self) -> *mut ffi::libinput_event {
        self.as_raw_mut()
    }
}

impl FromRaw<ffi::libinput_event> for Event {
    unsafe fn from_raw(event: *mut ffi::libinput_event, context: &Libinput) -> Self {
        match ffi::libinput_event_get_type(event) {
            ffi::libinput_event_type_LIBINPUT_EVENT_NONE => panic!("Trying to convert null event"),
            ffi::libinput_event_type_LIBINPUT_EVENT_DEVICE_ADDED
            | ffi::libinput_event_type_LIBINPUT_EVENT_DEVICE_REMOVED => Event::Device(
                DeviceEvent::from_raw(ffi::libinput_event_get_device_notify_event(event), context),
            ),
            ffi::libinput_event_type_LIBINPUT_EVENT_KEYBOARD_KEY => Event::Keyboard(
                KeyboardEvent::from_raw(ffi::libinput_event_get_keyboard_event(event), context),
            ),
            ffi::libinput_event_type_LIBINPUT_EVENT_POINTER_MOTION
            | ffi::libinput_event_type_LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE
            | ffi::libinput_event_type_LIBINPUT_EVENT_POINTER_BUTTON
            | ffi::libinput_event_type_LIBINPUT_EVENT_POINTER_AXIS => Event::Pointer(
                PointerEvent::from_raw(ffi::libinput_event_get_pointer_event(event), context),
            ),
            ffi::libinput_event_type_LIBINPUT_EVENT_TOUCH_DOWN
            | ffi::libinput_event_type_LIBINPUT_EVENT_TOUCH_UP
            | ffi::libinput_event_type_LIBINPUT_EVENT_TOUCH_MOTION
            | ffi::libinput_event_type_LIBINPUT_EVENT_TOUCH_CANCEL
            | ffi::libinput_event_type_LIBINPUT_EVENT_TOUCH_FRAME => Event::Touch(
                TouchEvent::from_raw(ffi::libinput_event_get_touch_event(event), context),
            ),
            ffi::libinput_event_type_LIBINPUT_EVENT_TABLET_TOOL_AXIS
            | ffi::libinput_event_type_LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY
            | ffi::libinput_event_type_LIBINPUT_EVENT_TABLET_TOOL_TIP
            | ffi::libinput_event_type_LIBINPUT_EVENT_TABLET_TOOL_BUTTON => {
                Event::Tablet(TabletToolEvent::from_raw(
                    ffi::libinput_event_get_tablet_tool_event(event),
                    context,
                ))
            }
            #[cfg(not(feature = "libinput_1_15"))]
            ffi::libinput_event_type_LIBINPUT_EVENT_TABLET_PAD_BUTTON
            | ffi::libinput_event_type_LIBINPUT_EVENT_TABLET_PAD_RING
            | ffi::libinput_event_type_LIBINPUT_EVENT_TABLET_PAD_STRIP => Event::TabletPad(
                TabletPadEvent::from_raw(ffi::libinput_event_get_tablet_pad_event(event), context),
            ),
            #[cfg(feature = "libinput_1_15")]
            ffi::libinput_event_type_LIBINPUT_EVENT_TABLET_PAD_BUTTON
            | ffi::libinput_event_type_LIBINPUT_EVENT_TABLET_PAD_RING
            | ffi::libinput_event_type_LIBINPUT_EVENT_TABLET_PAD_STRIP
            | ffi::libinput_event_type_LIBINPUT_EVENT_TABLET_PAD_KEY => Event::TabletPad(
                TabletPadEvent::from_raw(ffi::libinput_event_get_tablet_pad_event(event), context),
            ),
            ffi::libinput_event_type_LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN
            | ffi::libinput_event_type_LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE
            | ffi::libinput_event_type_LIBINPUT_EVENT_GESTURE_SWIPE_END
            | ffi::libinput_event_type_LIBINPUT_EVENT_GESTURE_PINCH_BEGIN
            | ffi::libinput_event_type_LIBINPUT_EVENT_GESTURE_PINCH_UPDATE
            | ffi::libinput_event_type_LIBINPUT_EVENT_GESTURE_PINCH_END => Event::Gesture(
                GestureEvent::from_raw(ffi::libinput_event_get_gesture_event(event), context),
            ),
            ffi::libinput_event_type_LIBINPUT_EVENT_SWITCH_TOGGLE => Event::Switch(
                SwitchEvent::from_raw(ffi::libinput_event_get_switch_event(event), context),
            ),
            _ => panic!("libinput returned invalid 'libinput_event_type'"),
        }
    }
}

impl AsRaw<ffi::libinput_event> for Event {
    fn as_raw(&self) -> *const ffi::libinput_event {
        match self {
            Event::Device(event) => event.as_raw_event() as *const _,
            Event::Keyboard(event) => event.as_raw_event() as *const _,
            Event::Pointer(event) => event.as_raw_event() as *const _,
            Event::Touch(event) => event.as_raw_event() as *const _,
            Event::Tablet(event) => event.as_raw_event() as *const _,
            Event::TabletPad(event) => event.as_raw_event() as *const _,
            Event::Gesture(event) => event.as_raw_event() as *const _,
            Event::Switch(event) => event.as_raw_event() as *const _,
        }
    }
}

impl Context for Event {
    fn context(&self) -> &crate::Libinput {
        match self {
            Event::Device(event) => event.context(),
            Event::Keyboard(event) => event.context(),
            Event::Pointer(event) => event.context(),
            Event::Touch(event) => event.context(),
            Event::Tablet(event) => event.context(),
            Event::TabletPad(event) => event.context(),
            Event::Gesture(event) => event.context(),
            Event::Switch(event) => event.context(),
        }
    }
}

macro_rules! ffi_event_struct {
    ($(#[$attr:meta])* struct $struct_name:ident, $ffi_name:path, $get_base_fn:path) => (
        #[derive(Eq)]
        $(#[$attr])*
        pub struct $struct_name
        {
            ffi: *mut $ffi_name,
            context: $crate::context::Libinput,
        }

        impl std::fmt::Debug for $struct_name {
            fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
                write!(f, "$struct_name @{:p}", self.as_raw())
            }
        }

        impl FromRaw<$ffi_name> for $struct_name
        {
            unsafe fn from_raw(ffi: *mut $ffi_name, context: &$crate::context::Libinput) -> Self {
                $struct_name {
                    ffi,
                    context: context.clone(),
                }
            }
        }

        impl AsRaw<$ffi_name> for $struct_name
        {
            fn as_raw(&self) -> *const $ffi_name {
                self.ffi as *const _
            }
        }

        impl $crate::Context for $struct_name {
            fn context(&self) -> &$crate::context::Libinput {
                &self.context
            }
        }

        impl PartialEq for $struct_name {
            fn eq(&self, other: &Self) -> bool {
                self.as_raw() == other.as_raw()
            }
        }

        impl std::hash::Hash for $struct_name {
            fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
                self.as_raw().hash(state);
            }
        }

        impl EventTrait for $struct_name {
            #[doc(hidden)]
            fn as_raw_event(&self) -> *mut $crate::ffi::libinput_event {
                unsafe { $get_base_fn(self.as_raw_mut()) }
            }
        }

        impl Drop for $struct_name {
            fn drop(&mut self) {
                unsafe { $crate::ffi::libinput_event_destroy(self.as_raw_event()) }
            }
        }
    )
}

pub mod device;
pub mod gesture;
pub mod keyboard;
pub mod pointer;
pub mod switch;
pub mod tablet_pad;
pub mod tablet_tool;
pub mod touch;

pub use self::device::DeviceEvent;
pub use self::gesture::GestureEvent;
pub use self::keyboard::KeyboardEvent;
pub use self::pointer::PointerEvent;
pub use self::switch::SwitchEvent;
pub use self::tablet_pad::TabletPadEvent;
pub use self::tablet_tool::TabletToolEvent;
pub use self::touch::TouchEvent;
<|endoftext|>


<commit_before>//! Message boxes APIs

use winapi::shared::windef::HWND;

use std::os::windows::ffi::OsStrExt;
use std::ffi;
use std::ptr;
use std::io;
use std::os::raw::{c_int, c_uint};

use crate::utils;

#[derive(Debug, PartialEq, Eq)]
///Result of user's interaction with message box
pub enum MsgBoxResult {
    ///Abort button is selected
    Abort,
    ///Cancel button is selected
    Cancel,
    ///Continue button is selected
    Continue,
    ///Ignore button is selected
    Ignore,
    ///No button is selected
    No,
    ///Ok button is selected
    Ok,
    ///Retry button is selected
    Retry,
    ///Try Again button is selected
    TryAgain,
    ///Yes button is selected
    Yes,
    ///Unknown result code. Non zero
    Ext(c_int),
}

impl From<c_int> for MsgBoxResult {
    fn from(value: c_int) -> MsgBoxResult {
        match value {
            3 => MsgBoxResult::Abort,
            2 => MsgBoxResult::Cancel,
            11 => MsgBoxResult::Continue,
            5 => MsgBoxResult::Ignore,
            7 => MsgBoxResult::No,
            1 => MsgBoxResult::Ok,
            4 => MsgBoxResult::Retry,
            10 => MsgBoxResult::TryAgain,
            6 => MsgBoxResult::Yes,
            value => MsgBoxResult::Ext(value),
        }
    }
}

///Message box modal dialogue
///
///If title is not specified, then Default is `Error`
///
///The default type is `winapi::um::winuser::MB_OK`
pub struct MessageBox {
    parent: HWND,
    text: Vec<u16>,
    caption: Option<Vec<u16>>,
    flags: c_uint,
}

impl MessageBox {
    ///Creates new instance with provided text message.
    pub fn new<T: AsRef<ffi::OsStr>>(text: T) -> Self {
        let mut text: Vec<u16> = text.as_ref().encode_wide().collect();
        text.push(0);

        Self {
            parent: ptr::null_mut(),
            text,
            caption: None,
            flags: winapi::um::winuser::MB_OK,
        }
    }

    ///Sets parent's window handle.
    pub fn parent(&mut self, parent: HWND) -> &mut Self {
        self.parent = parent;
        self
    }

    ///Sets flags value.
    pub fn set_flags(&mut self, flags: c_uint) -> &mut Self {
        self.flags = flags;
        self
    }

    ///Adds flags to existing ones.
    pub fn flags(&mut self, flags: c_uint) -> &mut Self {
        self.flags |= flags;
        self
    }

    ///Sets caption for message box.
    pub fn title<T: AsRef<ffi::OsStr>>(&mut self, text: T) -> &mut Self {
        let title = text.as_ref();

        self.caption = match self.caption.take() {
            Some(mut caption) => {
                caption.truncate(0);
                for ch in title.encode_wide() {
                    caption.push(ch);
                }
                caption.push(0);
                Some(caption)
            },
            None => {
                let mut title: Vec<u16> = title.encode_wide().collect();
                title.push(0);
                Some(title)
            },
        };

        self
    }

    ///Shows message box and returns once user closes it
    pub fn show(&self) -> io::Result<MsgBoxResult> {
        let caption = self.caption.as_ref().map(|caption| caption.as_ptr()).unwrap_or_else(|| ptr::null());

        match unsafe { winapi::um::winuser::MessageBoxW(self.parent, self.text.as_ptr(), caption, self.flags) } {
            0 => Err(utils::get_last_error()),
            n => Ok(MsgBoxResult::from(n)),
        }
    }
}
<commit_msg>Add shortcuts to create message box<commit_after>//! Message boxes APIs

use winapi::shared::windef::HWND;

use std::os::windows::ffi::OsStrExt;
use std::ffi;
use std::ptr;
use std::io;
use std::os::raw::{c_int, c_uint};

use crate::utils;

#[derive(Debug, PartialEq, Eq)]
///Result of user's interaction with message box
pub enum MsgBoxResult {
    ///Abort button is selected
    Abort,
    ///Cancel button is selected
    Cancel,
    ///Continue button is selected
    Continue,
    ///Ignore button is selected
    Ignore,
    ///No button is selected
    No,
    ///Ok button is selected
    Ok,
    ///Retry button is selected
    Retry,
    ///Try Again button is selected
    TryAgain,
    ///Yes button is selected
    Yes,
    ///Unknown result code. Non zero
    Ext(c_int),
}

impl From<c_int> for MsgBoxResult {
    fn from(value: c_int) -> MsgBoxResult {
        match value {
            3 => MsgBoxResult::Abort,
            2 => MsgBoxResult::Cancel,
            11 => MsgBoxResult::Continue,
            5 => MsgBoxResult::Ignore,
            7 => MsgBoxResult::No,
            1 => MsgBoxResult::Ok,
            4 => MsgBoxResult::Retry,
            10 => MsgBoxResult::TryAgain,
            6 => MsgBoxResult::Yes,
            value => MsgBoxResult::Ext(value),
        }
    }
}

///Message box modal dialogue
///
///If title is not specified, then Default is `Error`
///
///The default type is `winapi::um::winuser::MB_OK`
pub struct MessageBox {
    parent: HWND,
    text: Vec<u16>,
    caption: Option<Vec<u16>>,
    flags: c_uint,
}

impl MessageBox {
    ///Creates new instance with provided text message.
    pub fn new(text: &ffi::OsStr) -> Self {
        let mut text: Vec<u16> = text.encode_wide().collect();
        text.push(0);

        Self {
            parent: ptr::null_mut(),
            text,
            caption: None,
            flags: winapi::um::winuser::MB_OK,
        }
    }

    #[inline]
    ///Creates informational message box with Ok button
    pub fn info<T: AsRef<ffi::OsStr>>(text: T) -> Self {
        let mut res = Self::new(text.as_ref());
        res.flags |= winapi::um::winuser::MB_ICONINFORMATION;
        res
    }

    #[inline]
    ///Creates error message box with Ok button
    pub fn error<T: AsRef<ffi::OsStr>>(text: T) -> Self {
        let mut res = Self::new(text.as_ref());
        res.flags |= winapi::um::winuser::MB_ICONERROR;
        res
    }

    ///Sets parent's window handle.
    pub fn parent(&mut self, parent: HWND) -> &mut Self {
        self.parent = parent;
        self
    }

    ///Sets flags value.
    pub fn set_flags(&mut self, flags: c_uint) -> &mut Self {
        self.flags = flags;
        self
    }

    ///Adds flags to existing ones.
    pub fn flags(&mut self, flags: c_uint) -> &mut Self {
        self.flags |= flags;
        self
    }

    ///Sets caption for message box.
    pub fn title<T: AsRef<ffi::OsStr>>(&mut self, text: T) -> &mut Self {
        let title = text.as_ref();

        self.caption = match self.caption.take() {
            Some(mut caption) => {
                caption.truncate(0);
                for ch in title.encode_wide() {
                    caption.push(ch);
                }
                caption.push(0);
                Some(caption)
            },
            None => {
                let mut title: Vec<u16> = title.encode_wide().collect();
                title.push(0);
                Some(title)
            },
        };

        self
    }

    ///Shows message box and returns once user closes it
    pub fn show(&self) -> io::Result<MsgBoxResult> {
        let caption = self.caption.as_ref().map(|caption| caption.as_ptr()).unwrap_or_else(|| ptr::null());

        match unsafe { winapi::um::winuser::MessageBoxW(self.parent, self.text.as_ptr(), caption, self.flags) } {
            0 => Err(utils::get_last_error()),
            n => Ok(MsgBoxResult::from(n)),
        }
    }
}
<|endoftext|>


<commit_before>use crate::cxx_vector::{CxxVector, VectorElement};
use crate::fmt::display;
use crate::kind::Trivial;
use crate::string::CxxString;
use crate::ExternType;
use core::ffi::c_void;
use core::fmt::{self, Debug, Display};
use core::marker::PhantomData;
use core::mem::{self, MaybeUninit};
use core::ops::{Deref, DerefMut};
use core::pin::Pin;

/// Binding to C++ `std::unique_ptr<T, std::default_delete<T>>`.
#[repr(C)]
pub struct UniquePtr<T>
where
    T: UniquePtrTarget,
{
    repr: MaybeUninit<*mut c_void>,
    ty: PhantomData<T>,
}

impl<T> UniquePtr<T>
where
    T: UniquePtrTarget,
{
    /// Makes a new UniquePtr wrapping a null pointer.
    ///
    /// Matches the behavior of default-constructing a std::unique\_ptr.
    pub fn null() -> Self {
        UniquePtr {
            repr: T::__null(),
            ty: PhantomData,
        }
    }

    /// Allocates memory on the heap and makes a UniquePtr pointing to it.
    pub fn new(value: T) -> Self
    where
        T: ExternType<Kind = Trivial>,
    {
        UniquePtr {
            repr: T::__new(value),
            ty: PhantomData,
        }
    }

    /// Checks whether the UniquePtr does not own an object.
    ///
    /// This is the opposite of [std::unique_ptr\<T\>::operator bool](https://en.cppreference.com/w/cpp/memory/unique_ptr/operator_bool).
    pub fn is_null(&self) -> bool {
        let ptr = unsafe { T::__get(self.repr) };
        ptr.is_null()
    }

    /// Returns a reference to the object owned by this UniquePtr if any,
    /// otherwise None.
    pub fn as_ref(&self) -> Option<&T> {
        unsafe { T::__get(self.repr).as_ref() }
    }

    /// Returns a mutable pinned reference to the object owned by this UniquePtr
    /// if any, otherwise None.
    pub fn as_mut(&mut self) -> Option<Pin<&mut T>> {
        unsafe {
            let mut_reference = (T::__get(self.repr) as *mut T).as_mut()?;
            Some(Pin::new_unchecked(mut_reference))
        }
    }

    /// Returns a mutable pinned reference to the object owned by this
    /// UniquePtr.
    ///
    /// # Panics
    ///
    /// Panics if the UniquePtr holds a null pointer.
    pub fn pin_mut(&mut self) -> Pin<&mut T> {
        match self.as_mut() {
            Some(target) => target,
            None => panic!(
                "called pin_mut on a null UniquePtr<{}>",
                display(T::__typename),
            ),
        }
    }

    /// Consumes the UniquePtr, releasing its ownership of the heap-allocated T.
    ///
    /// Matches the behavior of [std::unique_ptr\<T\>::release](https://en.cppreference.com/w/cpp/memory/unique_ptr/release).
    pub fn into_raw(self) -> *mut T {
        let ptr = unsafe { T::__release(self.repr) };
        mem::forget(self);
        ptr
    }

    /// Constructs a UniquePtr retaking ownership of a pointer previously
    /// obtained from `into_raw`.
    ///
    /// # Safety
    ///
    /// This function is unsafe because improper use may lead to memory
    /// problems. For example a double-free may occur if the function is called
    /// twice on the same raw pointer.
    pub unsafe fn from_raw(raw: *mut T) -> Self {
        UniquePtr {
            repr: unsafe { T::__raw(raw) },
            ty: PhantomData,
        }
    }
}

unsafe impl<T> Send for UniquePtr<T> where T: Send + UniquePtrTarget {}
unsafe impl<T> Sync for UniquePtr<T> where T: Sync + UniquePtrTarget {}

impl<T> Drop for UniquePtr<T>
where
    T: UniquePtrTarget,
{
    fn drop(&mut self) {
        unsafe { T::__drop(self.repr) }
    }
}

impl<T> Deref for UniquePtr<T>
where
    T: UniquePtrTarget,
{
    type Target = T;

    fn deref(&self) -> &Self::Target {
        match self.as_ref() {
            Some(target) => target,
            None => panic!(
                "called deref on a null UniquePtr<{}>",
                display(T::__typename),
            ),
        }
    }
}

impl<T> DerefMut for UniquePtr<T>
where
    T: UniquePtrTarget + Unpin,
{
    fn deref_mut(&mut self) -> &mut Self::Target {
        match self.as_mut() {
            Some(target) => Pin::into_inner(target),
            None => panic!(
                "called deref_mut on a null UniquePtr<{}>",
                display(T::__typename),
            ),
        }
    }
}

impl<T> Debug for UniquePtr<T>
where
    T: Debug + UniquePtrTarget,
{
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        match self.as_ref() {
            None => formatter.write_str("nullptr"),
            Some(value) => Debug::fmt(value, formatter),
        }
    }
}

impl<T> Display for UniquePtr<T>
where
    T: Display + UniquePtrTarget,
{
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        match self.as_ref() {
            None => formatter.write_str("nullptr"),
            Some(value) => Display::fmt(value, formatter),
        }
    }
}

/// Trait bound for types which may be used as the `T` inside of a
/// `UniquePtr<T>` in generic code.
///
/// This trait has no publicly callable or implementable methods. Implementing
/// it outside of the CXX codebase is not supported.
///
/// # Example
///
/// A bound `T: UniquePtrTarget` may be necessary when manipulating
/// [`UniquePtr`] in generic code.
///
/// ```
/// use cxx::memory::{UniquePtr, UniquePtrTarget};
/// use std::fmt::Display;
///
/// pub fn take_generic_ptr<T>(ptr: UniquePtr<T>)
/// where
///     T: UniquePtrTarget + Display,
/// {
///     println!("the unique_ptr points to: {}", *ptr);
/// }
/// ```
///
/// Writing the same generic function without a `UniquePtrTarget` trait bound
/// would not compile.
pub unsafe trait UniquePtrTarget {
    #[doc(hidden)]
    fn __typename(f: &mut fmt::Formatter) -> fmt::Result;
    #[doc(hidden)]
    fn __null() -> MaybeUninit<*mut c_void>;
    #[doc(hidden)]
    fn __new(value: Self) -> MaybeUninit<*mut c_void>
    where
        Self: Sized,
    {
        // Opaque C types do not get this method because they can never exist by
        // value on the Rust side of the bridge.
        let _ = value;
        unreachable!()
    }
    #[doc(hidden)]
    unsafe fn __raw(raw: *mut Self) -> MaybeUninit<*mut c_void>;
    #[doc(hidden)]
    unsafe fn __get(repr: MaybeUninit<*mut c_void>) -> *const Self;
    #[doc(hidden)]
    unsafe fn __release(repr: MaybeUninit<*mut c_void>) -> *mut Self;
    #[doc(hidden)]
    unsafe fn __drop(repr: MaybeUninit<*mut c_void>);
}

extern "C" {
    #[link_name = "cxxbridge1$unique_ptr$std$string$null"]
    fn unique_ptr_std_string_null(this: *mut MaybeUninit<*mut c_void>);
    #[link_name = "cxxbridge1$unique_ptr$std$string$raw"]
    fn unique_ptr_std_string_raw(this: *mut MaybeUninit<*mut c_void>, raw: *mut CxxString);
    #[link_name = "cxxbridge1$unique_ptr$std$string$get"]
    fn unique_ptr_std_string_get(this: *const MaybeUninit<*mut c_void>) -> *const CxxString;
    #[link_name = "cxxbridge1$unique_ptr$std$string$release"]
    fn unique_ptr_std_string_release(this: *mut MaybeUninit<*mut c_void>) -> *mut CxxString;
    #[link_name = "cxxbridge1$unique_ptr$std$string$drop"]
    fn unique_ptr_std_string_drop(this: *mut MaybeUninit<*mut c_void>);
}

unsafe impl UniquePtrTarget for CxxString {
    fn __typename(f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str("CxxString")
    }
    fn __null() -> MaybeUninit<*mut c_void> {
        let mut repr = MaybeUninit::uninit();
        unsafe {
            unique_ptr_std_string_null(&mut repr);
        }
        repr
    }
    unsafe fn __raw(raw: *mut Self) -> MaybeUninit<*mut c_void> {
        let mut repr = MaybeUninit::uninit();
        unsafe { unique_ptr_std_string_raw(&mut repr, raw) }
        repr
    }
    unsafe fn __get(repr: MaybeUninit<*mut c_void>) -> *const Self {
        unsafe { unique_ptr_std_string_get(&repr) }
    }
    unsafe fn __release(mut repr: MaybeUninit<*mut c_void>) -> *mut Self {
        unsafe { unique_ptr_std_string_release(&mut repr) }
    }
    unsafe fn __drop(mut repr: MaybeUninit<*mut c_void>) {
        unsafe { unique_ptr_std_string_drop(&mut repr) }
    }
}

unsafe impl<T> UniquePtrTarget for CxxVector<T>
where
    T: VectorElement,
{
    fn __typename(f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "CxxVector<{}>", display(T::__typename))
    }
    fn __null() -> MaybeUninit<*mut c_void> {
        T::__unique_ptr_null()
    }
    unsafe fn __raw(raw: *mut Self) -> MaybeUninit<*mut c_void> {
        unsafe { T::__unique_ptr_raw(raw) }
    }
    unsafe fn __get(repr: MaybeUninit<*mut c_void>) -> *const Self {
        unsafe { T::__unique_ptr_get(repr) }
    }
    unsafe fn __release(repr: MaybeUninit<*mut c_void>) -> *mut Self {
        unsafe { T::__unique_ptr_release(repr) }
    }
    unsafe fn __drop(repr: MaybeUninit<*mut c_void>) {
        unsafe { T::__unique_ptr_drop(repr) }
    }
}
<commit_msg>Add Unpin impl for UniquePtr.<commit_after>use crate::cxx_vector::{CxxVector, VectorElement};
use crate::fmt::display;
use crate::kind::Trivial;
use crate::string::CxxString;
use crate::ExternType;
use core::ffi::c_void;
use core::fmt::{self, Debug, Display};
use core::marker::PhantomData;
use core::mem::{self, MaybeUninit};
use core::ops::{Deref, DerefMut};
use core::pin::Pin;

/// Binding to C++ `std::unique_ptr<T, std::default_delete<T>>`.
#[repr(C)]
pub struct UniquePtr<T>
where
    T: UniquePtrTarget,
{
    repr: MaybeUninit<*mut c_void>,
    ty: PhantomData<T>,
}

impl<T> UniquePtr<T>
where
    T: UniquePtrTarget,
{
    /// Makes a new UniquePtr wrapping a null pointer.
    ///
    /// Matches the behavior of default-constructing a std::unique\_ptr.
    pub fn null() -> Self {
        UniquePtr {
            repr: T::__null(),
            ty: PhantomData,
        }
    }

    /// Allocates memory on the heap and makes a UniquePtr pointing to it.
    pub fn new(value: T) -> Self
    where
        T: ExternType<Kind = Trivial>,
    {
        UniquePtr {
            repr: T::__new(value),
            ty: PhantomData,
        }
    }

    /// Checks whether the UniquePtr does not own an object.
    ///
    /// This is the opposite of [std::unique_ptr\<T\>::operator bool](https://en.cppreference.com/w/cpp/memory/unique_ptr/operator_bool).
    pub fn is_null(&self) -> bool {
        let ptr = unsafe { T::__get(self.repr) };
        ptr.is_null()
    }

    /// Returns a reference to the object owned by this UniquePtr if any,
    /// otherwise None.
    pub fn as_ref(&self) -> Option<&T> {
        unsafe { T::__get(self.repr).as_ref() }
    }

    /// Returns a mutable pinned reference to the object owned by this UniquePtr
    /// if any, otherwise None.
    pub fn as_mut(&mut self) -> Option<Pin<&mut T>> {
        unsafe {
            let mut_reference = (T::__get(self.repr) as *mut T).as_mut()?;
            Some(Pin::new_unchecked(mut_reference))
        }
    }

    /// Returns a mutable pinned reference to the object owned by this
    /// UniquePtr.
    ///
    /// # Panics
    ///
    /// Panics if the UniquePtr holds a null pointer.
    pub fn pin_mut(&mut self) -> Pin<&mut T> {
        match self.as_mut() {
            Some(target) => target,
            None => panic!(
                "called pin_mut on a null UniquePtr<{}>",
                display(T::__typename),
            ),
        }
    }

    /// Consumes the UniquePtr, releasing its ownership of the heap-allocated T.
    ///
    /// Matches the behavior of [std::unique_ptr\<T\>::release](https://en.cppreference.com/w/cpp/memory/unique_ptr/release).
    pub fn into_raw(self) -> *mut T {
        let ptr = unsafe { T::__release(self.repr) };
        mem::forget(self);
        ptr
    }

    /// Constructs a UniquePtr retaking ownership of a pointer previously
    /// obtained from `into_raw`.
    ///
    /// # Safety
    ///
    /// This function is unsafe because improper use may lead to memory
    /// problems. For example a double-free may occur if the function is called
    /// twice on the same raw pointer.
    pub unsafe fn from_raw(raw: *mut T) -> Self {
        UniquePtr {
            repr: unsafe { T::__raw(raw) },
            ty: PhantomData,
        }
    }
}

unsafe impl<T> Send for UniquePtr<T> where T: Send + UniquePtrTarget {}
unsafe impl<T> Sync for UniquePtr<T> where T: Sync + UniquePtrTarget {}

impl<T> Drop for UniquePtr<T>
where
    T: UniquePtrTarget,
{
    fn drop(&mut self) {
        unsafe { T::__drop(self.repr) }
    }
}

impl<T> Deref for UniquePtr<T>
where
    T: UniquePtrTarget,
{
    type Target = T;

    fn deref(&self) -> &Self::Target {
        match self.as_ref() {
            Some(target) => target,
            None => panic!(
                "called deref on a null UniquePtr<{}>",
                display(T::__typename),
            ),
        }
    }
}

impl<T> DerefMut for UniquePtr<T>
where
    T: UniquePtrTarget + Unpin,
{
    fn deref_mut(&mut self) -> &mut Self::Target {
        match self.as_mut() {
            Some(target) => Pin::into_inner(target),
            None => panic!(
                "called deref_mut on a null UniquePtr<{}>",
                display(T::__typename),
            ),
        }
    }
}

impl<T> Debug for UniquePtr<T>
where
    T: Debug + UniquePtrTarget,
{
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        match self.as_ref() {
            None => formatter.write_str("nullptr"),
            Some(value) => Debug::fmt(value, formatter),
        }
    }
}

impl<T> Display for UniquePtr<T>
where
    T: Display + UniquePtrTarget,
{
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        match self.as_ref() {
            None => formatter.write_str("nullptr"),
            Some(value) => Display::fmt(value, formatter),
        }
    }
}

/// UniquePtr is not a self-referential type and can be moved around freely.
/// Therefore it can be Unpin, even if its target is not Unpin.
impl<T> Unpin for UniquePtr<T> where T: UniquePtrTarget {}

/// Trait bound for types which may be used as the `T` inside of a
/// `UniquePtr<T>` in generic code.
///
/// This trait has no publicly callable or implementable methods. Implementing
/// it outside of the CXX codebase is not supported.
///
/// # Example
///
/// A bound `T: UniquePtrTarget` may be necessary when manipulating
/// [`UniquePtr`] in generic code.
///
/// ```
/// use cxx::memory::{UniquePtr, UniquePtrTarget};
/// use std::fmt::Display;
///
/// pub fn take_generic_ptr<T>(ptr: UniquePtr<T>)
/// where
///     T: UniquePtrTarget + Display,
/// {
///     println!("the unique_ptr points to: {}", *ptr);
/// }
/// ```
///
/// Writing the same generic function without a `UniquePtrTarget` trait bound
/// would not compile.
pub unsafe trait UniquePtrTarget {
    #[doc(hidden)]
    fn __typename(f: &mut fmt::Formatter) -> fmt::Result;
    #[doc(hidden)]
    fn __null() -> MaybeUninit<*mut c_void>;
    #[doc(hidden)]
    fn __new(value: Self) -> MaybeUninit<*mut c_void>
    where
        Self: Sized,
    {
        // Opaque C types do not get this method because they can never exist by
        // value on the Rust side of the bridge.
        let _ = value;
        unreachable!()
    }
    #[doc(hidden)]
    unsafe fn __raw(raw: *mut Self) -> MaybeUninit<*mut c_void>;
    #[doc(hidden)]
    unsafe fn __get(repr: MaybeUninit<*mut c_void>) -> *const Self;
    #[doc(hidden)]
    unsafe fn __release(repr: MaybeUninit<*mut c_void>) -> *mut Self;
    #[doc(hidden)]
    unsafe fn __drop(repr: MaybeUninit<*mut c_void>);
}

extern "C" {
    #[link_name = "cxxbridge1$unique_ptr$std$string$null"]
    fn unique_ptr_std_string_null(this: *mut MaybeUninit<*mut c_void>);
    #[link_name = "cxxbridge1$unique_ptr$std$string$raw"]
    fn unique_ptr_std_string_raw(this: *mut MaybeUninit<*mut c_void>, raw: *mut CxxString);
    #[link_name = "cxxbridge1$unique_ptr$std$string$get"]
    fn unique_ptr_std_string_get(this: *const MaybeUninit<*mut c_void>) -> *const CxxString;
    #[link_name = "cxxbridge1$unique_ptr$std$string$release"]
    fn unique_ptr_std_string_release(this: *mut MaybeUninit<*mut c_void>) -> *mut CxxString;
    #[link_name = "cxxbridge1$unique_ptr$std$string$drop"]
    fn unique_ptr_std_string_drop(this: *mut MaybeUninit<*mut c_void>);
}

unsafe impl UniquePtrTarget for CxxString {
    fn __typename(f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str("CxxString")
    }
    fn __null() -> MaybeUninit<*mut c_void> {
        let mut repr = MaybeUninit::uninit();
        unsafe {
            unique_ptr_std_string_null(&mut repr);
        }
        repr
    }
    unsafe fn __raw(raw: *mut Self) -> MaybeUninit<*mut c_void> {
        let mut repr = MaybeUninit::uninit();
        unsafe { unique_ptr_std_string_raw(&mut repr, raw) }
        repr
    }
    unsafe fn __get(repr: MaybeUninit<*mut c_void>) -> *const Self {
        unsafe { unique_ptr_std_string_get(&repr) }
    }
    unsafe fn __release(mut repr: MaybeUninit<*mut c_void>) -> *mut Self {
        unsafe { unique_ptr_std_string_release(&mut repr) }
    }
    unsafe fn __drop(mut repr: MaybeUninit<*mut c_void>) {
        unsafe { unique_ptr_std_string_drop(&mut repr) }
    }
}

unsafe impl<T> UniquePtrTarget for CxxVector<T>
where
    T: VectorElement,
{
    fn __typename(f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "CxxVector<{}>", display(T::__typename))
    }
    fn __null() -> MaybeUninit<*mut c_void> {
        T::__unique_ptr_null()
    }
    unsafe fn __raw(raw: *mut Self) -> MaybeUninit<*mut c_void> {
        unsafe { T::__unique_ptr_raw(raw) }
    }
    unsafe fn __get(repr: MaybeUninit<*mut c_void>) -> *const Self {
        unsafe { T::__unique_ptr_get(repr) }
    }
    unsafe fn __release(repr: MaybeUninit<*mut c_void>) -> *mut Self {
        unsafe { T::__unique_ptr_release(repr) }
    }
    unsafe fn __drop(repr: MaybeUninit<*mut c_void>) {
        unsafe { T::__unique_ptr_drop(repr) }
    }
}
<|endoftext|>