<commit_before>//! # TreeView Sample
//!
//! This sample demonstrates how to create a TreeView with either a ListStore or TreeStore.

#![feature(globs)]
#![crate_type = "bin"]

extern crate rgtk;

use rgtk::*;
use rgtk::gtk::signals;

fn append_text_column(tree: &mut gtk::TreeView) {
    let column = gtk::TreeViewColumn::new().unwrap();
    let cell = gtk::CellRendererText::new().unwrap();
    column.pack_start(&cell, true);
    column.add_attribute(&cell, "text", 0);
    tree.append_column(&column);
}

fn main() {
    gtk::init();

    let mut window = gtk::Window::new(gtk::window_type::TopLevel).unwrap();
    window.set_title("TreeView Sample");
    window.set_window_position(gtk::window_position::Center);

    window.connect(signals::DeleteEvent::new(|_| {
        gtk::main_quit();
        true
    }));

    let hello = String::from_str("Hello world !");

    // left pane

    let mut left_tree = gtk::TreeView::new().unwrap();
    let column_types = [glib::ffi::g_type_string];
    let left_store = gtk::ListStore::new(column_types).unwrap();
    let left_model = left_store.get_model().unwrap();
    left_tree.set_model(&left_model);
    left_tree.set_headers_visible(false);
    append_text_column(&mut left_tree);

    for _ in range(0i, 10i) {
        let iter = gtk::TreeIter::new().unwrap();
        left_store.append(&iter);
        left_store.set_string(&iter, 0, "I'm in a list");
    }

    // right pane

    let mut right_tree = gtk::TreeView::new().unwrap();
    let column_types = [glib::ffi::g_type_string];
    let right_store = gtk::TreeStore::new(column_types).unwrap();
    let right_model = right_store.get_model().unwrap();
    right_tree.set_model(&right_model);
    right_tree.set_headers_visible(false);
    append_text_column(&mut right_tree);
    let value = gtk::GValue::new().unwrap();

    value.init(gtk::g_type::String);
    value.set(&hello);

    for _ in range(0i, 10i) {
        let iter = gtk::TreeIter::new().unwrap();
        right_store.append(&iter, None);
        right_store.set_value(&iter, 0, &value);

        let child_iter = gtk::TreeIter::new().unwrap();
        right_store.append(&child_iter, Some(&iter));
        right_store.set_string(&child_iter, 0, "I'm a child node");
    }

    // display the panes

    let mut split_pane = gtk::Box::new(gtk::orientation::Horizontal, 10).unwrap();
    split_pane.set_size_request(-1, -1);
    split_pane.add(&left_tree);
    split_pane.add(&right_tree);

    window.add(&split_pane);
    window.show_all();
    gtk::main();
}
<commit_msg>Add get example<commit_after>//! # TreeView Sample
//!
//! This sample demonstrates how to create a TreeView with either a ListStore or TreeStore.

#![feature(globs)]
#![crate_type = "bin"]

extern crate rgtk;

use rgtk::*;
use rgtk::gtk::signals;

fn append_text_column(tree: &mut gtk::TreeView) {
    let column = gtk::TreeViewColumn::new().unwrap();
    let cell = gtk::CellRendererText::new().unwrap();
    column.pack_start(&cell, true);
    column.add_attribute(&cell, "text", 0);
    tree.append_column(&column);
}

fn main() {
    gtk::init();

    let mut window = gtk::Window::new(gtk::window_type::TopLevel).unwrap();
    window.set_title("TreeView Sample");
    window.set_window_position(gtk::window_position::Center);

    window.connect(signals::DeleteEvent::new(|_| {
        gtk::main_quit();
        true
    }));

    let hello = String::from_str("Hello world !");

    // left pane

    let mut left_tree = gtk::TreeView::new().unwrap();
    let column_types = [glib::ffi::g_type_string];
    let left_store = gtk::ListStore::new(column_types).unwrap();
    let left_model = left_store.get_model().unwrap();
    left_tree.set_model(&left_model);
    left_tree.set_headers_visible(false);
    append_text_column(&mut left_tree);

    for _ in range(0i, 10i) {
        let iter = gtk::TreeIter::new().unwrap();
        left_store.append(&iter);
        left_store.set_string(&iter, 0, "I'm in a list");
    }

    // right pane

    let mut right_tree = gtk::TreeView::new().unwrap();
    let column_types = [glib::ffi::g_type_string];
    let right_store = gtk::TreeStore::new(column_types).unwrap();
    let right_model = right_store.get_model().unwrap();
    right_tree.set_model(&right_model);
    right_tree.set_headers_visible(false);
    append_text_column(&mut right_tree);
    let value = gtk::GValue::new().unwrap();

    value.init(gtk::g_type::String);
    value.set(&hello);

    println!("gvalue.get example : {}", value.get::<String>());

    for _ in range(0i, 10i) {
        let iter = gtk::TreeIter::new().unwrap();
        right_store.append(&iter, None);
        right_store.set_value(&iter, 0, &value);

        let child_iter = gtk::TreeIter::new().unwrap();
        right_store.append(&child_iter, Some(&iter));
        right_store.set_string(&child_iter, 0, "I'm a child node");
    }

    // display the panes

    let mut split_pane = gtk::Box::new(gtk::orientation::Horizontal, 10).unwrap();
    split_pane.set_size_request(-1, -1);
    split_pane.add(&left_tree);
    split_pane.add(&right_tree);

    window.add(&split_pane);
    window.show_all();
    gtk::main();
}
<|endoftext|>


<commit_before>use std::net::SocketAddr;
use std::time::SystemTime;
use super::super::crypto::{Hash, PublicKey, Signature};
use super::{RawMessage, BitVec};
use super::super::blockchain;
use serde::{Serialize, Serializer, Deserialize, Deserializer};
use ::messages::utils::{U64, SystemTimeSerdeHelper};

pub const CONSENSUS: u16 = 0;

pub const CONNECT_MESSAGE_ID: u16 = 0;
pub const STATUS_MESSAGE_ID: u16 = 1;

pub const PROPOSE_MESSAGE_ID: u16 = 2;
pub const PREVOTE_MESSAGE_ID: u16 = 3;
pub const PRECOMMIT_MESSAGE_ID: u16 = 4;
pub const BLOCK_MESSAGE_ID: u16 = 5;

pub const REQUEST_PROPOSE_MESSAGE_ID: u16 = 6;
pub const REQUEST_TRANSACTIONS_MESSAGE_ID: u16 = 7;
pub const REQUEST_PREVOTES_MESSAGE_ID: u16 = 8;
pub const REQUEST_PEERS_MESSAGE_ID: u16 = 10;
pub const REQUEST_BLOCK_MESSAGE_ID: u16 = 11;

// когда присоединяются узлы
message! {
    Connect {
        const TYPE = CONSENSUS;
        const ID = CONNECT_MESSAGE_ID;
        const SIZE = 50;

        pub_key:        &PublicKey  [00 => 32]
        addr:           SocketAddr  [32 => 38]
        time:           SystemTime  [38 => 50]
    }
}

// консенсус
message! {
    Propose {
        const TYPE = CONSENSUS;
        const ID = PROPOSE_MESSAGE_ID;
        const SIZE = 56;

        validator:      u32         [00 => 04]
        height:         u64         [04 => 12]
        round:          u32         [12 => 16]
        prev_hash:      &Hash       [16 => 48]
        transactions:   &[Hash]     [48 => 56]
    }
}

// консенсус
message! {
    Prevote {
        const TYPE = CONSENSUS;
        const ID = PREVOTE_MESSAGE_ID;
        const SIZE = 52;

        validator:      u32         [00 => 04]
        height:         u64         [04 => 12]
        round:          u32         [12 => 16]
        propose_hash:   &Hash       [16 => 48]
        locked_round:   u32         [48 => 52]
    }
}

// консенсус
message! {
    Precommit {
        const TYPE = CONSENSUS;
        const ID = PRECOMMIT_MESSAGE_ID;
        const SIZE = 96;

        validator:      u32         [00 => 04]
        height:         u64         [08 => 16]
        round:          u32         [16 => 20]
        propose_hash:   &Hash       [20 => 52]
        block_hash:     &Hash       [52 => 84]
        time:           SystemTime  [84 => 96]
    }
}

#[derive(Serialize, Deserialize)]
struct PrecommitSerdeHelper {
    body: PrecommitBodySerdeHelper,
    signature: Signature,
}

#[derive(Serialize, Deserialize)]
struct PrecommitBodySerdeHelper {
   validator: u32,
   height: U64,
   round: u32,
   propose_hash: Hash,
   block_hash: Hash,
   time: SystemTimeSerdeHelper,
}

impl Serialize for Precommit {
    fn serialize<S>(&self, ser: &mut S) -> Result<(), S::Error>
        where S: Serializer
    {
        let body = PrecommitBodySerdeHelper{
            validator: self.validator(),
            height: U64(self.height()),
            round: self.round(),
            propose_hash: *self.propose_hash(),
            block_hash: *self.block_hash(),
            time: SystemTimeSerdeHelper(self.time()),
        };
        let helper = PrecommitSerdeHelper {
            body: body,
            signature: *self.raw.signature(),
        };
        helper.serialize(ser)
    }
}

impl Deserialize for Precommit {
    fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
        where D: Deserializer
    {
        let h = <PrecommitSerdeHelper>::deserialize(deserializer)?;

        let precommit = Precommit::new_with_signature(h.body.validator, h.body.height.0, h.body.round, &h.body.propose_hash, &h.body.block_hash, h.body.time.0, &h.signature);
        Ok(precommit)
    }
}

// сообщение о текущем состоянии
message! {
    Status {
        const TYPE = CONSENSUS;
        const ID = STATUS_MESSAGE_ID;
        const SIZE = 44;

        validator:      u32         [00 => 04]
        height:         u64         [04 => 12]
        last_hash:      &Hash       [12 => 44]
    }
}

