<commit_before>use std::fmt;
use std::path;

use super::*;

#[derive(Debug, Eq, PartialEq, Default, Clone, serde::Serialize, serde::Deserialize)]
#[serde(default)]
#[serde(rename_all = "snake_case")]
#[cfg_attr(feature = "unstable", serde(deny_unknown_fields))]
#[cfg_attr(not(feature = "unstable"), non_exhaustive)]
pub struct Frontmatter {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub permalink: Option<Permalink>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub slug: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub title: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub description: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub excerpt: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub categories: Option<Vec<String>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub tags: Option<Vec<String>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub excerpt_separator: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub published_date: Option<DateTime>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub format: Option<SourceFormat>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub templated: Option<bool>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub layout: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub is_draft: Option<bool>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub weight: Option<i32>,
    #[serde(skip_serializing_if = "liquid_core::Object::is_empty")]
    pub data: liquid_core::Object,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub pagination: Option<Pagination>,
    // Controlled by where the file is found.  We might allow control over the type at a later
    // point but we need to first define those semantics.
    #[serde(skip)]
    pub collection: Option<String>,
}

impl Frontmatter {
    pub fn empty() -> Self {
        Self::default()
    }

    pub fn merge_path(mut self, relpath: &path::Path) -> Self {
        if let Some(name) = relpath.file_name().and_then(|f| f.to_str()) {
            let mut split_name = crate::path::split_ext(name);

            #[cfg(feature = "preview_unstable")]
            if split_name.1 == Some("liquid") {
                self.templated.get_or_insert(true);
                split_name = crate::path::split_ext(split_name.0);
            } else {
                self.templated.get_or_insert(false);
            }

            let format = match split_name.1 {
                Some("md") => SourceFormat::Markdown,
                Some("wiki") => SourceFormat::Vimwiki,
                _ => SourceFormat::Raw,
            };
            self.format.get_or_insert(format);

            while split_name.1.is_some() {
                split_name = crate::path::split_ext(split_name.0);
            }

            if self.published_date.is_none() || self.slug.is_none() {
                let file_stem = split_name.0;
                let (file_date, file_stem) = crate::path::parse_file_stem(file_stem);
                if self.published_date.is_none() {
                    self.published_date = file_date;
                }
                if self.slug.is_none() {
                    let slug = crate::path::slugify(file_stem);
                    if self.title.is_none() {
                        self.title = Some(crate::path::titleize_slug(&slug));
                    }
                    self.slug = Some(slug);
                }
            }
        }

        self
    }

    pub fn merge(self, other: &Self) -> Self {
        let Self {
            permalink,
            slug,
            title,
            description,
            excerpt,
            categories,
            tags,
            excerpt_separator,
            published_date,
            format,
            templated,
            layout,
            is_draft,
            weight,
            collection,
            data,
            pagination,
        } = self;
        Self {
            permalink: permalink.or_else(|| other.permalink.clone()),
            slug: slug.or_else(|| other.slug.clone()),
            title: title.or_else(|| other.title.clone()),
            description: description.or_else(|| other.description.clone()),
            excerpt: excerpt.or_else(|| other.excerpt.clone()),
            categories: categories.or_else(|| other.categories.clone()),
            tags: tags.or_else(|| other.tags.clone()),
            excerpt_separator: excerpt_separator.or_else(|| other.excerpt_separator.clone()),
            published_date: published_date.or(other.published_date),
            format: format.or(other.format),
            templated: templated.or(other.templated),
            layout: layout.or_else(|| other.layout.clone()),
            is_draft: is_draft.or(other.is_draft),
            weight: weight.or(other.weight),
            collection: collection.or_else(|| other.collection.clone()),
            data: merge_objects(data, &other.data),
            pagination: merge_pagination(pagination, &other.pagination),
        }
    }
}

impl fmt::Display for Frontmatter {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let converted = serde_yaml::to_string(self).ok();
        if converted.as_deref() == Some("---\n{}") {
            Ok(())
        } else {
            write!(f, "{}", &converted.unwrap()[4..])
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "snake_case")]
#[cfg_attr(feature = "unstable", serde(deny_unknown_fields))]
#[cfg_attr(not(feature = "unstable"), non_exhaustive)]
pub enum PermalinkAlias {
    Path,
    #[cfg(not(feature = "unstable"))]
    #[doc(hidden)]
    #[serde(other)]
    Unknown,
}

#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
#[serde(untagged)]
#[cfg_attr(feature = "unstable", serde(deny_unknown_fields))]
#[cfg_attr(not(feature = "unstable"), non_exhaustive)]
pub enum Permalink {
    Alias(PermalinkAlias),
    Explicit(String),
}

impl Permalink {
    pub fn as_str(&self) -> &str {
        match self {
            Permalink::Alias(PermalinkAlias::Path) => "/{{parent}}/{{name}}{{ext}}",
            #[cfg(not(feature = "unstable"))]
            Permalink::Alias(PermalinkAlias::Unknown) => unreachable!("private variant"),
            Permalink::Explicit(path) => path.as_str(),
        }
    }
}

impl Default for Permalink {
    fn default() -> Self {
        Permalink::Alias(PermalinkAlias::Path)
    }
}

impl fmt::Display for Permalink {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.as_str())
    }
}

#[derive(Debug, Eq, PartialEq, Hash, Copy, Clone, serde::Serialize, serde::Deserialize)]
#[cfg_attr(feature = "preview_unstable", serde(rename_all = "snake_case"))]
#[cfg_attr(feature = "unstable", serde(deny_unknown_fields))]
#[cfg_attr(not(feature = "unstable"), non_exhaustive)]
pub enum SourceFormat {
    Raw,
    Markdown,
    Vimwiki,
    #[cfg(not(feature = "unstable"))]
    #[doc(hidden)]
    #[serde(other)]
    Unknown,
}

impl Default for SourceFormat {
    fn default() -> SourceFormat {
        SourceFormat::Raw
    }
}

/// Shallow merge of `liquid_core::Object`'s
fn merge_objects(
    mut primary: liquid_core::Object,
    secondary: &liquid_core::Object,
) -> liquid_core::Object {
    for (key, value) in secondary {
        primary
            .entry(key.to_owned())
            .or_insert_with(|| value.clone());
    }
    primary
}

fn merge_pagination(
    primary: Option<Pagination>,
    secondary: &Option<Pagination>,
) -> Option<Pagination> {
    if let Some(primary) = primary {
        if let Some(secondary) = secondary {
            Some(primary.merge(secondary))
        } else {
            Some(primary)
        }
    } else {
        secondary.clone()
    }
}

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

    #[test]
    fn display_empty() {
        let front = Frontmatter::empty();
        assert_eq!(&front.to_string(), "");
    }

    #[test]
    fn display_slug() {
        let front = Frontmatter {
            slug: Some("foo".to_owned()),
            ..Default::default()
        };
        assert_eq!(&front.to_string(), "slug: foo");
    }

    #[test]
    fn display_permalink_alias() {
        let front = Frontmatter {
            permalink: Some(Permalink::Alias(PermalinkAlias::Path)),
            ..Default::default()
        };
        assert_eq!(&front.to_string(), "permalink: path");
    }

    #[test]
    fn display_permalink_explicit() {
        let front = Frontmatter {
            permalink: Some(Permalink::Explicit("foo".to_owned())),
            ..Default::default()
        };
        assert_eq!(&front.to_string(), "permalink: foo");
    }
}
<commit_msg>fix(config): Port yaml fix over<commit_after>use std::fmt;
use std::path;

use super::*;

#[derive(Debug, Eq, PartialEq, Default, Clone, serde::Serialize, serde::Deserialize)]
#[serde(default)]
#[serde(rename_all = "snake_case")]
#[cfg_attr(feature = "unstable", serde(deny_unknown_fields))]
#[cfg_attr(not(feature = "unstable"), non_exhaustive)]
pub struct Frontmatter {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub permalink: Option<Permalink>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub slug: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub title: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub description: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub excerpt: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub categories: Option<Vec<String>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub tags: Option<Vec<String>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub excerpt_separator: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub published_date: Option<DateTime>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub format: Option<SourceFormat>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub templated: Option<bool>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub layout: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub is_draft: Option<bool>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub weight: Option<i32>,
    #[serde(skip_serializing_if = "liquid_core::Object::is_empty")]
    pub data: liquid_core::Object,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub pagination: Option<Pagination>,
    // Controlled by where the file is found.  We might allow control over the type at a later
    // point but we need to first define those semantics.
    #[serde(skip)]
    pub collection: Option<String>,
}

impl Frontmatter {
    pub fn empty() -> Self {
        Self::default()
    }

    pub fn merge_path(mut self, relpath: &path::Path) -> Self {
        if let Some(name) = relpath.file_name().and_then(|f| f.to_str()) {
            let mut split_name = crate::path::split_ext(name);

            #[cfg(feature = "preview_unstable")]
            if split_name.1 == Some("liquid") {
                self.templated.get_or_insert(true);
                split_name = crate::path::split_ext(split_name.0);
            } else {
                self.templated.get_or_insert(false);
            }

            let format = match split_name.1 {
                Some("md") => SourceFormat::Markdown,
                Some("wiki") => SourceFormat::Vimwiki,
                _ => SourceFormat::Raw,
            };
            self.format.get_or_insert(format);

            while split_name.1.is_some() {
                split_name = crate::path::split_ext(split_name.0);
            }

            if self.published_date.is_none() || self.slug.is_none() {
                let file_stem = split_name.0;
                let (file_date, file_stem) = crate::path::parse_file_stem(file_stem);
                if self.published_date.is_none() {
                    self.published_date = file_date;
                }
                if self.slug.is_none() {
                    let slug = crate::path::slugify(file_stem);
                    if self.title.is_none() {
                        self.title = Some(crate::path::titleize_slug(&slug));
                    }
                    self.slug = Some(slug);
                }
            }
        }

        self
    }

    pub fn merge(self, other: &Self) -> Self {
        let Self {
            permalink,
            slug,
            title,
            description,
            excerpt,
            categories,
            tags,
            excerpt_separator,
            published_date,
            format,
            templated,
            layout,
            is_draft,
            weight,
            collection,
            data,
            pagination,
        } = self;
        Self {
            permalink: permalink.or_else(|| other.permalink.clone()),
            slug: slug.or_else(|| other.slug.clone()),
            title: title.or_else(|| other.title.clone()),
            description: description.or_else(|| other.description.clone()),
            excerpt: excerpt.or_else(|| other.excerpt.clone()),
            categories: categories.or_else(|| other.categories.clone()),
            tags: tags.or_else(|| other.tags.clone()),
            excerpt_separator: excerpt_separator.or_else(|| other.excerpt_separator.clone()),
            published_date: published_date.or(other.published_date),
            format: format.or(other.format),
            templated: templated.or(other.templated),
            layout: layout.or_else(|| other.layout.clone()),
            is_draft: is_draft.or(other.is_draft),
            weight: weight.or(other.weight),
            collection: collection.or_else(|| other.collection.clone()),
            data: merge_objects(data, &other.data),
            pagination: merge_pagination(pagination, &other.pagination),
        }
    }
}

