<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#![deny(unsafe_code)]

#![crate_name = "servo_url"]
#![crate_type = "rlib"]

#![cfg_attr(feature = "servo", feature(plugin))]

#[cfg(feature = "servo")] extern crate serde;
#[cfg(feature = "servo")] #[macro_use] extern crate serde_derive;
#[cfg(feature = "servo")] extern crate heapsize;
#[cfg(feature = "servo")] #[macro_use] extern crate heapsize_derive;

extern crate url;

use std::fmt;
use std::net::IpAddr;
use std::ops::{Range, RangeFrom, RangeTo, RangeFull, Index};
use std::path::Path;
use std::sync::Arc;
use url::{Url, Origin, Position};

#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf, Serialize, Deserialize))]
pub struct ServoUrl(Arc<Url>);

impl ServoUrl {
    pub fn from_url(url: Url) -> Self {
        ServoUrl(Arc::new(url))
    }

    pub fn parse_with_base(base: Option<&Self>, input: &str) -> Result<Self, url::ParseError> {
        Url::options().base_url(base.map(|b| &*b.0)).parse(input).map(Self::from_url)
    }

    pub fn into_string(self) -> String {
        Arc::try_unwrap(self.0).unwrap_or_else(|s| (*s).clone()).into_string()
    }

    // NOTE: These methods return options that are always true temporarily until
    // we special-case some urls to avoid going through rust-url.
    pub fn into_url(self) -> Option<Url> {
        Some(Arc::try_unwrap(self.0).unwrap_or_else(|s| (*s).clone()))
    }

    pub fn as_url(&self) -> Option<&Arc<Url>> {
        Some(&self.0)
    }

    pub fn parse(input: &str) -> Result<Self, url::ParseError> {
        Url::parse(input).map(Self::from_url)
    }

    pub fn cannot_be_a_base(&self) -> bool {
        self.0.cannot_be_a_base()
    }

    pub fn domain(&self) -> Option<&str> {
        self.0.domain()
    }

    pub fn fragment(&self) -> Option<&str> {
        self.0.fragment()
    }

    pub fn path(&self) -> &str {
        self.0.path()
    }

    pub fn origin(&self) -> Origin {
        self.0.origin()
    }

    pub fn scheme(&self) -> &str {
        self.0.scheme()
    }

    pub fn is_secure_scheme(&self) -> bool {
        let scheme = self.scheme();
        scheme == "https" || scheme == "wss"
    }

    pub fn as_str(&self) -> &str {
        self.0.as_str()
    }

    pub fn as_mut_url(&mut self) -> Option<&mut Url> {
        Some(Arc::make_mut(&mut self.0))
    }

    pub fn set_username(&mut self, user: &str) -> Result<(), ()> {
        Arc::make_mut(&mut self.0).set_username(user)
    }

    pub fn set_ip_host(&mut self, addr: IpAddr) -> Result<(), ()> {
        Arc::make_mut(&mut self.0).set_ip_host(addr)
    }

    pub fn set_password(&mut self, pass: Option<&str>) -> Result<(), ()> {
        Arc::make_mut(&mut self.0).set_password(pass)
    }

    pub fn set_fragment(&mut self, fragment: Option<&str>) {
        Arc::make_mut(&mut self.0).set_fragment(fragment)
    }

    pub fn username(&self) -> &str {
        self.0.username()
    }

    pub fn password(&self) -> Option<&str> {
        self.0.password()
    }

    pub fn to_file_path(&self) -> Result<::std::path::PathBuf, ()> {
        self.0.to_file_path()
    }

    pub fn host(&self) -> Option<url::Host<&str>> {
        self.0.host()
    }

    pub fn host_str(&self) -> Option<&str> {
        self.0.host_str()
    }

    pub fn port(&self) -> Option<u16> {
        self.0.port()
    }

    pub fn port_or_known_default(&self) -> Option<u16> {
        self.0.port_or_known_default()
    }

    pub fn join(&self, input: &str) -> Result<ServoUrl, url::ParseError> {
        self.0.join(input).map(Self::from_url)
    }

    pub fn path_segments(&self) -> Option<::std::str::Split<char>> {
        self.0.path_segments()
    }

    pub fn query(&self) -> Option<&str> {
        self.0.query()
    }

    pub fn from_file_path<P: AsRef<Path>>(path: P) -> Result<Self, ()> {
        Ok(Self::from_url(try!(Url::from_file_path(path))))
    }
}

impl fmt::Display for ServoUrl {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(formatter)
    }
}

impl Index<RangeFull> for ServoUrl {
    type Output = str;
    fn index(&self, _: RangeFull) -> &str {
        &self.0[..]
    }
}

impl Index<RangeFrom<Position>> for ServoUrl {
    type Output = str;
    fn index(&self, range: RangeFrom<Position>) -> &str {
        &self.0[range]
    }
}

impl Index<RangeTo<Position>> for ServoUrl {
    type Output = str;
    fn index(&self, range: RangeTo<Position>) -> &str {
        &self.0[range]
    }
}

impl Index<Range<Position>> for ServoUrl {
    type Output = str;
    fn index(&self, range: Range<Position>) -> &str {
        &self.0[range]
    }
}

impl From<Url> for ServoUrl {
    fn from(url: Url) -> Self {
        ServoUrl::from_url(url)
    }
}
<commit_msg>Omit the 'ServoUrl()' wrapping in ServoUrl's Debug implementation.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#![deny(unsafe_code)]

#![crate_name = "servo_url"]
#![crate_type = "rlib"]

#![cfg_attr(feature = "servo", feature(plugin))]

#[cfg(feature = "servo")] extern crate serde;
#[cfg(feature = "servo")] #[macro_use] extern crate serde_derive;
#[cfg(feature = "servo")] extern crate heapsize;
#[cfg(feature = "servo")] #[macro_use] extern crate heapsize_derive;

extern crate url;

use std::fmt;
use std::net::IpAddr;
use std::ops::{Range, RangeFrom, RangeTo, RangeFull, Index};
use std::path::Path;
use std::sync::Arc;
use url::{Url, Origin, Position};

#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf, Serialize, Deserialize))]
pub struct ServoUrl(Arc<Url>);

impl ServoUrl {
    pub fn from_url(url: Url) -> Self {
        ServoUrl(Arc::new(url))
    }

    pub fn parse_with_base(base: Option<&Self>, input: &str) -> Result<Self, url::ParseError> {
        Url::options().base_url(base.map(|b| &*b.0)).parse(input).map(Self::from_url)
    }

    pub fn into_string(self) -> String {
        Arc::try_unwrap(self.0).unwrap_or_else(|s| (*s).clone()).into_string()
    }

    // NOTE: These methods return options that are always true temporarily until
    // we special-case some urls to avoid going through rust-url.
    pub fn into_url(self) -> Option<Url> {
        Some(Arc::try_unwrap(self.0).unwrap_or_else(|s| (*s).clone()))
    }

    pub fn as_url(&self) -> Option<&Arc<Url>> {
        Some(&self.0)
    }

    pub fn parse(input: &str) -> Result<Self, url::ParseError> {
        Url::parse(input).map(Self::from_url)
    }

    pub fn cannot_be_a_base(&self) -> bool {
        self.0.cannot_be_a_base()
    }

    pub fn domain(&self) -> Option<&str> {
        self.0.domain()
    }

    pub fn fragment(&self) -> Option<&str> {
        self.0.fragment()
    }

    pub fn path(&self) -> &str {
        self.0.path()
    }

    pub fn origin(&self) -> Origin {
        self.0.origin()
    }

    pub fn scheme(&self) -> &str {
        self.0.scheme()
    }

    pub fn is_secure_scheme(&self) -> bool {
        let scheme = self.scheme();
        scheme == "https" || scheme == "wss"
    }

    pub fn as_str(&self) -> &str {
        self.0.as_str()
    }

    pub fn as_mut_url(&mut self) -> Option<&mut Url> {
        Some(Arc::make_mut(&mut self.0))
    }

    pub fn set_username(&mut self, user: &str) -> Result<(), ()> {
        Arc::make_mut(&mut self.0).set_username(user)
    }

    pub fn set_ip_host(&mut self, addr: IpAddr) -> Result<(), ()> {
        Arc::make_mut(&mut self.0).set_ip_host(addr)
    }

    pub fn set_password(&mut self, pass: Option<&str>) -> Result<(), ()> {
        Arc::make_mut(&mut self.0).set_password(pass)
    }

    pub fn set_fragment(&mut self, fragment: Option<&str>) {
        Arc::make_mut(&mut self.0).set_fragment(fragment)
    }

    pub fn username(&self) -> &str {
        self.0.username()
    }

    pub fn password(&self) -> Option<&str> {
        self.0.password()
    }

    pub fn to_file_path(&self) -> Result<::std::path::PathBuf, ()> {
        self.0.to_file_path()
    }

    pub fn host(&self) -> Option<url::Host<&str>> {
        self.0.host()
    }

    pub fn host_str(&self) -> Option<&str> {
        self.0.host_str()
    }

    pub fn port(&self) -> Option<u16> {
        self.0.port()
    }

    pub fn port_or_known_default(&self) -> Option<u16> {
        self.0.port_or_known_default()
    }

    pub fn join(&self, input: &str) -> Result<ServoUrl, url::ParseError> {
        self.0.join(input).map(Self::from_url)
    }

    pub fn path_segments(&self) -> Option<::std::str::Split<char>> {
        self.0.path_segments()
    }

    pub fn query(&self) -> Option<&str> {
        self.0.query()
    }

    pub fn from_file_path<P: AsRef<Path>>(path: P) -> Result<Self, ()> {
        Ok(Self::from_url(try!(Url::from_file_path(path))))
    }
}

impl fmt::Display for ServoUrl {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(formatter)
    }
}

impl fmt::Debug for ServoUrl {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(formatter)
    }
}

impl Index<RangeFull> for ServoUrl {
    type Output = str;
    fn index(&self, _: RangeFull) -> &str {
        &self.0[..]
    }
}

impl Index<RangeFrom<Position>> for ServoUrl {
    type Output = str;
    fn index(&self, range: RangeFrom<Position>) -> &str {
        &self.0[range]
    }
}

impl Index<RangeTo<Position>> for ServoUrl {
    type Output = str;
    fn index(&self, range: RangeTo<Position>) -> &str {
        &self.0[range]
    }
}