// ответ на requestblock
message! {
    Block {
        const TYPE = CONSENSUS;
        const ID = BLOCK_MESSAGE_ID;
        const SIZE = 88;

        from:           &PublicKey          [00 => 32]
        to:             &PublicKey          [32 => 64]
        block:          blockchain::Block   [64 => 72]
        precommits:     Vec<Precommit>      [72 => 80]
        transactions:   Vec<RawMessage>     [80 => 88]
    }
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct BlockProof {
    pub block: blockchain::Block,
    pub precommits: Vec<Precommit>,
}

// запрос на получение предложения
message! {
    RequestPropose {
        const TYPE = CONSENSUS;
        const ID = REQUEST_PROPOSE_MESSAGE_ID;
        const SIZE = 104;

        from:           &PublicKey  [00 => 32]
        to:             &PublicKey  [32 => 64]
        height:         u64         [64 => 72]
        propose_hash:   &Hash       [72 => 104]
    }
}

// запрос транзакций по списку hash
message! {
    RequestTransactions {
        const TYPE = CONSENSUS;
        const ID = REQUEST_TRANSACTIONS_MESSAGE_ID;
        const SIZE = 72;

        from:           &PublicKey  [00 => 32]
        to:             &PublicKey  [32 => 64]
        txs:            &[Hash]     [64 => 72]
    }
}

// запрос prevotes
message! {
    RequestPrevotes {
        const TYPE = CONSENSUS;
        const ID = REQUEST_PREVOTES_MESSAGE_ID;
        const SIZE = 116;

        from:           &PublicKey  [00 => 32]
        to:             &PublicKey  [32 => 64]
        height:         u64         [64 => 72]
        round:          u32         [72 => 76]
        propose_hash:   &Hash       [76 => 108]
        validators:     BitVec      [108 => 116]
    }
}

// запрос узлов с которыми соединён
message! {
    RequestPeers {
        const TYPE = CONSENSUS;
        const ID = REQUEST_PEERS_MESSAGE_ID;
        const SIZE = 64;

        from:           &PublicKey  [00 => 32]
        to:             &PublicKey  [32 => 64]
    }
}
// запрос блоков
message! {
    RequestBlock {
        const TYPE = CONSENSUS;
        const ID = REQUEST_BLOCK_MESSAGE_ID;
        const SIZE = 72;

        from:           &PublicKey  [00 => 32]
        to:             &PublicKey  [32 => 64]
        height:         u64         [64 => 72]
    }
}
<commit_msg>Update messages IDs<commit_after>use std::net::SocketAddr;
use std::time::SystemTime;
use super::super::crypto::{Hash, PublicKey, Signature};
use super::{RawMessage, BitVec};
use super::super::blockchain;
use serde::{Serialize, Serializer, Deserialize, Deserializer};
use ::messages::utils::{U64, SystemTimeSerdeHelper};

pub const CONSENSUS: u16 = 0;

pub const CONNECT_MESSAGE_ID: u16 = 0;
pub const STATUS_MESSAGE_ID: u16 = 1;

pub const PROPOSE_MESSAGE_ID: u16 = 2;
pub const PREVOTE_MESSAGE_ID: u16 = 3;
pub const PRECOMMIT_MESSAGE_ID: u16 = 4;
pub const BLOCK_MESSAGE_ID: u16 = 5;

pub const REQUEST_PROPOSE_MESSAGE_ID: u16 = 6;
pub const REQUEST_TRANSACTIONS_MESSAGE_ID: u16 = 7;
pub const REQUEST_PREVOTES_MESSAGE_ID: u16 = 8;
pub const REQUEST_PEERS_MESSAGE_ID: u16 = 9;
pub const REQUEST_BLOCK_MESSAGE_ID: u16 = 10;

// когда присоединяются узлы
message! {
    Connect {
        const TYPE = CONSENSUS;
        const ID = CONNECT_MESSAGE_ID;
        const SIZE = 50;

        pub_key:        &PublicKey  [00 => 32]
        addr:           SocketAddr  [32 => 38]
        time:           SystemTime  [38 => 50]
    }
}

// консенсус
message! {
    Propose {
        const TYPE = CONSENSUS;
        const ID = PROPOSE_MESSAGE_ID;
        const SIZE = 56;

        validator:      u32         [00 => 04]
        height:         u64         [04 => 12]
        round:          u32         [12 => 16]
        prev_hash:      &Hash       [16 => 48]
        transactions:   &[Hash]     [48 => 56]
    }
}

// консенсус
message! {
    Prevote {
        const TYPE = CONSENSUS;
        const ID = PREVOTE_MESSAGE_ID;
        const SIZE = 52;

        validator:      u32         [00 => 04]
        height:         u64         [04 => 12]
        round:          u32         [12 => 16]
        propose_hash:   &Hash       [16 => 48]
        locked_round:   u32         [48 => 52]
    }
}

// консенсус
message! {
    Precommit {
        const TYPE = CONSENSUS;
        const ID = PRECOMMIT_MESSAGE_ID;
        const SIZE = 96;

        validator:      u32         [00 => 04]
        height:         u64         [08 => 16]
        round:          u32         [16 => 20]
        propose_hash:   &Hash       [20 => 52]
        block_hash:     &Hash       [52 => 84]
        time:           SystemTime  [84 => 96]
    }
}

#[derive(Serialize, Deserialize)]
struct PrecommitSerdeHelper {
    body: PrecommitBodySerdeHelper,
    signature: Signature,
}

#[derive(Serialize, Deserialize)]
struct PrecommitBodySerdeHelper {
   validator: u32,
   height: U64,
   round: u32,
   propose_hash: Hash,
   block_hash: Hash,
   time: SystemTimeSerdeHelper,
}

impl Serialize for Precommit {
    fn serialize<S>(&self, ser: &mut S) -> Result<(), S::Error>
        where S: Serializer
    {
        let body = PrecommitBodySerdeHelper{
            validator: self.validator(),
            height: U64(self.height()),
            round: self.round(),
            propose_hash: *self.propose_hash(),
            block_hash: *self.block_hash(),
            time: SystemTimeSerdeHelper(self.time()),
        };
        let helper = PrecommitSerdeHelper {
            body: body,
            signature: *self.raw.signature(),
        };
        helper.serialize(ser)
    }
}

impl Deserialize for Precommit {
    fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
        where D: Deserializer
    {
        let h = <PrecommitSerdeHelper>::deserialize(deserializer)?;

        let precommit = Precommit::new_with_signature(h.body.validator, h.body.height.0, h.body.round, &h.body.propose_hash, &h.body.block_hash, h.body.time.0, &h.signature);
        Ok(precommit)
    }
}

// сообщение о текущем состоянии
message! {
    Status {
        const TYPE = CONSENSUS;
        const ID = STATUS_MESSAGE_ID;
        const SIZE = 44;

        validator:      u32         [00 => 04]
        height:         u64         [04 => 12]
        last_hash:      &Hash       [12 => 44]
    }
}

// ответ на requestblock
message! {
    Block {
        const TYPE = CONSENSUS;
        const ID = BLOCK_MESSAGE_ID;
        const SIZE = 88;

        from:           &PublicKey          [00 => 32]
        to:             &PublicKey          [32 => 64]
        block:          blockchain::Block   [64 => 72]
        precommits:     Vec<Precommit>      [72 => 80]
        transactions:   Vec<RawMessage>     [80 => 88]
    }
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct BlockProof {
    pub block: blockchain::Block,
    pub precommits: Vec<Precommit>,
}

// запрос на получение предложения
message! {
    RequestPropose {
        const TYPE = CONSENSUS;
        const ID = REQUEST_PROPOSE_MESSAGE_ID;
        const SIZE = 104;

        from:           &PublicKey  [00 => 32]
        to:             &PublicKey  [32 => 64]
        height:         u64         [64 => 72]
        propose_hash:   &Hash       [72 => 104]
    }
}

// запрос транзакций по списку hash
message! {
    RequestTransactions {
        const TYPE = CONSENSUS;
        const ID = REQUEST_TRANSACTIONS_MESSAGE_ID;
        const SIZE = 72;

        from:           &PublicKey  [00 => 32]
        to:             &PublicKey  [32 => 64]
        txs:            &[Hash]     [64 => 72]
    }
}

// запрос prevotes
message! {
    RequestPrevotes {
        const TYPE = CONSENSUS;
        const ID = REQUEST_PREVOTES_MESSAGE_ID;
        const SIZE = 116;

        from:           &PublicKey  [00 => 32]
        to:             &PublicKey  [32 => 64]
        height:         u64         [64 => 72]
        round:          u32         [72 => 76]
        propose_hash:   &Hash       [76 => 108]
        validators:     BitVec      [108 => 116]
    }
}

// запрос узлов с которыми соединён
message! {
    RequestPeers {
        const TYPE = CONSENSUS;
        const ID = REQUEST_PEERS_MESSAGE_ID;
        const SIZE = 64;

        from:           &PublicKey  [00 => 32]
        to:             &PublicKey  [32 => 64]
    }
}
// запрос блоков
message! {
    RequestBlock {
        const TYPE = CONSENSUS;
        const ID = REQUEST_BLOCK_MESSAGE_ID;
        const SIZE = 72;

        from:           &PublicKey  [00 => 32]
        to:             &PublicKey  [32 => 64]
        height:         u64         [64 => 72]
    }
}
<|endoftext|>


<commit_before>// program should terminate even if a thread is blocked on I/O.
// https://github.com/fortanix/rust-sgx/issues/109

// run-pass
// ignore-emscripten no threads support

use std::{net::TcpListener, sync::mpsc, thread};

fn main() {
    let (tx, rx) = mpsc::channel();
    thread::spawn(move || {
        let listen = TcpListener::bind("0.0.0.0:0").unwrap();
        tx.send(()).unwrap();
        while let Ok(_) = listen.accept() {}
    });
    rx.recv().unwrap();
    for _ in 0..3 { thread::yield_now(); }
    println!("Exiting main thread");
}
<commit_msg>Auto merge of #86669 - Smittyvb:satisfy-windows-defender, r=Mark-Simulacrum<commit_after>// program should terminate even if a thread is blocked on I/O.
// https://github.com/fortanix/rust-sgx/issues/109

// run-pass
// ignore-emscripten no threads support

use std::{net::TcpListener, sync::mpsc, thread};

fn main() {
    let (tx, rx) = mpsc::channel();
    thread::spawn(move || {
        let listen = TcpListener::bind("127.0.0.1:0").unwrap();
        tx.send(()).unwrap();
        while let Ok(_) = listen.accept() {}
    });
    rx.recv().unwrap();
    for _ in 0..3 { thread::yield_now(); }
    println!("Exiting main thread");
}
<|endoftext|>


<commit_before>//! `GET /_matrix/federation/*/query/profile`
//!
//! Endpoint to query profile information with a user id and optional field.

pub mod v1 {
    //! `/v1/` ([spec])
    //!
    //! [spec]: https://spec.matrix.org/v1.2/server-server-api/#get_matrixfederationv1queryprofile

    use ruma_common::{api::ruma_api, serde::StringEnum, MxcUri, UserId};

    use crate::PrivOwnedStr;

    ruma_api! {
        metadata: {
            description: "Get profile information, such as a display name or avatar, for a given user.",
            name: "get_profile_information",
            method: GET,
            stable_path: "/_matrix/federation/v1/query/profile",
            rate_limited: false,
            authentication: ServerSignatures,
            added: 1.0,
        }

        request: {
            /// User ID to query.
            #[ruma_api(query)]
            pub user_id: &'a UserId,

            /// Profile field to query.
            #[serde(skip_serializing_if = "Option::is_none")]
            #[ruma_api(query)]
            pub field: Option<&'a ProfileField>,
        }

        #[derive(Default)]
        response: {
            /// Display name of the user.
            #[serde(skip_serializing_if = "Option::is_none")]
            pub displayname: Option<String>,

            /// Avatar URL for the user's avatar.
            ///
            /// If you activate the `compat` feature, this field being an empty string in JSON will result
            /// in `None` here during deserialization.
            #[serde(skip_serializing_if = "Option::is_none")]
            #[cfg_attr(
                feature = "compat",
                serde(default, deserialize_with = "ruma_common::serde::empty_string_as_none")
            )]
            pub avatar_url: Option<Box<MxcUri>>,

            /// The [BlurHash](https://blurha.sh) for the avatar pointed to by `avatar_url`.
            ///
            /// This uses the unstable prefix in
            /// [MSC2448](https://github.com/matrix-org/matrix-spec-proposals/pull/2448).
            #[cfg(feature = "unstable-msc2448")]
            #[serde(rename = "xyz.amorgan.blurhash", skip_serializing_if = "Option::is_none")]
            pub blurhash: Option<String>,
        }
    }

    impl<'a> Request<'a> {
        /// Creates a new `Request` with the given user id.
        pub fn new(user_id: &'a UserId) -> Self {
            Self { user_id, field: None }
        }
    }

    impl Response {
        /// Creates an empty `Response`.
        pub fn new() -> Self {
            Default::default()
        }
    }

    /// Profile fields to specify in query.
    ///
    /// This type can hold an arbitrary string. To check for formats that are not available as a
    /// documented variant here, use its string representation, obtained through `.as_str()`.
    #[derive(Clone, Debug, PartialEq, Eq, StringEnum)]
    #[non_exhaustive]
    pub enum ProfileField {
        /// Display name of the user.
        #[ruma_enum(rename = "displayname")]
        DisplayName,

        /// Avatar URL for the user's avatar.
        #[ruma_enum(rename = "avatar_url")]
        AvatarUrl,

        #[doc(hidden)]
        _Custom(PrivOwnedStr),
    }

    impl ProfileField {
        /// Creates a string slice from this `ProfileField`.
        pub fn as_str(&self) -> &str {
            self.as_ref()
        }
    }
}
<commit_msg>federation-api: Deserialize stable names for unstable features<commit_after>//! `GET /_matrix/federation/*/query/profile`
//!
//! Endpoint to query profile information with a user id and optional field.

pub mod v1 {
    //! `/v1/` ([spec])
    //!
    //! [spec]: https://spec.matrix.org/v1.2/server-server-api/#get_matrixfederationv1queryprofile

    use ruma_common::{api::ruma_api, serde::StringEnum, MxcUri, UserId};

    use crate::PrivOwnedStr;

    ruma_api! {
        metadata: {
            description: "Get profile information, such as a display name or avatar, for a given user.",
            name: "get_profile_information",
            method: GET,
            stable_path: "/_matrix/federation/v1/query/profile",
            rate_limited: false,
            authentication: ServerSignatures,
            added: 1.0,
        }

        request: {
            /// User ID to query.
            #[ruma_api(query)]
            pub user_id: &'a UserId,

            /// Profile field to query.
            #[serde(skip_serializing_if = "Option::is_none")]
            #[ruma_api(query)]
            pub field: Option<&'a ProfileField>,
        }

        #[derive(Default)]
        response: {
            /// Display name of the user.
            #[serde(skip_serializing_if = "Option::is_none")]
            pub displayname: Option<String>,

            /// Avatar URL for the user's avatar.
            ///
            /// If you activate the `compat` feature, this field being an empty string in JSON will result
            /// in `None` here during deserialization.
            #[serde(skip_serializing_if = "Option::is_none")]
            #[cfg_attr(
                feature = "compat",
                serde(default, deserialize_with = "ruma_common::serde::empty_string_as_none")
            )]
            pub avatar_url: Option<Box<MxcUri>>,