impl fmt::Display for Frontmatter {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let converted = serde_yaml::to_string(self).expect("should always be valid");
        let subset = converted
            .strip_prefix("---")
            .unwrap_or_else(|| converted.as_str())
            .trim();
        let converted = if subset == "{}" { "" } else { subset };
        if converted.is_empty() {
            Ok(())
        } else {
            write!(f, "{}", converted)
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "snake_case")]
#[cfg_attr(feature = "unstable", serde(deny_unknown_fields))]
#[cfg_attr(not(feature = "unstable"), non_exhaustive)]
pub enum PermalinkAlias {
    Path,
    #[cfg(not(feature = "unstable"))]
    #[doc(hidden)]
    #[serde(other)]
    Unknown,
}

#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
#[serde(untagged)]
#[cfg_attr(feature = "unstable", serde(deny_unknown_fields))]
#[cfg_attr(not(feature = "unstable"), non_exhaustive)]
pub enum Permalink {
    Alias(PermalinkAlias),
    Explicit(String),
}

impl Permalink {
    pub fn as_str(&self) -> &str {
        match self {
            Permalink::Alias(PermalinkAlias::Path) => "/{{parent}}/{{name}}{{ext}}",
            #[cfg(not(feature = "unstable"))]
            Permalink::Alias(PermalinkAlias::Unknown) => unreachable!("private variant"),
            Permalink::Explicit(path) => path.as_str(),
        }
    }
}

impl Default for Permalink {
    fn default() -> Self {
        Permalink::Alias(PermalinkAlias::Path)
    }
}

impl fmt::Display for Permalink {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.as_str())
    }
}

#[derive(Debug, Eq, PartialEq, Hash, Copy, Clone, serde::Serialize, serde::Deserialize)]
#[cfg_attr(feature = "preview_unstable", serde(rename_all = "snake_case"))]
#[cfg_attr(feature = "unstable", serde(deny_unknown_fields))]
#[cfg_attr(not(feature = "unstable"), non_exhaustive)]
pub enum SourceFormat {
    Raw,
    Markdown,
    Vimwiki,
    #[cfg(not(feature = "unstable"))]
    #[doc(hidden)]
    #[serde(other)]
    Unknown,
}

impl Default for SourceFormat {
    fn default() -> SourceFormat {
        SourceFormat::Raw
    }
}

/// Shallow merge of `liquid_core::Object`'s
fn merge_objects(
    mut primary: liquid_core::Object,
    secondary: &liquid_core::Object,
) -> liquid_core::Object {
    for (key, value) in secondary {
        primary
            .entry(key.to_owned())
            .or_insert_with(|| value.clone());
    }
    primary
}

fn merge_pagination(
    primary: Option<Pagination>,
    secondary: &Option<Pagination>,
) -> Option<Pagination> {
    if let Some(primary) = primary {
        if let Some(secondary) = secondary {
            Some(primary.merge(secondary))
        } else {
            Some(primary)
        }
    } else {
        secondary.clone()
    }
}

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

    #[test]
    fn display_empty() {
        let front = Frontmatter::empty();
        assert_eq!(&front.to_string(), "");
    }

    #[test]
    fn display_slug() {
        let front = Frontmatter {
            slug: Some("foo".to_owned()),
            ..Default::default()
        };
        assert_eq!(&front.to_string(), "slug: foo");
    }

    #[test]
    fn display_permalink_alias() {
        let front = Frontmatter {
            permalink: Some(Permalink::Alias(PermalinkAlias::Path)),
            ..Default::default()
        };
        assert_eq!(&front.to_string(), "permalink: path");
    }

    #[test]
    fn display_permalink_explicit() {
        let front = Frontmatter {
            permalink: Some(Permalink::Explicit("foo".to_owned())),
            ..Default::default()
        };
        assert_eq!(&front.to_string(), "permalink: foo");
    }
}
<|endoftext|>


<commit_before>use futures::{task, Sink, Poll, Async, AsyncSink, sync::mpsc, stream::Stream};
use tokio::net::TcpStream;
use std::net::SocketAddr;
use tokio_codec::Framed;
use std::{fmt, io};

use super::rpc::*;

type Tx = mpsc::UnboundedSender<RpcPayload>;
type Rx = mpsc::UnboundedReceiver<RpcPayload>;
type RpcFrame = Framed<TcpStream, codec::RpcCodec>;

#[repr(u8)]
#[derive(Copy, Clone, Debug)]
pub enum ClientType {
    NODE,
    WALLET
}

#[derive(Clone)]
pub struct Sender(Tx);

impl Sender {
    #[inline]
    pub fn send(&self, payload: RpcPayload) {
        self.0.unbounded_send(payload).unwrap();
    }
}

pub struct Peer {
    pub client_type: ClientType,
    pub addr: SocketAddr,
    tx: Tx,
    rx: Rx,
    frame: RpcFrame
}

impl Peer {
    pub fn new(client_type: ClientType,
                addr: SocketAddr,
                frame: RpcFrame) -> Peer {
        let (tx, rx) = mpsc::unbounded();
        Peer {
            client_type,
            frame,
            addr,
            tx,
            rx
        }
    }

    pub fn get_sender(&self) -> Sender {
        Sender(self.tx.clone())
    }
}

impl fmt::Debug for Peer {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Peer {{ client_type: {:?}, addr: {:?} }}",
                &self.client_type,
                &self.addr)
    }
}

impl Stream for Peer {
    type Item = RpcPayload;
    type Error = io::Error;

    fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
        if let Async::Ready(msg) = self.frame.poll()? {
            if let Some(msg) = msg {
                return Ok(Async::Ready(Some(msg)))
            } else {
                return Ok(Async::Ready(None))
            }
        }

        while let Async::Ready(msg) = self.rx.poll().unwrap() {
            if let Some(msg) = msg {
                let res = self.frame.start_send(msg).unwrap();
                match res {
                    AsyncSink::Ready => {},
                    AsyncSink::NotReady(msg) => {
                        self.tx.unbounded_send(msg).unwrap();
                        task::current().notify();
                        break;
                    }
                }
            }
        }
        self.frame.poll_complete()?;

        Ok(Async::NotReady)
    }
}

impl ::std::ops::Drop for Peer {
    fn drop(&mut self) {
        debug!("Peer dropped: {:?}", self);
    }
}
<commit_msg>Simplify polling on Peers<commit_after>use futures::{task, Sink, Poll, Async, AsyncSink, sync::mpsc, stream::Stream};
use tokio::net::TcpStream;
use std::net::SocketAddr;
use tokio_codec::Framed;
use std::{fmt, io};

use super::rpc::*;

type Tx = mpsc::UnboundedSender<RpcPayload>;
type Rx = mpsc::UnboundedReceiver<RpcPayload>;
type RpcFrame = Framed<TcpStream, codec::RpcCodec>;

#[repr(u8)]
#[derive(Copy, Clone, Debug)]
pub enum ClientType {
    NODE,
    WALLET
}

#[derive(Clone)]
pub struct Sender(Tx);

impl Sender {
    #[inline]
    pub fn send(&self, payload: RpcPayload) {
        self.0.unbounded_send(payload).unwrap();
    }
}

pub struct Peer {
    pub client_type: ClientType,
    pub addr: SocketAddr,
    tx: Tx,
    rx: Rx,
    frame: RpcFrame
}

impl Peer {
    pub fn new(client_type: ClientType,
                addr: SocketAddr,
                frame: RpcFrame) -> Peer {
        let (tx, rx) = mpsc::unbounded();
        Peer {
            client_type,
            frame,
            addr,
            tx,
            rx
        }
    }

    pub fn get_sender(&self) -> Sender {
        Sender(self.tx.clone())
    }
}

impl fmt::Debug for Peer {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Peer {{ client_type: {:?}, addr: {:?} }}",
                &self.client_type,
                &self.addr)
    }
}

impl Stream for Peer {
    type Item = RpcPayload;
    type Error = io::Error;

    fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
        if let Async::Ready(msg) = self.frame.poll()? {
            return Ok(Async::Ready(msg))
        }

        while let Async::Ready(msg) = self.rx.poll().unwrap() {
            if let Some(msg) = msg {
                let res = self.frame.start_send(msg).unwrap();
                match res {
                    AsyncSink::Ready => {},
                    AsyncSink::NotReady(msg) => {
                        self.tx.unbounded_send(msg).unwrap();
                        task::current().notify();
                        break;
                    }
                }
            }
        }
        self.frame.poll_complete()?;

        Ok(Async::NotReady)
    }
}

impl ::std::ops::Drop for Peer {
    fn drop(&mut self) {
        debug!("Peer dropped: {:?}", self);
    }
}
<|endoftext|>


<commit_before>use basetypes::*;

// "CastlingRights" holds information about which player (white or
// black) is allowed to castle on which side (queen-side or
// king-side).
//
// The lowest 4 bits of the value contain the whole needed
// information. It is laid out the following way:
//
//  usize                                             3           0
//  +-----------------------------------------------+---+---+---+---+
//  |                                               |   |   |   |   |
//  |                   Unused                      |Castling flags |
//  |                                               |   |   |   |   |
//  +-----------------------------------------------+---+---+---+---+
//
//  bit 0 -- if set, white can castle on queen-side;
//  bit 1 -- if set, white can castle on king-side;
//  bit 2 -- if set, black can castle on queen-side;
//  bit 3 -- if set, black can castle on king-side.
#[derive(Debug)]
#[derive(Clone, Copy)]
pub struct CastlingRights(usize);

impl CastlingRights {
    // Create a new instance.
    #[inline(always)]
    pub fn new() -> CastlingRights {
        CastlingRights(0)
    }

    // Get the contained raw value.
    #[inline(always)]
    pub fn get_value(&self) -> usize {
        self.0
    }

    // Grant castling rights according to a given 4-bit mask (bit-wise
    // OR-ing the previous value with "mask").
    //
    // Returns which bits were zero before, and were turned to one.
    pub fn grant(&mut self, mask: usize) -> usize {
        if mask > 0b1111 {
            panic!("invalid mask");
        }
        let before = self.0;
        self.0 |= mask;
        !before & mask
    }

    // Update the castling rights with a 4-bit mask (bit-wise AND-ing
    // the previous value with "mask").
    #[inline(always)]
    pub fn update_with_mask(&mut self, mask: usize) {
        self.0 &= mask;
    }

    // Return if the player "color" can castle on the given "side".
    #[inline(always)]
    pub fn can_castle(&self, color: Color, side: CastlingSide) -> bool {
        assert!(color <= 1);
        assert!(side <= 1);
        (1 << (color << 1) << side) & self.0 != 0
    }