impl Index<Range<Position>> for ServoUrl {
    type Output = str;
    fn index(&self, range: Range<Position>) -> &str {
        &self.0[range]
    }
}

impl From<Url> for ServoUrl {
    fn from(url: Url) -> Self {
        ServoUrl::from_url(url)
    }
}
<|endoftext|>


<commit_before>pub trait EventStore {
    type Id;
    type Event;

    fn write_events<Events>(&self, aggregate_id: &Self::Id, events: Events)
        where Events: IntoIterator<Item = Self::Event>;

    fn read_events(&self, aggregate_id: &Self::Id) -> Vec<Self::Event>;
}

pub trait SnapshotStore {}

pub trait ProjectionStore {}
<commit_msg>Flesh out the EventStore trait some more<commit_after>extern crate futures;

use futures::Stream;

/// An event with associated metadata that corresponds to how it was stored in
/// the event store.
pub struct PersistedEvent<Offset, Event> {
    /// The global offset of the event in the event store.
    pub global_offset: Offset,
    /// The offset within a single stream.
    pub stream_offset: Offset,
    /// The event that was stored by the client of the event store.
    pub event: Event,
}

/// A repository for storing historical event logs.
pub trait EventStore {
    /// The unique identifier of a stream in the event store
    type StreamId;

    /// The type of the offests into the event store and its streams
    type Offset;

    /// The event store's native serialized form
    type SerializedEvent;

    /// A lazily loaded stream of events in the event store's native form
    type EventStream: Stream<Item = PersistedEvent<Self::Offset, Self::SerializedEvent>>;

    /// Persist the events to the event store
    fn persist_events<Events>(&self,
                              stream_id: &Self::StreamId,
                              stream_offset: Self::Offset,
                              events: Events)
        where Events: IntoIterator<Item = Self::SerializedEvent>;

    /// Read the events back from the event store
    fn get_events(&self, stream_id: &Self::StreamId) -> Self::EventStream;
}

pub trait SnapshotStore {}

pub trait ProjectionStore {}
<|endoftext|>


<commit_before>// Copyright 2014-2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// 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.

//! Checks for uses of mutex where an atomic value could be used
//!
//! This lint is **warn** by default

use crate::rustc::hir::Expr;
use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
use crate::rustc::ty::{self, Ty};
use crate::rustc::{declare_tool_lint, lint_array};
use crate::syntax::ast;
use crate::utils::{match_type, paths, span_lint};

/// **What it does:** Checks for usages of `Mutex<X>` where an atomic will do.
///
/// **Why is this bad?** Using a mutex just to make access to a plain bool or
/// reference sequential is shooting flies with cannons.
/// `std::atomic::AtomicBool` and `std::atomic::AtomicPtr` are leaner and
/// faster.
///
/// **Known problems:** This lint cannot detect if the mutex is actually used
/// for waiting before a critical section.
///
/// **Example:**
/// ```rust
/// let x = Mutex::new(&y);
/// ```
declare_clippy_lint! {
    pub MUTEX_ATOMIC,
    perf,
    "using a mutex where an atomic value could be used instead"
}

/// **What it does:** Checks for usages of `Mutex<X>` where `X` is an integral
/// type.
///
/// **Why is this bad?** Using a mutex just to make access to a plain integer
/// sequential is
/// shooting flies with cannons. `std::atomic::usize` is leaner and faster.
///
/// **Known problems:** This lint cannot detect if the mutex is actually used
/// for waiting before a critical section.
///
/// **Example:**
/// ```rust
/// let x = Mutex::new(0usize);
/// ```
declare_clippy_lint! {
    pub MUTEX_INTEGER,
    nursery,
    "using a mutex for an integer type"
}

impl LintPass for MutexAtomic {
    fn get_lints(&self) -> LintArray {
        lint_array!(MUTEX_ATOMIC, MUTEX_INTEGER)
    }
}

pub struct MutexAtomic;

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutexAtomic {
    fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
        let ty = cx.tables.expr_ty(expr);
        if let ty::Adt(_, subst) = ty.sty {
            if match_type(cx, ty, &paths::MUTEX) {
                let mutex_param = subst.type_at(0);
                if let Some(atomic_name) = get_atomic_name(mutex_param) {
                    let msg = format!(
                        "Consider using an {} instead of a Mutex here. If you just want the locking \
                         behaviour and not the internal type, consider using Mutex<()>.",
                        atomic_name
                    );
                    match mutex_param.sty {
                        ty::Uint(t) if t != ast::UintTy::Usize => span_lint(cx, MUTEX_INTEGER, expr.span, &msg),
                        ty::Int(t) if t != ast::IntTy::Isize => span_lint(cx, MUTEX_INTEGER, expr.span, &msg),
                        _ => span_lint(cx, MUTEX_ATOMIC, expr.span, &msg),
                    };
                }
            }
        }
    }
}

fn get_atomic_name(ty: Ty<'_>) -> Option<(&'static str)> {
    match ty.sty {
        ty::Bool => Some("AtomicBool"),
        ty::Uint(_) => Some("AtomicUsize"),
        ty::Int(_) => Some("AtomicIsize"),
        ty::RawPtr(_) => Some("AtomicPtr"),
        _ => None,
    }
}
<commit_msg>mutex_atomic: Correct location of AtomicBool and friends<commit_after>// Copyright 2014-2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// 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.

//! Checks for uses of mutex where an atomic value could be used
//!
//! This lint is **warn** by default

use crate::rustc::hir::Expr;
use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
use crate::rustc::ty::{self, Ty};
use crate::rustc::{declare_tool_lint, lint_array};
use crate::syntax::ast;
use crate::utils::{match_type, paths, span_lint};

/// **What it does:** Checks for usages of `Mutex<X>` where an atomic will do.
///
/// **Why is this bad?** Using a mutex just to make access to a plain bool or
/// reference sequential is shooting flies with cannons.
/// `std::sync::atomic::AtomicBool` and `std::sync::atomic::AtomicPtr` are leaner and
/// faster.
///
/// **Known problems:** This lint cannot detect if the mutex is actually used
/// for waiting before a critical section.
///
/// **Example:**
/// ```rust
/// let x = Mutex::new(&y);
/// ```
declare_clippy_lint! {
    pub MUTEX_ATOMIC,
    perf,
    "using a mutex where an atomic value could be used instead"
}

/// **What it does:** Checks for usages of `Mutex<X>` where `X` is an integral
/// type.
///
/// **Why is this bad?** Using a mutex just to make access to a plain integer
/// sequential is
/// shooting flies with cannons. `std::sync::atomic::AtomicUsize` is leaner and faster.
///
/// **Known problems:** This lint cannot detect if the mutex is actually used
/// for waiting before a critical section.
///
/// **Example:**
/// ```rust
/// let x = Mutex::new(0usize);
/// ```
declare_clippy_lint! {
    pub MUTEX_INTEGER,
    nursery,
    "using a mutex for an integer type"
}

impl LintPass for MutexAtomic {
    fn get_lints(&self) -> LintArray {
        lint_array!(MUTEX_ATOMIC, MUTEX_INTEGER)
    }
}

pub struct MutexAtomic;

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutexAtomic {
    fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
        let ty = cx.tables.expr_ty(expr);
        if let ty::Adt(_, subst) = ty.sty {
            if match_type(cx, ty, &paths::MUTEX) {
                let mutex_param = subst.type_at(0);
                if let Some(atomic_name) = get_atomic_name(mutex_param) {
                    let msg = format!(
                        "Consider using an {} instead of a Mutex here. If you just want the locking \
                         behaviour and not the internal type, consider using Mutex<()>.",
                        atomic_name
                    );
                    match mutex_param.sty {
                        ty::Uint(t) if t != ast::UintTy::Usize => span_lint(cx, MUTEX_INTEGER, expr.span, &msg),
                        ty::Int(t) if t != ast::IntTy::Isize => span_lint(cx, MUTEX_INTEGER, expr.span, &msg),
                        _ => span_lint(cx, MUTEX_ATOMIC, expr.span, &msg),
                    };
                }
            }
        }
    }
}

fn get_atomic_name(ty: Ty<'_>) -> Option<(&'static str)> {
    match ty.sty {
        ty::Bool => Some("AtomicBool"),
        ty::Uint(_) => Some("AtomicUsize"),
        ty::Int(_) => Some("AtomicIsize"),
        ty::RawPtr(_) => Some("AtomicPtr"),
        _ => None,
    }
}
<|endoftext|>


<commit_before>use std;
use std::error;
use std::io;

use anyhow::Error;
use anyhow::Result;

#[derive(Debug, thiserror::Error)]
pub enum ErrorKind {
    #[error("bailin' out")]
    Rewind,

    /// format is (probably) legal, but we refuse to support its feature
    #[error("unsupported feature: {0}")]
    UnsupportedFeature(String),

    /// a major problem, but we believe we can recover
    #[error("invalid format: {0}")]
    RecoverableFailure(String),
}

#[derive(Debug, PartialEq)]
pub enum FormatErrorType {
    Rewind,
    Other,
}

pub fn classify_format_error_result<T>(res: &Result<T>) -> Option<FormatErrorType> {
    // if res.is_ok() {
    return None;
    // }

    // let error = res.as_ref().err().unwrap();
    //
    // let broken_ref = error.iter().last().unwrap();
    //
    // if let Some(e) = unsafe_staticify(broken_ref).downcast_ref::<Error>() {
    //     is_format_error(e)
    // } else if unsafe_staticify(broken_ref).is::<zip::result::ZipError>() {
    //     // Most zip errors should be wrapped in an errors::Error,
    //     // but https://github.com/brson/error-chain/issues/159
    //
    //     // This is just a copy-paste of is_format_error's Zip(_) => Other
    //     Some(FormatErrorType::Other)
    // } else if unsafe_staticify(broken_ref).is::<ext4::Error>() {
    //     // see zip comment above
    //     Some(FormatErrorType::Other)
    // } else if let Some(e) = unsafe_staticify(broken_ref).downcast_ref::<io::Error>() {
    //     is_io_format_error(e).unwrap_or(None)
    // } else {
    //     //            self.log(1, || format!("unexpectedly failed to match an error type: {:?}", broken_ref))?;
    //     None
    // }
}