            /// The [BlurHash](https://blurha.sh) for the avatar pointed to by `avatar_url`.
            ///
            /// This uses the unstable prefix in
            /// [MSC2448](https://github.com/matrix-org/matrix-spec-proposals/pull/2448).
            #[cfg(feature = "unstable-msc2448")]
            #[serde(
                rename = "xyz.amorgan.blurhash",
                alias = "blurhash",
                skip_serializing_if = "Option::is_none"
            )]
            pub blurhash: Option<String>,
        }
    }

    impl<'a> Request<'a> {
        /// Creates a new `Request` with the given user id.
        pub fn new(user_id: &'a UserId) -> Self {
            Self { user_id, field: None }
        }
    }

    impl Response {
        /// Creates an empty `Response`.
        pub fn new() -> Self {
            Default::default()
        }
    }

    /// Profile fields to specify in query.
    ///
    /// This type can hold an arbitrary string. To check for formats that are not available as a
    /// documented variant here, use its string representation, obtained through `.as_str()`.
    #[derive(Clone, Debug, PartialEq, Eq, StringEnum)]
    #[non_exhaustive]
    pub enum ProfileField {
        /// Display name of the user.
        #[ruma_enum(rename = "displayname")]
        DisplayName,

        /// Avatar URL for the user's avatar.
        #[ruma_enum(rename = "avatar_url")]
        AvatarUrl,

        #[doc(hidden)]
        _Custom(PrivOwnedStr),
    }

    impl ProfileField {
        /// Creates a string slice from this `ProfileField`.
        pub fn as_str(&self) -> &str {
            self.as_ref()
        }
    }
}
<|endoftext|>


<commit_before>use regex::Regex;
use std::fs::File;
use std::io::prelude::*;
use std::io::Error;
use utils;

#[derive(Debug, PartialEq)]
pub struct OSRelease {
    pub distro: Option<String>,
    pub version: Option<String>,
}

fn read_file(filename: &str) -> Result<String, Error> {
    let mut file = File::open(filename)?;
    let mut contents = String::new();
    file.read_to_string(&mut contents)?;
    Ok(contents)
}

pub fn retrieve() -> Option<OSRelease> {
    if utils::file_exists("/etc/os-release") {
        if let Ok(release) = read_file("/etc/os-release") {
            Some(parse(release))
        } else {
            None
        }
    } else {
        if let Ok(release) = read_file("/usr/lib/os-release") {
            Some(parse(release))
        } else {
            None
        }
    }
}