    // Return a bitboard with the set of squares that should be vacant
    // in order for the specified ("color", "side") castling move to
    // be possible.
    #[inline(always)]
    pub fn obstacles(&self, color: Color, side: CastlingSide) -> u64 {
        const OBSTACLES: [[u64; 2]; 2] = [[1 << B1 | 1 << C1 | 1 << D1, 1 << F1 | 1 << G1],
                                          [1 << B8 | 1 << C8 | 1 << D8, 1 << F8 | 1 << G8]];
        if self.can_castle(color, side) {
            OBSTACLES[color][side]
        } else {
            // Castling is not allowed, therefore every piece on every
            // square on the board can be considered an obstacle.
            UNIVERSAL_SET
        }
    }

    // Return a 2-bit value representing the castling rights for the
    // player "color".
    #[inline(always)]
    pub fn get_for(&self, color: Color) -> usize {
        assert!(color <= 1);
        if color == WHITE {
            self.0 & 0b0011
        } else {
            self.0 >> 2
        }
    }

    // Set the castling rights for the player "color" with a 2-bit
    // value ("rights").
    #[inline(always)]
    pub fn set_for(&mut self, color: Color, rights: usize) {
        assert!(color <= 1);
        if rights > 0b11 {
            // Since the raw value of "CastlingRights" frequently is used
            // as an array index without boundary checking, we guarantee
            // that the raw value is always less than 16 by sanitizing the
            // passed "rights".
            panic!("invalid castling rights");
        }
        self.0 = if color == WHITE {
            self.0 & 0b1100 | rights
        } else {
            self.0 & 0b0011 | rights << 2
        }
    }
}

// Castling flags
pub const CASTLE_WHITE_QUEENSIDE: usize = 1 << 0;
pub const CASTLE_WHITE_KINGSIDE: usize = 1 << 1;
pub const CASTLE_BLACK_QUEENSIDE: usize = 1 << 2;
pub const CASTLE_BLACK_KINGSIDE: usize = 1 << 3;
<commit_msg>Relax inline attribures<commit_after>use basetypes::*;

// "CastlingRights" holds information about which player (white or
// black) is allowed to castle on which side (queen-side or
// king-side).
//
// The lowest 4 bits of the value contain the whole needed
// information. It is laid out the following way:
//
//  usize                                             3           0
//  +-----------------------------------------------+---+---+---+---+
//  |                                               |   |   |   |   |
//  |                   Unused                      |Castling flags |
//  |                                               |   |   |   |   |
//  +-----------------------------------------------+---+---+---+---+
//
//  bit 0 -- if set, white can castle on queen-side;
//  bit 1 -- if set, white can castle on king-side;
//  bit 2 -- if set, black can castle on queen-side;
//  bit 3 -- if set, black can castle on king-side.
#[derive(Debug)]
#[derive(Clone, Copy)]
pub struct CastlingRights(usize);

impl CastlingRights {
    // Create a new instance.
    #[inline(always)]
    pub fn new() -> CastlingRights {
        CastlingRights(0)
    }

    // Get the contained raw value.
    #[inline(always)]
    pub fn get_value(&self) -> usize {
        self.0
    }

    // Grant castling rights according to a given 4-bit mask (bit-wise
    // OR-ing the previous value with "mask").
    //
    // Returns which bits were zero before, and were turned to one.
    pub fn grant(&mut self, mask: usize) -> usize {
        if mask > 0b1111 {
            panic!("invalid mask");
        }
        let before = self.0;
        self.0 |= mask;
        !before & mask
    }

    // Update the castling rights with a 4-bit mask (bit-wise AND-ing
    // the previous value with "mask").
    #[inline(always)]
    pub fn update_with_mask(&mut self, mask: usize) {
        self.0 &= mask;
    }

    // Return if the player "color" can castle on the given "side".
    #[inline(always)]
    pub fn can_castle(&self, color: Color, side: CastlingSide) -> bool {
        assert!(color <= 1);
        assert!(side <= 1);
        (1 << (color << 1) << side) & self.0 != 0
    }

    // Return a bitboard with the set of squares that should be vacant
    // in order for the specified ("color", "side") castling move to
    // be possible.
    #[inline]
    pub fn obstacles(&self, color: Color, side: CastlingSide) -> u64 {
        const OBSTACLES: [[u64; 2]; 2] = [[1 << B1 | 1 << C1 | 1 << D1, 1 << F1 | 1 << G1],
                                          [1 << B8 | 1 << C8 | 1 << D8, 1 << F8 | 1 << G8]];
        if self.can_castle(color, side) {
            OBSTACLES[color][side]
        } else {
            // Castling is not allowed, therefore every piece on every
            // square on the board can be considered an obstacle.
            UNIVERSAL_SET
        }
    }

    // Return a 2-bit value representing the castling rights for the
    // player "color".
    #[inline(always)]
    pub fn get_for(&self, color: Color) -> usize {
        assert!(color <= 1);
        if color == WHITE {
            self.0 & 0b0011
        } else {
            self.0 >> 2
        }
    }

    // Set the castling rights for the player "color" with a 2-bit
    // value ("rights").
    #[inline]
    pub fn set_for(&mut self, color: Color, rights: usize) {
        assert!(color <= 1);
        if rights > 0b11 {
            // Since the raw value of "CastlingRights" frequently is used
            // as an array index without boundary checking, we guarantee
            // that the raw value is always less than 16 by sanitizing the
            // passed "rights".
            panic!("invalid castling rights");
        }
        self.0 = if color == WHITE {
            self.0 & 0b1100 | rights
        } else {
            self.0 & 0b0011 | rights << 2
        }
    }
}

// Castling flags
pub const CASTLE_WHITE_QUEENSIDE: usize = 1 << 0;
pub const CASTLE_WHITE_KINGSIDE: usize = 1 << 1;
pub const CASTLE_BLACK_QUEENSIDE: usize = 1 << 2;
pub const CASTLE_BLACK_KINGSIDE: usize = 1 << 3;
<|endoftext|>


<commit_before>#![deny(missing_docs, warnings)]
#![feature(macro_rules)]

//! The `zip!` macro

/// This macro emulates an "any-arity" free function that zips iterators
///
/// **Note** This macro calls `into_iter()` on the inputs. For this reason, this macro won't work
/// until `IntoIterator` lands in stdlib, or unless you provide your own `IntoIterator` trait.
///
/// # Examples
///
/// ```
/// # #![feature(phase)]
/// # extern crate zip;
/// # #[phase(plugin)]
/// # extern crate zip_macros;
/// # use std::slice;
/// # trait IntoIterator<T, I> where I: Iterator<T> {
/// #     fn into_iter(self) -> I;
/// # }
/// # impl<T, I> IntoIterator<T, I> for I where I: Iterator<T> {
/// #     fn into_iter(self) -> I { self }
/// # }
/// # impl<'a, T> IntoIterator<&'a T, slice::Iter<'a, T>> for &'a [T] {
/// #     fn into_iter(self) -> slice::Iter<'a, T> { self.iter() }
/// # }
/// # impl<'a, T> IntoIterator<&'a mut T, slice::IterMut<'a, T>> for &'a mut [T] {
/// #     fn into_iter(self) -> slice::IterMut<'a, T> { self.iter_mut() }
/// # }
/// # fn main() {
/// let chars = &['a', 'b', 'c'];
/// let mut v = vec![0u, 1, 2];
///
/// for (&c, i, &mut j) in zip!(chars, range(0u, 5), &mut *v) {
///     assert!(i < 3);
///     assert_eq!(i, j);
/// }
/// # }
/// ```
#[macro_export]
macro_rules! zip {
    ($a:expr, $b:expr) => {
        ::zip::Zip2(($a).into_iter(), ($b).into_iter())
    };
    ($a:expr, $b:expr, $c:expr) => {
        ::zip::Zip3(($a).into_iter(), ($b).into_iter(), ($c).into_iter())
    };
    ($a:expr, $b:expr, $c:expr, $d:expr) => {
        ::zip::Zip4(($a).into_iter(), ($b).into_iter(), ($c).into_iter(), ($d).into_iter())
    };
    ($a:expr, $b:expr, $c:expr, $d:expr, $e:expr) => {
        ::zip::Zip5(
            ($a).into_iter(),
            ($b).into_iter(),
            ($c).into_iter(),
            ($d).into_iter(),
            ($e).into_iter(),
        )
    };
    ($($x:expr),+,) => { zip!($($x),+) }
}
<commit_msg>fix(doctest): update to rust nightly<commit_after>#![deny(missing_docs, warnings)]
#![feature(macro_rules)]

//! The `zip!` macro

/// This macro emulates an "any-arity" free function that zips iterators
///
/// **Note** This macro calls `into_iter()` on the inputs. For this reason, this macro won't work
/// until `IntoIterator` lands in stdlib, or unless you provide your own `IntoIterator` trait.
///
/// # Examples
///
/// ```
/// # #![feature(phase)]
/// # extern crate zip;
/// # #[phase(plugin)]
/// # extern crate zip_macros;
/// # use std::slice;
/// # trait IntoIterator<T, I> where I: Iterator<Item=T> {
/// #     fn into_iter(self) -> I;
/// # }
/// # impl<T, I> IntoIterator<T, I> for I where I: Iterator<Item=T> {
/// #     fn into_iter(self) -> I { self }
/// # }
/// # impl<'a, T> IntoIterator<&'a T, slice::Iter<'a, T>> for &'a [T] {
/// #     fn into_iter(self) -> slice::Iter<'a, T> { self.iter() }
/// # }
/// # impl<'a, T> IntoIterator<&'a mut T, slice::IterMut<'a, T>> for &'a mut [T] {
/// #     fn into_iter(self) -> slice::IterMut<'a, T> { self.iter_mut() }
/// # }
/// # fn main() {
/// let chars = &['a', 'b', 'c'];
/// let mut v = vec![0u, 1, 2];
///
/// for (&c, i, &mut j) in zip!(chars, range(0u, 5), &mut *v) {
///     assert!(i < 3);
///     assert_eq!(i, j);
/// }
/// # }
/// ```
#[macro_export]
macro_rules! zip {
    ($a:expr, $b:expr) => {
        ::zip::Zip2(($a).into_iter(), ($b).into_iter())
    };
    ($a:expr, $b:expr, $c:expr) => {
        ::zip::Zip3(($a).into_iter(), ($b).into_iter(), ($c).into_iter())
    };
    ($a:expr, $b:expr, $c:expr, $d:expr) => {
        ::zip::Zip4(($a).into_iter(), ($b).into_iter(), ($c).into_iter(), ($d).into_iter())
    };
    ($a:expr, $b:expr, $c:expr, $d:expr, $e:expr) => {
        ::zip::Zip5(
            ($a).into_iter(),
            ($b).into_iter(),
            ($c).into_iter(),
            ($d).into_iter(),
            ($e).into_iter(),
        )
    };
    ($($x:expr),+,) => { zip!($($x),+) }
}
<|endoftext|>


<commit_before>//! [Mocktopus](https://docs.rs/mocktopus) procedural macros making items mockable
#![doc(html_logo_url = "https://raw.githubusercontent.com/CodeSandwich/mocktopus/master/logo.png",
    html_favicon_url = "https://raw.githubusercontent.com/CodeSandwich/mocktopus/master/logo.png")]

#![feature(iterator_for_each, proc_macro)]