fn is_format_error(e: &Error) -> Option<FormatErrorType> {
    // match *e.kind() {
    //     ErrorKind::Rewind => {
    //         return Some(FormatErrorType::Rewind);
    //     }
    //     ErrorKind::Tar(_) | ErrorKind::RecoverableFailure(_) | ErrorKind::UnsupportedFeature(_) => {
    //         return Some(FormatErrorType::Other);
    //     }
    //     ErrorKind::Io(ref e) => {
    //         if let Some(result) = is_io_format_error(e) {
    //             return result;
    //         }
    //     }
    //
    //     ErrorKind::Ext4(_) => {
    //         return Some(FormatErrorType::Other);
    //     }
    //
    //     ErrorKind::Zip(_) => {
    //         return Some(FormatErrorType::Other);
    //     }
    //
    //     ErrorKind::Msg(_) => {
    //         return None;
    //     }
    // }

    None
}

fn is_io_format_error(e: &io::Error) -> Option<Option<FormatErrorType>> {
    // if there's an actual error code (regardless of what it is),
    // it's probably not from a library
    if e.raw_os_error().is_some() {
        return Some(None);
    }

    match e.kind() {
        io::ErrorKind::InvalidData
        | io::ErrorKind::InvalidInput
        | io::ErrorKind::Other
        | io::ErrorKind::UnexpectedEof => return Some(Some(FormatErrorType::Other)),
        io::ErrorKind::BrokenPipe | io::ErrorKind::NotFound | io::ErrorKind::PermissionDenied => {
            return Some(None)
        }
        _ => {}
    }

    None
}

/// UNSAFE UNSAFE UNSAFE UNSAFE UNSAFE UNSAFE UNSAFE UNSAFE UNSAFE UNSAFE UNSAFE UNSAFE
/// UNSAFE UNSAFE UNSAFE UNSAFE UNSAFE UNSAFE UNSAFE UNSAFE UNSAFE UNSAFE UNSAFE UNSAFE
/// UNSAFE UNSAFE UNSAFE UNSAFE UNSAFE UNSAFE UNSAFE UNSAFE UNSAFE UNSAFE UNSAFE UNSAFE
/// UNSAFE UNSAFE UNSAFE UNSAFE UNSAFE UNSAFE UNSAFE UNSAFE UNSAFE UNSAFE UNSAFE UNSAFE
/// UNSAFE UNSAFE UNSAFE UNSAFE UNSAFE UNSAFE UNSAFE UNSAFE UNSAFE UNSAFE UNSAFE UNSAFE
///
/// TODO: working around https://github.com/rust-lang/rust/issues/35943
/// TODO: i.e. error.cause() is totally useless
///
/// This allows methods from the `Any` trait to be executed, e.g.
/// `is::<>` `and downcast_ref::<>`. I recommend you run them immediately;
/// i.e. don't even put the result of the method into a local.
fn unsafe_staticify(err: &dyn error::Error) -> &'static dyn error::Error {
    unsafe { std::mem::transmute(err) }
}

#[cfg(test)]
mod tests {
    use super::*;
    use anyhow::Context;
    use std::error::Error as Foo;
    use std::io;
    use zip;

    fn simulate_failure(input: bool) -> zip::result::ZipResult<bool> {
        if !input {
            Ok(input)
        } else {
            Err(zip::result::ZipError::FileNotFound)
        }
    }

    fn simulate_second_failure(input: bool) -> zip::result::ZipResult<bool> {
        if !input {
            Ok(input)
        } else {
            Err(zip::result::ZipError::Io(io::ErrorKind::BrokenPipe.into()))
        }
    }

    #[test]
    #[ignore]
    fn real_format_error() {
        let failure = simulate_failure(true).with_context(|| "oops");
        assert!(classify_format_error_result(&failure).unwrap() == FormatErrorType::Other);
    }

    #[test]
    fn io_error_is_not_format() {
        let err: io::Error = io::ErrorKind::BrokenPipe.into();
        let res: Result<()> = Err(err).with_context(|| "oops");
        assert!(classify_format_error_result(&res).is_none())
    }

    #[test]
    fn nested_zip_failure_is_not_format() {
        let failure = simulate_second_failure(true).with_context(|| "oops");
        assert!(classify_format_error_result(&failure).is_none())
    }

    // #[test]
    // fn chain_syntax_irrelevant() {
    //     let literate = simulate_failure(true)
    //         .with_context(|| "whoopsie")
    //         .unwrap_err();
    //     let explicit = Error::with_chain(simulate_failure(true).unwrap_err(), "whoopsie");
    //
    //     match literate.kind() {
    //         &ErrorKind::Msg(_) => {}
    //         _ => panic!(),
    //     };
    //     match explicit.kind() {
    //         &ErrorKind::Msg(_) => {}
    //         _ => panic!(),
    //     }
    //
    //     let lit_cause = explicit.cause().unwrap();
    //     assert!(unsafe_staticify(lit_cause).is::<zip::result::ZipError>());
    //
    //     let exp_cause = explicit.cause().unwrap();
    //     assert!(unsafe_staticify(exp_cause).is::<zip::result::ZipError>());
    // }
}
<commit_msg>feat: maybe the errors work?<commit_after>use std;
use std::io;

use anyhow::Result;

#[derive(Debug, thiserror::Error)]
pub enum ErrorKind {
    #[error("bailin' out")]
    Rewind,

    /// format is (probably) legal, but we refuse to support its feature
    #[error("unsupported feature: {0}")]
    UnsupportedFeature(String),
}

#[derive(Debug, PartialEq)]
pub enum FormatErrorType {
    Rewind,
    Other,
}

pub fn classify_format_error_result<T>(res: &Result<T>) -> Option<FormatErrorType> {
    let error = match res {
        Ok(_) => return None,
        Err(err) => err,
    };

    let root_cause = error.root_cause();

    if let Some(e) = root_cause.downcast_ref::<ErrorKind>() {
        is_format_error(e)
    } else if root_cause.is::<zip::result::ZipError>() {
        // This is just a copy-paste of is_format_error's Zip(_) => Other
        Some(FormatErrorType::Other)
    } else if root_cause.is::<ext4::Error>() {
        // see zip comment above
        Some(FormatErrorType::Other)
    } else if let Some(e) = root_cause.downcast_ref::<io::Error>() {
        is_io_format_error(e).unwrap_or(None)
    } else {
        //            self.log(1, || format!("unexpectedly failed to match an error type: {:?}", broken_ref))?;
        None
    }
}

fn is_format_error(e: &ErrorKind) -> Option<FormatErrorType> {
    match e {
        ErrorKind::Rewind => {
            return Some(FormatErrorType::Rewind);
        }
        ErrorKind::UnsupportedFeature(_) => {
            return Some(FormatErrorType::Other);
        }
    }
}

fn is_io_format_error(e: &io::Error) -> Option<Option<FormatErrorType>> {
    // if there's an actual error code (regardless of what it is),
    // it's probably not from a library
    if e.raw_os_error().is_some() {
        return Some(None);
    }

    match e.kind() {
        io::ErrorKind::InvalidData
        | io::ErrorKind::InvalidInput
        | io::ErrorKind::Other
        | io::ErrorKind::UnexpectedEof => return Some(Some(FormatErrorType::Other)),
        io::ErrorKind::BrokenPipe | io::ErrorKind::NotFound | io::ErrorKind::PermissionDenied => {
            return Some(None)
        }
        _ => {}
    }

    None
}

#[cfg(test)]
mod tests {
    use super::*;
    use anyhow::Context;
    use std::io;
    use zip;

    fn simulate_failure(input: bool) -> zip::result::ZipResult<bool> {
        if !input {
            Ok(input)
        } else {
            Err(zip::result::ZipError::FileNotFound)
        }
    }

    fn simulate_second_failure(input: bool) -> zip::result::ZipResult<bool> {
        if !input {
            Ok(input)
        } else {
            Err(zip::result::ZipError::Io(io::ErrorKind::BrokenPipe.into()))
        }
    }

    #[test]
    fn real_format_error() {
        let failure = simulate_failure(true).with_context(|| "oops");
        assert_eq!(classify_format_error_result(&failure).unwrap(), FormatErrorType::Other);
    }

    #[test]
    fn io_error_is_not_format() {
        let err: io::Error = io::ErrorKind::BrokenPipe.into();
        let res: Result<()> = Err(err).with_context(|| "oops");
        assert!(classify_format_error_result(&res).is_none())
    }

    #[test]
    fn nested_zip_failure_is_not_format() {
        let failure = simulate_second_failure(true).with_context(|| "oops");
        assert!(classify_format_error_result(&failure).is_none())
    }

    #[test]
    fn chain_syntax_irrelevant() {
        let explicit = simulate_failure(true).context("whoopsie").unwrap_err();
        let exp_cause = explicit.source().unwrap();
        assert!(exp_cause.is::<zip::result::ZipError>());
    }
}
<|endoftext|>


<commit_before>//! TCP relay client implementation

use std::{
    io,
    net::SocketAddr,
    pin::Pin,
    task::{self, Poll},
};

use log::trace;
use tokio::{net::TcpStream, prelude::*};

use crate::relay::socks5::{
    self,
    Address,
    Command,
    HandshakeRequest,
    HandshakeResponse,
    Reply,
    TcpRequestHeader,
    TcpResponseHeader,
};

use super::ProxyStream;
use crate::{config::ServerConfig, context::SharedContext};

/// Socks5 proxy client
pub struct Socks5Client {
    stream: TcpStream,
}

impl Socks5Client {
    /// Connects to `addr` via `proxy`
    pub async fn connect<A>(addr: A, proxy: &SocketAddr) -> io::Result<Socks5Client>
    where
        Address: From<A>,
    {
        let mut s = TcpStream::connect(proxy).await?;

        // 1. Handshake
        let hs = HandshakeRequest::new(vec![socks5::SOCKS5_AUTH_METHOD_NONE]);
        trace!("client connected, going to send handshake: {:?}", hs);

        hs.write_to(&mut s).await?;
        s.flush().await?;

        let hsp = HandshakeResponse::read_from(&mut s).await?;

        trace!("got handshake response: {:?}", hsp);
        assert_eq!(hsp.chosen_method, socks5::SOCKS5_AUTH_METHOD_NONE);

        // 2. Send request header
        let h = TcpRequestHeader::new(Command::TcpConnect, From::from(addr));
        trace!("going to connect, req: {:?}", h);

        h.write_to(&mut s).await?;
        s.flush().await?;
        let hp = TcpResponseHeader::read_from(&mut s).await?;

        trace!("got response: {:?}", hp);
        match hp.reply {
            Reply::Succeeded => (),
            r => {
                let err = io::Error::new(io::ErrorKind::Other, format!("{}", r));
                return Err(err);
            }
        }

        Ok(Socks5Client { stream: s })
    }