pub fn parse(file: String) -> OSRelease {
    let distrib_regex = Regex::new(r#"NAME="(\w+)"#).unwrap();
    let version_regex = Regex::new(r#"VERSION_ID="?([\w\.]+)"#).unwrap();

    let distro = match distrib_regex.captures_iter(&file).next() {
        Some(m) => match m.get(1) {
            Some(distro) => Some(distro.as_str().to_owned()),
            None => None,
        },
        None => None,
    };

    let version = match version_regex.captures_iter(&file).next() {
        Some(m) => match m.get(1) {
            Some(version) => Some(version.as_str().to_owned()),
            None => None,
        },
        None => None,
    };

    OSRelease { distro, version }
}

mod tests {
    use super::*;

    #[test]
    fn parse_ubuntu_18_04_os_release() {
        let sample = "\
        NAME=\"Ubuntu\"\
        VERSION=\"18.04 LTS (Bionic Beaver)\"
        ID=ubuntu
        ID_LIKE=debian
        PRETTY_NAME=\"Ubuntu 18.04 LTS\"\
        VERSION_ID=\"18.04\"\
        HOME_URL=\"https://www.ubuntu.com/\"\
        SUPPORT_URL=\"https://help.ubuntu.com/\"\
        BUG_REPORT_URL=\"https://bugs.launchpad.net/ubuntu\"\
        PRIVACY_POLICY_URL=\"https://www.ubuntu.com/legal/terms-and-policies/privacy-policy\"\
        VERSION_CODENAME=bionic
        UBUNTU_CODENAME=bionic
        ".to_string();

        assert_eq!(
            parse(sample),
            OSRelease {
                distro: Some("Ubuntu".to_string()),
                version: Some("18.04".to_string()),
            }
        );
    }

    #[test]
    fn parse_alpine_3_9_5_os_release() {
        let sample = "\
        NAME=\"Alpine Linux\"
        ID=alpine
        VERSION_ID=3.9.5
        PRETTY_NAME=\"Alpine Linux v3.9\"
        HOME_URL=\"https://alpinelinux.org/\"
        BUG_REPORT_URL=\"https://bugs.alpinelinux.org/\"
        ".to_string();

        assert_eq!(
            parse(sample),
            OSRelease {
                distro: Some("Alpine".to_string()),
                version: Some("3.9.5".to_string()),
            }
        );
    }

    #[test]
    fn parse_deepin_20_3_os_release() {
        let sample = "\
        PRETTY_NAME=\"Deepin 20.3\"
        NAME=\"Deepin\"
        VERSION_ID=\"20.3\"
        VERSION=\"20.3\"
        ID=Deepin
        HOME_URL=\"https://www.deepin.org/\"
        ".to_string();

        assert_eq!(
            parse(sample),
            OSRelease {
                distro: Some("Deepin".to_string()),
                version: Some("20.3".to_string()),
            }
        );
    }

    #[test]
    fn parse_kali_2021_4_os_release() {
        let sample = "\
        PRETTY_NAME=\"Kali Linux GNU/Linux Rolling\"
        NAME=\"Kali GNU/Linux\"
        ID=kali
        VERSION=\"2021.4\"
        VERSION_ID=\"2021.4\"
        VERSION_CODENAME=\"kali-rolling\"
        ID_LIKE=debian
        HOME_URL=\"https://www.kali.org/\"
        SUPPORT_URL=\"https://forums.kali.org/\"
        BUG_REPORT_URL=\"https://bugs.kali.org\"
        ".to_string();

        assert_eq!(
            parse(sample),
            OSRelease {
                distro: Some("Kali".to_string()),
                version: Some("2021.4".to_string()),
            }
        );
    }
}
<commit_msg>Updated NAME<commit_after>use regex::Regex;
use std::fs::File;
use std::io::prelude::*;
use std::io::Error;
use utils;

#[derive(Debug, PartialEq)]
pub struct OSRelease {
    pub distro: Option<String>,
    pub version: Option<String>,
}

fn read_file(filename: &str) -> Result<String, Error> {
    let mut file = File::open(filename)?;
    let mut contents = String::new();
    file.read_to_string(&mut contents)?;
    Ok(contents)
}

pub fn retrieve() -> Option<OSRelease> {
    if utils::file_exists("/etc/os-release") {
        if let Ok(release) = read_file("/etc/os-release") {
            Some(parse(release))
        } else {
            None
        }
    } else {
        if let Ok(release) = read_file("/usr/lib/os-release") {
            Some(parse(release))
        } else {
            None
        }
    }
}

pub fn parse(file: String) -> OSRelease {
    let distrib_regex = Regex::new(r#"NAME="(\w+)"#).unwrap();
    let version_regex = Regex::new(r#"VERSION_ID="?([\w\.]+)"#).unwrap();

    let distro = match distrib_regex.captures_iter(&file).next() {
        Some(m) => match m.get(1) {
            Some(distro) => Some(distro.as_str().to_owned()),
            None => None,
        },
        None => None,
    };

    let version = match version_regex.captures_iter(&file).next() {
        Some(m) => match m.get(1) {
            Some(version) => Some(version.as_str().to_owned()),
            None => None,
        },
        None => None,
    };

    OSRelease { distro, version }
}

mod tests {
    use super::*;

    #[test]
    fn parse_ubuntu_18_04_os_release() {
        let sample = "\
        NAME=\"Ubuntu\"\
        VERSION=\"18.04 LTS (Bionic Beaver)\"
        ID=ubuntu
        ID_LIKE=debian
        PRETTY_NAME=\"Ubuntu 18.04 LTS\"\
        VERSION_ID=\"18.04\"\
        HOME_URL=\"https://www.ubuntu.com/\"\
        SUPPORT_URL=\"https://help.ubuntu.com/\"\
        BUG_REPORT_URL=\"https://bugs.launchpad.net/ubuntu\"\
        PRIVACY_POLICY_URL=\"https://www.ubuntu.com/legal/terms-and-policies/privacy-policy\"\
        VERSION_CODENAME=bionic
        UBUNTU_CODENAME=bionic
        ".to_string();

        assert_eq!(
            parse(sample),
            OSRelease {
                distro: Some("Ubuntu".to_string()),
                version: Some("18.04".to_string()),
            }
        );
    }

    #[test]
    fn parse_alpine_3_9_5_os_release() {
        let sample = "\
        NAME=\"Alpine Linux\"
        ID=alpine
        VERSION_ID=3.9.5
        PRETTY_NAME=\"Alpine Linux v3.9\"
        HOME_URL=\"https://alpinelinux.org/\"
        BUG_REPORT_URL=\"https://bugs.alpinelinux.org/\"
        ".to_string();

        assert_eq!(
            parse(sample),
            OSRelease {
                distro: Some("Alpine".to_string()),
                version: Some("3.9.5".to_string()),
            }
        );
    }

    #[test]
    fn parse_deepin_20_3_os_release() {
        let sample = "\
        PRETTY_NAME=\"Deepin 20.3\"
        NAME=\"Deepin\"
        VERSION_ID=\"20.3\"
        VERSION=\"20.3\"
        ID=Deepin
        HOME_URL=\"https://www.deepin.org/\"
        ".to_string();

        assert_eq!(
            parse(sample),
            OSRelease {
                distro: Some("Deepin".to_string()),
                version: Some("20.3".to_string()),
            }
        );
    }

    #[test]
    fn parse_kali_2021_4_os_release() {
        let sample = "\
        PRETTY_NAME=\"Kali Linux GNU/Linux Rolling\"
        NAME=\"Kali\"
        ID=kali
        VERSION=\"2021.4\"
        VERSION_ID=\"2021.4\"
        VERSION_CODENAME=\"kali-rolling\"
        ID_LIKE=debian
        HOME_URL=\"https://www.kali.org/\"
        SUPPORT_URL=\"https://forums.kali.org/\"
        BUG_REPORT_URL=\"https://bugs.kali.org\"
        ".to_string();

        assert_eq!(
            parse(sample),
            OSRelease {
                distro: Some("Kali".to_string()),
                version: Some("2021.4".to_string()),
            }
        );
    }
}
<|endoftext|>


<commit_before>//! Types for the *m.ignored_user_list* event.

use ruma_identifiers::UserId;
use serde::{Deserialize, Serialize};

use crate::{EventType, FromRaw};

/// A list of users to ignore.
#[derive(Clone, Debug, PartialEq, Serialize)]
#[serde(rename = "m.ignored_user_list", tag = "type")]
pub struct IgnoredUserListEvent {
    /// The event's content.
    pub content: IgnoredUserListEventContent,
}

impl FromRaw for IgnoredUserListEvent {
    type Raw = raw::IgnoredUserListEvent;

    fn from_raw(raw: raw::IgnoredUserListEvent) -> Self {
        Self {
            content: FromRaw::from_raw(raw.content),
        }
    }
}

/// The payload for `IgnoredUserListEvent`.
#[derive(Clone, Debug, PartialEq, Serialize)]
pub struct IgnoredUserListEventContent {
    /// A list of users to ignore.
    #[serde(with = "ruma_serde::vec_as_map_of_empty")]
    pub ignored_users: Vec<UserId>,
}

impl FromRaw for IgnoredUserListEventContent {
    type Raw = raw::IgnoredUserListEventContent;

    fn from_raw(raw: raw::IgnoredUserListEventContent) -> Self {
        Self {
            ignored_users: raw.ignored_users,
        }
    }
}

impl_event!(
    IgnoredUserListEvent,
    IgnoredUserListEventContent,
    EventType::IgnoredUserList
);

pub(crate) mod raw {
    use super::*;

    /// A list of users to ignore.
    #[derive(Clone, Debug, Deserialize)]
    pub struct IgnoredUserListEvent {
        /// The event's content.
        pub content: IgnoredUserListEventContent,
    }

    /// The payload for `IgnoredUserListEvent`.
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct IgnoredUserListEventContent {
        /// A list of users to ignore.
        #[serde(with = "ruma_serde::vec_as_map_of_empty")]
        pub ignored_users: Vec<UserId>,
    }
}

#[cfg(test)]
mod tests {
    use std::convert::TryFrom;

    use ruma_identifiers::UserId;
    use serde_json::{from_value as from_json_value, json, to_value as to_json_value};

    use super::{IgnoredUserListEvent, IgnoredUserListEventContent};
    use crate::EventJson;

    #[test]
    fn serialization() {
        let ignored_user_list_event = IgnoredUserListEvent {
            content: IgnoredUserListEventContent {
                ignored_users: vec![UserId::try_from("@carl:example.com").unwrap()],
            },
        };

        let json_data = json!({
            "content": {
                "ignored_users": {
                    "@carl:example.com": {}
                }
            },
            "type": "m.ignored_user_list"
        });

        assert_eq!(to_json_value(ignored_user_list_event).unwrap(), json_data);
    }

    #[test]
    fn deserialization() {
        let json_data = json!({
            "content": {
                "ignored_users": {
                    "@carl:example.com": {}
                }
            },
            "type": "m.ignored_user_list"
        });

        let actual = from_json_value::<EventJson<IgnoredUserListEvent>>(json_data)
            .unwrap()
            .deserialize()
            .unwrap();

        let expected = IgnoredUserListEvent {
            content: IgnoredUserListEventContent {
                ignored_users: vec![UserId::try_from("@carl:example.com").unwrap()],
            },
        };

        assert_eq!(actual, expected);
    }
}
<commit_msg>Update ignored_user_list tests<commit_after>//! Types for the *m.ignored_user_list* event.

use ruma_identifiers::UserId;
use serde::{Deserialize, Serialize};

use crate::{EventType, FromRaw};

/// A list of users to ignore.
#[derive(Clone, Debug, PartialEq, Serialize)]
#[serde(rename = "m.ignored_user_list", tag = "type")]
pub struct IgnoredUserListEvent {
    /// The event's content.
    pub content: IgnoredUserListEventContent,
}

impl FromRaw for IgnoredUserListEvent {
    type Raw = raw::IgnoredUserListEvent;

    fn from_raw(raw: raw::IgnoredUserListEvent) -> Self {
        Self {
            content: FromRaw::from_raw(raw.content),
        }
    }
}

/// The payload for `IgnoredUserListEvent`.
#[derive(Clone, Debug, PartialEq, Serialize)]
pub struct IgnoredUserListEventContent {
    /// A list of users to ignore.
    #[serde(with = "ruma_serde::vec_as_map_of_empty")]
    pub ignored_users: Vec<UserId>,
}

impl FromRaw for IgnoredUserListEventContent {
    type Raw = raw::IgnoredUserListEventContent;

    fn from_raw(raw: raw::IgnoredUserListEventContent) -> Self {
        Self {
            ignored_users: raw.ignored_users,
        }
    }
}

impl_event!(
    IgnoredUserListEvent,
    IgnoredUserListEventContent,
    EventType::IgnoredUserList
);

pub(crate) mod raw {
    use super::*;

    /// A list of users to ignore.
    #[derive(Clone, Debug, Deserialize)]
    pub struct IgnoredUserListEvent {
        /// The event's content.
        pub content: IgnoredUserListEventContent,
    }

    /// The payload for `IgnoredUserListEvent`.
    #[derive(Clone, Debug, Deserialize, Serialize)]
    pub struct IgnoredUserListEventContent {
        /// A list of users to ignore.
        #[serde(with = "ruma_serde::vec_as_map_of_empty")]
        pub ignored_users: Vec<UserId>,
    }
}

#[cfg(test)]
mod tests {
    use std::convert::TryFrom;

    use matches::assert_matches;
    use ruma_identifiers::UserId;
    use serde_json::{from_value as from_json_value, json, to_value as to_json_value};

    use super::{IgnoredUserListEvent, IgnoredUserListEventContent};
    use crate::EventJson;

    #[test]
    fn serialization() {
        let ignored_user_list_event = IgnoredUserListEvent {
            content: IgnoredUserListEventContent {
                ignored_users: vec![UserId::try_from("@carl:example.com").unwrap()],
            },
        };

        let json = json!({
            "content": {
                "ignored_users": {
                    "@carl:example.com": {}
                }
            },
            "type": "m.ignored_user_list"
        });

        assert_eq!(to_json_value(ignored_user_list_event).unwrap(), json);
    }

    #[test]
    fn deserialization() {
        let json = json!({
            "content": {
                "ignored_users": {
                    "@carl:example.com": {}
                }
            },
            "type": "m.ignored_user_list"
        });

        assert_matches!(
            from_json_value::<EventJson<IgnoredUserListEvent>>(json)
            .unwrap()
            .deserialize()
                .unwrap(),
            IgnoredUserListEvent {
                content: IgnoredUserListEventContent { ignored_users, },
            } if ignored_users == vec![UserId::try_from("@carl:example.com").unwrap()]
        );
    }
}
<|endoftext|>


<commit_before>#[cfg(feature = "unstable")]
mod renderer;
#[cfg(feature = "unstable")]
mod texture;
pub mod matrix;
#[cfg(feature = "unstable")]
mod image;

#[cfg(feature = "unstable")]
pub use self::image::*;
#[cfg(feature = "unstable")]
pub use self::renderer::{GenericRenderer, Renderer};
#[cfg(feature = "unstable")]
pub use self::texture::{Texture, TextureFormat};
<commit_msg>Matrix can't be stale yet<commit_after>#[cfg(feature = "unstable")]
mod renderer;
#[cfg(feature = "unstable")]
mod texture;
#[cfg(feature = "unstable")]
pub mod matrix;
#[cfg(feature = "unstable")]
mod image;

#[cfg(feature = "unstable")]
pub use self::image::*;
#[cfg(feature = "unstable")]
pub use self::renderer::{GenericRenderer, Renderer};
#[cfg(feature = "unstable")]
pub use self::texture::{Texture, TextureFormat};
<|endoftext|>


<commit_before>// Copyright 2014-2016 bluss and ndarray developers.
//
// 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.

//! Constructor methods for ndarray
//!
//!

use libnum::{Zero, One, Float};

use imp_prelude::*;
use {Shape, StrideShape};
use dimension;
use linspace;
use error::{self, ShapeError, ErrorKind};
use Indexes;

/// Constructor methods for one-dimensional arrays.
///
/// Note that the constructor methods apply to `Array` and `RcArray`,
/// the two array types that have owned storage.
impl<S> ArrayBase<S, Ix>
    where S: DataOwned
{
    /// Create a one-dimensional array from a vector (no copying needed).
    ///
    /// ```rust
    /// use ndarray::Array;
    ///
    /// let array = Array::from_vec(vec![1., 2., 3., 4.]);
    /// ```
    pub fn from_vec(v: Vec<S::Elem>) -> ArrayBase<S, Ix> {
        unsafe { Self::from_shape_vec_unchecked(v.len() as Ix, v) }
    }

    /// Create a one-dimensional array from an iterable.
    ///
    /// ```rust
    /// use ndarray::{Array, arr1};
    ///
    /// let array = Array::from_iter((0..5).map(|x| x * x));
    /// assert!(array == arr1(&[0, 1, 4, 9, 16]))
    /// ```
    pub fn from_iter(iterable: I) -> ArrayBase<S, Ix>
        where I: IntoIterator<Item=S::Elem>
    {
        Self::from_vec(iterable.into_iter().collect())
    }

    /// Create a one-dimensional array from the inclusive interval
    /// `[start, end]` with `n` elements. `F` must be a floating point type.
    ///
    /// ```rust
    /// use ndarray::{Array, arr1};
    ///
    /// let array = Array::linspace(0., 1., 5);
    /// assert!(array == arr1(&[0.0, 0.25, 0.5, 0.75, 1.0]))
    /// ```
    pub fn linspace<F>(start: F, end: F, n: usize) -> ArrayBase<S, Ix>
        where S: Data<Elem=F>,
              F: Float,
    {
        Self::from_vec(::iterators::to_vec(linspace::linspace(start, end, n)))
    }

    /// Create a one-dimensional array from the half-open interval
    /// `[start, end)` with elements spaced by `step`. `F` must be a floating point type.
    ///
    /// ```rust
    /// use ndarray::{Array, arr1};
    ///
    /// let array = Array::range(0., 5., 1.);
    /// assert!(array == arr1(&[0., 1., 2., 3., 4.]))
    /// ```
    pub fn range<F>(start: F, end: F, step: F) -> ArrayBase<S, Ix>
        where S: Data<Elem=F>,
              F: Float,
    {
        Self::from_vec(::iterators::to_vec(linspace::range(start, end, step)))
    }
}

/// Constructor methods for two-dimensional arrays.
impl<S, A> ArrayBase<S, (Ix, Ix)>
    where S: DataOwned<Elem=A>,
{
    /// Create an identity matrix of size `n` (square 2D array).
    ///
    /// **Panics** if `n * n` would overflow usize.
    pub fn eye(n: Ix) -> ArrayBase<S, (Ix, Ix)>
        where S: DataMut,
              A: Clone + Zero + One,
    {
        let mut eye = Self::zeros((n, n));
        for a_ii in eye.diag_mut() {
            *a_ii = A::one();
        }
        eye
    }
}

macro_rules! size_checked_unwrap {
    ($dim:expr) => {
        match $dim.size_checked() {
            Some(sz) => sz,
            None => panic!("ndarray: Shape too large, number of elements overflows usize"),
        }
    }
}

/// Constructor methods for n-dimensional arrays.
impl<S, A, D> ArrayBase<S, D>
    where S: DataOwned<Elem=A>,
          D: Dimension,
{
    /// Create an array with copies of `elem`, shape `shape`.
    ///
    /// **Panics** if the number of elements in `shape` would overflow usize.
    ///
    /// ```
    /// use ndarray::{Array, arr3, ShapeBuilder};
    ///
    /// let a = Array::from_elem((2, 2, 2), 1.);
    ///
    /// assert!(
    ///     a == arr3(&[[[1., 1.],
    ///                  [1., 1.]],
    ///                 [[1., 1.],
    ///                  [1., 1.]]])
    /// );
    /// assert!(a.strides() == &[4, 2, 1]);
    ///
    /// let b = Array::from_elem((2, 2, 2).f(), 1.);
    /// assert!(b.strides() == &[1, 2, 4]);
    /// ```
    pub fn from_elem<Sh>(shape: Sh, elem: A) -> ArrayBase<S, D>
        where A: Clone,
              Sh: Into<Shape<D>>,
    {
        // Note: We don't need to check the case of a size between
        // isize::MAX -> usize::MAX; in this case, the vec constructor itself
        // panics.
        let shape = shape.into();
        let size = size_checked_unwrap!(shape.dim);
        let v = vec![elem; size];
        unsafe { Self::from_shape_vec_unchecked(shape, v) }
    }

    /// Create an array with zeros, shape `shape`.
    ///
    /// **Panics** if the number of elements in `shape` would overflow usize.
    pub fn zeros<Sh>(shape: Sh) -> ArrayBase<S, D>
        where A: Clone + Zero,
              Sh: Into<Shape<D>>,
    {
        Self::from_elem(shape, A::zero())
    }

    /// Create an array with default values, shape `shape`
    ///
    /// **Panics** if the number of elements in `shape` would overflow usize.
    pub fn default<Sh>(shape: Sh) -> ArrayBase<S, D>
        where A: Default,
              Sh: Into<Shape<D>>,
    {
        let shape = shape.into();
        let v = (0..shape.dim.size()).map(|_| A::default()).collect();
        unsafe { Self::from_shape_vec_unchecked(shape, v) }
    }

    /// Create an array with values created by the function `f`.
    ///
    /// The elements are visited in arbitirary order.
    ///
    /// **Panics** if the number of elements in `shape` would overflow usize.
    pub fn from_shape_fn<Sh, F>(shape: Sh, f: F) -> ArrayBase<S, D>
        where Sh: Into<Shape<D>>,
              F: FnMut(D) -> A,
    {
        let shape = shape.into();
        let v = Indexes::new(shape.dim.clone()).map(f).collect();
        unsafe { Self::from_shape_vec_unchecked(shape, v) }
    }

    /// Create an array with the given shape from a vector. (No cloning of
    /// elements needed.)
    ///
    /// ----
    ///
    /// For a contiguous c- or f-order shape, the following applies:
    ///
    /// **Errors** if `shape` does not correspond to the number of elements in `v`.
    ///
    /// ----
    ///
    /// For custom strides, the following applies:
    ///
    /// **Errors** if strides and dimensions can point out of bounds of `v`.

    /// **Errors** if strides allow multiple indices to point to the same element.
    ///
    /// ```
    /// use ndarray::prelude::*;
    ///
    /// let a = Array::from_shape_vec((2, 2), vec![1., 2., 3., 4.]);
    /// assert!(a.is_ok());
    ///
    /// let b = Array::from_shape_vec((2, 2).strides((1, 2)),
    ///                                    vec![1., 2., 3., 4.]).unwrap();
    /// assert!(
    ///     b == arr2(&[[1., 3.],
    ///                 [2., 4.]])
    /// );
    /// ```
    pub fn from_shape_vec<Sh>(shape: Sh, v: Vec) -> Result<ArrayBase<S, D>, ShapeError>
        where Sh: Into<StrideShape<D>>,
    {
        // eliminate the type parameter Sh as soon as possible
        Self::from_shape_vec_impl(shape.into(), v)
    }

    fn from_shape_vec_impl(shape: StrideShape<D>, v: Vec) -> Result<ArrayBase<S, D>, ShapeError>
    {
        if shape.custom {
            Self::from_vec_dim_stride(shape.dim, shape.strides, v)
        } else {
            let dim = shape.dim;
            let strides = shape.strides;
            if dim.size_checked() != Some(v.len()) {
                return Err(error::incompatible_shapes(&v.len(), &dim));
            }
            unsafe { Ok(Self::from_vec_dim_stride_unchecked(dim, strides, v)) }
        }
    }

    /// Create an array from a vector and interpret it according to the
    /// provided dimensions and strides. (No cloning of elements needed.)
    ///
    /// Unsafe because dimension and strides are unchecked.
    pub unsafe fn from_shape_vec_unchecked<Sh>(shape: Sh, v: Vec) -> ArrayBase<S, D>
        where Sh: Into<StrideShape<D>>,
    {
        let shape = shape.into();
        Self::from_vec_dim_stride_unchecked(shape.dim, shape.strides, v)
    }

    fn from_vec_dim_stride(dim: D, strides: D, v: Vec)
        -> Result<ArrayBase<S, D>, ShapeError>
    {
        dimension::can_index_slice(&v, &dim, &strides).map(|_| {
            unsafe {
                Self::from_vec_dim_stride_unchecked(dim, strides, v)
            }
        })
    }

    unsafe fn from_vec_dim_stride_unchecked(dim: D, strides: D, mut v: Vec)
        -> ArrayBase<S, D>
    {
        // debug check for issues that indicates wrong use of this constructor
        debug_assert!(match dimension::can_index_slice(&v, &dim, &strides) {
            Ok(_) => true,
            Err(ref e) => match e.kind() {
                ErrorKind::OutOfBounds => false,
                ErrorKind::RangeLimited => false,
                _ => true,
            }
        });
        ArrayBase {
            ptr: v.as_mut_ptr(),
            data: DataOwned::new(v),
            strides: strides,
            dim: dim
        }
    }

}
<commit_msg>`use` to_vec<commit_after>// Copyright 2014-2016 bluss and ndarray developers.
//
// 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.

//! Constructor methods for ndarray
//!
//!

use libnum::{Zero, One, Float};

use imp_prelude::*;
use {Shape, StrideShape};
use dimension;
use linspace;
use error::{self, ShapeError, ErrorKind};
use Indexes;
use iterators::to_vec;

/// Constructor methods for one-dimensional arrays.
///
/// Note that the constructor methods apply to `Array` and `RcArray`,
/// the two array types that have owned storage.
impl<S> ArrayBase<S, Ix>
    where S: DataOwned
{
    /// Create a one-dimensional array from a vector (no copying needed).
    ///
    /// ```rust
    /// use ndarray::Array;
    ///
    /// let array = Array::from_vec(vec![1., 2., 3., 4.]);
    /// ```
    pub fn from_vec(v: Vec<S::Elem>) -> ArrayBase<S, Ix> {
        unsafe { Self::from_shape_vec_unchecked(v.len() as Ix, v) }
    }

    /// Create a one-dimensional array from an iterable.
    ///
    /// ```rust
    /// use ndarray::{Array, arr1};
    ///
    /// let array = Array::from_iter((0..5).map(|x| x * x));
    /// assert!(array == arr1(&[0, 1, 4, 9, 16]))
    /// ```
    pub fn from_iter(iterable: I) -> ArrayBase<S, Ix>
        where I: IntoIterator<Item=S::Elem>
    {
        Self::from_vec(iterable.into_iter().collect())
    }

    /// Create a one-dimensional array from the inclusive interval
    /// `[start, end]` with `n` elements. `F` must be a floating point type.
    ///
    /// ```rust
    /// use ndarray::{Array, arr1};
    ///
    /// let array = Array::linspace(0., 1., 5);
    /// assert!(array == arr1(&[0.0, 0.25, 0.5, 0.75, 1.0]))
    /// ```
    pub fn linspace<F>(start: F, end: F, n: usize) -> ArrayBase<S, Ix>
        where S: Data<Elem=F>,
              F: Float,
    {
        Self::from_vec(to_vec(linspace::linspace(start, end, n)))
    }

    /// Create a one-dimensional array from the half-open interval
    /// `[start, end)` with elements spaced by `step`. `F` must be a floating point type.
    ///
    /// ```rust
    /// use ndarray::{Array, arr1};
    ///
    /// let array = Array::range(0., 5., 1.);
    /// assert!(array == arr1(&[0., 1., 2., 3., 4.]))
    /// ```
    pub fn range<F>(start: F, end: F, step: F) -> ArrayBase<S, Ix>
        where S: Data<Elem=F>,
              F: Float,
    {
        Self::from_vec(to_vec(linspace::range(start, end, step)))
    }
}

/// Constructor methods for two-dimensional arrays.
impl<S, A> ArrayBase<S, (Ix, Ix)>
    where S: DataOwned<Elem=A>,
{
    /// Create an identity matrix of size `n` (square 2D array).
    ///
    /// **Panics** if `n * n` would overflow usize.
    pub fn eye(n: Ix) -> ArrayBase<S, (Ix, Ix)>
        where S: DataMut,
              A: Clone + Zero + One,
    {
        let mut eye = Self::zeros((n, n));
        for a_ii in eye.diag_mut() {
            *a_ii = A::one();
        }
        eye
    }
}

macro_rules! size_checked_unwrap {
    ($dim:expr) => {
        match $dim.size_checked() {
            Some(sz) => sz,
            None => panic!("ndarray: Shape too large, number of elements overflows usize"),
        }
    }
}

/// Constructor methods for n-dimensional arrays.
impl<S, A, D> ArrayBase<S, D>
    where S: DataOwned<Elem=A>,
          D: Dimension,
{
    /// Create an array with copies of `elem`, shape `shape`.
    ///
    /// **Panics** if the number of elements in `shape` would overflow usize.
    ///
    /// ```
    /// use ndarray::{Array, arr3, ShapeBuilder};
    ///
    /// let a = Array::from_elem((2, 2, 2), 1.);
    ///
    /// assert!(
    ///     a == arr3(&[[[1., 1.],
    ///                  [1., 1.]],
    ///                 [[1., 1.],
    ///                  [1., 1.]]])
    /// );
    /// assert!(a.strides() == &[4, 2, 1]);
    ///
    /// let b = Array::from_elem((2, 2, 2).f(), 1.);
    /// assert!(b.strides() == &[1, 2, 4]);
    /// ```
    pub fn from_elem<Sh>(shape: Sh, elem: A) -> ArrayBase<S, D>
        where A: Clone,
              Sh: Into<Shape<D>>,
    {
        // Note: We don't need to check the case of a size between
        // isize::MAX -> usize::MAX; in this case, the vec constructor itself
        // panics.
        let shape = shape.into();
        let size = size_checked_unwrap!(shape.dim);
        let v = vec![elem; size];
        unsafe { Self::from_shape_vec_unchecked(shape, v) }
    }

    /// Create an array with zeros, shape `shape`.
    ///
    /// **Panics** if the number of elements in `shape` would overflow usize.
    pub fn zeros<Sh>(shape: Sh) -> ArrayBase<S, D>
        where A: Clone + Zero,
              Sh: Into<Shape<D>>,
    {
        Self::from_elem(shape, A::zero())
    }

    /// Create an array with default values, shape `shape`
    ///
    /// **Panics** if the number of elements in `shape` would overflow usize.
    pub fn default<Sh>(shape: Sh) -> ArrayBase<S, D>
        where A: Default,
              Sh: Into<Shape<D>>,
    {
        let shape = shape.into();
        let v = (0..shape.dim.size()).map(|_| A::default()).collect();
        unsafe { Self::from_shape_vec_unchecked(shape, v) }
    }

    /// Create an array with values created by the function `f`.
    ///
    /// The elements are visited in arbitirary order.
    ///
    /// **Panics** if the number of elements in `shape` would overflow usize.
    pub fn from_shape_fn<Sh, F>(shape: Sh, f: F) -> ArrayBase<S, D>
        where Sh: Into<Shape<D>>,
              F: FnMut(D) -> A,
    {
        let shape = shape.into();
        let v = Indexes::new(shape.dim.clone()).map(f).collect();
        unsafe { Self::from_shape_vec_unchecked(shape, v) }
    }

    /// Create an array with the given shape from a vector. (No cloning of
    /// elements needed.)
    ///
    /// ----
    ///
    /// For a contiguous c- or f-order shape, the following applies:
    ///
    /// **Errors** if `shape` does not correspond to the number of elements in `v`.
    ///
    /// ----
    ///
    /// For custom strides, the following applies:
    ///
    /// **Errors** if strides and dimensions can point out of bounds of `v`.

    /// **Errors** if strides allow multiple indices to point to the same element.
    ///
    /// ```
    /// use ndarray::prelude::*;
    ///
    /// let a = Array::from_shape_vec((2, 2), vec![1., 2., 3., 4.]);
    /// assert!(a.is_ok());
    ///
    /// let b = Array::from_shape_vec((2, 2).strides((1, 2)),
    ///                                    vec![1., 2., 3., 4.]).unwrap();
    /// assert!(
    ///     b == arr2(&[[1., 3.],
    ///                 [2., 4.]])
    /// );
    /// ```
    pub fn from_shape_vec<Sh>(shape: Sh, v: Vec) -> Result<ArrayBase<S, D>, ShapeError>
        where Sh: Into<StrideShape<D>>,
    {
        // eliminate the type parameter Sh as soon as possible
        Self::from_shape_vec_impl(shape.into(), v)
    }

    fn from_shape_vec_impl(shape: StrideShape<D>, v: Vec) -> Result<ArrayBase<S, D>, ShapeError>
    {
        if shape.custom {
            Self::from_vec_dim_stride(shape.dim, shape.strides, v)
        } else {
            let dim = shape.dim;
            let strides = shape.strides;
            if dim.size_checked() != Some(v.len()) {
                return Err(error::incompatible_shapes(&v.len(), &dim));
            }
            unsafe { Ok(Self::from_vec_dim_stride_unchecked(dim, strides, v)) }
        }
    }

    /// Create an array from a vector and interpret it according to the
    /// provided dimensions and strides. (No cloning of elements needed.)
    ///
    /// Unsafe because dimension and strides are unchecked.
    pub unsafe fn from_shape_vec_unchecked<Sh>(shape: Sh, v: Vec) -> ArrayBase<S, D>
        where Sh: Into<StrideShape<D>>,
    {
        let shape = shape.into();
        Self::from_vec_dim_stride_unchecked(shape.dim, shape.strides, v)
    }

    fn from_vec_dim_stride(dim: D, strides: D, v: Vec)
        -> Result<ArrayBase<S, D>, ShapeError>
    {
        dimension::can_index_slice(&v, &dim, &strides).map(|_| {
            unsafe {
                Self::from_vec_dim_stride_unchecked(dim, strides, v)
            }
        })
    }

    unsafe fn from_vec_dim_stride_unchecked(dim: D, strides: D, mut v: Vec)
        -> ArrayBase<S, D>
    {
        // debug check for issues that indicates wrong use of this constructor
        debug_assert!(match dimension::can_index_slice(&v, &dim, &strides) {
            Ok(_) => true,
            Err(ref e) => match e.kind() {
                ErrorKind::OutOfBounds => false,
                ErrorKind::RangeLimited => false,
                _ => true,
            }
        });
        ArrayBase {
            ptr: v.as_mut_ptr(),
            data: DataOwned::new(v),
            strides: strides,
            dim: dim
        }
    }

}
<|endoftext|>


<commit_before>//! Completion API
use std::collections::BTreeSet;
use std::fs;
use std::path::{self,Path};

use super::Result;

// TODO: let the implementers choose/find word boudaries ???
// (line, pos) is like (rl_line_buffer, rl_point) to make contextual completion ("select t.na| from tbl as t")
// TOOD: make &self &mut self ???
// TODO: change update signature: _line: Into<String>

/// To be called for tab-completion.
pub trait Completer {
    /// Takes the currently edited `line` with the cursor `pos`ition and
    /// returns the start position and the completion candidates for the partial word to be completed.
    /// "ls /usr/loc" => Ok((3, vec!["/usr/local/"]))
    fn complete(&self, line: &str, pos: usize) -> Result<(usize, Vec<String>)>;
    /// Takes the currently edited `line` with the cursor `pos`ition and
    /// the `elected` candidate.
    /// Returns the new line content and cursor position.
    fn update(&self, line: &str, pos: usize, start: usize, elected: &str) -> (String, usize) {
        let mut buf = String::from(&line[..start]);
        buf.push_str(elected);
        //buf.push(' ');
        let new_pos = buf.len();
        buf.push_str(&line[pos..]);
        (buf, new_pos)
    }
}

pub struct FilenameCompleter {
    break_chars: BTreeSet<char>
}

static DEFAULT_BREAK_CHARS : [char; 18] = [ ' ', '\t', '\n', '"', '\\', '\'', '`', '@', '$',
            '>', '<', '=', ';', '|', '&', '{', '(', '\0' ];

impl FilenameCompleter {
    pub fn new() -> FilenameCompleter {
        FilenameCompleter { break_chars: DEFAULT_BREAK_CHARS.iter().cloned().collect() }
    }
}

impl Completer for FilenameCompleter {
    fn complete(&self, line: &str, pos: usize) -> Result<(usize, Vec<String>)> {
        let (start, path) = extract_word(line, pos, &self.break_chars);
        let matches = try!(filename_complete(path));
        Ok((start, matches))
    }
}

fn filename_complete(path: &str) -> Result<Vec<String>> {
    use std::env::{current_dir,home_dir};

    let sep = path::MAIN_SEPARATOR;
    let (dir_name, file_name) = match path.rfind(sep) {
        Some(idx) => path.split_at(idx+sep.len_utf8()),
        None => ("", path)
    };

    let dir_path = Path::new(dir_name);
    let dir = if dir_path.starts_with("~") { // ~[/...]
        if let Some(home) = home_dir() {
            match dir_path.relative_from("~") {
                Some(rel_path) => home.join(rel_path),
                None => home
            }
        } else {
            dir_path.to_path_buf()
        }
    } else if dir_path.is_relative() { // TODO ~user[/...] (https://crates.io/crates/users)
        if let Ok(cwd) = current_dir() {
            cwd.join(dir_path)
        } else {
            dir_path.to_path_buf()
        }
    } else {
        dir_path.to_path_buf()
    };

    let mut entries: Vec<String> = Vec::new();
    for entry in try!(fs::read_dir(dir)) {
        let entry = try!(entry);
        if let Some(s) = entry.file_name().to_str() {
            if s.starts_with(file_name) {
                let mut path = String::from(dir_name) + s;
                if try!(fs::metadata(entry.path())).is_dir() {
                    path.push(sep);
                }
                entries.push(path);
            }
        }
    }
    Ok(entries)
}

pub fn extract_word<'l>(line: &'l str, pos: usize, break_chars: &BTreeSet<char>) -> (usize, &'l str) {
    let line = &line[..pos];
    if line.is_empty() {
        return (0, line);
    }
    match line.char_indices().rev().find(|&(_, c)| break_chars.contains(&c)) {
        Some((i, c)) => {
            let start = i+c.len_utf8();
            (start, &line[start..])
        },
        None => (0, line)
    }
}

#[cfg(test)]
mod tests {
    use std::collections::BTreeSet;

    #[test]
    pub fn extract_word() {
        let break_chars: BTreeSet<char> = super::DEFAULT_BREAK_CHARS.iter().cloned().collect();
        let line = "ls '/usr/local/b";
        assert_eq!((4, "/usr/local/b"), super::extract_word(line, line.len(), &break_chars));
    }
}<commit_msg>Improve Completer#update function.<commit_after>//! Completion API
use std::collections::BTreeSet;
use std::fs;
use std::path::{self,Path};

use super::Result;

// TODO: let the implementers choose/find word boudaries ???
// (line, pos) is like (rl_line_buffer, rl_point) to make contextual completion ("select t.na| from tbl as t")
// TOOD: make &self &mut self ???
// TODO: change update signature: _line: Into<String>

/// To be called for tab-completion.
pub trait Completer {
    /// Takes the currently edited `line` with the cursor `pos`ition and
    /// returns the start position and the completion candidates for the partial word to be completed.
    /// "ls /usr/loc" => Ok((3, vec!["/usr/local/"]))
    fn complete(&self, line: &str, pos: usize) -> Result<(usize, Vec<String>)>;
    /// Takes the currently edited `line` with the cursor `pos`ition and
    /// the `elected` candidate.
    /// Returns the new line content and cursor position.
    fn update(&self, line: &str, pos: usize, start: usize, elected: &str) -> (String, usize) {
        let mut buf = String::with_capacity(start + elected.len() + line.len() - pos);
        buf.push_str(&line[..start]);
        buf.push_str(elected);
        //buf.push(' ');
        let new_pos = buf.len();
        buf.push_str(&line[pos..]);
        (buf, new_pos)
    }
}

pub struct FilenameCompleter {
    break_chars: BTreeSet<char>
}

static DEFAULT_BREAK_CHARS : [char; 18] = [ ' ', '\t', '\n', '"', '\\', '\'', '`', '@', '$',
            '>', '<', '=', ';', '|', '&', '{', '(', '\0' ];

impl FilenameCompleter {
    pub fn new() -> FilenameCompleter {
        FilenameCompleter { break_chars: DEFAULT_BREAK_CHARS.iter().cloned().collect() }
    }
}

impl Completer for FilenameCompleter {
    fn complete(&self, line: &str, pos: usize) -> Result<(usize, Vec<String>)> {
        let (start, path) = extract_word(line, pos, &self.break_chars);
        let matches = try!(filename_complete(path));
        Ok((start, matches))
    }
}

fn filename_complete(path: &str) -> Result<Vec<String>> {
    use std::env::{current_dir,home_dir};

    let sep = path::MAIN_SEPARATOR;
    let (dir_name, file_name) = match path.rfind(sep) {
        Some(idx) => path.split_at(idx+sep.len_utf8()),
        None => ("", path)
    };

    let dir_path = Path::new(dir_name);
    let dir = if dir_path.starts_with("~") { // ~[/...]
        if let Some(home) = home_dir() {
            match dir_path.relative_from("~") {
                Some(rel_path) => home.join(rel_path),
                None => home
            }
        } else {
            dir_path.to_path_buf()
        }
    } else if dir_path.is_relative() { // TODO ~user[/...] (https://crates.io/crates/users)
        if let Ok(cwd) = current_dir() {
            cwd.join(dir_path)
        } else {
            dir_path.to_path_buf()
        }
    } else {
        dir_path.to_path_buf()
    };

    let mut entries: Vec<String> = Vec::new();
    for entry in try!(fs::read_dir(dir)) {
        let entry = try!(entry);
        if let Some(s) = entry.file_name().to_str() {
            if s.starts_with(file_name) {
                let mut path = String::from(dir_name) + s;
                if try!(fs::metadata(entry.path())).is_dir() {
                    path.push(sep);
                }
                entries.push(path);
            }
        }
    }
    Ok(entries)
}

pub fn extract_word<'l>(line: &'l str, pos: usize, break_chars: &BTreeSet<char>) -> (usize, &'l str) {
    let line = &line[..pos];
    if line.is_empty() {
        return (0, line);
    }
    match line.char_indices().rev().find(|&(_, c)| break_chars.contains(&c)) {
        Some((i, c)) => {
            let start = i+c.len_utf8();
            (start, &line[start..])
        },
        None => (0, line)
    }
}

#[cfg(test)]
mod tests {
    use std::collections::BTreeSet;

    #[test]
    pub fn extract_word() {
        let break_chars: BTreeSet<char> = super::DEFAULT_BREAK_CHARS.iter().cloned().collect();
        let line = "ls '/usr/local/b";
        assert_eq!((4, "/usr/local/b"), super::extract_word(line, line.len(), &break_chars));
    }
}<|endoftext|>


<commit_before>// http://rosettacode.org/wiki/Palindrome_detection

// Returns true if the string is a palindrome
fn palindrome(string: &str) -> bool {
    // The first part of the string
    let forward = string.chars().take(string.len() / 2);

    // The second part of the string in reverse order
    let reverse = string.chars().rev().take(string.len() / 2);

    // We group the two parts of the string in tuples
    let mut both_directions = forward.zip(reverse);

    // The word is a palindrome if each tuple contains two times
    // the same character
    both_directions.all(|(a, b)| {a == b})
}

// Demonstration code
fn main() {
    let test_strings = ["nope", "eevee", "lalala", "rust", "lalalal"];
    for &string in &test_strings {
        println!("{}: {}", string, palindrome(string));
    }
}

#[test]
fn test_palindromes() {
    let palindromes = ["eevee", "lalalal", "オオオオ", "", "anna"];
    let non_palindromes = ["nope", "lalala", "car", "rain", "house", "computer", "rust"];

    assert!(palindromes.iter().all(|&s| palindrome(s)));
    assert!(non_palindromes.iter().all(|&s| !palindrome(s)));
}
<commit_msg>palindrome: Add link to "Test a function"<commit_after>// http://rosettacode.org/wiki/Palindrome_detection
// http://rosettacode.org/wiki/Test_a_function

// Returns true if the string is a palindrome
fn palindrome(string: &str) -> bool {
    // The first part of the string
    let forward = string.chars().take(string.len() / 2);

    // The second part of the string in reverse order
    let reverse = string.chars().rev().take(string.len() / 2);

    // We group the two parts of the string in tuples
    let mut both_directions = forward.zip(reverse);

    // The word is a palindrome if each tuple contains two times
    // the same character
    both_directions.all(|(a, b)| {a == b})
}

// Demonstration code
fn main() {
    let test_strings = ["nope", "eevee", "lalala", "rust", "lalalal"];
    for &string in &test_strings {
        println!("{}: {}", string, palindrome(string));
    }
}

#[test]
fn test_palindromes() {
    let palindromes = ["eevee", "lalalal", "オオオオ", "", "anna"];
    let non_palindromes = ["nope", "lalala", "car", "rain", "house", "computer", "rust"];

    assert!(palindromes.iter().all(|&s| palindrome(s)));
    assert!(non_palindromes.iter().all(|&s| !palindrome(s)));
}
<|endoftext|>


<commit_before>//! Parsing functionality - get cookie data

use std::collections::treemap::TreeMap;
use url;
use serialize::json;
use serialize::json::{Json, Null};
use iron::{Request, Response, Middleware, Alloy};
use iron::middleware::{Status, Continue};
use super::Cookie;

#[cfg(test)]
mod test;

/// The cookie parsing `Middleware`.
///
/// It will parse the body of a cookie into the alloy, under type `Cookie`.
///
/// This middleware should be linked (added to the `Chain`)
/// before any other middleware using cookies, or the parsed cookie
/// will not be available to that middleware.
#[deriving(Clone)]
pub struct CookieParser {
    secret: Option<String>
}

impl CookieParser {
    /// Create a new instance of the cookie parsing `Middleware`.
    ///
    /// This instance will parse both RFC 6265-styled cookies:
    /// `key=value; key=value;`
    /// and json-styled cookies, as set with `res.set_json_cookie(...)`.
    pub fn new() -> CookieParser { CookieParser{ secret: None} }

    /// Create a cookie parser with secret, for signed cookies.
    ///
    /// This instance will parse any cookies that have been signed by
    /// you, or that are unsigned. It will not parse those cookies signed by others.
    ///
    /// Otherwise, it will behave exactly like that produced by `new`.
    pub fn signed(secret: String) -> CookieParser { CookieParser{ secret: Some(secret) } }
}

impl Middleware for CookieParser {
    /// Parse the cookie received in the HTTP header.
    ///
    /// This will parse the body of a cookie into the alloy, under type `Cookie`.
    fn enter(&mut self, req: &mut Request, _res: &mut Response, alloy: &mut Alloy) -> Status {
        // Initialize a cookie. This will store parsed cookies and generate signatures.
        let mut new_cookie = Cookie::new(self.secret.clone());

        match req.headers.extensions.find_mut(&"Cookie".to_string()) {
            Some(cookies) => {
                // Initialize an empty json object.
                let mut new_json = json::Object(box TreeMap::new());
                new_cookie.map =
                    cookies
                        .as_slice()
                        .split(';')
                        // Decode from uri component encoding
                        .map(|substr| {
                            let vec: Vec<&str> = substr.splitn('=', 1).collect();
                            let key = from_rfc_compliant(*vec.get(0));
                            let val = from_rfc_compliant(*vec.get(1));
                            (key, val) })
                        // Check for signed cookies, and filter those not signed by us
                        .filter_map(|cookie| strip_signature(cookie, &new_cookie))
                        // Move json cookies into a separate container
                        .filter(|cookie| parse_json(cookie, &mut new_json))
                        .collect();

                // This cannot be inserted via iterators because strip_signature
                // is already borrowing new_cookie.
                new_cookie.json = new_json;
            },
            None => ()
        }
        alloy.insert(new_cookie);
        Continue
    }
}

fn from_rfc_compliant(string: &str) -> String {
    url::decode_component(
        string
            .chars()
            .skip_while(is_whitespace)
            .collect::<String>().as_slice())
}

fn is_whitespace(c: &char) -> bool {
    match *c {
        ' '|'\r'|'\t'|'\n' => true,
        _                  => false
    }
}

fn strip_signature((key, val): (String, String), signer: &Cookie) -> Option<(String, String)> {
    if val.len() > 2 && val.as_slice().slice(0, 2) == "s:" {
        // Extract the signature (in hex), appended onto the cookie after `.`
        return regex!(r"\.[^\.]*$").find(val.as_slice())
            // If it was signed by us, clear the signature
            .and_then(|(beg, end)| {
                signer.sign(&val.as_slice().slice(2, beg).to_string())
                    // We need to maintain access to (beg, end), so we chain the signature
                    .and_then(|signature| {
                        // If the signature is valid, strip it
                        if val.as_slice().slice(beg + 1, end) == signature.as_slice() {
                            // key must be cloned to move out of the closure capture
                            Some((key.clone(), val.as_slice().slice(2, beg).to_string()))
                        // Else, remove the cookie
                        } else {
                            None
                        }
                    })
            })
    }
    Some((key, val))
}

fn parse_json(&(ref key, ref val): &(String, String), json: &mut Json) -> bool {
    if val.len() > 2 && val.as_slice().slice(0, 2) == "j:" {
        match *json {
            json::Object(ref mut root) => {
                root.insert(key.clone(),
                    match json::from_str(val.as_slice().slice_from(2)) {
                        Ok(obj) => obj,
                        Err(_)  => Null
                    });
            },
            _                    => ()
        }
        return true
    }
    false
}
<commit_msg>(fix) Fixed Json inclusion filter.<commit_after>//! Parsing functionality - get cookie data

use std::collections::treemap::TreeMap;
use url;
use serialize::json;
use serialize::json::{Json, Null};
use iron::{Request, Response, Middleware, Alloy};
use iron::middleware::{Status, Continue};
use super::Cookie;

#[cfg(test)]
mod test;

/// The cookie parsing `Middleware`.
///
/// It will parse the body of a cookie into the alloy, under type `Cookie`.
///
/// This middleware should be linked (added to the `Chain`)
/// before any other middleware using cookies, or the parsed cookie
/// will not be available to that middleware.
#[deriving(Clone)]
pub struct CookieParser {
    secret: Option<String>
}

impl CookieParser {
    /// Create a new instance of the cookie parsing `Middleware`.
    ///
    /// This instance will parse both RFC 6265-styled cookies:
    /// `key=value; key=value;`
    /// and json-styled cookies, as set with `res.set_json_cookie(...)`.
    pub fn new() -> CookieParser { CookieParser{ secret: None} }

    /// Create a cookie parser with secret, for signed cookies.
    ///
    /// This instance will parse any cookies that have been signed by
    /// you, or that are unsigned. It will not parse those cookies signed by others.
    ///
    /// Otherwise, it will behave exactly like that produced by `new`.
    pub fn signed(secret: String) -> CookieParser { CookieParser{ secret: Some(secret) } }
}

impl Middleware for CookieParser {
    /// Parse the cookie received in the HTTP header.
    ///
    /// This will parse the body of a cookie into the alloy, under type `Cookie`.
    fn enter(&mut self, req: &mut Request, _res: &mut Response, alloy: &mut Alloy) -> Status {
        // Initialize a cookie. This will store parsed cookies and generate signatures.
        let mut new_cookie = Cookie::new(self.secret.clone());

        match req.headers.extensions.find_mut(&"Cookie".to_string()) {
            Some(cookies) => {
                // Initialize an empty json object.
                let mut new_json = json::Object(box TreeMap::new());
                new_cookie.map =
                    cookies
                        .as_slice()
                        .split(';')
                        // Decode from uri component encoding
                        .map(|substr| {
                            let vec: Vec<&str> = substr.splitn('=', 1).collect();
                            let key = from_rfc_compliant(*vec.get(0));
                            let val = from_rfc_compliant(*vec.get(1));
                            (key, val) })
                        // Check for signed cookies, and filter those not signed by us
                        .filter_map(|cookie| strip_signature(cookie, &new_cookie))
                        // Move json cookies into a separate container
                        .filter(|cookie| parse_json(cookie, &mut new_json))
                        .collect();

                // This cannot be inserted via iterators because strip_signature
                // is already borrowing new_cookie.
                new_cookie.json = new_json;
            },
            None => ()
        }
        alloy.insert(new_cookie);
        Continue
    }
}

fn from_rfc_compliant(string: &str) -> String {
    url::decode_component(
        string
            .chars()
            .skip_while(is_whitespace)
            .collect::<String>().as_slice())
}

fn is_whitespace(c: &char) -> bool {
    match *c {
        ' '|'\r'|'\t'|'\n' => true,
        _                  => false
    }
}

fn strip_signature((key, val): (String, String), signer: &Cookie) -> Option<(String, String)> {
    if val.len() > 2 && val.as_slice().slice(0, 2) == "s:" {
        // Extract the signature (in hex), appended onto the cookie after `.`
        return regex!(r"\.[^\.]*$").find(val.as_slice())
            // If it was signed by us, clear the signature
            .and_then(|(beg, end)| {
                signer.sign(&val.as_slice().slice(2, beg).to_string())
                    // We need to maintain access to (beg, end), so we chain the signature
                    .and_then(|signature| {
                        // If the signature is valid, strip it
                        if val.as_slice().slice(beg + 1, end) == signature.as_slice() {
                            // key must be cloned to move out of the closure capture
                            Some((key.clone(), val.as_slice().slice(2, beg).to_string()))
                        // Else, remove the cookie
                        } else {
                            None
                        }
                    })
            })
    }
    Some((key, val))
}

fn parse_json(&(ref key, ref val): &(String, String), json: &mut Json) -> bool {
    if val.len() > 2 && val.as_slice().slice(0, 2) == "j:" {
        match *json {
            json::Object(ref mut root) => {
                root.insert(key.clone(),
                    match json::from_str(val.as_slice().slice_from(2)) {
                        Ok(obj) => obj,
                        Err(_)  => Null
                    });
            },
            _                    => ()
        }
        return false
    }
    true
}
<|endoftext|>


<commit_before>//! Netherrack-specific I/O operations for Rust

pub mod reader;

pub mod writer;

#[cfg(test)]
mod test {

    use super::reader::NetherrackReader;
    use super::writer::NetherrackWriter;

    use std::io::Cursor;

    #[test]
    fn test_read_write_unsigned_varint_32() {

        let mut vector = Cursor::new(vec![0u8; 0]);

        assert!(vector.write_unsigned_varint_32(15).is_ok());
        assert!(vector.write_unsigned_varint_32(2111111111).is_ok());
        assert!(vector.write_unsigned_varint_32(3463465).is_ok());

        vector.set_position(0);

        assert_eq!(15, vector.read_unsigned_varint_32().unwrap());
        assert_eq!(2111111111, vector.read_unsigned_varint_32().unwrap());
        assert_eq!(3463465, vector.read_unsigned_varint_32().unwrap());

    }

}
<commit_msg>Test native use of Varint32 zero<commit_after>//! Netherrack-specific I/O operations for Rust

pub mod reader;

pub mod writer;

#[cfg(test)]
mod test {

    use super::reader::NetherrackReader;
    use super::writer::NetherrackWriter;

    use std::io::Cursor;

    #[test]
    fn test_read_write_unsigned_varint_32() {

        let mut vector = Cursor::new(vec![0u8; 0]);

        assert!(vector.write_unsigned_varint_32(15).is_ok());
        assert!(vector.write_unsigned_varint_32(0).is_ok());
        assert!(vector.write_unsigned_varint_32(2111111111).is_ok());
        assert!(vector.write_unsigned_varint_32(3463465).is_ok());

        vector.set_position(0);

        assert_eq!(15, vector.read_unsigned_varint_32().unwrap());
        assert_eq!(0, vector.read_unsigned_varint_32().unwrap());
        assert_eq!(2111111111, vector.read_unsigned_varint_32().unwrap());
        assert_eq!(3463465, vector.read_unsigned_varint_32().unwrap());

    }

}
<|endoftext|>


<commit_before>use std::time::{Duration, SystemTime, Instant};
use std::convert::TryFrom;

use rustc_target::abi::LayoutOf;

use crate::stacked_borrows::Tag;
use crate::*;
use helpers::{immty_from_int_checked, immty_from_uint_checked};

/// Returns the time elapsed between the provided time and the unix epoch as a `Duration`.
pub fn system_time_to_duration<'tcx>(time: &SystemTime) -> InterpResult<'tcx, Duration> {
    time.duration_since(SystemTime::UNIX_EPOCH)
        .map_err(|_| err_unsup_format!("times before the Unix epoch are not supported").into())
}

impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
    fn clock_gettime(
        &mut self,
        clk_id_op: OpTy<'tcx, Tag>,
        tp_op: OpTy<'tcx, Tag>,
    ) -> InterpResult<'tcx, i32> {
        let this = self.eval_context_mut();

        this.assert_target_os("linux", "clock_gettime");
        this.check_no_isolation("clock_gettime")?;

        let clk_id = this.read_scalar(clk_id_op)?.to_i32()?;
        let tp = this.deref_operand(tp_op)?;

        let duration = if clk_id == this.eval_libc_i32("CLOCK_REALTIME")? {
            system_time_to_duration(&SystemTime::now())?
        } else if clk_id == this.eval_libc_i32("CLOCK_MONOTONIC")? {
            // Absolute time does not matter, only relative time does, so we can just
            // use our own time anchor here.
            Instant::now().duration_since(this.machine.time_anchor)
        } else {
            let einval = this.eval_libc("EINVAL")?;
            this.set_last_error(einval)?;
            return Ok(-1);
        };

        let tv_sec = duration.as_secs();
        let tv_nsec = duration.subsec_nanos();

        let imms = [
            immty_from_int_checked(tv_sec, this.libc_ty_layout("time_t")?)?,
            immty_from_int_checked(tv_nsec, this.libc_ty_layout("c_long")?)?,
        ];

        this.write_packed_immediates(tp, &imms)?;

        Ok(0)
    }

    fn gettimeofday(
        &mut self,
        tv_op: OpTy<'tcx, Tag>,
        tz_op: OpTy<'tcx, Tag>,
    ) -> InterpResult<'tcx, i32> {
        let this = self.eval_context_mut();

        this.assert_target_os("macos", "gettimeofday");
        this.check_no_isolation("gettimeofday")?;

        // Using tz is obsolete and should always be null
        let tz = this.read_scalar(tz_op)?.not_undef()?;
        if !this.is_null(tz)? {
            let einval = this.eval_libc("EINVAL")?;
            this.set_last_error(einval)?;
            return Ok(-1);
        }

        let tv = this.deref_operand(tv_op)?;

        let duration = system_time_to_duration(&SystemTime::now())?;
        let tv_sec = duration.as_secs();
        let tv_usec = duration.subsec_micros();

        let imms = [
            immty_from_int_checked(tv_sec, this.libc_ty_layout("time_t")?)?,
            immty_from_int_checked(tv_usec, this.libc_ty_layout("suseconds_t")?)?,
        ];

        this.write_packed_immediates(tv, &imms)?;

        Ok(0)
    }

    #[allow(non_snake_case)]
    fn GetSystemTimeAsFileTime(&mut self, LPFILETIME_op: OpTy<'tcx, Tag>) -> InterpResult<'tcx> {
        let this = self.eval_context_mut();

        this.assert_target_os("windows", "GetSystemTimeAsFileTime");
        this.check_no_isolation("GetSystemTimeAsFileTime")?;

        let NANOS_PER_SEC = this.eval_windows_u64("time", "NANOS_PER_SEC")?;
        let INTERVALS_PER_SEC = this.eval_windows_u64("time", "INTERVALS_PER_SEC")?;
        let INTERVALS_TO_UNIX_EPOCH = this.eval_windows_u64("time", "INTERVALS_TO_UNIX_EPOCH")?;
        let NANOS_PER_INTERVAL = NANOS_PER_SEC / INTERVALS_PER_SEC;
        let SECONDS_TO_UNIX_EPOCH = INTERVALS_TO_UNIX_EPOCH / INTERVALS_PER_SEC;

        let duration = system_time_to_duration(&SystemTime::now())? + Duration::from_secs(SECONDS_TO_UNIX_EPOCH);
        let duration_ticks = u64::try_from(duration.as_nanos() / u128::from(NANOS_PER_INTERVAL))
            .map_err(|_| err_unsup_format!("programs running more than 2^64 Windows ticks after the Windows epoch are not supported"))?;

        let dwLowDateTime = u32::try_from(duration_ticks & 0x00000000FFFFFFFF).unwrap();
        let dwHighDateTime = u32::try_from((duration_ticks & 0xFFFFFFFF00000000) >> 32).unwrap();
        let DWORD_tylayout = this.layout_of(this.tcx.types.u32)?;
        let imms = [
            immty_from_uint_checked(dwLowDateTime, DWORD_tylayout)?,
            immty_from_uint_checked(dwHighDateTime, DWORD_tylayout)?,
        ];
        this.write_packed_immediates(this.deref_operand(LPFILETIME_op)?, &imms)?;
        Ok(())
    }

    #[allow(non_snake_case)]
    fn QueryPerformanceCounter(&mut self, lpPerformanceCount_op: OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
        let this = self.eval_context_mut();

        this.assert_target_os("windows", "QueryPerformanceCounter");
        this.check_no_isolation("QueryPerformanceCounter")?;

        // QueryPerformanceCounter uses a hardware counter as its basis.
        // Miri will emulate a counter with a resolution of 1 nanosecond.
        let duration = Instant::now().duration_since(this.machine.time_anchor);
        let qpc = i64::try_from(duration.as_nanos())
            .map_err(|_| err_unsup_format!("programs running longer than 2^63 nanoseconds are not supported"))?;
        this.write_scalar(Scalar::from_i64(qpc), this.deref_operand(lpPerformanceCount_op)?.into())?;
        Ok(-1) // return non-zero on success
    }

    #[allow(non_snake_case)]
    fn QueryPerformanceFrequency(&mut self, lpFrequency_op: OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
        let this = self.eval_context_mut();

        this.assert_target_os("windows", "QueryPerformanceFrequency");
        this.check_no_isolation("QueryPerformanceFrequency")?;

        // Retrieves the frequency of the hardware performance counter.
        // The frequency of the performance counter is fixed at system boot and
        // is consistent across all processors.
        // Miri emulates a "hardware" performance counter with a resolution of 1ns,
        // and thus 10^9 counts per second.
        this.write_scalar(Scalar::from_i64(1_000_000_000), this.deref_operand(lpFrequency_op)?.into())?;
        Ok(-1) // Return non-zero on success
    }

    fn mach_absolute_time(&self) -> InterpResult<'tcx, u64> {
        let this = self.eval_context_ref();

        this.assert_target_os("macos", "mach_absolute_time");
        this.check_no_isolation("mach_absolute_time")?;

        // This returns a u64, with time units determined dynamically by `mach_timebase_info`.
        // We return plain nanoseconds.
        let duration = Instant::now().duration_since(this.machine.time_anchor);
        u64::try_from(duration.as_nanos())
            .map_err(|_| err_unsup_format!("programs running longer than 2^64 nanoseconds are not supported").into())
    }

    fn mach_timebase_info(&mut self, info_op: OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
        let this = self.eval_context_mut();

        this.assert_target_os("macos", "mach_timebase_info");
        this.check_no_isolation("mach_timebase_info")?;

        let info = this.deref_operand(info_op)?;

        // Since we return nanoseconds instead of ticks from
        // `mach_absolute_time`, we don't need to scale the absolute
        // time.
        let (numer, denom) = (1,1);
        let imms = [
            immty_from_int_checked(numer, this.machine.layouts.u32)?,
            immty_from_int_checked(denom, this.machine.layouts.u32)?
        ];

        this.write_packed_immediates(info, &imms)?;
        Ok(0) // KERN_SUCCESS
    }
}
<commit_msg>Reword comment in mach_timebase_info<commit_after>use std::time::{Duration, SystemTime, Instant};
use std::convert::TryFrom;