extern crate proc_macro;
extern crate proc_macro2;
extern crate syn;
extern crate quote;

mod display_delegate;
mod item_injector;
mod header_builder;
mod lifetime_remover;

use proc_macro::TokenStream;
use quote::ToTokens;

/// Procedural macro, makes items and their sub-items mockable
///
/// # Valid to annotate
/// - module definitions (makes all its valid to annotate items annotated, even if stored in another file)
///
/// ```
/// #[mockable]
/// mod module {
///     mod nested {
///         fn mockable() { ... }
///     }
/// }
/// ```
/// - standalone functions
///
/// ```
/// #[mockable]
/// fn mockable() { ... }
/// ```
/// - struct impl blocks (makes all functions inside mockable)
///
/// ```
/// #[mockable]
/// impl Structure {
///     fn mockable() { ... }
/// }
/// ```
/// - trait impl blocks (makes all functions inside mockable)
///
/// ```
/// #[mockable]
/// impl Trait for Structure {
///     fn mockable() { ... }
/// }
/// ```
/// - traits (makes all default functions inside mockable)
///
/// ```
/// #[mockable]
/// trait Trait {
///     fn mockable() { ... }
/// }
/// ```
/// # Invalid to annotate **(WILL FAIL TO COMPILE OR BREAK MOCKING!)**
///
/// - single functions in struct impls
///
/// ```
/// impl Structure {
///     #[mockable] //INVALID USAGE!
///     fn mockable() { ... }
/// }
/// ```
/// - single functions in trait impls
///
/// ```
/// impl Trait for Structure {
///     #[mockable] //INVALID USAGE!
///     fn mockable() { ... }
/// }
/// ```
/// - single default functions in traits
///
/// ```
/// trait Trait {
///     #[mockable] //INVALID USAGE!
///     fn mockable() { ... }
/// }
/// ```
///
/// # Indifferent to annotate
/// - already mockable items (inside annotated modules)
/// - const functions (they are impossible to mock)
/// - unsafe functions (they are impossible to mock)
/// - any macro generated items (they are impossible to mock)
/// - any other items
#[proc_macro_attribute]
pub fn mockable(_: TokenStream, token_stream: TokenStream) -> TokenStream {
    let mut item: syn::Item = syn::parse(token_stream).unwrap();
    item_injector::inject_item(&mut item);
    item.into_tokens().into()
}

/// Procedural macro, guards items from being made mockable by enclosing item.
///
/// # Valid to annotate
/// - module definitions
///
/// ```
/// #[mockable]
/// mod module {
///     #[not_mockable]
///     mod nested {
///         fn not_mockable() { ... }
///     }
/// }
/// ```
/// - standalone functions
///
/// ```
/// #[mockable]
/// mod module {
///     #[not_mockable]
///     fn not_mockable() { ... }
/// }
/// ```
/// - struct impl blocks
///
/// ```
/// #[mockable]
/// mod module {
///     #[not_mockable]
///     impl Struct {
///         fn not_mockable() { ... }
///     }
/// }
/// ```
/// - trait impl blocks
///
/// ```
/// #[mockable]
/// mod module {
///     #[not_mockable]
///     impl Trait for Struct {
///         fn not_mockable() { ... }
///     }
/// }
/// ```
/// - traits
///
/// ```
/// #[mockable]
/// mod module {
///     #[not_mockable]
///     trait Trait {
///         fn not_mockable() { ... }
///     }
/// }
/// ```
/// - single functions in struct impls
///
/// ```
/// #[mockable]
/// impl Struct {
///     #[not_mockable]
///     fn not_mockable() { ... }
/// }
/// ```
/// - single functions in trait impls
///
/// ```
/// #[mockable]
/// impl Trait for Struct {
///     #[not_mockable]
///     fn not_mockable() { ... }
/// }
/// ```
/// - single default functions in traits
///
/// ```
/// #[mockable]
/// trait Trait {
///     #[not_mockable]
///     fn not_mockable() { ... }
/// }
/// ```
///
/// # Indifferent to annotate
/// - items not made mockable by enclosing item
/// - any other items
#[proc_macro_attribute]
pub fn not_mockable(_: TokenStream, token_stream: TokenStream) -> TokenStream {
    token_stream
}

<commit_msg>Make annotated item parse failure only raise error and not fail compilation<commit_after>//! [Mocktopus](https://docs.rs/mocktopus) procedural macros making items mockable
#![doc(html_logo_url = "https://raw.githubusercontent.com/CodeSandwich/mocktopus/master/logo.png",
    html_favicon_url = "https://raw.githubusercontent.com/CodeSandwich/mocktopus/master/logo.png")]

#![feature(iterator_for_each, proc_macro)]

extern crate proc_macro;
extern crate proc_macro2;
extern crate syn;
extern crate quote;

mod display_delegate;
mod item_injector;
mod header_builder;
mod lifetime_remover;

use proc_macro::{Diagnostic, Level, Span, TokenStream};
use quote::ToTokens;

/// Procedural macro, makes items and their sub-items mockable
///
/// # Valid to annotate
/// - module definitions (makes all its valid to annotate items annotated, even if stored in another file)
///
/// ```
/// #[mockable]
/// mod module {
///     mod nested {
///         fn mockable() { ... }
///     }
/// }
/// ```
/// - standalone functions
///
/// ```
/// #[mockable]
/// fn mockable() { ... }
/// ```
/// - struct impl blocks (makes all functions inside mockable)
///
/// ```
/// #[mockable]
/// impl Structure {
///     fn mockable() { ... }
/// }
/// ```
/// - trait impl blocks (makes all functions inside mockable)
///
/// ```
/// #[mockable]
/// impl Trait for Structure {
///     fn mockable() { ... }
/// }
/// ```
/// - traits (makes all default functions inside mockable)
///
/// ```
/// #[mockable]
/// trait Trait {
///     fn mockable() { ... }
/// }
/// ```
/// # Invalid to annotate **(WILL FAIL TO COMPILE OR BREAK MOCKING!)**
///
/// - single functions in struct impls
///
/// ```
/// impl Structure {
///     #[mockable] //INVALID USAGE!
///     fn mockable() { ... }
/// }
/// ```
/// - single functions in trait impls
///
/// ```
/// impl Trait for Structure {
///     #[mockable] //INVALID USAGE!
///     fn mockable() { ... }
/// }
/// ```
/// - single default functions in traits
///
/// ```
/// trait Trait {
///     #[mockable] //INVALID USAGE!
///     fn mockable() { ... }
/// }
/// ```
///
/// # Indifferent to annotate
/// - already mockable items (inside annotated modules)
/// - const functions (they are impossible to mock)
/// - unsafe functions (they are impossible to mock)
/// - any macro generated items (they are impossible to mock)
/// - any other items
#[proc_macro_attribute]
pub fn mockable(_: TokenStream, token_stream: TokenStream) -> TokenStream {
    let mut item: syn::Item = match syn::parse(token_stream.clone()) {
        Ok(item) => item,
        Err(err) => {
            Span::call_site()
                .warning("Failed to make code mockable")
                .error(format!("Failed to parse: {}", err))
                .emit();
            return token_stream;
        }
    };
    item_injector::inject_item(&mut item);
    item.into_tokens().into()
}

/// Procedural macro, guards items from being made mockable by enclosing item.
///
/// # Valid to annotate
/// - module definitions
///
/// ```
/// #[mockable]
/// mod module {
///     #[not_mockable]
///     mod nested {
///         fn not_mockable() { ... }
///     }
/// }
/// ```
/// - standalone functions
///
/// ```
/// #[mockable]
/// mod module {
///     #[not_mockable]
///     fn not_mockable() { ... }
/// }
/// ```
/// - struct impl blocks
///
/// ```
/// #[mockable]
/// mod module {
///     #[not_mockable]
///     impl Struct {
///         fn not_mockable() { ... }
///     }
/// }
/// ```
/// - trait impl blocks
///
/// ```
/// #[mockable]
/// mod module {
///     #[not_mockable]
///     impl Trait for Struct {
///         fn not_mockable() { ... }
///     }
/// }
/// ```
/// - traits
///
/// ```
/// #[mockable]
/// mod module {
///     #[not_mockable]
///     trait Trait {
///         fn not_mockable() { ... }
///     }
/// }
/// ```
/// - single functions in struct impls
///
/// ```
/// #[mockable]
/// impl Struct {
///     #[not_mockable]
///     fn not_mockable() { ... }
/// }
/// ```
/// - single functions in trait impls
///
/// ```
/// #[mockable]
/// impl Trait for Struct {
///     #[not_mockable]
///     fn not_mockable() { ... }
/// }
/// ```
/// - single default functions in traits
///
/// ```
/// #[mockable]
/// trait Trait {
///     #[not_mockable]
///     fn not_mockable() { ... }
/// }
/// ```
///
/// # Indifferent to annotate
/// - items not made mockable by enclosing item
/// - any other items
#[proc_macro_attribute]
pub fn not_mockable(_: TokenStream, token_stream: TokenStream) -> TokenStream {
    token_stream
}

<|endoftext|>


<commit_before>import std._uint;
import std._int;
import front.ast;

type filename = str;
type pos = rec(uint line, uint col);
type span = rec(filename filename, pos lo, pos hi);
type spanned[T] = rec(T node, span span);

tag ty_mach {
    ty_i8;
    ty_i16;
    ty_i32;
    ty_i64;

    ty_u8;
    ty_u16;
    ty_u32;
    ty_u64;

    ty_f32;
    ty_f64;
}

fn ty_mach_to_str(ty_mach tm) -> str {
    alt (tm) {
        case (ty_u8) { ret "u8"; }
        case (ty_u16) { ret "u16"; }
        case (ty_u32) { ret "u32"; }
        case (ty_u64) { ret "u64"; }

        case (ty_i8) { ret "i8"; }
        case (ty_i16) { ret "i16"; }
        case (ty_i32) { ret "i32"; }
        case (ty_i64) { ret "i64"; }

        case (ty_f32) { ret "f32"; }
        case (ty_f64) { ret "f64"; }
    }
}

fn new_str_hash[V]() -> std.map.hashmap[str,V] {
    let std.map.hashfn[str] hasher = std._str.hash;
    let std.map.eqfn[str] eqer = std._str.eq;
    ret std.map.mk_hashmap[str,V](hasher, eqer);
}

fn new_def_hash[V]() -> std.map.hashmap[ast.def_id,V] {

    fn hash(&ast.def_id d) -> uint {
        let uint u = d._0 as uint;
        u <<= 16u;
        u |= d._1 as uint;
        ret u;
    }

    fn eq(&ast.def_id a, &ast.def_id b) -> bool {
        ret a._0 == b._0 && a._1 == b._1;
    }

    let std.map.hashfn[ast.def_id] hasher = hash;
    let std.map.eqfn[ast.def_id] eqer = eq;
    ret std.map.mk_hashmap[ast.def_id,V](hasher, eqer);
}

fn istr(int i) -> str {
    ret _int.to_str(i, 10u);
}