    /// UDP Associate `addr` via `proxy`
    pub async fn udp_associate<A>(addr: A, proxy: &SocketAddr) -> io::Result<(Socks5Client, Address)>
    where
        Address: From<A>,
    {
        let mut s = TcpStream::connect(proxy).await?;

        // 1. Handshake
        let hs = HandshakeRequest::new(vec![socks5::SOCKS5_AUTH_METHOD_NONE]);
        trace!("client connected, going to send handshake: {:?}", hs);

        hs.write_to(&mut s).await?;
        s.flush().await?;

        let hsp = HandshakeResponse::read_from(&mut s).await?;

        trace!("got handshake response: {:?}", hsp);
        assert_eq!(hsp.chosen_method, socks5::SOCKS5_AUTH_METHOD_NONE);

        // 2. Send request header
        let h = TcpRequestHeader::new(Command::UdpAssociate, From::from(addr));
        trace!("going to connect, req: {:?}", h);

        h.write_to(&mut s).await?;
        s.flush().await?;
        let hp = TcpResponseHeader::read_from(&mut s).await?;

        trace!("got response: {:?}", hp);
        match hp.reply {
            Reply::Succeeded => (),
            r => {
                let err = io::Error::new(io::ErrorKind::Other, format!("{}", r));
                return Err(err);
            }
        }

        Ok((Socks5Client { stream: s }, hp.address))
    }
}

impl AsyncRead for Socks5Client {
    fn poll_read(mut self: Pin<&mut Self>, cx: &mut task::Context, buf: &mut [u8]) -> Poll<Result<usize, io::Error>> {
        Pin::new(&mut self.stream).poll_read(cx, buf)
    }
}

impl AsyncWrite for Socks5Client {
    fn poll_write(mut self: Pin<&mut Self>, cx: &mut task::Context, buf: &[u8]) -> Poll<Result<usize, io::Error>> {
        Pin::new(&mut self.stream).poll_write(cx, buf)
    }

    fn poll_flush(mut self: Pin<&mut Self>, cx: &mut task::Context) -> Poll<Result<(), io::Error>> {
        Pin::new(&mut self.stream).poll_flush(cx)
    }

    fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut task::Context) -> Poll<Result<(), io::Error>> {
        Pin::new(&mut self.stream).poll_shutdown(cx)
    }
}

pub(crate) struct ServerClient {
    pub stream: ProxyStream,
}

impl ServerClient {
    pub(crate) async fn connect(
        context: SharedContext,
        addr: &Address,
        svr_cfg: &ServerConfig,
    ) -> io::Result<ServerClient> {
        let stream = ProxyStream::connect_proxied(context, svr_cfg, addr).await?;
        Ok(ServerClient { stream })
    }
}
<commit_msg>TcpStream does not have flush()<commit_after>//! TCP relay client implementation

use std::{
    io,
    net::SocketAddr,
    pin::Pin,
    task::{self, Poll},
};

use log::trace;
use tokio::{net::TcpStream, prelude::*};

use crate::relay::socks5::{
    self,
    Address,
    Command,
    HandshakeRequest,
    HandshakeResponse,
    Reply,
    TcpRequestHeader,
    TcpResponseHeader,
};

use super::ProxyStream;
use crate::{config::ServerConfig, context::SharedContext};

/// Socks5 proxy client
pub struct Socks5Client {
    stream: TcpStream,
}

impl Socks5Client {
    /// Connects to `addr` via `proxy`
    pub async fn connect<A>(addr: A, proxy: &SocketAddr) -> io::Result<Socks5Client>
    where
        Address: From<A>,
    {
        let mut s = TcpStream::connect(proxy).await?;

        // 1. Handshake
        let hs = HandshakeRequest::new(vec![socks5::SOCKS5_AUTH_METHOD_NONE]);
        trace!("client connected, going to send handshake: {:?}", hs);

        hs.write_to(&mut s).await?;

        let hsp = HandshakeResponse::read_from(&mut s).await?;

        trace!("got handshake response: {:?}", hsp);
        assert_eq!(hsp.chosen_method, socks5::SOCKS5_AUTH_METHOD_NONE);

        // 2. Send request header
        let h = TcpRequestHeader::new(Command::TcpConnect, From::from(addr));
        trace!("going to connect, req: {:?}", h);
        h.write_to(&mut s).await?;

        let hp = TcpResponseHeader::read_from(&mut s).await?;

        trace!("got response: {:?}", hp);
        match hp.reply {
            Reply::Succeeded => (),
            r => {
                let err = io::Error::new(io::ErrorKind::Other, format!("{}", r));
                return Err(err);
            }
        }

        Ok(Socks5Client { stream: s })
    }

    /// UDP Associate `addr` via `proxy`
    pub async fn udp_associate<A>(addr: A, proxy: &SocketAddr) -> io::Result<(Socks5Client, Address)>
    where
        Address: From<A>,
    {
        let mut s = TcpStream::connect(proxy).await?;

        // 1. Handshake
        let hs = HandshakeRequest::new(vec![socks5::SOCKS5_AUTH_METHOD_NONE]);
        trace!("client connected, going to send handshake: {:?}", hs);

        hs.write_to(&mut s).await?;
        s.flush().await?;

        let hsp = HandshakeResponse::read_from(&mut s).await?;

        trace!("got handshake response: {:?}", hsp);
        assert_eq!(hsp.chosen_method, socks5::SOCKS5_AUTH_METHOD_NONE);

        // 2. Send request header
        let h = TcpRequestHeader::new(Command::UdpAssociate, From::from(addr));
        trace!("going to connect, req: {:?}", h);

        h.write_to(&mut s).await?;
        s.flush().await?;
        let hp = TcpResponseHeader::read_from(&mut s).await?;

        trace!("got response: {:?}", hp);
        match hp.reply {
            Reply::Succeeded => (),
            r => {
                let err = io::Error::new(io::ErrorKind::Other, format!("{}", r));
                return Err(err);
            }
        }

        Ok((Socks5Client { stream: s }, hp.address))
    }
}

impl AsyncRead for Socks5Client {
    fn poll_read(mut self: Pin<&mut Self>, cx: &mut task::Context, buf: &mut [u8]) -> Poll<Result<usize, io::Error>> {
        Pin::new(&mut self.stream).poll_read(cx, buf)
    }
}

impl AsyncWrite for Socks5Client {
    fn poll_write(mut self: Pin<&mut Self>, cx: &mut task::Context, buf: &[u8]) -> Poll<Result<usize, io::Error>> {
        Pin::new(&mut self.stream).poll_write(cx, buf)
    }

    fn poll_flush(mut self: Pin<&mut Self>, cx: &mut task::Context) -> Poll<Result<(), io::Error>> {
        Pin::new(&mut self.stream).poll_flush(cx)
    }

    fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut task::Context) -> Poll<Result<(), io::Error>> {
        Pin::new(&mut self.stream).poll_shutdown(cx)
    }
}

pub(crate) struct ServerClient {
    pub stream: ProxyStream,
}

impl ServerClient {
    pub(crate) async fn connect(
        context: SharedContext,
        addr: &Address,
        svr_cfg: &ServerConfig,
    ) -> io::Result<ServerClient> {
        let stream = ProxyStream::connect_proxied(context, svr_cfg, addr).await?;
        Ok(ServerClient { stream })
    }
}
<|endoftext|>


<commit_before>// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

use anyhow::{anyhow, Result};
use regex::Regex;
use std::io::ErrorKind;
use std::process::{Child, Command, Stdio};
use std::sync::{Arc, Mutex};
use std::time::{Duration, Instant};

use crate::transport::verilator::stdout;

/// Verilator startup options.
pub struct Options {
    /// The verilator executable.
    pub executable: String,
    /// The ROM image used to boot the CPU.
    pub rom_image: String,
    /// The flash image stored in internal flash memory.
    pub flash_image: String,
    /// The OTP settings.
    pub otp_image: String,
    /// Any extra arguments to verilator.
    pub extra_args: Vec<String>,
    /// Timeout for starting verilator.
    pub timeout: Duration,
}

pub struct Subprocess {
    child: Child,
    accumulated_output: Arc<Mutex<String>>,
}

impl Subprocess {
    /// Starts a verilator [`Subprocess`] based on [`Options`].
    pub fn from_options(options: Options) -> Result<Self> {
        let mut command = Command::new(&options.executable);
        let mut args = Vec::new();

        if !options.rom_image.is_empty() {
            args.push(format!("--meminit=rom,{}", options.rom_image));
        }
        if !options.flash_image.is_empty() {
            args.push(format!("--meminit=flash,{}", options.flash_image));
        }
        if !options.otp_image.is_empty() {
            args.push(format!("--meminit=otp,{}", options.otp_image));
        }
        args.extend_from_slice(&options.extra_args);
        command.args(&args[..]);

        log::info!("Spawning verilator: {:?} {:?}", options.executable, args);

        let mut child = command
            .stdin(Stdio::null())
            .stdout(Stdio::piped())
            .stderr(Stdio::inherit())
            .spawn()?;
        let accumulator: Arc<Mutex<String>> = Default::default();
        let stdout = child.stdout.take().unwrap();
        let a = Arc::clone(&accumulator);
        std::thread::spawn(move || stdout::accumulate(stdout, a));

        Ok(Subprocess {
            child,
            accumulated_output: accumulator,
        })
    }

    /// Finds a string within the verilator output.
    /// It is assumed that the [`Regex`] `re` has exactly one capture group.
    pub fn find(&mut self, re: &Regex, deadline: Instant) -> Result<String> {
        // Regex captures_len: Capture group 0 is the full match.  Subsequent
        // capture groups are the individual capture groups in the regex.
        // We expect only one user-specified capture group in the regex,
        // and thus expect a capture length of two.
        assert_eq!(re.captures_len(), 2);
        while deadline > Instant::now() {
            {
                let a = self.accumulated_output.lock().unwrap();
                if let Some(captures) = re.captures(&a.as_str()) {
                    let val = captures.get(1).expect("expected a capture");
                    return Ok(val.as_str().to_owned());
                }
            }
            std::thread::sleep(Duration::from_millis(50));
        }
        Err(anyhow!("Timed out"))
    }