use rustc_target::abi::LayoutOf;

use crate::stacked_borrows::Tag;
use crate::*;
use helpers::{immty_from_int_checked, immty_from_uint_checked};

/// Returns the time elapsed between the provided time and the unix epoch as a `Duration`.
pub fn system_time_to_duration<'tcx>(time: &SystemTime) -> InterpResult<'tcx, Duration> {
    time.duration_since(SystemTime::UNIX_EPOCH)
        .map_err(|_| err_unsup_format!("times before the Unix epoch are not supported").into())
}

impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
    fn clock_gettime(
        &mut self,
        clk_id_op: OpTy<'tcx, Tag>,
        tp_op: OpTy<'tcx, Tag>,
    ) -> InterpResult<'tcx, i32> {
        let this = self.eval_context_mut();

        this.assert_target_os("linux", "clock_gettime");
        this.check_no_isolation("clock_gettime")?;

        let clk_id = this.read_scalar(clk_id_op)?.to_i32()?;
        let tp = this.deref_operand(tp_op)?;

        let duration = if clk_id == this.eval_libc_i32("CLOCK_REALTIME")? {
            system_time_to_duration(&SystemTime::now())?
        } else if clk_id == this.eval_libc_i32("CLOCK_MONOTONIC")? {
            // Absolute time does not matter, only relative time does, so we can just
            // use our own time anchor here.
            Instant::now().duration_since(this.machine.time_anchor)
        } else {
            let einval = this.eval_libc("EINVAL")?;
            this.set_last_error(einval)?;
            return Ok(-1);
        };

        let tv_sec = duration.as_secs();
        let tv_nsec = duration.subsec_nanos();

        let imms = [
            immty_from_int_checked(tv_sec, this.libc_ty_layout("time_t")?)?,
            immty_from_int_checked(tv_nsec, this.libc_ty_layout("c_long")?)?,
        ];

        this.write_packed_immediates(tp, &imms)?;

        Ok(0)
    }

    fn gettimeofday(
        &mut self,
        tv_op: OpTy<'tcx, Tag>,
        tz_op: OpTy<'tcx, Tag>,
    ) -> InterpResult<'tcx, i32> {
        let this = self.eval_context_mut();

        this.assert_target_os("macos", "gettimeofday");
        this.check_no_isolation("gettimeofday")?;

        // Using tz is obsolete and should always be null
        let tz = this.read_scalar(tz_op)?.not_undef()?;
        if !this.is_null(tz)? {
            let einval = this.eval_libc("EINVAL")?;
            this.set_last_error(einval)?;
            return Ok(-1);
        }

        let tv = this.deref_operand(tv_op)?;

        let duration = system_time_to_duration(&SystemTime::now())?;
        let tv_sec = duration.as_secs();
        let tv_usec = duration.subsec_micros();

        let imms = [
            immty_from_int_checked(tv_sec, this.libc_ty_layout("time_t")?)?,
            immty_from_int_checked(tv_usec, this.libc_ty_layout("suseconds_t")?)?,
        ];

        this.write_packed_immediates(tv, &imms)?;

        Ok(0)
    }

    #[allow(non_snake_case)]
    fn GetSystemTimeAsFileTime(&mut self, LPFILETIME_op: OpTy<'tcx, Tag>) -> InterpResult<'tcx> {
        let this = self.eval_context_mut();

        this.assert_target_os("windows", "GetSystemTimeAsFileTime");
        this.check_no_isolation("GetSystemTimeAsFileTime")?;

        let NANOS_PER_SEC = this.eval_windows_u64("time", "NANOS_PER_SEC")?;
        let INTERVALS_PER_SEC = this.eval_windows_u64("time", "INTERVALS_PER_SEC")?;
        let INTERVALS_TO_UNIX_EPOCH = this.eval_windows_u64("time", "INTERVALS_TO_UNIX_EPOCH")?;
        let NANOS_PER_INTERVAL = NANOS_PER_SEC / INTERVALS_PER_SEC;
        let SECONDS_TO_UNIX_EPOCH = INTERVALS_TO_UNIX_EPOCH / INTERVALS_PER_SEC;

        let duration = system_time_to_duration(&SystemTime::now())? + Duration::from_secs(SECONDS_TO_UNIX_EPOCH);
        let duration_ticks = u64::try_from(duration.as_nanos() / u128::from(NANOS_PER_INTERVAL))
            .map_err(|_| err_unsup_format!("programs running more than 2^64 Windows ticks after the Windows epoch are not supported"))?;

        let dwLowDateTime = u32::try_from(duration_ticks & 0x00000000FFFFFFFF).unwrap();
        let dwHighDateTime = u32::try_from((duration_ticks & 0xFFFFFFFF00000000) >> 32).unwrap();
        let DWORD_tylayout = this.layout_of(this.tcx.types.u32)?;
        let imms = [
            immty_from_uint_checked(dwLowDateTime, DWORD_tylayout)?,
            immty_from_uint_checked(dwHighDateTime, DWORD_tylayout)?,
        ];
        this.write_packed_immediates(this.deref_operand(LPFILETIME_op)?, &imms)?;
        Ok(())
    }

    #[allow(non_snake_case)]
    fn QueryPerformanceCounter(&mut self, lpPerformanceCount_op: OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
        let this = self.eval_context_mut();

        this.assert_target_os("windows", "QueryPerformanceCounter");
        this.check_no_isolation("QueryPerformanceCounter")?;

        // QueryPerformanceCounter uses a hardware counter as its basis.
        // Miri will emulate a counter with a resolution of 1 nanosecond.
        let duration = Instant::now().duration_since(this.machine.time_anchor);
        let qpc = i64::try_from(duration.as_nanos())
            .map_err(|_| err_unsup_format!("programs running longer than 2^63 nanoseconds are not supported"))?;
        this.write_scalar(Scalar::from_i64(qpc), this.deref_operand(lpPerformanceCount_op)?.into())?;
        Ok(-1) // return non-zero on success
    }

    #[allow(non_snake_case)]
    fn QueryPerformanceFrequency(&mut self, lpFrequency_op: OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
        let this = self.eval_context_mut();

        this.assert_target_os("windows", "QueryPerformanceFrequency");
        this.check_no_isolation("QueryPerformanceFrequency")?;

        // Retrieves the frequency of the hardware performance counter.
        // The frequency of the performance counter is fixed at system boot and
        // is consistent across all processors.
        // Miri emulates a "hardware" performance counter with a resolution of 1ns,
        // and thus 10^9 counts per second.
        this.write_scalar(Scalar::from_i64(1_000_000_000), this.deref_operand(lpFrequency_op)?.into())?;
        Ok(-1) // Return non-zero on success
    }

    fn mach_absolute_time(&self) -> InterpResult<'tcx, u64> {
        let this = self.eval_context_ref();

        this.assert_target_os("macos", "mach_absolute_time");
        this.check_no_isolation("mach_absolute_time")?;

        // This returns a u64, with time units determined dynamically by `mach_timebase_info`.
        // We return plain nanoseconds.
        let duration = Instant::now().duration_since(this.machine.time_anchor);
        u64::try_from(duration.as_nanos())
            .map_err(|_| err_unsup_format!("programs running longer than 2^64 nanoseconds are not supported").into())
    }

    fn mach_timebase_info(&mut self, info_op: OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
        let this = self.eval_context_mut();

        this.assert_target_os("macos", "mach_timebase_info");
        this.check_no_isolation("mach_timebase_info")?;

        let info = this.deref_operand(info_op)?;

        // Since our emulated ticks in `mach_absolute_time` *are* nanoseconds,
        // no scaling needs to happen.
        let (numer, denom) = (1,1);
        let imms = [
            immty_from_int_checked(numer, this.machine.layouts.u32)?,
            immty_from_int_checked(denom, this.machine.layouts.u32)?
        ];

        this.write_packed_immediates(info, &imms)?;
        Ok(0) // KERN_SUCCESS
    }
}
<|endoftext|>