// FIXME: Weird bug. Due to the way we auto-deref + in +=, we can't append a
// boxed value to a vector-of-boxes using +=.  Best to figure out a way to fix
// this. Deref-on-demand or something? It's a hazard of the ambiguity between
// single-element and vector append.
fn append[T](&mutable vec[T] v, &T t) {
    v += t;
}

//
// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C ../.. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
//
<commit_msg>rustc: Expose common.def_eq().<commit_after>import std._uint;
import std._int;
import front.ast;

type filename = str;
type pos = rec(uint line, uint col);
type span = rec(filename filename, pos lo, pos hi);
type spanned[T] = rec(T node, span span);

tag ty_mach {
    ty_i8;
    ty_i16;
    ty_i32;
    ty_i64;

    ty_u8;
    ty_u16;
    ty_u32;
    ty_u64;

    ty_f32;
    ty_f64;
}

fn ty_mach_to_str(ty_mach tm) -> str {
    alt (tm) {
        case (ty_u8) { ret "u8"; }
        case (ty_u16) { ret "u16"; }
        case (ty_u32) { ret "u32"; }
        case (ty_u64) { ret "u64"; }

        case (ty_i8) { ret "i8"; }
        case (ty_i16) { ret "i16"; }
        case (ty_i32) { ret "i32"; }
        case (ty_i64) { ret "i64"; }

        case (ty_f32) { ret "f32"; }
        case (ty_f64) { ret "f64"; }
    }
}

fn new_str_hash[V]() -> std.map.hashmap[str,V] {
    let std.map.hashfn[str] hasher = std._str.hash;
    let std.map.eqfn[str] eqer = std._str.eq;
    ret std.map.mk_hashmap[str,V](hasher, eqer);
}

fn def_eq(&ast.def_id a, &ast.def_id b) -> bool {
    ret a._0 == b._0 && a._1 == b._1;
}

fn new_def_hash[V]() -> std.map.hashmap[ast.def_id,V] {

    fn hash(&ast.def_id d) -> uint {
        let uint u = d._0 as uint;
        u <<= 16u;
        u |= d._1 as uint;
        ret u;
    }

    let std.map.hashfn[ast.def_id] hasher = hash;
    let std.map.eqfn[ast.def_id] eqer = def_eq;
    ret std.map.mk_hashmap[ast.def_id,V](hasher, eqer);
}

fn istr(int i) -> str {
    ret _int.to_str(i, 10u);
}

// FIXME: Weird bug. Due to the way we auto-deref + in +=, we can't append a
// boxed value to a vector-of-boxes using +=.  Best to figure out a way to fix
// this. Deref-on-demand or something? It's a hazard of the ambiguity between
// single-element and vector append.
fn append[T](&mutable vec[T] v, &T t) {
    v += t;
}

//
// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C ../.. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
//
<|endoftext|>


<commit_before>// Copyright (c) 2013-2015 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

use mio::util::Slab;
use mio::Socket;
use {EventPort, Promise, PromiseFulfiller, Result, new_promise_and_fulfiller};
use private::{with_current_event_loop};

pub trait MutBuf {
    fn mut_bytes<'a>(&'a mut self) -> &'a mut [u8];
}

pub trait Buf {
    fn bytes<'a>(&'a self) -> &'a [u8];
}

impl MutBuf for Vec<u8> {
    fn mut_bytes<'a>(&'a mut self) -> &'a mut [u8] {
        self
    }
}

impl <T> Buf for T where T: AsRef<[u8]> {
    fn bytes<'a>(&'a self) -> &'a [u8] {
        self.as_ref()
    }
}

pub trait AsyncRead {
    fn read<T>(self: Self, buf: T, min_bytes: usize, max_bytes: usize) -> Promise<(Self, T, usize)>
        where T: MutBuf;
}

pub trait AsyncWrite {
    fn write<T>(self: Self, buf: T) -> Promise<(Self, T)>
        where T: Buf;
}

#[derive(Copy, Clone)]
pub struct NetworkAddress {
    address: ::std::net::SocketAddr,
}

impl NetworkAddress {
    pub fn new(address: ::std::net::SocketAddr) -> NetworkAddress {
        NetworkAddress { address: address }
    }

    pub fn listen(self) -> Result<ConnectionReceiver> {
        let socket = try!(::mio::tcp::TcpSocket::v4());
        try!(socket.set_reuseaddr(true));
        try!(socket.bind(&self.address));
        let token = FdObserver::new();
        Ok(ConnectionReceiver { listener: try!(socket.listen(256)),
                                token: token })
    }

    pub fn connect(self) -> Promise<AsyncIoStream> {
        let socket = ::mio::tcp::TcpSocket::v4().unwrap();
        let token = FdObserver::new();
        let (stream, _) = socket.connect(&self.address).unwrap();
        with_current_event_loop(move |event_loop| {
            event_loop.event_port.borrow_mut().reactor.register_opt(&stream, token,
                                                                    ::mio::Interest::writable(),
                                                                    ::mio::PollOpt::edge()|
                                                                    ::mio::PollOpt::oneshot()).unwrap();
            let promise =
                event_loop.event_port.borrow_mut().handler.observers[token].when_becomes_writable();
            return promise.map(move |()| {
                // TODO check for error.

                return with_current_event_loop(move |event_loop| {
                    event_loop.event_port.borrow_mut().reactor.reregister(
                        &stream, token,
                        ::mio::Interest::writable() | ::mio::Interest::readable(),
                        ::mio::PollOpt::edge()).unwrap();
                    return Ok(AsyncIoStream { stream: stream, token: token });
                });

            });
        })
    }
}

pub struct ConnectionReceiver {
    listener: ::mio::tcp::TcpListener,
    token: ::mio::Token,
}

impl Drop for ConnectionReceiver {
    fn drop(&mut self) {
        // deregister the token
    }
}

impl ConnectionReceiver {
    pub fn accept(self) -> Promise<(ConnectionReceiver, AsyncIoStream)> {
        with_current_event_loop(move |event_loop| {
            let promise =
                event_loop.event_port.borrow_mut().handler.observers[self.token].when_becomes_readable();
            event_loop.event_port.borrow_mut().reactor.register_opt(&self.listener, self.token,
                                                                    ::mio::Interest::readable(),
                                                                    ::mio::PollOpt::edge()|
                                                                    ::mio::PollOpt::oneshot()).unwrap();
            return promise.map(move |()| {
                let stream = try!(self.listener.accept()).unwrap();
                let token = FdObserver::new();
                return Ok((self, AsyncIoStream::new(stream, token)));
            });
        })
    }
}

#[allow(dead_code)]
pub struct AsyncIoStream {
    stream: ::mio::tcp::TcpStream,
    token: ::mio::Token,
}

impl AsyncIoStream {
    fn new(stream: ::mio::tcp::TcpStream, token: ::mio::Token) -> AsyncIoStream {
        with_current_event_loop(move |event_loop| {
            event_loop.event_port.borrow_mut().reactor.register_opt(
                &stream, token,
                ::mio::Interest::readable() | ::mio::Interest::writable(),
                ::mio::PollOpt::level()).unwrap();
            AsyncIoStream { stream: stream, token: token }
        })
    }

    fn read_internal<T>(mut self,
                        mut buf: T,
                        start: usize,
                        min_bytes: usize,
                        max_bytes: usize) -> Promise<(Self, T, usize)> where T: MutBuf {
        if start >= min_bytes {
            return Promise::fulfilled((self, buf, start));
        } else {
            with_current_event_loop(move |event_loop| {
                let promise =
                    event_loop.event_port.borrow_mut().handler.observers[self.token].when_becomes_readable();
                return promise.then(move |()| {
                    use mio::TryRead;
                    let n = try!(self.stream.read_slice(&mut buf.mut_bytes()[start..])).unwrap();
                    return Ok(self.read_internal(buf, start + n, min_bytes, max_bytes));
                });
            })
        }
    }

    fn write_internal<T>(mut self,
                         buf: T,
                         cursor: usize) -> Promise<(Self, T)> where T: Buf {
        if cursor == buf.bytes().len() {
            return Promise::fulfilled((self, buf));
        } else {
            with_current_event_loop(move |event_loop| {
                let promise =
                    event_loop.event_port.borrow_mut().handler.observers[self.token].when_becomes_writable();
                return promise.then(move |()| {
                    use mio::TryWrite;
                    let n = try!(self.stream.write_slice(&buf.bytes()[cursor..])).unwrap();
                    return Ok(self.write_internal(buf, cursor + n));
                });
            })
        }
    }
}

impl AsyncRead for AsyncIoStream {
    fn read<T>(self, buf: T,
               min_bytes: usize,
               max_bytes: usize) -> Promise<(Self, T, usize)> where T: MutBuf {
        self.read_internal(buf, 0, min_bytes, max_bytes)
    }
}

impl AsyncWrite for AsyncIoStream {
    fn write<T>(self, buf: T) -> Promise<(Self, T)> where T: Buf {
        self.write_internal(buf, 0)
    }
}

pub struct FdObserver {
    read_fulfiller: Option<Box<PromiseFulfiller<()>>>,
    write_fulfiller: Option<Box<PromiseFulfiller<()>>>,
}

impl FdObserver {
    pub fn new() -> ::mio::Token {
        with_current_event_loop(move |event_loop| {

            let observer = FdObserver { read_fulfiller: None, write_fulfiller: None };
            let event_port = &mut *event_loop.event_port.borrow_mut();
            let token = match event_port.handler.observers.insert(observer) {
                Ok(tok) => tok,
                Err(_obs) => panic!("could not insert observer."),
            };
            return token;
        })
    }

    pub fn when_becomes_readable(&mut self) -> Promise<()> {
        let (promise, fulfiller) = new_promise_and_fulfiller();
        self.read_fulfiller = Some(fulfiller);
        return promise;
    }

    pub fn when_becomes_writable(&mut self) -> Promise<()> {
        let (promise, fulfiller) = new_promise_and_fulfiller();
        self.write_fulfiller = Some(fulfiller);
        return promise;
    }
}

pub struct MioEventPort {
    handler: Handler,
    reactor: ::mio::EventLoop<Handler>,
}

pub struct Handler {
    observers: Slab<FdObserver>,
}

impl MioEventPort {
    pub fn new() -> Result<MioEventPort> {
        Ok(MioEventPort {
            handler: Handler { observers: Slab::new(100) },
            reactor: try!(::mio::EventLoop::new()),
        })
    }
}

impl ::mio::Handler for Handler {
    type Timeout = ();
    type Message = ();
    fn readable(&mut self, _event_loop: &mut ::mio::EventLoop<Handler>,
                token: ::mio::Token, _hint: ::mio::ReadHint) {
        match ::std::mem::replace(&mut self.observers[token].read_fulfiller, None) {
            Some(fulfiller) => {
                fulfiller.fulfill(())
            }
            None => {
                ()
            }
        }
    }
    fn writable(&mut self, _event_loop: &mut ::mio::EventLoop<Handler>, token: ::mio::Token) {
        match ::std::mem::replace(&mut self.observers[token].write_fulfiller, None) {
            Some(fulfiller) => fulfiller.fulfill(()),
            None => (),
        }
    }
}