    /// Kill the verilator subprocess.
    pub fn kill(&mut self) -> Result<()> {
        match self.child.kill() {
            Err(error) if error.kind() != ErrorKind::InvalidInput => Err(error.into()),
            _ => Ok(()),
        }
    }
}

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

    fn echo_subprocess() -> Result<Subprocess> {
        let options = Options {
            executable: "/bin/echo".to_owned(),
            rom_image: "".to_owned(),
            flash_image: "".to_owned(),
            otp_image: "".to_owned(),
            extra_args: vec!["abc 123 def 456".to_owned()],
            timeout: Duration::from_secs(5),
        };
        Subprocess::from_options(options)
    }

    #[test]
    fn test_find_regex() -> Result<()> {
        let mut subprocess = echo_subprocess()?;
        let regex = Regex::new("abc (.*) def")?;
        let deadline = Instant::now() + Duration::from_secs(5);
        let found = subprocess.find(&regex, deadline)?;
        assert_eq!(found, "123");
        Ok(())
    }

    #[test]
    fn test_kill() -> Result<()> {
        let mut subprocess = echo_subprocess()?;
        subprocess.kill()?;
        Ok(())
    }
}
<commit_msg>[opentitantool] More verbose listing of verilator invocation for copying<commit_after>// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

use anyhow::{anyhow, Result};
use regex::Regex;
use std::io::ErrorKind;
use std::process::{Child, Command, Stdio};
use std::sync::{Arc, Mutex};
use std::time::{Duration, Instant};

use crate::transport::verilator::stdout;

/// Verilator startup options.
pub struct Options {
    /// The verilator executable.
    pub executable: String,
    /// The ROM image used to boot the CPU.
    pub rom_image: String,
    /// The flash image stored in internal flash memory.
    pub flash_image: String,
    /// The OTP settings.
    pub otp_image: String,
    /// Any extra arguments to verilator.
    pub extra_args: Vec<String>,
    /// Timeout for starting verilator.
    pub timeout: Duration,
}

pub struct Subprocess {
    child: Child,
    accumulated_output: Arc<Mutex<String>>,
}

impl Subprocess {
    /// Starts a verilator [`Subprocess`] based on [`Options`].
    pub fn from_options(options: Options) -> Result<Self> {
        let mut command = Command::new(&options.executable);
        let mut args = Vec::new();

        if !options.rom_image.is_empty() {
            args.push(format!("--meminit=rom,{}", options.rom_image));
        }
        if !options.flash_image.is_empty() {
            args.push(format!("--meminit=flash,{}", options.flash_image));
        }
        if !options.otp_image.is_empty() {
            args.push(format!("--meminit=otp,{}", options.otp_image));
        }
        args.extend_from_slice(&options.extra_args);
        command.args(&args[..]);

        log::info!("CWD: {:?}", std::env::current_dir());
        log::info!(
            "Spawning verilator: {:?} {:?}",
            options.executable,
            args.join(" ")
        );

        let mut child = command
            .stdin(Stdio::null())
            .stdout(Stdio::piped())
            .stderr(Stdio::inherit())
            .spawn()?;
        let accumulator: Arc<Mutex<String>> = Default::default();
        let stdout = child.stdout.take().unwrap();
        let a = Arc::clone(&accumulator);
        std::thread::spawn(move || stdout::accumulate(stdout, a));

        Ok(Subprocess {
            child,
            accumulated_output: accumulator,
        })
    }

    /// Finds a string within the verilator output.
    /// It is assumed that the [`Regex`] `re` has exactly one capture group.
    pub fn find(&mut self, re: &Regex, deadline: Instant) -> Result<String> {
        // Regex captures_len: Capture group 0 is the full match.  Subsequent
        // capture groups are the individual capture groups in the regex.
        // We expect only one user-specified capture group in the regex,
        // and thus expect a capture length of two.
        assert_eq!(re.captures_len(), 2);
        while deadline > Instant::now() {
            {
                let a = self.accumulated_output.lock().unwrap();
                if let Some(captures) = re.captures(&a.as_str()) {
                    let val = captures.get(1).expect("expected a capture");
                    return Ok(val.as_str().to_owned());
                }
            }
            std::thread::sleep(Duration::from_millis(50));
        }
        Err(anyhow!("Timed out"))
    }

    /// Kill the verilator subprocess.
    pub fn kill(&mut self) -> Result<()> {
        match self.child.kill() {
            Err(error) if error.kind() != ErrorKind::InvalidInput => Err(error.into()),
            _ => Ok(()),
        }
    }
}

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

    fn echo_subprocess() -> Result<Subprocess> {
        let options = Options {
            executable: "/bin/echo".to_owned(),
            rom_image: "".to_owned(),
            flash_image: "".to_owned(),
            otp_image: "".to_owned(),
            extra_args: vec!["abc 123 def 456".to_owned()],
            timeout: Duration::from_secs(5),
        };
        Subprocess::from_options(options)
    }

    #[test]
    fn test_find_regex() -> Result<()> {
        let mut subprocess = echo_subprocess()?;
        let regex = Regex::new("abc (.*) def")?;
        let deadline = Instant::now() + Duration::from_secs(5);
        let found = subprocess.find(&regex, deadline)?;
        assert_eq!(found, "123");
        Ok(())
    }

    #[test]
    fn test_kill() -> Result<()> {
        let mut subprocess = echo_subprocess()?;
        subprocess.kill()?;
        Ok(())
    }
}
<|endoftext|>


<commit_before>use std::prelude::v1::*;

use std::sync::{Arc, Mutex};
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::mpsc;
use std::thread;
use std::fmt;

use futures_core::*;
use futures_core::task::{self, Wake, Waker, LocalMap};
use futures_core::executor::{Executor, SpawnError};

use enter;
use num_cpus;
use unpark_mutex::UnparkMutex;

/// A thread pool intended to run CPU intensive work.
///
/// This thread pool will hand out futures representing the completed work
/// that happens on the thread pool itself, and the futures can then be later
/// composed with other work as part of an overall computation.
///
/// The worker threads associated with a thread pool are kept alive so long as
/// there is an open handle to the `ThreadPool` or there is work running on them. Once
/// all work has been drained and all references have gone away the worker
/// threads will be shut down.
///
/// Currently `ThreadPool` implements `Clone` which just clones a new reference to
/// the underlying thread pool.
///
/// **Note:** if you use ThreadPool inside a library it's better accept a
/// `ThreadPoolBuilder` object for thread configuration rather than configuring just
/// pool size.  This not only future proof for other settings but also allows
/// user to attach monitoring tools to lifecycle hooks.
pub struct ThreadPool {
    state: Arc<PoolState>,
}

/// Thread pool configuration object
///
/// ThreadPoolBuilder starts with a number of workers equal to the number
/// of CPUs on the host. But you can change it until you call `create()`.
pub struct ThreadPoolBuilder {
    pool_size: usize,
    stack_size: usize,
    name_prefix: Option<String>,
    after_start: Option<Arc<Fn(usize) + Send + Sync>>,
    before_stop: Option<Arc<Fn(usize) + Send + Sync>>,
}

trait AssertSendSync: Send + Sync {}
impl AssertSendSync for ThreadPool {}

struct PoolState {
    tx: Mutex<mpsc::Sender<Message>>,
    rx: Mutex<mpsc::Receiver<Message>>,
    cnt: AtomicUsize,
    size: usize,
}

impl fmt::Debug for ThreadPool {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("ThreadPool")
            .field("size", &self.state.size)
            .finish()
    }
}

impl fmt::Debug for ThreadPoolBuilder {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("ThreadPoolBuilder")
            .field("pool_size", &self.pool_size)
            .field("name_prefix", &self.name_prefix)
            .finish()
    }
}

enum Message {
    Run(Task),
    Close,
}

impl ThreadPool {
    /// Creates a new thread pool with `size` worker threads associated with it.
    ///
    /// The returned handle can use `execute` to run work on this thread pool,
    /// and clones can be made of it to get multiple references to the same
    /// thread pool.
    ///
    /// This is a shortcut for:
    ///
    /// ```rust
    /// # use futures_executor::{ThreadPoolBuilder, ThreadPool};
    /// #
    /// # fn new(size: usize) -> ThreadPool {
    /// ThreadPoolBuilder::new().pool_size(size).create()
    /// # }
    /// ```
    ///
    /// # Panics
    ///
    /// Panics if `size == 0`.
    pub fn new(size: usize) -> ThreadPool {
        ThreadPoolBuilder::new().pool_size(size).create()
    }

    /// Creates a new thread pool with a number of workers equal to the number
    /// of CPUs on the host.
    ///
    /// This is a shortcut for:
    ///
    /// ```rust
    /// # use futures_executor::{ThreadPoolBuilder, ThreadPool};
    /// #
    /// # fn new_num_cpus() -> ThreadPool {
    /// ThreadPoolBuilder::new().create()
    /// # }
    /// ```
    pub fn new_num_cpus() -> ThreadPool {
        ThreadPoolBuilder::new().create()
    }

    /// dox
    pub fn builder() -> ThreadPoolBuilder {
        ThreadPoolBuilder::new()
    }
}

impl Executor for ThreadPool {
    fn spawn(&mut self, f: Box<Future<Item = (), Error = ()> + Send>) -> Result<(), SpawnError> {
        let task = Task {
            spawn: f,
            map: LocalMap::new(),
            wake_handle: Arc::new(WakeHandle {
                exec: self.clone(),
                mutex: UnparkMutex::new(),
            }),
            exec: self.clone(),
        };
        self.state.send(Message::Run(task));
        Ok(())
    }
}

impl PoolState {
    fn send(&self, msg: Message) {
        self.tx.lock().unwrap().send(msg).unwrap();
    }

    fn work(&self,
            idx: usize,
            after_start: Option<Arc<Fn(usize) + Send + Sync>>,
            before_stop: Option<Arc<Fn(usize) + Send + Sync>>) {
        let _scope = enter().unwrap();
        after_start.map(|fun| fun(idx));
        loop {
            let msg = self.rx.lock().unwrap().recv().unwrap();
            match msg {
                Message::Run(r) => r.run(),
                Message::Close => break,
            }
        }
        before_stop.map(|fun| fun(idx));
    }
}

impl Clone for ThreadPool {
    fn clone(&self) -> ThreadPool {
        self.state.cnt.fetch_add(1, Ordering::Relaxed);
        ThreadPool { state: self.state.clone() }
    }
}

