chromium/mojo/public/rust/system/mojo_types.rs

// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

//! This module contains a variety of types which are used
//! for representing representing flag arguments a little bit
//! better than just as u32 and some other basic Mojo types that
//! we need to expose.
//!
//! This module also provides MojoResult which is the canonical
//! result coding system used by Mojo.
//!
//! Many places in the system code directly import this module as
//! a whole because it is intended to be used that way. It contains
//! all of the basic types needed by all system-level Mojo bindings.

use crate::ffi::types::{self, *};
use std::fmt;
use std::u64;

pub use types::MojoHandle;
pub use types::MojoMessageHandle;
pub use types::MojoTimeTicks;

/// Represents a deadline for wait() calls.
pub type MojoDeadline = u64;
pub static MOJO_INDEFINITE: MojoDeadline = u64::MAX;

pub use crate::wait_set::WaitSetResult;

/// MojoResult represents anything that can happen
/// as a result of performing some operation in Mojo.
///
/// It's implementation matches exactly that found in
/// the Mojo C API so this enum can be used across the
/// FFI boundary simply by using "as u32".
#[derive(Copy, Clone, Debug, PartialEq)]
#[repr(u32)]
pub enum MojoResult {
    Okay = 0,
    Cancelled = 1,
    Unknown = 2,
    InvalidArgument = 3,
    DeadlineExceeded = 4,
    NotFound = 5,
    AlreadyExists = 6,
    PermissionDenied = 7,
    ResourceExhausted = 8,
    FailedPrecondition = 9,
    Aborted = 10,
    OutOfRange = 11,
    Unimplemented = 12,
    Internal = 13,
    Unavailable = 14,
    DataLoss = 15,
    Busy = 16,
    ShouldWait = 17,
    InvalidResult,
}

impl MojoResult {
    /// Convert a raw u32 code given by the C Mojo functions
    /// into a MojoResult.
    pub fn from_code(code: MojoResultCode) -> MojoResult {
        match code as u32 {
            0 => MojoResult::Okay,
            1 => MojoResult::Cancelled,
            2 => MojoResult::Unknown,
            3 => MojoResult::InvalidArgument,
            4 => MojoResult::DeadlineExceeded,
            5 => MojoResult::NotFound,
            6 => MojoResult::AlreadyExists,
            7 => MojoResult::PermissionDenied,
            8 => MojoResult::ResourceExhausted,
            9 => MojoResult::FailedPrecondition,
            10 => MojoResult::Aborted,
            11 => MojoResult::OutOfRange,
            12 => MojoResult::Unimplemented,
            13 => MojoResult::Internal,
            14 => MojoResult::Unavailable,
            15 => MojoResult::DataLoss,
            16 => MojoResult::Busy,
            17 => MojoResult::ShouldWait,
            _ => MojoResult::InvalidResult,
        }
    }

    pub fn to_str(&self) -> &'static str {
        match *self {
            MojoResult::Okay => "OK",
            MojoResult::Cancelled => "Cancelled",
            MojoResult::Unknown => "Unknown",
            MojoResult::InvalidArgument => "Invalid Argument",
            MojoResult::DeadlineExceeded => "Deadline Exceeded",
            MojoResult::NotFound => "Not Found",
            MojoResult::AlreadyExists => "Already Exists",
            MojoResult::PermissionDenied => "Permission Denied",
            MojoResult::ResourceExhausted => "Resource Exhausted",
            MojoResult::FailedPrecondition => "Failed Precondition",
            MojoResult::Aborted => "Aborted",
            MojoResult::OutOfRange => "Out Of Range",
            MojoResult::Unimplemented => "Unimplemented",
            MojoResult::Internal => "Internal",
            MojoResult::Unavailable => "Unavailable",
            MojoResult::DataLoss => "Data Loss",
            MojoResult::Busy => "Busy",
            MojoResult::ShouldWait => "Should Wait",
            MojoResult::InvalidResult => "Something went very wrong",
        }
    }

    /// For convenience in code using `Result<_, _>`, maps Okay to Ok(()) and
    /// other results to Err(self).
    pub fn into_result(self) -> Result<(), MojoResult> {
        match self {
            MojoResult::Okay => Ok(()),
            e => Err(e),
        }
    }
}

impl fmt::Display for MojoResult {
    /// Allow a MojoResult to be displayed in a sane manner.
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.to_str())
    }
}

bitflags::bitflags! {
    #[derive(Clone, Copy, Default)]
    #[repr(transparent)]
    pub struct HandleSignals: MojoHandleSignals {
        const READABLE = 1 << 0;
        const WRITABLE = 1 << 1;
        const PEER_CLOSED = 1 <<2;
        const NEW_DATA_READABLE = 1 <<3;
        const PEER_REMOTE = 1 << 4;
        const QUOTA_EXCEEDED = 1 << 5;
    }
}

impl HandleSignals {
    /// Check if the readable flag is set.
    pub fn is_readable(&self) -> bool {
        self.contains(HandleSignals::READABLE)
    }

    /// Check if the writable flag is set.
    pub fn is_writable(&self) -> bool {
        self.contains(HandleSignals::WRITABLE)
    }

    /// Check if the peer-closed flag is set.
    pub fn is_peer_closed(&self) -> bool {
        self.contains(HandleSignals::PEER_CLOSED)
    }
}

/// Represents the signals state of a handle: which signals are satisfied,
/// and which are satisfiable.
#[repr(transparent)]
#[derive(Clone, Copy, Debug)]
pub struct SignalsState(pub MojoHandleSignalsState);

impl SignalsState {
    /// Generates a new SignalsState
    pub fn new(satisfied: HandleSignals, satisfiable: HandleSignals) -> SignalsState {
        SignalsState(MojoHandleSignalsState {
            satisfied_signals: satisfied.bits(),
            satisfiable_signals: satisfiable.bits(),
        })
    }
    /// Gets a reference to the satisfied signals
    pub fn satisfied(&self) -> HandleSignals {
        HandleSignals::from_bits_truncate(self.0.satisfied_signals)
    }
    /// Gets a reference to the satisfiable signals
    pub fn satisfiable(&self) -> HandleSignals {
        HandleSignals::from_bits_truncate(self.0.satisfiable_signals)
    }

    /// Return the wrapped Mojo FFI struct.
    pub fn to_raw(self) -> MojoHandleSignalsState {
        self.0
    }

    /// Get a pointer to the inner struct for FFI calls.
    pub fn as_raw_mut_ptr(&mut self) -> *mut MojoHandleSignalsState {
        &mut self.0 as *mut _
    }
}

impl std::default::Default for SignalsState {
    fn default() -> Self {
        SignalsState(MojoHandleSignalsState { satisfied_signals: 0, satisfiable_signals: 0 })
    }
}