impl EventPort for MioEventPort {
    fn wait(&mut self) -> bool {
        self.reactor.run_once(&mut self.handler).unwrap();
        return false;
    }

    fn poll(&mut self) -> bool {
        self.reactor.run_once(&mut self.handler).unwrap();
        return false;
    }
}

// alternate approach below =========

pub enum StepResult<S, T> {
   TheresMore(S),
   Done(T)
}

/// Intermediate state for a reading a T.
pub trait AsyncReadState<T> {

   /// Reads as much as possible without blocking. If done, returns the final T value. Otherwise
   /// returns the new intermediate state T.
   fn read_step(self, r: &mut ::std::io::Read) -> ::std::io::Result<StepResult<Self, T>>;
}

/// Gives back `r` once the T has been completely read.
pub fn read_async<R, S, T>(_r: R, _state: S) -> Promise<(R, T)>
  where R: ::std::io::Read + 'static,
        S: AsyncReadState<T> + 'static,
        T: 'static {
            unimplemented!();
}
<commit_msg>Use Deref and DerefMut.<commit_after>// Copyright (c) 2013-2015 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

use std::ops::{DerefMut, Deref};
use mio::util::Slab;
use mio::Socket;
use {EventPort, Promise, PromiseFulfiller, Result, new_promise_and_fulfiller};
use private::{with_current_event_loop};

pub trait AsyncRead {
    fn read<T>(self: Self, buf: T, min_bytes: usize, max_bytes: usize) -> Promise<(Self, T, usize)>
        where T: DerefMut<Target=[u8]>;
}

pub trait AsyncWrite {
    fn write<T>(self: Self, buf: T) -> Promise<(Self, T)>
        where T: Deref<Target=[u8]>;
}

#[derive(Copy, Clone)]
pub struct NetworkAddress {
    address: ::std::net::SocketAddr,
}

impl NetworkAddress {
    pub fn new(address: ::std::net::SocketAddr) -> NetworkAddress {
        NetworkAddress { address: address }
    }

    pub fn listen(self) -> Result<ConnectionReceiver> {
        let socket = try!(::mio::tcp::TcpSocket::v4());
        try!(socket.set_reuseaddr(true));
        try!(socket.bind(&self.address));
        let token = FdObserver::new();
        Ok(ConnectionReceiver { listener: try!(socket.listen(256)),
                                token: token })
    }

    pub fn connect(self) -> Promise<AsyncIoStream> {
        let socket = ::mio::tcp::TcpSocket::v4().unwrap();
        let token = FdObserver::new();
        let (stream, _) = socket.connect(&self.address).unwrap();
        with_current_event_loop(move |event_loop| {
            event_loop.event_port.borrow_mut().reactor.register_opt(&stream, token,
                                                                    ::mio::Interest::writable(),
                                                                    ::mio::PollOpt::edge()|
                                                                    ::mio::PollOpt::oneshot()).unwrap();
            let promise =
                event_loop.event_port.borrow_mut().handler.observers[token].when_becomes_writable();
            return promise.map(move |()| {
                // TODO check for error.

                return with_current_event_loop(move |event_loop| {
                    event_loop.event_port.borrow_mut().reactor.reregister(
                        &stream, token,
                        ::mio::Interest::writable() | ::mio::Interest::readable(),
                        ::mio::PollOpt::edge()).unwrap();
                    return Ok(AsyncIoStream { stream: stream, token: token });
                });

            });
        })
    }
}

pub struct ConnectionReceiver {
    listener: ::mio::tcp::TcpListener,
    token: ::mio::Token,
}

impl Drop for ConnectionReceiver {
    fn drop(&mut self) {
        // deregister the token
    }
}

impl ConnectionReceiver {
    pub fn accept(self) -> Promise<(ConnectionReceiver, AsyncIoStream)> {
        with_current_event_loop(move |event_loop| {
            let promise =
                event_loop.event_port.borrow_mut().handler.observers[self.token].when_becomes_readable();
            event_loop.event_port.borrow_mut().reactor.register_opt(&self.listener, self.token,
                                                                    ::mio::Interest::readable(),
                                                                    ::mio::PollOpt::edge()|
                                                                    ::mio::PollOpt::oneshot()).unwrap();
            return promise.map(move |()| {
                let stream = try!(self.listener.accept()).unwrap();
                let token = FdObserver::new();
                return Ok((self, AsyncIoStream::new(stream, token)));
            });
        })
    }
}

#[allow(dead_code)]
pub struct AsyncIoStream {
    stream: ::mio::tcp::TcpStream,
    token: ::mio::Token,
}

impl AsyncIoStream {
    fn new(stream: ::mio::tcp::TcpStream, token: ::mio::Token) -> AsyncIoStream {
        with_current_event_loop(move |event_loop| {
            event_loop.event_port.borrow_mut().reactor.register_opt(
                &stream, token,
                ::mio::Interest::readable() | ::mio::Interest::writable(),
                ::mio::PollOpt::level()).unwrap();
            AsyncIoStream { stream: stream, token: token }
        })
    }

    fn read_internal<T>(mut self,
                        mut buf: T,
                        start: usize,
                        min_bytes: usize,
                        max_bytes: usize) -> Promise<(Self, T, usize)> where T: DerefMut<Target=[u8]> {
        if start >= min_bytes {
            return Promise::fulfilled((self, buf, start));
        } else {
            with_current_event_loop(move |event_loop| {
                let promise =
                    event_loop.event_port.borrow_mut().handler.observers[self.token].when_becomes_readable();
                return promise.then(move |()| {
                    use mio::TryRead;
                    let n = try!(self.stream.read_slice(&mut buf[start..])).unwrap();
                    return Ok(self.read_internal(buf, start + n, min_bytes, max_bytes));
                });
            })
        }
    }

    fn write_internal<T>(mut self,
                         buf: T,
                         cursor: usize) -> Promise<(Self, T)> where T: Deref<Target=[u8]> {
        if cursor == buf.len() {
            return Promise::fulfilled((self, buf));
        } else {
            with_current_event_loop(move |event_loop| {
                let promise =
                    event_loop.event_port.borrow_mut().handler.observers[self.token].when_becomes_writable();
                return promise.then(move |()| {
                    use mio::TryWrite;
                    let n = try!(self.stream.write_slice(&buf[cursor..])).unwrap();
                    return Ok(self.write_internal(buf, cursor + n));
                });
            })
        }
    }
}

impl AsyncRead for AsyncIoStream {
    fn read<T>(self, buf: T,
               min_bytes: usize,
               max_bytes: usize) -> Promise<(Self, T, usize)> where T: DerefMut<Target=[u8]> {
        self.read_internal(buf, 0, min_bytes, max_bytes)
    }
}

impl AsyncWrite for AsyncIoStream {
    fn write<T>(self, buf: T) -> Promise<(Self, T)> where T: Deref<Target=[u8]> {
        self.write_internal(buf, 0)
    }
}

pub struct FdObserver {
    read_fulfiller: Option<Box<PromiseFulfiller<()>>>,
    write_fulfiller: Option<Box<PromiseFulfiller<()>>>,
}

impl FdObserver {
    pub fn new() -> ::mio::Token {
        with_current_event_loop(move |event_loop| {

            let observer = FdObserver { read_fulfiller: None, write_fulfiller: None };
            let event_port = &mut *event_loop.event_port.borrow_mut();
            let token = match event_port.handler.observers.insert(observer) {
                Ok(tok) => tok,
                Err(_obs) => panic!("could not insert observer."),
            };
            return token;
        })
    }

    pub fn when_becomes_readable(&mut self) -> Promise<()> {
        let (promise, fulfiller) = new_promise_and_fulfiller();
        self.read_fulfiller = Some(fulfiller);
        return promise;
    }

    pub fn when_becomes_writable(&mut self) -> Promise<()> {
        let (promise, fulfiller) = new_promise_and_fulfiller();
        self.write_fulfiller = Some(fulfiller);
        return promise;
    }
}

pub struct MioEventPort {
    handler: Handler,
    reactor: ::mio::EventLoop<Handler>,
}

pub struct Handler {
    observers: Slab<FdObserver>,
}

impl MioEventPort {
    pub fn new() -> Result<MioEventPort> {
        Ok(MioEventPort {
            handler: Handler { observers: Slab::new(100) },
            reactor: try!(::mio::EventLoop::new()),
        })
    }
}

impl ::mio::Handler for Handler {
    type Timeout = ();
    type Message = ();
    fn readable(&mut self, _event_loop: &mut ::mio::EventLoop<Handler>,
                token: ::mio::Token, _hint: ::mio::ReadHint) {
        match ::std::mem::replace(&mut self.observers[token].read_fulfiller, None) {
            Some(fulfiller) => {
                fulfiller.fulfill(())
            }
            None => {
                ()
            }
        }
    }
    fn writable(&mut self, _event_loop: &mut ::mio::EventLoop<Handler>, token: ::mio::Token) {
        match ::std::mem::replace(&mut self.observers[token].write_fulfiller, None) {
            Some(fulfiller) => fulfiller.fulfill(()),
            None => (),
        }
    }
}

impl EventPort for MioEventPort {
    fn wait(&mut self) -> bool {
        self.reactor.run_once(&mut self.handler).unwrap();
        return false;
    }

    fn poll(&mut self) -> bool {
        self.reactor.run_once(&mut self.handler).unwrap();
        return false;
    }
}

// alternate approach below =========

pub enum StepResult<S, T> {
   TheresMore(S),
   Done(T)
}

/// Intermediate state for a reading a T.
pub trait AsyncReadState<T> {

   /// Reads as much as possible without blocking. If done, returns the final T value. Otherwise
   /// returns the new intermediate state T.
   fn read_step(self, r: &mut ::std::io::Read) -> ::std::io::Result<StepResult<Self, T>>;
}

/// Gives back `r` once the T has been completely read.
pub fn read_async<R, S, T>(_r: R, _state: S) -> Promise<(R, T)>
  where R: ::std::io::Read + 'static,
        S: AsyncReadState<T> + 'static,
        T: 'static {
            unimplemented!();
}
<|endoftext|>


<commit_before>// Copyright (c) 2013-2015 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

use std::rc::Rc;
use std::cell::RefCell;
use std::ops::{DerefMut, Deref};
use handle_table::{HandleTable, Handle};
use {EventPort, Promise, PromiseFulfiller, Result, new_promise_and_fulfiller};
use private::{with_current_event_loop};

/// A nonblocking input bytestream.
pub trait AsyncRead : 'static {

    /// Attempts to read `buf.len()` bytes from the stream, writing them into `buf`.
    /// Returns `self`, the modified `buf`, and the number of bytes actually read.
    /// Returns as soon as `min_bytes` are read or EOF is encountered.
    fn try_read<T>(self: Self, buf: T, min_bytes: usize) -> Promise<(Self, T, usize)>
        where T: DerefMut<Target=[u8]>;

    /// Like `try_read()`, but returns an error if EOF is encountered before `min_bytes`
    /// can be read.
    fn read<T>(self: Self, buf: T, min_bytes: usize) -> Promise<(Self, T, usize)>
        where T: DerefMut<Target=[u8]>, Self: Sized
    {
        return self.try_read(buf, min_bytes).map(move |(s, buf, n)| {
            if n < min_bytes {
                return Err(Box::new(::std::io::Error::new(::std::io::ErrorKind::Other, "Premature EOF")))
            } else {
                return Ok((s, buf, n));
            }
        });
    }
}