impl Drop for ThreadPool {
    fn drop(&mut self) {
        if self.state.cnt.fetch_sub(1, Ordering::Relaxed) == 1 {
            for _ in 0..self.state.size {
                self.state.send(Message::Close);
            }
        }
    }
}

impl ThreadPoolBuilder {
    /// Create a builder a number of workers equal to the number
    /// of CPUs on the host.
    pub fn new() -> ThreadPoolBuilder {
        ThreadPoolBuilder {
            pool_size: num_cpus::get(),
            stack_size: 0,
            name_prefix: None,
            after_start: None,
            before_stop: None,
        }
    }

    /// Set size of a future ThreadPool
    ///
    /// The size of a thread pool is the number of worker threads spawned
    pub fn pool_size(&mut self, size: usize) -> &mut Self {
        self.pool_size = size;
        self
    }

    /// Set stack size of threads in the pool.
    pub fn stack_size(&mut self, stack_size: usize) -> &mut Self {
        self.stack_size = stack_size;
        self
    }

    /// Set thread name prefix of a future ThreadPool
    ///
    /// Thread name prefix is used for generating thread names. For example, if prefix is
    /// `my-pool-`, then threads in the pool will get names like `my-pool-1` etc.
    pub fn name_prefix<S: Into<String>>(&mut self, name_prefix: S) -> &mut Self {
        self.name_prefix = Some(name_prefix.into());
        self
    }

    /// Execute function `f` right after each thread is started but before
    /// running any jobs on it.
    ///
    /// This is initially intended for bookkeeping and monitoring uses.
    /// The `f` will be deconstructed after the `builder` is deconstructed
    /// and all threads in the pool has executed it.
    ///
    /// The closure provided will receive an index corresponding to which worker
    /// thread it's running on.
    pub fn after_start<F>(&mut self, f: F) -> &mut Self
        where F: Fn(usize) + Send + Sync + 'static
    {
        self.after_start = Some(Arc::new(f));
        self
    }

    /// Execute function `f` before each worker thread stops.
    ///
    /// This is initially intended for bookkeeping and monitoring uses.
    /// The `f` will be deconstructed after the `builder` is deconstructed
    /// and all threads in the pool has executed it.
    ///
    /// The closure provided will receive an index corresponding to which worker
    /// thread it's running on.
    pub fn before_stop<F>(&mut self, f: F) -> &mut Self
        where F: Fn(usize) + Send + Sync + 'static
    {
        self.before_stop = Some(Arc::new(f));
        self
    }

    /// Create ThreadPool with configured parameters
    ///
    /// # Panics
    ///
    /// Panics if `pool_size == 0`.
    pub fn create(&mut self) -> ThreadPool {
        let (tx, rx) = mpsc::channel();
        let pool = ThreadPool {
            state: Arc::new(PoolState {
                tx: Mutex::new(tx),
                rx: Mutex::new(rx),
                cnt: AtomicUsize::new(1),
                size: self.pool_size,
            }),
        };
        assert!(self.pool_size > 0);

        for counter in 0..self.pool_size {
            let state = pool.state.clone();
            let after_start = self.after_start.clone();
            let before_stop = self.before_stop.clone();
            let mut thread_builder = thread::Builder::new();
            if let Some(ref name_prefix) = self.name_prefix {
                thread_builder = thread_builder.name(format!("{}{}", name_prefix, counter));
            }
            if self.stack_size > 0 {
                thread_builder = thread_builder.stack_size(self.stack_size);
            }
            thread_builder.spawn(move || state.work(counter, after_start, before_stop)).unwrap();
        }
        return pool
    }
}

/// Units of work submitted to an `Executor`, currently only created
/// internally.
struct Task {
    spawn: Box<Future<Item = (), Error = ()> + Send>,
    map: LocalMap,
    exec: ThreadPool,
    wake_handle: Arc<WakeHandle>,
}

struct WakeHandle {
    mutex: UnparkMutex<Task>,
    exec: ThreadPool,
}

impl Task {
    /// Actually run the task (invoking `poll` on its future) on the current
    /// thread.
    pub fn run(self) {
        let Task { mut spawn, wake_handle, mut map, mut exec } = self;
        let waker = Waker::from(wake_handle.clone());

        // SAFETY: the ownership of this `Task` object is evidence that
        // we are in the `POLLING`/`REPOLL` state for the mutex.
        unsafe {
            wake_handle.mutex.start_poll();

            loop {
                let res = {
                    let mut cx = task::Context::new(&mut map, &waker, &mut exec);
                    spawn.poll(&mut cx)
                };
                match res {
                    Ok(Async::Pending) => {}
                    Ok(Async::Ready(())) |
                    Err(()) => return wake_handle.mutex.complete(),
                }
                let task = Task {
                    spawn,
                    map,
                    wake_handle: wake_handle.clone(),
                    exec: exec
                };
                match wake_handle.mutex.wait(task) {
                    Ok(()) => return,            // we've waited
                    Err(r) => { // someone's notified us
                        spawn = r.spawn;
                        map = r.map;
                        exec = r.exec;
                    }
                }
            }
        }
    }
}

impl fmt::Debug for Task {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("Task")
            .field("contents", &"...")
            .finish()
    }
}

impl Wake for WakeHandle {
    fn wake(&self) {
        match self.mutex.notify() {
            Ok(task) => self.exec.state.send(Message::Run(task)),
            Err(()) => {}
        }
    }
}

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

    #[test]
    fn test_drop_after_start() {
        let (tx, rx) = mpsc::sync_channel(2);
        let _cpu_pool = ThreadPoolBuilder::new()
            .pool_size(2)
            .after_start(move |_| tx.send(1).unwrap()).create();

        // After ThreadPoolBuilder is deconstructed, the tx should be droped
        // so that we can use rx as an iterator.
        let count = rx.into_iter().count();
        assert_eq!(count, 2);
    }
}
<commit_msg>Add `run` to `ThreadPool`<commit_after>use std::prelude::v1::*;

use std::sync::{Arc, Mutex};
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::mpsc;
use std::thread;
use std::fmt;

use futures_core::*;
use futures_core::task::{self, Wake, Waker, LocalMap};
use futures_core::executor::{Executor, SpawnError};

use enter;
use num_cpus;
use unpark_mutex::UnparkMutex;

/// A thread pool intended to run CPU intensive work.
///
/// This thread pool will hand out futures representing the completed work
/// that happens on the thread pool itself, and the futures can then be later
/// composed with other work as part of an overall computation.
///
/// The worker threads associated with a thread pool are kept alive so long as
/// there is an open handle to the `ThreadPool` or there is work running on them. Once
/// all work has been drained and all references have gone away the worker
/// threads will be shut down.
///
/// Currently `ThreadPool` implements `Clone` which just clones a new reference to
/// the underlying thread pool.
///
/// **Note:** if you use ThreadPool inside a library it's better accept a
/// `ThreadPoolBuilder` object for thread configuration rather than configuring just
/// pool size.  This not only future proof for other settings but also allows
/// user to attach monitoring tools to lifecycle hooks.
pub struct ThreadPool {
    state: Arc<PoolState>,
}

/// Thread pool configuration object
///
/// ThreadPoolBuilder starts with a number of workers equal to the number
/// of CPUs on the host. But you can change it until you call `create()`.
pub struct ThreadPoolBuilder {
    pool_size: usize,
    stack_size: usize,
    name_prefix: Option<String>,
    after_start: Option<Arc<Fn(usize) + Send + Sync>>,
    before_stop: Option<Arc<Fn(usize) + Send + Sync>>,
}

trait AssertSendSync: Send + Sync {}
impl AssertSendSync for ThreadPool {}

struct PoolState {
    tx: Mutex<mpsc::Sender<Message>>,
    rx: Mutex<mpsc::Receiver<Message>>,
    cnt: AtomicUsize,
    size: usize,
}

impl fmt::Debug for ThreadPool {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("ThreadPool")
            .field("size", &self.state.size)
            .finish()
    }
}

impl fmt::Debug for ThreadPoolBuilder {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("ThreadPoolBuilder")
            .field("pool_size", &self.pool_size)
            .field("name_prefix", &self.name_prefix)
            .finish()
    }
}

enum Message {
    Run(Task),
    Close,
}

impl ThreadPool {
    /// Creates a new thread pool with a number of workers equal to the number
    /// of CPUs on the host.
    pub fn new() -> ThreadPool {
        ThreadPoolBuilder::new().create()
    }

    /// dox
    pub fn builder() -> ThreadPoolBuilder {
        ThreadPoolBuilder::new()
    }

    /// dox
    pub fn run<F: Future>(&mut self, f: F) -> Result<F::Item, F::Error> {
        ::LocalPool::new().run_until(f, self)
    }
}

impl Executor for ThreadPool {
    fn spawn(&mut self, f: Box<Future<Item = (), Error = ()> + Send>) -> Result<(), SpawnError> {
        let task = Task {
            spawn: f,
            map: LocalMap::new(),
            wake_handle: Arc::new(WakeHandle {
                exec: self.clone(),
                mutex: UnparkMutex::new(),
            }),
            exec: self.clone(),
        };
        self.state.send(Message::Run(task));
        Ok(())
    }
}

impl PoolState {
    fn send(&self, msg: Message) {
        self.tx.lock().unwrap().send(msg).unwrap();
    }

    fn work(&self,
            idx: usize,
            after_start: Option<Arc<Fn(usize) + Send + Sync>>,
            before_stop: Option<Arc<Fn(usize) + Send + Sync>>) {
        let _scope = enter().unwrap();
        after_start.map(|fun| fun(idx));
        loop {
            let msg = self.rx.lock().unwrap().recv().unwrap();
            match msg {
                Message::Run(r) => r.run(),
                Message::Close => break,
            }
        }
        before_stop.map(|fun| fun(idx));
    }
}

impl Clone for ThreadPool {
    fn clone(&self) -> ThreadPool {
        self.state.cnt.fetch_add(1, Ordering::Relaxed);
        ThreadPool { state: self.state.clone() }
    }
}

impl Drop for ThreadPool {
    fn drop(&mut self) {
        if self.state.cnt.fetch_sub(1, Ordering::Relaxed) == 1 {
            for _ in 0..self.state.size {
                self.state.send(Message::Close);
            }
        }
    }
}

impl ThreadPoolBuilder {
    /// Create a builder a number of workers equal to the number
    /// of CPUs on the host.
    pub fn new() -> ThreadPoolBuilder {
        ThreadPoolBuilder {
            pool_size: num_cpus::get(),
            stack_size: 0,
            name_prefix: None,
            after_start: None,
            before_stop: None,
        }
    }