/// A nonblocking output bytestream.
pub trait AsyncWrite : 'static {
    /// Attempts to write all `buf.len()` bytes from `buf` into the stream. Returns `self` and `buf`
    /// once all of the bytes have been written.
    fn write<T>(self: Self, buf: T) -> Promise<(Self, T)> where T: Deref<Target=[u8]>;
}

pub struct Slice<T> where T: Deref<Target=[u8]> {
    pub buf: T,
    pub end: usize,
}

impl <T> Slice<T> where T: Deref<Target=[u8]> {
    pub fn new(buf: T, end: usize) -> Slice<T> {
        Slice { buf: buf, end: end }
    }
}

impl <T> Deref for Slice<T> where T: Deref<Target=[u8]> {
    type Target=[u8];
    fn deref<'a>(&'a self) -> &'a [u8] {
        &self.buf[0..self.end]
    }
}

#[derive(Copy, Clone)]
pub struct NetworkAddress {
    address: ::std::net::SocketAddr,
}

impl NetworkAddress {
    pub fn new<T : ::std::net::ToSocketAddrs>(address: T) -> Result<NetworkAddress> {
        match try!(address.to_socket_addrs()).next() {
            Some(addr) => return Ok(NetworkAddress { address: addr }),
            None => unimplemented!(),
        }
    }

    pub fn listen(self) -> Result<ConnectionReceiver> {
        let socket = try!(::mio::tcp::TcpSocket::v4());
        try!(socket.set_reuseaddr(true));
        try!(socket.bind(&self.address));
        let handle = FdObserver::new();
        let listener = try!(socket.listen(256));

        return with_current_event_loop(move |event_loop| {
            try!(event_loop.event_port.borrow_mut().reactor.register_opt(&listener, ::mio::Token(handle.val),
                                                                         ::mio::Interest::readable(),
                                                                         ::mio::PollOpt::edge()));
            Ok(ConnectionReceiver { listener: listener,
                                    handle: handle })
        });
    }

    pub fn connect(self) -> Promise<(AsyncOutputStream, AsyncInputStream)> {
        let socket = ::mio::tcp::TcpSocket::v4().unwrap();
        let handle = FdObserver::new();
        let token = ::mio::Token(handle.val);
        let (stream, _) = socket.connect(&self.address).unwrap();
        with_current_event_loop(move |event_loop| {
            event_loop.event_port.borrow_mut().reactor.register_opt(&stream, token,
                                                                    ::mio::Interest::writable(),
                                                                    ::mio::PollOpt::edge()).unwrap();
            let promise =
                event_loop.event_port.borrow_mut().handler.observers[handle].when_becomes_writable();
            return promise.map(move |()| {
                // TODO check for error.

                return with_current_event_loop(move |event_loop| {
                    try!(event_loop.event_port.borrow_mut().reactor.reregister(
                        &stream, token,
                        ::mio::Interest::writable() | ::mio::Interest::readable(),
                        ::mio::PollOpt::edge()));
                    return Ok(AsyncIo::new(stream, handle));
                });

            });
        })
    }
}

pub struct ConnectionReceiver {
    listener: ::mio::tcp::TcpListener,
    handle: Handle,
}

impl Drop for ConnectionReceiver {
    fn drop(&mut self) {
        // deregister the token
    }
}

impl ConnectionReceiver {

    fn accept_internal(self) -> Result<Promise<(ConnectionReceiver, (AsyncOutputStream, AsyncInputStream))>> {
        let accept_result = try!(self.listener.accept());
        match accept_result {
            Some(stream) => {
                let handle = FdObserver::new();
                return with_current_event_loop(move |event_loop| {
                    try!(event_loop.event_port.borrow_mut().reactor.register_opt(
                        &stream, ::mio::Token(handle.val),
                        ::mio::Interest::writable() | ::mio::Interest::readable(),
                        ::mio::PollOpt::edge()));
                    return Ok(Promise::fulfilled((self, AsyncIo::new(stream, handle))));
                });
            }
            None => {
                return with_current_event_loop(move |event_loop| {
                    let promise =
                        event_loop.event_port.borrow_mut().handler.observers[self.handle].when_becomes_readable();
                    return Ok(promise.then(move |()| {
                        return self.accept_internal();
                    }));
                });
            }
        }
    }

    pub fn accept(self) -> Promise<(ConnectionReceiver, (AsyncOutputStream, AsyncInputStream))> {
        return Promise::fulfilled(()).then(move |()| {return self.accept_internal(); });
    }
}

pub struct AsyncInputStream {
    hub: Rc<RefCell<AsyncIo>>
}

pub struct AsyncOutputStream {
    hub: Rc<RefCell<AsyncIo>>
}

struct AsyncIo {
    stream: ::mio::tcp::TcpStream,
    handle: Handle,
}

impl AsyncIo {
    fn new(stream: ::mio::tcp::TcpStream, handle: Handle) -> (AsyncOutputStream, AsyncInputStream) {
        let hub = Rc::new(RefCell::new(AsyncIo { stream: stream, handle: handle }));

        (AsyncOutputStream { hub: hub.clone() }, AsyncInputStream { hub: hub } )
    }
}

impl AsyncInputStream {
    fn try_read_internal<T>(self,
                            mut buf: T,
                            mut already_read: usize,
                            min_bytes: usize) -> Result<Promise<(Self, T, usize)>> where T: DerefMut<Target=[u8]> {
        use mio::TryRead;

        while already_read < min_bytes {
            let read_result = try!(self.hub.borrow_mut().stream.read_slice(&mut buf[already_read..]));
            match read_result {
                Some(0) => {
                    // EOF
                    return Ok(Promise::fulfilled((self, buf, already_read)));
                }
                Some(n) => {
                    already_read += n;
                }
                None => { // would block
                    return with_current_event_loop(move |event_loop| {
                        let promise =
                            event_loop.event_port.borrow_mut()
                            .handler.observers[self.hub.borrow().handle].when_becomes_readable();
                        return Ok(promise.then(move |()| {
                            return self.try_read_internal(buf, already_read, min_bytes);
                        }));
                    });
                }
            }
        }

        return Ok(Promise::fulfilled((self, buf, already_read)));
    }
}

impl AsyncOutputStream {
    fn write_internal<T>(self,
                         buf: T,
                         mut already_written: usize) -> Result<Promise<(Self, T)>> where T: Deref<Target=[u8]> {
        use mio::TryWrite;

        while already_written < buf.len() {
            let write_result = try!(self.hub.borrow_mut().stream.write_slice(&buf[already_written..]));
            match write_result {
                Some(n) => {
                    already_written += n;
                }
                None => { // would block
                    return with_current_event_loop(move |event_loop| {
                        let promise =
                            event_loop.event_port.borrow_mut()
                            .handler.observers[self.hub.borrow().handle].when_becomes_writable();
                        return Ok(promise.then(move |()| {
                            return self.write_internal(buf, already_written);
                        }));
                    });
                }
            }
        }

        return Ok(Promise::fulfilled((self, buf)));
    }
}

impl AsyncRead for AsyncInputStream {
    fn try_read<T>(self, buf: T,
               min_bytes: usize) -> Promise<(Self, T, usize)> where T: DerefMut<Target=[u8]> {
        return Promise::fulfilled(()).then(move |()| {
            return self.try_read_internal(buf, 0, min_bytes);
        });
    }
}

impl AsyncWrite for AsyncOutputStream {
    fn write<T>(self, buf: T) -> Promise<(Self, T)> where T: Deref<Target=[u8]> {
        return Promise::fulfilled(()).then(move |()| {
            return self.write_internal(buf, 0);
        });
    }
}

pub struct FdObserver {
    read_fulfiller: Option<Box<PromiseFulfiller<()>>>,
    write_fulfiller: Option<Box<PromiseFulfiller<()>>>,
}

impl FdObserver {
    pub fn new() -> Handle {
        with_current_event_loop(move |event_loop| {

            let observer = FdObserver { read_fulfiller: None, write_fulfiller: None };
            let event_port = &mut *event_loop.event_port.borrow_mut();
            return event_port.handler.observers.push(observer);
        })
    }

    pub fn when_becomes_readable(&mut self) -> Promise<()> {
        let (promise, fulfiller) = new_promise_and_fulfiller();
        self.read_fulfiller = Some(fulfiller);
        return promise;
    }

    pub fn when_becomes_writable(&mut self) -> Promise<()> {
        let (promise, fulfiller) = new_promise_and_fulfiller();
        self.write_fulfiller = Some(fulfiller);
        return promise;
    }
}

pub struct MioEventPort {
    handler: Handler,
    reactor: ::mio::EventLoop<Handler>,
}

pub struct Handler {
    observers: HandleTable<FdObserver>,
}

impl MioEventPort {
    pub fn new() -> Result<MioEventPort> {
        Ok(MioEventPort {
            handler: Handler { observers: HandleTable::new() },
            reactor: try!(::mio::EventLoop::new()),
        })
    }
}

impl ::mio::Handler for Handler {
    type Timeout = ();
    type Message = ();
    fn readable(&mut self, _event_loop: &mut ::mio::EventLoop<Handler>,
                token: ::mio::Token, _hint: ::mio::ReadHint) {
        match ::std::mem::replace(&mut self.observers[Handle {val: token.0}].read_fulfiller, None) {
            Some(fulfiller) => {
                fulfiller.fulfill(())
            }
            None => {
                ()
            }
        }
    }
    fn writable(&mut self, _event_loop: &mut ::mio::EventLoop<Handler>, token: ::mio::Token) {
        match ::std::mem::replace(&mut self.observers[Handle { val: token.0}].write_fulfiller, None) {
            Some(fulfiller) => fulfiller.fulfill(()),
            None => (),
        }
    }
}

impl EventPort for MioEventPort {
    fn wait(&mut self) -> bool {
        self.reactor.run_once(&mut self.handler).unwrap();
        return false;
    }

    fn poll(&mut self) -> bool {
        self.reactor.run_once(&mut self.handler).unwrap();
        return false;
    }
}
<commit_msg>impl Drop for AsyncIo<commit_after>// Copyright (c) 2013-2015 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

use std::rc::Rc;
use std::cell::RefCell;
use std::ops::{DerefMut, Deref};
use handle_table::{HandleTable, Handle};
use {EventPort, Promise, PromiseFulfiller, Result, new_promise_and_fulfiller};
use private::{with_current_event_loop};

/// A nonblocking input bytestream.
pub trait AsyncRead : 'static {

    /// Attempts to read `buf.len()` bytes from the stream, writing them into `buf`.
    /// Returns `self`, the modified `buf`, and the number of bytes actually read.
    /// Returns as soon as `min_bytes` are read or EOF is encountered.
    fn try_read<T>(self: Self, buf: T, min_bytes: usize) -> Promise<(Self, T, usize)>
        where T: DerefMut<Target=[u8]>;

    /// Like `try_read()`, but returns an error if EOF is encountered before `min_bytes`
    /// can be read.
    fn read<T>(self: Self, buf: T, min_bytes: usize) -> Promise<(Self, T, usize)>
        where T: DerefMut<Target=[u8]>, Self: Sized
    {
        return self.try_read(buf, min_bytes).map(move |(s, buf, n)| {
            if n < min_bytes {
                return Err(Box::new(::std::io::Error::new(::std::io::ErrorKind::Other, "Premature EOF")))
            } else {
                return Ok((s, buf, n));
            }
        });
    }
}

/// A nonblocking output bytestream.
pub trait AsyncWrite : 'static {
    /// Attempts to write all `buf.len()` bytes from `buf` into the stream. Returns `self` and `buf`
    /// once all of the bytes have been written.
    fn write<T>(self: Self, buf: T) -> Promise<(Self, T)> where T: Deref<Target=[u8]>;
}

pub struct Slice<T> where T: Deref<Target=[u8]> {
    pub buf: T,
    pub end: usize,
}

impl <T> Slice<T> where T: Deref<Target=[u8]> {
    pub fn new(buf: T, end: usize) -> Slice<T> {
        Slice { buf: buf, end: end }
    }
}

impl <T> Deref for Slice<T> where T: Deref<Target=[u8]> {
    type Target=[u8];
    fn deref<'a>(&'a self) -> &'a [u8] {
        &self.buf[0..self.end]
    }
}

#[derive(Copy, Clone)]
pub struct NetworkAddress {
    address: ::std::net::SocketAddr,
}

impl NetworkAddress {
    pub fn new<T : ::std::net::ToSocketAddrs>(address: T) -> Result<NetworkAddress> {
        match try!(address.to_socket_addrs()).next() {
            Some(addr) => return Ok(NetworkAddress { address: addr }),
            None => unimplemented!(),
        }
    }

    pub fn listen(self) -> Result<ConnectionReceiver> {
        let socket = try!(::mio::tcp::TcpSocket::v4());
        try!(socket.set_reuseaddr(true));
        try!(socket.bind(&self.address));
        let handle = FdObserver::new();
        let listener = try!(socket.listen(256));

        return with_current_event_loop(move |event_loop| {
            try!(event_loop.event_port.borrow_mut().reactor.register_opt(&listener, ::mio::Token(handle.val),
                                                                         ::mio::Interest::readable(),
                                                                         ::mio::PollOpt::edge()));
            Ok(ConnectionReceiver { listener: listener,
                                    handle: handle })
        });
    }

    pub fn connect(self) -> Promise<(AsyncOutputStream, AsyncInputStream)> {
        let socket = ::mio::tcp::TcpSocket::v4().unwrap();
        let handle = FdObserver::new();
        let token = ::mio::Token(handle.val);
        let (stream, _) = socket.connect(&self.address).unwrap();
        with_current_event_loop(move |event_loop| {
            event_loop.event_port.borrow_mut().reactor.register_opt(&stream, token,
                                                                    ::mio::Interest::writable(),
                                                                    ::mio::PollOpt::edge()).unwrap();
            let promise =
                event_loop.event_port.borrow_mut().handler.observers[handle].when_becomes_writable();
            return promise.map(move |()| {
                // TODO check for error.

                return with_current_event_loop(move |event_loop| {
                    try!(event_loop.event_port.borrow_mut().reactor.reregister(
                        &stream, token,
                        ::mio::Interest::writable() | ::mio::Interest::readable(),
                        ::mio::PollOpt::edge()));
                    return Ok(AsyncIo::new(stream, handle));
                });

            });
        })
    }
}

pub struct ConnectionReceiver {
    listener: ::mio::tcp::TcpListener,
    handle: Handle,
}

impl Drop for ConnectionReceiver {
    fn drop(&mut self) {
        // deregister the token
    }
}

impl ConnectionReceiver {

    fn accept_internal(self) -> Result<Promise<(ConnectionReceiver, (AsyncOutputStream, AsyncInputStream))>> {
        let accept_result = try!(self.listener.accept());
        match accept_result {
            Some(stream) => {
                let handle = FdObserver::new();
                return with_current_event_loop(move |event_loop| {
                    try!(event_loop.event_port.borrow_mut().reactor.register_opt(
                        &stream, ::mio::Token(handle.val),
                        ::mio::Interest::writable() | ::mio::Interest::readable(),
                        ::mio::PollOpt::edge()));
                    return Ok(Promise::fulfilled((self, AsyncIo::new(stream, handle))));
                });
            }
            None => {
                return with_current_event_loop(move |event_loop| {
                    let promise =
                        event_loop.event_port.borrow_mut().handler.observers[self.handle].when_becomes_readable();
                    return Ok(promise.then(move |()| {
                        return self.accept_internal();
                    }));
                });
            }
        }
    }

    pub fn accept(self) -> Promise<(ConnectionReceiver, (AsyncOutputStream, AsyncInputStream))> {
        return Promise::fulfilled(()).then(move |()| {return self.accept_internal(); });
    }
}

pub struct AsyncInputStream {
    hub: Rc<RefCell<AsyncIo>>
}

pub struct AsyncOutputStream {
    hub: Rc<RefCell<AsyncIo>>
}

struct AsyncIo {
    stream: ::mio::tcp::TcpStream,
    handle: Handle,
}

impl Drop for AsyncIo {
    fn drop(&mut self) {
        return with_current_event_loop(move |event_loop| {
            event_loop.event_port.borrow_mut().handler.observers.remove(self.handle);
            event_loop.event_port.borrow_mut().reactor.deregister(&self.stream);
        });
    }
}

impl AsyncIo {
    fn new(stream: ::mio::tcp::TcpStream, handle: Handle) -> (AsyncOutputStream, AsyncInputStream) {
        let hub = Rc::new(RefCell::new(AsyncIo { stream: stream, handle: handle }));

        (AsyncOutputStream { hub: hub.clone() }, AsyncInputStream { hub: hub } )
    }
}

impl AsyncInputStream {
    fn try_read_internal<T>(self,
                            mut buf: T,
                            mut already_read: usize,
                            min_bytes: usize) -> Result<Promise<(Self, T, usize)>> where T: DerefMut<Target=[u8]> {
        use mio::TryRead;

        while already_read < min_bytes {
            let read_result = try!(self.hub.borrow_mut().stream.read_slice(&mut buf[already_read..]));
            match read_result {
                Some(0) => {
                    // EOF
                    return Ok(Promise::fulfilled((self, buf, already_read)));
                }
                Some(n) => {
                    already_read += n;
                }
                None => { // would block
                    return with_current_event_loop(move |event_loop| {
                        let promise =
                            event_loop.event_port.borrow_mut()
                            .handler.observers[self.hub.borrow().handle].when_becomes_readable();
                        return Ok(promise.then(move |()| {
                            return self.try_read_internal(buf, already_read, min_bytes);
                        }));
                    });
                }
            }
        }

        return Ok(Promise::fulfilled((self, buf, already_read)));
    }
}

impl AsyncOutputStream {
    fn write_internal<T>(self,
                         buf: T,
                         mut already_written: usize) -> Result<Promise<(Self, T)>> where T: Deref<Target=[u8]> {
        use mio::TryWrite;

        while already_written < buf.len() {
            let write_result = try!(self.hub.borrow_mut().stream.write_slice(&buf[already_written..]));
            match write_result {
                Some(n) => {
                    already_written += n;
                }
                None => { // would block
                    return with_current_event_loop(move |event_loop| {
                        let promise =
                            event_loop.event_port.borrow_mut()
                            .handler.observers[self.hub.borrow().handle].when_becomes_writable();
                        return Ok(promise.then(move |()| {
                            return self.write_internal(buf, already_written);
                        }));
                    });
                }
            }
        }

        return Ok(Promise::fulfilled((self, buf)));
    }
}

impl AsyncRead for AsyncInputStream {
    fn try_read<T>(self, buf: T,
               min_bytes: usize) -> Promise<(Self, T, usize)> where T: DerefMut<Target=[u8]> {
        return Promise::fulfilled(()).then(move |()| {
            return self.try_read_internal(buf, 0, min_bytes);
        });
    }
}

impl AsyncWrite for AsyncOutputStream {
    fn write<T>(self, buf: T) -> Promise<(Self, T)> where T: Deref<Target=[u8]> {
        return Promise::fulfilled(()).then(move |()| {
            return self.write_internal(buf, 0);
        });
    }
}

pub struct FdObserver {
    read_fulfiller: Option<Box<PromiseFulfiller<()>>>,
    write_fulfiller: Option<Box<PromiseFulfiller<()>>>,
}

impl FdObserver {
    pub fn new() -> Handle {
        with_current_event_loop(move |event_loop| {

            let observer = FdObserver { read_fulfiller: None, write_fulfiller: None };
            let event_port = &mut *event_loop.event_port.borrow_mut();
            return event_port.handler.observers.push(observer);
        })
    }

    pub fn when_becomes_readable(&mut self) -> Promise<()> {
        let (promise, fulfiller) = new_promise_and_fulfiller();
        self.read_fulfiller = Some(fulfiller);
        return promise;
    }

    pub fn when_becomes_writable(&mut self) -> Promise<()> {
        let (promise, fulfiller) = new_promise_and_fulfiller();
        self.write_fulfiller = Some(fulfiller);
        return promise;
    }
}

pub struct MioEventPort {
    handler: Handler,
    reactor: ::mio::EventLoop<Handler>,
}

pub struct Handler {
    observers: HandleTable<FdObserver>,
}

impl MioEventPort {
    pub fn new() -> Result<MioEventPort> {
        Ok(MioEventPort {
            handler: Handler { observers: HandleTable::new() },
            reactor: try!(::mio::EventLoop::new()),
        })
    }
}

impl ::mio::Handler for Handler {
    type Timeout = ();
    type Message = ();
    fn readable(&mut self, _event_loop: &mut ::mio::EventLoop<Handler>,
                token: ::mio::Token, _hint: ::mio::ReadHint) {
        match ::std::mem::replace(&mut self.observers[Handle {val: token.0}].read_fulfiller, None) {
            Some(fulfiller) => {
                fulfiller.fulfill(())
            }
            None => {
                ()
            }
        }
    }
    fn writable(&mut self, _event_loop: &mut ::mio::EventLoop<Handler>, token: ::mio::Token) {
        match ::std::mem::replace(&mut self.observers[Handle { val: token.0}].write_fulfiller, None) {
            Some(fulfiller) => fulfiller.fulfill(()),
            None => (),
        }
    }
}

impl EventPort for MioEventPort {
    fn wait(&mut self) -> bool {
        self.reactor.run_once(&mut self.handler).unwrap();
        return false;
    }

    fn poll(&mut self) -> bool {
        self.reactor.run_once(&mut self.handler).unwrap();
        return false;
    }
}
<|endoftext|>