    /// Set size of a future ThreadPool
    ///
    /// The size of a thread pool is the number of worker threads spawned
    pub fn pool_size(&mut self, size: usize) -> &mut Self {
        self.pool_size = size;
        self
    }

    /// Set stack size of threads in the pool.
    pub fn stack_size(&mut self, stack_size: usize) -> &mut Self {
        self.stack_size = stack_size;
        self
    }

    /// Set thread name prefix of a future ThreadPool
    ///
    /// Thread name prefix is used for generating thread names. For example, if prefix is
    /// `my-pool-`, then threads in the pool will get names like `my-pool-1` etc.
    pub fn name_prefix<S: Into<String>>(&mut self, name_prefix: S) -> &mut Self {
        self.name_prefix = Some(name_prefix.into());
        self
    }

    /// Execute function `f` right after each thread is started but before
    /// running any jobs on it.
    ///
    /// This is initially intended for bookkeeping and monitoring uses.
    /// The `f` will be deconstructed after the `builder` is deconstructed
    /// and all threads in the pool has executed it.
    ///
    /// The closure provided will receive an index corresponding to which worker
    /// thread it's running on.
    pub fn after_start<F>(&mut self, f: F) -> &mut Self
        where F: Fn(usize) + Send + Sync + 'static
    {
        self.after_start = Some(Arc::new(f));
        self
    }

    /// Execute function `f` before each worker thread stops.
    ///
    /// This is initially intended for bookkeeping and monitoring uses.
    /// The `f` will be deconstructed after the `builder` is deconstructed
    /// and all threads in the pool has executed it.
    ///
    /// The closure provided will receive an index corresponding to which worker
    /// thread it's running on.
    pub fn before_stop<F>(&mut self, f: F) -> &mut Self
        where F: Fn(usize) + Send + Sync + 'static
    {
        self.before_stop = Some(Arc::new(f));
        self
    }

    /// Create ThreadPool with configured parameters
    ///
    /// # Panics
    ///
    /// Panics if `pool_size == 0`.
    pub fn create(&mut self) -> ThreadPool {
        let (tx, rx) = mpsc::channel();
        let pool = ThreadPool {
            state: Arc::new(PoolState {
                tx: Mutex::new(tx),
                rx: Mutex::new(rx),
                cnt: AtomicUsize::new(1),
                size: self.pool_size,
            }),
        };
        assert!(self.pool_size > 0);

        for counter in 0..self.pool_size {
            let state = pool.state.clone();
            let after_start = self.after_start.clone();
            let before_stop = self.before_stop.clone();
            let mut thread_builder = thread::Builder::new();
            if let Some(ref name_prefix) = self.name_prefix {
                thread_builder = thread_builder.name(format!("{}{}", name_prefix, counter));
            }
            if self.stack_size > 0 {
                thread_builder = thread_builder.stack_size(self.stack_size);
            }
            thread_builder.spawn(move || state.work(counter, after_start, before_stop)).unwrap();
        }
        return pool
    }
}

/// Units of work submitted to an `Executor`, currently only created
/// internally.
struct Task {
    spawn: Box<Future<Item = (), Error = ()> + Send>,
    map: LocalMap,
    exec: ThreadPool,
    wake_handle: Arc<WakeHandle>,
}

struct WakeHandle {
    mutex: UnparkMutex<Task>,
    exec: ThreadPool,
}

impl Task {
    /// Actually run the task (invoking `poll` on its future) on the current
    /// thread.
    pub fn run(self) {
        let Task { mut spawn, wake_handle, mut map, mut exec } = self;
        let waker = Waker::from(wake_handle.clone());

        // SAFETY: the ownership of this `Task` object is evidence that
        // we are in the `POLLING`/`REPOLL` state for the mutex.
        unsafe {
            wake_handle.mutex.start_poll();

            loop {
                let res = {
                    let mut cx = task::Context::new(&mut map, &waker, &mut exec);
                    spawn.poll(&mut cx)
                };
                match res {
                    Ok(Async::Pending) => {}
                    Ok(Async::Ready(())) |
                    Err(()) => return wake_handle.mutex.complete(),
                }
                let task = Task {
                    spawn,
                    map,
                    wake_handle: wake_handle.clone(),
                    exec: exec
                };
                match wake_handle.mutex.wait(task) {
                    Ok(()) => return,            // we've waited
                    Err(r) => { // someone's notified us
                        spawn = r.spawn;
                        map = r.map;
                        exec = r.exec;
                    }
                }
            }
        }
    }
}

impl fmt::Debug for Task {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("Task")
            .field("contents", &"...")
            .finish()
    }
}

impl Wake for WakeHandle {
    fn wake(&self) {
        match self.mutex.notify() {
            Ok(task) => self.exec.state.send(Message::Run(task)),
            Err(()) => {}
        }
    }
}

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

    #[test]
    fn test_drop_after_start() {
        let (tx, rx) = mpsc::sync_channel(2);
        let _cpu_pool = ThreadPoolBuilder::new()
            .pool_size(2)
            .after_start(move |_| tx.send(1).unwrap()).create();

        // After ThreadPoolBuilder is deconstructed, the tx should be droped
        // so that we can use rx as an iterator.
        let count = rx.into_iter().count();
        assert_eq!(count, 2);
    }
}
<|endoftext|>


<commit_before>
struct Node<T> {
    payload: T,
    next: Box<Option<T>>,
    previous: Box<Option<T>>,
}

impl<T> Node<T> {
    pub fn new(payload: T) -> Node<T> {
        Node::<T> {
            payload: payload,
            next: Box::new(None),
            previous: Box::new(None),
        }
    }

    pub fn payload(&self) -> Option<&T> {
        Some(&self.payload)
    }
}

#[test]
fn test_node_new() {
    let expected = Node {
        payload: "test",
        next: Box::new(None),
        previous: Box::new(None),
    };
    let node: Node<&str> = Node::new("test");

    assert_eq!(expected.payload,  node.payload);
    assert_eq!(expected.next,     node.next);
    assert_eq!(expected.previous, node.previous);
}

#[test]
fn test_node_payload() {
    let node: Node<&str> = Node::new("test");
    assert_eq!(&"test", node.payload().unwrap());
}
<commit_msg>Added LinkedList struct with empty `add`<commit_after>
struct Node<T> {
    payload: T,
    next: Box<Option<Node<T>>>,
    previous: Box<Option<Node<T>>>,
}

impl<T> Node<T> {
    pub fn new(payload: T) -> Node<T> {
        Node::<T> {
            payload: payload,
            next: Box::new(None),
            previous: Box::new(None),
        }
    }

    pub fn payload(&self) -> Option<&T> {
        Some(&self.payload)
    }
}

struct LinkedList<T> {
    root: Box<Option<Node<T>>>,
}

impl<T> LinkedList<T> {
    pub fn new() -> LinkedList<T> {
        LinkedList::<T> {
            root: Box::new(None),
        }
    }

    fn add(node: Node<T>) {

        let last_node = &node;

        //loop {
        //    if last_node.payload == None {
        //        last_node = node;
        //        break;
        //    }
        //}
    }
}

#[test]
fn test_node_new() {
    let expected = Node {
        payload: "test",
        next: Box::new(None),
        previous: Box::new(None),
    };
    let node: Node<&str> = Node::new("test");

    assert_eq!(expected.payload,  node.payload);
    assert_eq!(expected.next,     node.next);
    assert_eq!(expected.previous, node.previous);
}

#[test]
fn test_node_payload() {
    let node: Node<&str> = Node::new("test");
    assert_eq!(&"test", node.payload().unwrap());
}
<|endoftext|>


<commit_before>use simba::simd::SimdValue;

use crate::base::Vector4;
use crate::geometry::Quaternion;
use crate::{RealField, Scalar};

impl<N: Scalar + SimdValue> SimdValue for Quaternion<N>
where N::Element: Scalar
{
    type Element = Quaternion<N::Element>;
    type SimdBool = N::SimdBool;

    #[inline]
    fn lanes() -> usize {
        N::lanes()
    }

    #[inline]
    fn splat(val: Self::Element) -> Self {
        Vector4::splat(val.coords).into()
    }

    #[inline]
    fn extract(&self, i: usize) -> Self::Element {
        self.coords.extract(i).into()
    }

    #[inline]
    unsafe fn extract_unchecked(&self, i: usize) -> Self::Element {
        self.coords.extract_unchecked(i).into()
    }

    #[inline]
    fn replace(&mut self, i: usize, val: Self::Element) {
        self.coords.replace(i, val.coords)
    }

    #[inline]
    unsafe fn replace_unchecked(&mut self, i: usize, val: Self::Element) {
        self.coords.replace_unchecked(i, val.coords)
    }

    #[inline]
    fn select(self, cond: Self::SimdBool, other: Self) -> Self {
        self.coords.select(cond, other.coords).into()
    }
}
<commit_msg>Add missing implementatino of SimdValue for UnitQuaternion.<commit_after>use simba::simd::SimdValue;

use crate::base::Vector4;
use crate::geometry::{Quaternion, UnitQuaternion};
use crate::{RealField, Scalar};

impl<N: Scalar + SimdValue> SimdValue for Quaternion<N>
where N::Element: Scalar
{
    type Element = Quaternion<N::Element>;
    type SimdBool = N::SimdBool;

    #[inline]
    fn lanes() -> usize {
        N::lanes()
    }

    #[inline]
    fn splat(val: Self::Element) -> Self {
        Vector4::splat(val.coords).into()
    }

    #[inline]
    fn extract(&self, i: usize) -> Self::Element {
        self.coords.extract(i).into()
    }

    #[inline]
    unsafe fn extract_unchecked(&self, i: usize) -> Self::Element {
        self.coords.extract_unchecked(i).into()
    }

    #[inline]
    fn replace(&mut self, i: usize, val: Self::Element) {
        self.coords.replace(i, val.coords)
    }

    #[inline]
    unsafe fn replace_unchecked(&mut self, i: usize, val: Self::Element) {
        self.coords.replace_unchecked(i, val.coords)
    }

    #[inline]
    fn select(self, cond: Self::SimdBool, other: Self) -> Self {
        self.coords.select(cond, other.coords).into()
    }
}

impl<N: Scalar + SimdValue> SimdValue for UnitQuaternion<N>
where N::Element: Scalar
{
    type Element = UnitQuaternion<N::Element>;
    type SimdBool = N::SimdBool;

    #[inline]
    fn lanes() -> usize {
        N::lanes()
    }

    #[inline]
    fn splat(val: Self::Element) -> Self {
        UnitQuaternion::new_unchecked(Quaternion::splat(val.into_inner()))
    }

    #[inline]
    fn extract(&self, i: usize) -> Self::Element {
        UnitQuaternion::new_unchecked(self.as_ref().extract(i))
    }

    #[inline]
    unsafe fn extract_unchecked(&self, i: usize) -> Self::Element {
        UnitQuaternion::new_unchecked(self.as_ref().extract_unchecked(i))
    }

    #[inline]
    fn replace(&mut self, i: usize, val: Self::Element) {
        self.as_mut_unchecked().replace(i, val.into_inner())
    }

    #[inline]
    unsafe fn replace_unchecked(&mut self, i: usize, val: Self::Element) {
        self.as_mut_unchecked()
            .replace_unchecked(i, val.into_inner())
    }

    #[inline]
    fn select(self, cond: Self::SimdBool, other: Self) -> Self {
        UnitQuaternion::new_unchecked(self.into_inner().select(cond, other.into_inner()))
    }
}
<|endoftext|>


<commit_before>// Copyright 2014 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.

use dot;
use rustc::mir::repr::*;
use std::borrow::IntoCow;

#[derive(Copy, Clone, PartialEq, Eq)]
pub struct EdgeIndex {
    source: BasicBlock,
    target: BasicBlock,
    index: usize,
}

impl<'a,'tcx> dot::Labeller<'a, BasicBlock, EdgeIndex> for Mir<'tcx> {
    fn graph_id(&'a self) -> dot::Id<'a> {
        dot::Id::new("Mir").unwrap()
    }

    fn node_id(&'a self, n: &BasicBlock) -> dot::Id<'a> {
        dot::Id::new(format!("BB{}", n.index())).unwrap()
    }

    fn node_shape(&'a self, _: &BasicBlock) -> Option<dot::LabelText<'a>> {
        Some(dot::LabelText::label("none"))
    }

    fn node_label(&'a self, &n: &BasicBlock) -> dot::LabelText<'a> {
        let mut buffer = String::new();
        buffer.push_str("
");

        buffer.push_str("
");
        buffer.push_str(&format!("{:?}", n));
        buffer.push_str("
");

        let data = self.basic_block_data(n);
        for statement in &data.statements {
            buffer.push_str("
");
            buffer.push_str(&escape(format!("{:?}", statement)));
            buffer.push_str("
");
        }

        buffer.push_str("
");
        buffer.push_str(&escape(format!("{:?}", &data.terminator)));
        buffer.push_str("
");

        buffer.push_str("
");

        dot::LabelText::html(buffer)
    }

    fn edge_label(&'a self, edge: &EdgeIndex) -> dot::LabelText<'a> {
        dot::LabelText::label(format!("{}", edge.index))
    }
}

impl<'a,'tcx> dot::GraphWalk<'a, BasicBlock, EdgeIndex> for Mir<'tcx> {
    fn nodes(&'a self) -> dot::Nodes<'a, BasicBlock> {
        self.all_basic_blocks().into_cow()
    }

    fn edges(&'a self) -> dot::Edges<'a, EdgeIndex> {
        self.all_basic_blocks()
            .into_iter()
            .flat_map(|source| {
                self.basic_block_data(source)
                    .terminator
                    .successors()
                    .iter()
                    .enumerate()
                    .map(move |(index, &target)| {
                        EdgeIndex {
                            source: source,
                            target: target,
                            index: index,
                        }
                    })
            })
            .collect::<Vec<_>>()
            .into_cow()
    }

    fn source(&'a self, edge: &EdgeIndex) -> BasicBlock {
        edge.source
    }

    fn target(&'a self, edge: &EdgeIndex) -> BasicBlock {
        edge.target
    }
}

fn escape(text: String) -> String {
    let text = dot::escape_html(&text);
    let text = all_to_subscript("Temp", text);
    let text = all_to_subscript("Var", text);
    let text = all_to_subscript("Arg", text);
    let text = all_to_subscript("BB", text);
    text
}

/// A call like `all_to_subscript("Temp", "Temp(123)")` will convert
/// to `Temp₁₂₃`.
fn all_to_subscript(header: &str, mut text: String) -> String {
    let mut offset = 0;
    while offset < text.len() {
        if let Some(text1) = to_subscript1(header, &text, &mut offset) {
            text = text1;
        }
    }
    return text;

    /// Looks for `Foo(\d*)` where `header=="Foo"` and replaces the `\d` with subscripts.
    /// Updates `offset` to point to the next location where we might want to search.
    /// Returns an updated string if changes were made, else None.
    fn to_subscript1(header: &str, text: &str, offset: &mut usize) -> Option<String> {
        let a = match text[*offset..].find(header) {
            None => {
                *offset = text.len();
                return None;
            }
            Some(a) => a + *offset,
        };

        // Example:
        //
        // header: "Foo"
        // text:   ....Foo(123)...
        //             ^  ^
        //             a  b

        let b = a + header.len();
        *offset = b;

        let mut chars = text[b..].chars();
        if Some('(') != chars.next() {
            return None;
        }

        let mut result = String::new();
        result.push_str(&text[..b]);

        while let Some(c) = chars.next() {
            if c == ')' {
                break;
            }
            if !c.is_digit(10) {
                return None;
            }

            // 0x208 is _0 in unicode, 0x209 is _1, etc
            const SUBSCRIPTS: &'static str = "₀₁₂₃₄₅₆₇₈₉";
            let n = (c as usize) - ('0' as usize);
            result.extend(SUBSCRIPTS.chars().skip(n).take(1));
        }

        result.extend(chars);
        return Some(result);
    }
}
<commit_msg>Auto merge of #30469 - nagisa:mir-gv-prettify, r=luqmana<commit_after>// Copyright 2014 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.

use dot;
use rustc::mir::repr::*;
use std::borrow::IntoCow;

#[derive(Copy, Clone, PartialEq, Eq)]
pub struct EdgeIndex {
    source: BasicBlock,
    target: BasicBlock,
    index: usize,
}

impl<'a,'tcx> dot::Labeller<'a, BasicBlock, EdgeIndex> for Mir<'tcx> {
    fn graph_id(&'a self) -> dot::Id<'a> {
        dot::Id::new("Mir").unwrap()
    }

    fn node_id(&'a self, n: &BasicBlock) -> dot::Id<'a> {
        dot::Id::new(format!("BB{}", n.index())).unwrap()
    }

    fn node_shape(&'a self, _: &BasicBlock) -> Option<dot::LabelText<'a>> {
        Some(dot::LabelText::label("none"))
    }

    fn node_label(&'a self, &n: &BasicBlock) -> dot::LabelText<'a> {
        let mut buffer = String::new();
        buffer.push_str("
");

        buffer.push_str("
");
        buffer.push_str(&escape(format!("{:?}", n)));
        buffer.push_str("
");

        let data = self.basic_block_data(n);
        for statement in &data.statements {
            buffer.push_str("
");
            buffer.push_str(&escape(format!("{:?}", statement)));
            buffer.push_str("
");
        }

        buffer.push_str("
");
        buffer.push_str(&escape(format!("{:?}", &data.terminator)));
        buffer.push_str("
");

        buffer.push_str("
");

        dot::LabelText::html(buffer)
    }

    fn edge_label(&'a self, edge: &EdgeIndex) -> dot::LabelText<'a> {
        dot::LabelText::label(format!("{}", edge.index))
    }
}

impl<'a,'tcx> dot::GraphWalk<'a, BasicBlock, EdgeIndex> for Mir<'tcx> {
    fn nodes(&'a self) -> dot::Nodes<'a, BasicBlock> {
        self.all_basic_blocks().into_cow()
    }

    fn edges(&'a self) -> dot::Edges<'a, EdgeIndex> {
        self.all_basic_blocks()
            .into_iter()
            .flat_map(|source| {
                self.basic_block_data(source)
                    .terminator
                    .successors()
                    .iter()
                    .enumerate()
                    .map(move |(index, &target)| {
                        EdgeIndex {
                            source: source,
                            target: target,
                            index: index,
                        }
                    })
            })
            .collect::<Vec<_>>()
            .into_cow()
    }

    fn source(&'a self, edge: &EdgeIndex) -> BasicBlock {
        edge.source
    }

    fn target(&'a self, edge: &EdgeIndex) -> BasicBlock {
        edge.target
    }
}

fn escape(text: String) -> String {
    let text = dot::escape_html(&text);
    let text = all_to_subscript("Temp", text);
    let text = all_to_subscript("Var", text);
    let text = all_to_subscript("Arg", text);
    let text = all_to_subscript("BB", text);
    text
}

/// A call like `all_to_subscript("Temp", "Temp(123)")` will convert
/// to `Temp₁₂₃`.
fn all_to_subscript(header: &str, mut text: String) -> String {
    let mut offset = 0;
    while offset < text.len() {
        if let Some(text1) = to_subscript1(header, &text, &mut offset) {
            text = text1;
        }
    }
    return text;

    /// Looks for `Foo(\d*)` where `header=="Foo"` and replaces the `\d` with subscripts.
    /// Updates `offset` to point to the next location where we might want to search.
    /// Returns an updated string if changes were made, else None.
    fn to_subscript1(header: &str, text: &str, offset: &mut usize) -> Option<String> {
        let a = match text[*offset..].find(header) {
            None => {
                *offset = text.len();
                return None;
            }
            Some(a) => a + *offset,
        };

        // Example:
        //
        // header: "Foo"
        // text:   ....Foo(123)...
        //             ^  ^
        //             a  b

        let b = a + header.len();
        *offset = b;

        let mut chars = text[b..].chars();
        if Some('(') != chars.next() {
            return None;
        }

        let mut result = String::new();
        result.push_str(&text[..b]);

        while let Some(c) = chars.next() {
            if c == ')' {
                break;
            }
            if !c.is_digit(10) {
                return None;
            }

            // 0x208 is _0 in unicode, 0x209 is _1, etc
            const SUBSCRIPTS: &'static str = "₀₁₂₃₄₅₆₇₈₉";
            let n = (c as usize) - ('0' as usize);
            result.extend(SUBSCRIPTS.chars().skip(n).take(1));
        }

        result.extend(chars);
        return Some(result);
    }
}
<|endoftext|>