<commit_before>// See LICENSE file for copyright and license details.

use core::types::MInt;
use visualizer::mgl::{Vbo, Vao, Triangles};
use visualizer::types::{Color3, VertexCoord, TextureCoord};
use visualizer::shader::Shader;
use visualizer::texture::Texture;

pub struct MeshId{pub id: MInt}

pub struct Mesh {
    vertex_coords_vbo: Vbo,
    color_vbo: Option<Vbo>,
    texture_coords_vbo: Option<Vbo>,
    texture: Option<Texture>,
    length: MInt,
    vao: Vao,
}

impl Mesh {
    pub fn new(data: &[VertexCoord]) -> Mesh {
        let length = data.len() as MInt;
        Mesh {
            vertex_coords_vbo: Vbo::from_data(data),
            color_vbo: None,
            texture_coords_vbo: None,
            texture: None,
            length: length,
            vao: Vao::new(),
        }
    }

    pub fn set_color(&mut self, data: &[Color3]) {
        assert_eq!(self.length, data.len() as MInt);
        self.color_vbo = Some(Vbo::from_data(data));
    }

    pub fn set_texture(&mut self, texture: Texture, data: &[TextureCoord]) {
        assert_eq!(self.length, data.len() as MInt);
        self.texture_coords_vbo = Some(Vbo::from_data(data));
        self.texture = Some(texture);
    }

    pub fn prepare(&mut self, shader: &Shader) {
        self.vao.bind();
        shader.activate();
        if !self.texture_coords_vbo.is_none() {
            self.texture_coords_vbo.get_ref().bind();
            shader.enable_attr("in_texture_coordinates", 2);
        }
        if !self.color_vbo.is_none() {
            self.color_vbo.get_ref().bind();
            shader.enable_attr("color", 3);
        }
        self.vertex_coords_vbo.bind();
        shader.enable_attr("in_vertex_coordinates", 3);
        self.vao.unbind();
    }

    pub fn draw(&self, shader: &Shader) {
        self.vao.bind();
        if !self.texture.is_none() {
            self.texture.unwrap().enable(shader);
        }
        self.vao.draw_array(Triangles, self.length);
        self.vao.unbind();
    }
}

// vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab:
<commit_msg>Replaced few 'unwrap' and 'is_none' with 'match'<commit_after>// See LICENSE file for copyright and license details.

use core::types::MInt;
use visualizer::mgl::{Vbo, Vao, Triangles};
use visualizer::types::{Color3, VertexCoord, TextureCoord};
use visualizer::shader::Shader;
use visualizer::texture::Texture;

pub struct MeshId{pub id: MInt}

pub struct Mesh {
    vertex_coords_vbo: Vbo,
    color_vbo: Option<Vbo>,
    texture_coords_vbo: Option<Vbo>,
    texture: Option<Texture>,
    length: MInt,
    vao: Vao,
}

impl Mesh {
    pub fn new(data: &[VertexCoord]) -> Mesh {
        let length = data.len() as MInt;
        Mesh {
            vertex_coords_vbo: Vbo::from_data(data),
            color_vbo: None,
            texture_coords_vbo: None,
            texture: None,
            length: length,
            vao: Vao::new(),
        }
    }

    pub fn set_color(&mut self, data: &[Color3]) {
        assert_eq!(self.length, data.len() as MInt);
        self.color_vbo = Some(Vbo::from_data(data));
    }

    pub fn set_texture(&mut self, texture: Texture, data: &[TextureCoord]) {
        assert_eq!(self.length, data.len() as MInt);
        self.texture_coords_vbo = Some(Vbo::from_data(data));
        self.texture = Some(texture);
    }

    pub fn prepare(&mut self, shader: &Shader) {
        self.vao.bind();
        shader.activate();
        match self.texture_coords_vbo {
            Some(ref vbo) => {
                vbo.bind();
                shader.enable_attr("in_texture_coordinates", 2);
            },
            None => {},
        }
        match self.color_vbo {
            Some(ref vbo) => {
                vbo.bind();
                shader.enable_attr("color", 3);
            },
            None => {},
        }
        self.vertex_coords_vbo.bind();
        shader.enable_attr("in_vertex_coordinates", 3);
        self.vao.unbind();
    }

    pub fn draw(&self, shader: &Shader) {
        self.vao.bind();
        match self.texture {
            Some(ref texture) => texture.enable(shader),
            None => {},
        }
        self.vao.draw_array(Triangles, self.length);
        self.vao.unbind();
    }
}

// vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab:
<|endoftext|>


<commit_before>use rustc_hash::FxHashSet;

use ra_syntax::{ast, AstNode, TextRange, Direction, SyntaxKind, SyntaxKind::*, SyntaxElement, T};
use ra_db::SourceDatabase;

use crate::{FileId, db::RootDatabase};

#[derive(Debug)]
pub struct HighlightedRange {
    pub range: TextRange,
    pub tag: &'static str,
}

fn is_control_keyword(kind: SyntaxKind) -> bool {
    match kind {
        T![for]
        | T![loop]
        | T![while]
        | T![continue]
        | T![break]
        | T![if]
        | T![else]
        | T![match]
        | T![return] => true,
        _ => false,
    }
}

pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRange> {
    let source_file = db.parse(file_id);

    // Visited nodes to handle highlighting priorities
    let mut highlighted: FxHashSet<SyntaxElement> = FxHashSet::default();
    let mut res = Vec::new();
    for node in source_file.syntax().descendants_with_tokens() {
        if highlighted.contains(&node) {
            continue;
        }
        let tag = match node.kind() {
            COMMENT => "comment",
            STRING | RAW_STRING | RAW_BYTE_STRING | BYTE_STRING => "string",
            ATTR => "attribute",
            NAME_REF => {
                if let Some(name_ref) = node.as_node().and_then(|n| ast::NameRef::cast(n)) {
                    use crate::name_ref_kind::{classify_name_ref, NameRefKind::*};
                    use hir::{ModuleDef, ImplItem};

                    // FIXME: try to reuse the SourceAnalyzers
                    let analyzer = hir::SourceAnalyzer::new(db, file_id, name_ref.syntax(), None);
                    match classify_name_ref(db, &analyzer, name_ref) {
                        Some(Method(_)) => "function",
                        Some(Macro(_)) => "macro",
                        Some(FieldAccess(_)) => "field",
                        Some(AssocItem(ImplItem::Method(_))) => "function",
                        Some(AssocItem(ImplItem::Const(_))) => "constant",
                        Some(AssocItem(ImplItem::TypeAlias(_))) => "type",
                        Some(Def(ModuleDef::Module(_))) => "module",
                        Some(Def(ModuleDef::Function(_))) => "function",
                        Some(Def(ModuleDef::Struct(_))) => "type",
                        Some(Def(ModuleDef::Union(_))) => "type",
                        Some(Def(ModuleDef::Enum(_))) => "type",
                        Some(Def(ModuleDef::EnumVariant(_))) => "constant",
                        Some(Def(ModuleDef::Const(_))) => "constant",
                        Some(Def(ModuleDef::Static(_))) => "constant",
                        Some(Def(ModuleDef::Trait(_))) => "type",
                        Some(Def(ModuleDef::TypeAlias(_))) => "type",
                        Some(SelfType(_)) => "type",
                        Some(Pat(_)) => "text",
                        Some(SelfParam(_)) => "type",
                        Some(GenericParam(_)) => "type",
                        None => "text",
                    }
                } else {
                    "text"
                }
            }
            NAME => "function",
            TYPE_ALIAS_DEF | TYPE_ARG | TYPE_PARAM => "type",
            INT_NUMBER | FLOAT_NUMBER | CHAR | BYTE => "literal",
            LIFETIME => "parameter",
            T![unsafe] => "keyword.unsafe",
            k if is_control_keyword(k) => "keyword.control",
            k if k.is_keyword() => "keyword",
            _ => {
                if let Some(macro_call) = node.as_node().and_then(ast::MacroCall::cast) {
                    if let Some(path) = macro_call.path() {
                        if let Some(segment) = path.segment() {
                            if let Some(name_ref) = segment.name_ref() {
                                highlighted.insert(name_ref.syntax().into());
                                let range_start = name_ref.syntax().range().start();
                                let mut range_end = name_ref.syntax().range().end();
                                for sibling in path.syntax().siblings_with_tokens(Direction::Next) {
                                    match sibling.kind() {
                                        T![!] | IDENT => range_end = sibling.range().end(),
                                        _ => (),
                                    }
                                }
                                res.push(HighlightedRange {
                                    range: TextRange::from_to(range_start, range_end),
                                    tag: "macro",
                                })
                            }
                        }
                    }
                }
                continue;
            }
        };
        res.push(HighlightedRange { range: node.range(), tag })
    }
    res
}

#[cfg(test)]
mod tests {
    use insta::assert_debug_snapshot_matches;

    use crate::mock_analysis::single_file;

    #[test]
    fn test_highlighting() {
        let (analysis, file_id) = single_file(
            r#"
#[derive(Clone, Debug)]
struct Foo {
    pub x: i32,
    pub y: i32,
}

fn foo<T>() -> T {
    unimplemented!();
}

// comment
fn main() {}
    println!("Hello, {}!", 92);

    let mut vec = Vec::new();
    vec.push(Foo { x: 0, y: 1 });
    unsafe { vec.set_len(0); }
"#,
        );
        let result = analysis.highlight(file_id);
        assert_debug_snapshot_matches!("highlighting", result);
    }
}
<commit_msg>profile highlighting<commit_after>use rustc_hash::FxHashSet;

use ra_syntax::{ast, AstNode, TextRange, Direction, SyntaxKind, SyntaxKind::*, SyntaxElement, T};
use ra_db::SourceDatabase;
use ra_prof::profile;

use crate::{FileId, db::RootDatabase};

#[derive(Debug)]
pub struct HighlightedRange {
    pub range: TextRange,
    pub tag: &'static str,
}

fn is_control_keyword(kind: SyntaxKind) -> bool {
    match kind {
        T![for]
        | T![loop]
        | T![while]
        | T![continue]
        | T![break]
        | T![if]
        | T![else]
        | T![match]
        | T![return] => true,
        _ => false,
    }
}

pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRange> {
    let _p = profile("highlight");

    let source_file = db.parse(file_id);

    // Visited nodes to handle highlighting priorities
    let mut highlighted: FxHashSet<SyntaxElement> = FxHashSet::default();
    let mut res = Vec::new();
    for node in source_file.syntax().descendants_with_tokens() {
        if highlighted.contains(&node) {
            continue;
        }
        let tag = match node.kind() {
            COMMENT => "comment",
            STRING | RAW_STRING | RAW_BYTE_STRING | BYTE_STRING => "string",
            ATTR => "attribute",
            NAME_REF => {
                if let Some(name_ref) = node.as_node().and_then(|n| ast::NameRef::cast(n)) {
                    use crate::name_ref_kind::{classify_name_ref, NameRefKind::*};
                    use hir::{ModuleDef, ImplItem};

                    // FIXME: try to reuse the SourceAnalyzers
                    let analyzer = hir::SourceAnalyzer::new(db, file_id, name_ref.syntax(), None);
                    match classify_name_ref(db, &analyzer, name_ref) {
                        Some(Method(_)) => "function",
                        Some(Macro(_)) => "macro",
                        Some(FieldAccess(_)) => "field",
                        Some(AssocItem(ImplItem::Method(_))) => "function",
                        Some(AssocItem(ImplItem::Const(_))) => "constant",
                        Some(AssocItem(ImplItem::TypeAlias(_))) => "type",
                        Some(Def(ModuleDef::Module(_))) => "module",
                        Some(Def(ModuleDef::Function(_))) => "function",
                        Some(Def(ModuleDef::Struct(_))) => "type",
                        Some(Def(ModuleDef::Union(_))) => "type",
                        Some(Def(ModuleDef::Enum(_))) => "type",
                        Some(Def(ModuleDef::EnumVariant(_))) => "constant",
                        Some(Def(ModuleDef::Const(_))) => "constant",
                        Some(Def(ModuleDef::Static(_))) => "constant",
                        Some(Def(ModuleDef::Trait(_))) => "type",
                        Some(Def(ModuleDef::TypeAlias(_))) => "type",
                        Some(SelfType(_)) => "type",
                        Some(Pat(_)) => "text",
                        Some(SelfParam(_)) => "type",
                        Some(GenericParam(_)) => "type",
                        None => "text",
                    }
                } else {
                    "text"
                }
            }
            NAME => "function",
            TYPE_ALIAS_DEF | TYPE_ARG | TYPE_PARAM => "type",
            INT_NUMBER | FLOAT_NUMBER | CHAR | BYTE => "literal",
            LIFETIME => "parameter",
            T![unsafe] => "keyword.unsafe",
            k if is_control_keyword(k) => "keyword.control",
            k if k.is_keyword() => "keyword",
            _ => {
                if let Some(macro_call) = node.as_node().and_then(ast::MacroCall::cast) {
                    if let Some(path) = macro_call.path() {
                        if let Some(segment) = path.segment() {
                            if let Some(name_ref) = segment.name_ref() {
                                highlighted.insert(name_ref.syntax().into());
                                let range_start = name_ref.syntax().range().start();
                                let mut range_end = name_ref.syntax().range().end();
                                for sibling in path.syntax().siblings_with_tokens(Direction::Next) {
                                    match sibling.kind() {
                                        T![!] | IDENT => range_end = sibling.range().end(),
                                        _ => (),
                                    }
                                }
                                res.push(HighlightedRange {
                                    range: TextRange::from_to(range_start, range_end),
                                    tag: "macro",
                                })
                            }
                        }
                    }
                }
                continue;
            }
        };
        res.push(HighlightedRange { range: node.range(), tag })
    }
    res
}

#[cfg(test)]
mod tests {
    use insta::assert_debug_snapshot_matches;

    use crate::mock_analysis::single_file;

    #[test]
    fn test_highlighting() {
        let (analysis, file_id) = single_file(
            r#"
#[derive(Clone, Debug)]
struct Foo {
    pub x: i32,
    pub y: i32,
}

fn foo<T>() -> T {
    unimplemented!();
}

// comment
fn main() {}
    println!("Hello, {}!", 92);

    let mut vec = Vec::new();
    vec.push(Foo { x: 0, y: 1 });
    unsafe { vec.set_len(0); }
"#,
        );
        let result = analysis.highlight(file_id);
        assert_debug_snapshot_matches!("highlighting", result);
    }
}
<|endoftext|>


<commit_before>#[cfg(any(target_os = "linux", target_os = "android"))]
use std::os::unix::io::AsRawFd;
use std::{
    io::{self, Error, ErrorKind},
    mem,
    net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6},
};
#[cfg(any(target_os = "android"))]
use std::{os::unix::io::RawFd, path::Path};

use cfg_if::cfg_if;
use tokio::net::{TcpSocket, TcpStream, UdpSocket};

use crate::net::{AddrFamily, ConnectOpts};

/// Convert `sockaddr_storage` to `SocketAddr`
#[allow(dead_code)]
pub fn sockaddr_to_std(saddr: &libc::sockaddr_storage) -> io::Result<SocketAddr> {
    match saddr.ss_family as libc::c_int {
        libc::AF_INET => unsafe {
            let addr: SocketAddrV4 = mem::transmute_copy(saddr);
            Ok(SocketAddr::V4(addr))
        },
        libc::AF_INET6 => unsafe {
            let addr: SocketAddrV6 = mem::transmute_copy(saddr);
            Ok(SocketAddr::V6(addr))
        },
        _ => {
            let err = Error::new(ErrorKind::InvalidData, "family must be either AF_INET or AF_INET6");
            Err(err)
        }
    }
}

cfg_if! {
    if #[cfg(target_os = "android")] {
        mod uds;

        /// This is a RPC for Android to `protect()` socket for connecting to remote servers
        ///
        /// https://developer.android.com/reference/android/net/VpnService#protect(java.net.Socket)
        ///
        /// More detail could be found in [shadowsocks-android](https://github.com/shadowsocks/shadowsocks-android) project.
        async fn protect<P: AsRef<Path>>(protect_path: P, fd: RawFd) -> io::Result<()> {
            use tokio::io::AsyncReadExt;

            let mut stream = self::uds::UnixStream::connect(protect_path).await?;

            // send fds
            let dummy: [u8; 1] = [1];
            let fds: [RawFd; 1] = [fd];
            stream.send_with_fd(&dummy, &fds).await?;

            // receive the return value
            let mut response = [0; 1];
            stream.read_exact(&mut response).await?;

            if response[0] == 0xFF {
                return Err(Error::new(ErrorKind::Other, "protect() failed"));
            }

            Ok(())
        }
    }
}

/// create a new TCP stream
#[inline(always)]
#[allow(unused_variables)]
pub async fn tcp_stream_connect(saddr: &SocketAddr, config: &ConnectOpts) -> io::Result<TcpStream> {
    let socket = match *saddr {
        SocketAddr::V4(..) => TcpSocket::new_v4()?,
        SocketAddr::V6(..) => TcpSocket::new_v6()?,
    };

    // Any traffic to localhost should not be protected
    // This is a workaround for VPNService
    #[cfg(target_os = "android")]
    if !saddr.ip().is_loopback() {
        use std::time::Duration;
        use tokio::time;

        if let Some(ref path) = config.vpn_protect_path {
            // RPC calls to `VpnService.protect()`
            // Timeout in 3 seconds like shadowsocks-libev
            match time::timeout(Duration::from_secs(3), protect(path, socket.as_raw_fd())).await {
                Ok(Ok(..)) => {}
                Ok(Err(err)) => return Err(err),
                Err(..) => return Err(Error::new(ErrorKind::TimedOut, "protect() timeout")),
            }
        }
    }

    // Set SO_MARK for mark-based routing on Linux (since 2.6.25)
    // NOTE: This will require CAP_NET_ADMIN capability (root in most cases)
    #[cfg(any(target_os = "linux", target_os = "android"))]
    if let Some(mark) = config.fwmark {
        let ret = unsafe {
            libc::setsockopt(
                socket.as_raw_fd(),
                libc::SOL_SOCKET,
                libc::SO_MARK,
                &mark as *const _ as *const _,
                mem::size_of_val(&mark) as libc::socklen_t,
            )
        };
        if ret != 0 {
            return Err(Error::last_os_error());
        }
    }

    // Set SO_BINDTODEVICE for binding to a specific interface
    #[cfg(any(target_os = "linux", target_os = "android"))]
    if let Some(ref iface) = config.bind_interface {
        use nix::sys::socket::{setsockopt, sockopt::BindToDevice};
        if let Err(err) = setsockopt::<BindToDevice>(socket.as_raw_fd(), BindToDevice, iface) {
            return match err.as_errno() {
                Some(errno) => Err(errno.into()),
                None => Err(Error::new(ErrorKind::Other, err)),
            };
        }
    }

    // Binds to IP address
    if let Some(ip) = config.bind_local_addr {
        match (ip, saddr.ip()) {
            (IpAddr::V4(..), IpAddr::V4(..)) => {
                socket.bind(SocketAddr::new(ip, 0))?;
            }
            (IpAddr::V6(..), IpAddr::V6(..)) => {
                socket.bind(SocketAddr::new(ip, 0))?;
            }
            _ => {}
        }
    }

    // Set `SO_SNDBUF`
    if let Some(buf_size) = config.tcp.send_buffer_size {
        socket.set_send_buffer_size(buf_size)?;
    }

    // Set `SO_RCVBUF`
    if let Some(buf_size) = config.tcp.recv_buffer_size {
        socket.set_recv_buffer_size(buf_size)?;
    }

    // it's important that the socket is protected before connecting
    let stream = socket.connect(*saddr).await?;

    if config.tcp.nodelay {
        stream.set_nodelay(true)?;
    }

    Ok(stream)
}

/// Create a `UdpSocket` for connecting to `addr`
#[inline(always)]
#[allow(unused_variables)]
pub async fn create_outbound_udp_socket(af: AddrFamily, config: &ConnectOpts) -> io::Result<UdpSocket> {
    let bind_addr = match (af, config.bind_local_addr) {
        (AddrFamily::Ipv4, Some(IpAddr::V4(ip))) => SocketAddr::new(ip.into(), 0),
        (AddrFamily::Ipv6, Some(IpAddr::V6(ip))) => SocketAddr::new(ip.into(), 0),
        (AddrFamily::Ipv4, ..) => SocketAddr::new(Ipv4Addr::UNSPECIFIED.into(), 0),
        (AddrFamily::Ipv6, ..) => SocketAddr::new(Ipv6Addr::UNSPECIFIED.into(), 0),
    };

    let socket = UdpSocket::bind(bind_addr).await?;

    // Any traffic except localhost should be protected
    // This is a workaround for VPNService
    #[cfg(target_os = "android")]
    {
        if let Some(ref path) = config.vpn_protect_path {
            protect(path, socket.as_raw_fd()).await?;
        }
    }

    // Set SO_MARK for mark-based routing on Linux (since 2.6.25)
    // NOTE: This will require CAP_NET_ADMIN capability (root in most cases)
    #[cfg(any(target_os = "linux", target_os = "android"))]
    if let Some(mark) = config.fwmark {
        let ret = unsafe {
            libc::setsockopt(
                socket.as_raw_fd(),
                libc::SOL_SOCKET,
                libc::SO_MARK,
                &mark as *const _ as *const _,
                mem::size_of_val(&mark) as libc::socklen_t,
            )
        };
        if ret != 0 {
            return Err(Error::last_os_error());
        }
    }

    // Set SO_BINDTODEVICE for binding to a specific interface
    #[cfg(any(target_os = "linux", target_os = "android"))]
    if let Some(ref iface) = config.bind_interface {
        use nix::sys::socket::{setsockopt, sockopt::BindToDevice};
        if let Err(err) = setsockopt::<BindToDevice>(socket.as_raw_fd(), BindToDevice, iface) {
            return match err.as_errno() {
                Some(errno) => Err(errno.into()),
                None => Err(Error::new(ErrorKind::Other, err)),
            };
        }
    }

    Ok(socket)
}

/// Create a `UdpSocket` binded to `addr`
#[inline(always)]
pub async fn create_udp_socket(addr: &SocketAddr) -> io::Result<UdpSocket> {
    UdpSocket::bind(addr).await
}
<commit_msg>set timeout for VpnService.protect() for UDP sockets<commit_after>#[cfg(any(target_os = "linux", target_os = "android"))]
use std::os::unix::io::AsRawFd;
use std::{
    io::{self, Error, ErrorKind},
    mem,
    net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6},
};
#[cfg(any(target_os = "android"))]
use std::{os::unix::io::RawFd, path::Path};

use cfg_if::cfg_if;
use tokio::net::{TcpSocket, TcpStream, UdpSocket};

use crate::net::{AddrFamily, ConnectOpts};

/// Convert `sockaddr_storage` to `SocketAddr`
#[allow(dead_code)]
pub fn sockaddr_to_std(saddr: &libc::sockaddr_storage) -> io::Result<SocketAddr> {
    match saddr.ss_family as libc::c_int {
        libc::AF_INET => unsafe {
            let addr: SocketAddrV4 = mem::transmute_copy(saddr);
            Ok(SocketAddr::V4(addr))
        },
        libc::AF_INET6 => unsafe {
            let addr: SocketAddrV6 = mem::transmute_copy(saddr);
            Ok(SocketAddr::V6(addr))
        },
        _ => {
            let err = Error::new(ErrorKind::InvalidData, "family must be either AF_INET or AF_INET6");
            Err(err)
        }
    }
}

cfg_if! {
    if #[cfg(target_os = "android")] {
        mod uds;

        /// This is a RPC for Android to `protect()` socket for connecting to remote servers
        ///
        /// https://developer.android.com/reference/android/net/VpnService#protect(java.net.Socket)
        ///
        /// More detail could be found in [shadowsocks-android](https://github.com/shadowsocks/shadowsocks-android) project.
        async fn protect<P: AsRef<Path>>(protect_path: P, fd: RawFd) -> io::Result<()> {
            use tokio::io::AsyncReadExt;

            let mut stream = self::uds::UnixStream::connect(protect_path).await?;

            // send fds
            let dummy: [u8; 1] = [1];
            let fds: [RawFd; 1] = [fd];
            stream.send_with_fd(&dummy, &fds).await?;

            // receive the return value
            let mut response = [0; 1];
            stream.read_exact(&mut response).await?;

            if response[0] == 0xFF {
                return Err(Error::new(ErrorKind::Other, "protect() failed"));
            }

            Ok(())
        }
    }
}

/// create a new TCP stream
#[inline(always)]
#[allow(unused_variables)]
pub async fn tcp_stream_connect(saddr: &SocketAddr, config: &ConnectOpts) -> io::Result<TcpStream> {
    let socket = match *saddr {
        SocketAddr::V4(..) => TcpSocket::new_v4()?,
        SocketAddr::V6(..) => TcpSocket::new_v6()?,
    };

    // Any traffic to localhost should not be protected
    // This is a workaround for VPNService
    #[cfg(target_os = "android")]
    if !saddr.ip().is_loopback() {
        use std::time::Duration;
        use tokio::time;

        if let Some(ref path) = config.vpn_protect_path {
            // RPC calls to `VpnService.protect()`
            // Timeout in 3 seconds like shadowsocks-libev
            match time::timeout(Duration::from_secs(3), protect(path, socket.as_raw_fd())).await {
                Ok(Ok(..)) => {}
                Ok(Err(err)) => return Err(err),
                Err(..) => return Err(Error::new(ErrorKind::TimedOut, "protect() timeout")),
            }
        }
    }

    // Set SO_MARK for mark-based routing on Linux (since 2.6.25)
    // NOTE: This will require CAP_NET_ADMIN capability (root in most cases)
    #[cfg(any(target_os = "linux", target_os = "android"))]
    if let Some(mark) = config.fwmark {
        let ret = unsafe {
            libc::setsockopt(
                socket.as_raw_fd(),
                libc::SOL_SOCKET,
                libc::SO_MARK,
                &mark as *const _ as *const _,
                mem::size_of_val(&mark) as libc::socklen_t,
            )
        };
        if ret != 0 {
            return Err(Error::last_os_error());
        }
    }

    // Set SO_BINDTODEVICE for binding to a specific interface
    #[cfg(any(target_os = "linux", target_os = "android"))]
    if let Some(ref iface) = config.bind_interface {
        use nix::sys::socket::{setsockopt, sockopt::BindToDevice};
        if let Err(err) = setsockopt::<BindToDevice>(socket.as_raw_fd(), BindToDevice, iface) {
            return match err.as_errno() {
                Some(errno) => Err(errno.into()),
                None => Err(Error::new(ErrorKind::Other, err)),
            };
        }
    }

    // Binds to IP address
    if let Some(ip) = config.bind_local_addr {
        match (ip, saddr.ip()) {
            (IpAddr::V4(..), IpAddr::V4(..)) => {
                socket.bind(SocketAddr::new(ip, 0))?;
            }
            (IpAddr::V6(..), IpAddr::V6(..)) => {
                socket.bind(SocketAddr::new(ip, 0))?;
            }
            _ => {}
        }
    }

    // Set `SO_SNDBUF`
    if let Some(buf_size) = config.tcp.send_buffer_size {
        socket.set_send_buffer_size(buf_size)?;
    }

    // Set `SO_RCVBUF`
    if let Some(buf_size) = config.tcp.recv_buffer_size {
        socket.set_recv_buffer_size(buf_size)?;
    }

    // it's important that the socket is protected before connecting
    let stream = socket.connect(*saddr).await?;

    if config.tcp.nodelay {
        stream.set_nodelay(true)?;
    }

    Ok(stream)
}

/// Create a `UdpSocket` for connecting to `addr`
#[inline(always)]
#[allow(unused_variables)]
pub async fn create_outbound_udp_socket(af: AddrFamily, config: &ConnectOpts) -> io::Result<UdpSocket> {
    let bind_addr = match (af, config.bind_local_addr) {
        (AddrFamily::Ipv4, Some(IpAddr::V4(ip))) => SocketAddr::new(ip.into(), 0),
        (AddrFamily::Ipv6, Some(IpAddr::V6(ip))) => SocketAddr::new(ip.into(), 0),
        (AddrFamily::Ipv4, ..) => SocketAddr::new(Ipv4Addr::UNSPECIFIED.into(), 0),
        (AddrFamily::Ipv6, ..) => SocketAddr::new(Ipv6Addr::UNSPECIFIED.into(), 0),
    };

    let socket = UdpSocket::bind(bind_addr).await?;

    // Any traffic except localhost should be protected
    // This is a workaround for VPNService
    #[cfg(target_os = "android")]
    {
        use std::time::Duration;
        use tokio::time;

        if let Some(ref path) = config.vpn_protect_path {
            // RPC calls to `VpnService.protect()`
            // Timeout in 3 seconds like shadowsocks-libev
            match time::timeout(Duration::from_secs(3), protect(path, socket.as_raw_fd())).await {
                Ok(Ok(..)) => {}
                Ok(Err(err)) => return Err(err),
                Err(..) => return Err(Error::new(ErrorKind::TimedOut, "protect() timeout")),
            }
        }
    }

    // Set SO_MARK for mark-based routing on Linux (since 2.6.25)
    // NOTE: This will require CAP_NET_ADMIN capability (root in most cases)
    #[cfg(any(target_os = "linux", target_os = "android"))]
    if let Some(mark) = config.fwmark {
        let ret = unsafe {
            libc::setsockopt(
                socket.as_raw_fd(),
                libc::SOL_SOCKET,
                libc::SO_MARK,
                &mark as *const _ as *const _,
                mem::size_of_val(&mark) as libc::socklen_t,
            )
        };
        if ret != 0 {
            return Err(Error::last_os_error());
        }
    }

    // Set SO_BINDTODEVICE for binding to a specific interface
    #[cfg(any(target_os = "linux", target_os = "android"))]
    if let Some(ref iface) = config.bind_interface {
        use nix::sys::socket::{setsockopt, sockopt::BindToDevice};
        if let Err(err) = setsockopt::<BindToDevice>(socket.as_raw_fd(), BindToDevice, iface) {
            return match err.as_errno() {
                Some(errno) => Err(errno.into()),
                None => Err(Error::new(ErrorKind::Other, err)),
            };
        }
    }

    Ok(socket)
}

/// Create a `UdpSocket` binded to `addr`
#[inline(always)]
pub async fn create_udp_socket(addr: &SocketAddr) -> io::Result<UdpSocket> {
    UdpSocket::bind(addr).await
}
<|endoftext|>


<commit_before>// See LICENSE file for copyright and license details.

use cgmath::vector::Vector2;
use core::types::UnitId;
use core::game_state::GameState;
use core::misc::add_quad_to_vec;
use core::fs::FileSystem;
use visualizer::scene::{
    Scene,
    SceneNode,
    SELECTION_NODE_ID,
};
use visualizer::geom;
use visualizer::mesh::{Mesh, MeshId};
use visualizer::texture::Texture;
use visualizer::types::{MFloat, WorldPos, TextureCoord};
use visualizer::shader::Shader;

// TODO: Reuse in other places
static SELECTION_MARKER_HEIGHT: MFloat = 0.01;

pub struct SelectionManager {
    unit_id: Option<UnitId>,
    mesh_id: MeshId,
}

impl SelectionManager {
    pub fn new(mesh_id: MeshId) -> SelectionManager {
        SelectionManager {
            unit_id: None,
            mesh_id: mesh_id,
        }
    }

    fn set_unit_id(&mut self, unit_id: UnitId) {
        self.unit_id = Some(unit_id);
    }

    fn get_pos(&self, state: &GameState) -> WorldPos {
        let unit_id = self.unit_id.unwrap();
        let map_pos = state.units.get(&unit_id).pos;
        let mut world_pos = geom::map_pos_to_world_pos(map_pos);
        world_pos.v.z += SELECTION_MARKER_HEIGHT;
        world_pos
    }

    pub fn move_selection_marker(
        &self,
        state: &GameState,
        scene: &mut Scene
    ) {
        let node = scene.nodes.get_mut(&SELECTION_NODE_ID);
        node.pos = self.get_pos(state);
    }

    pub fn create_selection_marker(
        &mut self,
        state: &GameState,
        scene: &mut Scene,
        unit_id: UnitId
    ) {
        self.set_unit_id(unit_id);
        if scene.nodes.find(&SELECTION_NODE_ID).is_some() {
            scene.nodes.remove(&SELECTION_NODE_ID);
        }
        let node = SceneNode {
            pos: self.get_pos(state),
            rot: 0.0,
            mesh_id: Some(self.mesh_id),
            children: Vec::new(),
        };
        scene.nodes.insert(SELECTION_NODE_ID, node);
    }

    pub fn deselect(&mut self, scene: &mut Scene) {
        scene.nodes.remove(&SELECTION_NODE_ID);
        self.unit_id = None;
    }
}

pub fn get_selection_mesh(fs: &FileSystem, shader: &Shader) -> Mesh {
    let tex = Texture::new(&fs.get(&Path::new("data/shell.png")));
    let mut vertex_data = Vec::new();
    let mut tex_data = Vec::new();
    let scale_1 = 0.6;
    let scale_2 = scale_1 + 0.05;
    for num in range(0i32, 6) {
        let vertex_1_1 = geom::index_to_hex_vertex_s(scale_1, num);
        let vertex_1_2 = geom::index_to_hex_vertex_s(scale_2, num);
        let vertex_2_1 = geom::index_to_hex_vertex_s(scale_1, num + 1);
        let vertex_2_2 = geom::index_to_hex_vertex_s(scale_2, num + 1);
        add_quad_to_vec(
            &mut vertex_data,
            vertex_2_1,
            vertex_2_2,
            vertex_1_2,
            vertex_1_1,
        );
        add_quad_to_vec(
            &mut tex_data,
            TextureCoord{v: Vector2{x: 0.0, y: 0.0}},
            TextureCoord{v: Vector2{x: 0.0, y: 1.0}},
            TextureCoord{v: Vector2{x: 1.0, y: 1.0}},
            TextureCoord{v: Vector2{x: 1.0, y: 0.0}},
        );
    }
    let mut mesh = Mesh::new(vertex_data.as_slice());
    mesh.set_texture(tex, tex_data.as_slice());
    mesh.prepare(shader);
    mesh
}

// vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab:
<commit_msg>visualizer/selection.rs: Replaced SELECTION_MARKER_HEIGHT with geom::lift()<commit_after>// See LICENSE file for copyright and license details.

use cgmath::vector::Vector2;
use core::types::UnitId;
use core::game_state::GameState;
use core::misc::add_quad_to_vec;
use core::fs::FileSystem;
use visualizer::scene::{
    Scene,
    SceneNode,
    SELECTION_NODE_ID,
};
use visualizer::geom;
use visualizer::mesh::{Mesh, MeshId};
use visualizer::texture::Texture;
use visualizer::types::{WorldPos, TextureCoord};
use visualizer::shader::Shader;

pub struct SelectionManager {
    unit_id: Option<UnitId>,
    mesh_id: MeshId,
}

impl SelectionManager {
    pub fn new(mesh_id: MeshId) -> SelectionManager {
        SelectionManager {
            unit_id: None,
            mesh_id: mesh_id,
        }
    }

    fn set_unit_id(&mut self, unit_id: UnitId) {
        self.unit_id = Some(unit_id);
    }

    fn get_pos(&self, state: &GameState) -> WorldPos {
        let unit_id = self.unit_id.unwrap();
        let map_pos = state.units.get(&unit_id).pos;
        WorldPos{v: geom::lift(geom::map_pos_to_world_pos(map_pos).v)}
    }

    pub fn move_selection_marker(
        &self,
        state: &GameState,
        scene: &mut Scene
    ) {
        let node = scene.nodes.get_mut(&SELECTION_NODE_ID);
        node.pos = self.get_pos(state);
    }

    pub fn create_selection_marker(
        &mut self,
        state: &GameState,
        scene: &mut Scene,
        unit_id: UnitId
    ) {
        self.set_unit_id(unit_id);
        if scene.nodes.find(&SELECTION_NODE_ID).is_some() {
            scene.nodes.remove(&SELECTION_NODE_ID);
        }
        let node = SceneNode {
            pos: self.get_pos(state),
            rot: 0.0,
            mesh_id: Some(self.mesh_id),
            children: Vec::new(),
        };
        scene.nodes.insert(SELECTION_NODE_ID, node);
    }

    pub fn deselect(&mut self, scene: &mut Scene) {
        scene.nodes.remove(&SELECTION_NODE_ID);
        self.unit_id = None;
    }
}

pub fn get_selection_mesh(fs: &FileSystem, shader: &Shader) -> Mesh {
    let tex = Texture::new(&fs.get(&Path::new("data/shell.png")));
    let mut vertex_data = Vec::new();
    let mut tex_data = Vec::new();
    let scale_1 = 0.6;
    let scale_2 = scale_1 + 0.05;
    for num in range(0i32, 6) {
        let vertex_1_1 = geom::index_to_hex_vertex_s(scale_1, num);
        let vertex_1_2 = geom::index_to_hex_vertex_s(scale_2, num);
        let vertex_2_1 = geom::index_to_hex_vertex_s(scale_1, num + 1);
        let vertex_2_2 = geom::index_to_hex_vertex_s(scale_2, num + 1);
        add_quad_to_vec(
            &mut vertex_data,
            vertex_2_1,
            vertex_2_2,
            vertex_1_2,
            vertex_1_1,
        );
        add_quad_to_vec(
            &mut tex_data,
            TextureCoord{v: Vector2{x: 0.0, y: 0.0}},
            TextureCoord{v: Vector2{x: 0.0, y: 1.0}},
            TextureCoord{v: Vector2{x: 1.0, y: 1.0}},
            TextureCoord{v: Vector2{x: 1.0, y: 0.0}},
        );
    }
    let mut mesh = Mesh::new(vertex_data.as_slice());
    mesh.set_texture(tex, tex_data.as_slice());
    mesh.prepare(shader);
    mesh
}

// vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab:
<|endoftext|>


<commit_before>use game_status::RoundParameters;
use game_status::GameStatus;
use game_status::GameInstanceState;
use game_status::RoundState;
use game_status::HeartsGameInstanceState;

use card::Card;
use card::dto::CardDto;
use deal::Deal;
use deal::dto::DealDto;
use deal::dto::InProgressDealDto;

use player::PlayerName;

use std::collections::BTreeMap;

#[derive(Deserialize, Debug)]
pub struct GameStatusDto {
    #[serde(rename="CurrentGameId")]
    current_game_id: String,
    #[serde(rename="CurrentGameState")]
    current_game_state: String,
    #[serde(rename="CurrentRoundId")]
    current_round_id: u32,
    #[serde(rename="CurrentRoundState")]
    current_round_state: String,
    #[serde(rename="RoundParameters")]
    round_parameters: RoundParametersDto,
    #[serde(rename="MyGameState")]
    my_game_state: String,
    #[serde(rename="MyGameStateDescription")]
    my_game_state_description: String,
    #[serde(rename="MyGameParticipants")]
    my_game_participants: Vec<GameParticipantDto>,
    #[serde(rename="MyInitialHand")]
    my_initial_hand: Vec<CardDto>,
    #[serde(rename="CardsPassedByMe")]
    cards_passed_by_me: Vec<CardDto>,
    #[serde(rename="CardsPassedToMe")]
    cards_passed_to_me: Vec<CardDto>,
    #[serde(rename="MyFinalHand")]
    my_final_hand: Vec<CardDto>,
    #[serde(rename="MyCurrentHand")]
    my_current_hand: Vec<CardDto>,
    #[serde(rename="MyGameDeals")]
    my_game_deals: Vec<DealDto>,
    #[serde(rename="MyInProgressDeal")]
    my_in_progress_deal: InProgressDealDto,
    #[serde(rename="IsMyTurn")]
    is_my_turn: bool,
}

impl From<GameStatusDto> for GameStatus {
    fn from(dto: GameStatusDto) -> GameStatus {
        GameStatus {
            current_game_id: dto.current_game_id,
            current_game_state: GameInstanceState::from(&dto.current_game_state as &str),
            current_round_id: dto.current_round_id,
            current_round_state: RoundState::from(&dto.current_round_state as &str),
            round_parameters: RoundParameters::from(dto.round_parameters),
            my_game_state: HeartsGameInstanceState::from(&dto.my_game_state as &str),
            my_game_players: dto.my_game_participants.into_iter().map(|participant| participant.team_name).collect(),
            my_initial_hand: dto.my_initial_hand.into_iter().map(Card::from).collect(),
            my_final_hand: dto.my_final_hand.into_iter().map(Card::from).collect(),
            my_current_hand: dto.my_current_hand.into_iter().map(Card::from).collect(),
            my_game_deals: dto.my_game_deals.into_iter().map(Deal::from).collect(),
            my_in_progress_deal: Deal::from(dto.my_in_progress_deal),
            is_my_turn: dto.is_my_turn,
        }
    }
}

#[derive(Deserialize, Debug)]
pub struct RoundParametersDto {
    #[serde(rename="RoundId")]
    round_id: u32,
    #[serde(rename="InitiationPhaseInSeconds")]
    initiation_phase_in_seconds: u32,
    #[serde(rename="PassingPhaseInSeconds")]
    passing_phase_in_seconds: u32,
    #[serde(rename="DealingPhaseInSeconds")]
    dealing_phase_in_seconds: u32,
    #[serde(rename="FinishingPhaseInSeconds")]
    finishing_phase_in_seconds: u32,
    #[serde(rename="NumberOfCardsTobePassed")]
    number_of_cards_to_be_passed: u32,
    #[serde(rename="CardPoints")]
    card_points: Vec<CardPointsDto>
}

impl From<RoundParametersDto> for RoundParameters {
    fn from(dto: RoundParametersDto) -> RoundParameters {
        let mut card_points: BTreeMap<Card, i32> = BTreeMap::new();
        for card_points_dto in dto.card_points {
            card_points.insert(Card::from(card_points_dto.card), card_points_dto.points);
        }

        RoundParameters {
            round_id: dto.round_id,
            initiation_phase_in_seconds: dto.initiation_phase_in_seconds,
            passing_phase_in_seconds: dto.passing_phase_in_seconds,
            dealing_phase_in_seconds: dto.dealing_phase_in_seconds,
            finishing_phase_in_seconds: dto.finishing_phase_in_seconds,
            number_of_cards_to_be_passed: dto.number_of_cards_to_be_passed,
            card_points: card_points,
        }
    }
}

#[derive(Deserialize, Debug)]
pub struct CardPointsDto {
    #[serde(rename="Card")]
    card: CardDto,
    #[serde(rename="Point")]
    points: i32,
}

#[derive(Deserialize, Debug)]
pub struct GameParticipantDto {
    #[serde(rename="TeamName")]
    team_name: PlayerName,
    #[serde(rename="LeftParticipant")]
    left_participant: PlayerName,
    #[serde(rename="NumberOfCardsInHand")]
    number_of_cards_in_hand: u32,
    #[serde(rename="HasTurn")]
    has_turn: bool,
    #[serde(rename="CurrentScore")]
    current_score: u32,
}
<commit_msg>cleanup<commit_after>use game_status::RoundParameters;
use game_status::GameStatus;
use game_status::GameInstanceState;
use game_status::RoundState;
use game_status::HeartsGameInstanceState;

use card::Card;
use card::dto::CardDto;
use deal::Deal;
use deal::dto::DealDto;
use deal::dto::InProgressDealDto;

use player::PlayerName;

#[derive(Deserialize, Debug)]
pub struct GameStatusDto {
    #[serde(rename="CurrentGameId")]
    current_game_id: String,
    #[serde(rename="CurrentGameState")]
    current_game_state: String,
    #[serde(rename="CurrentRoundId")]
    current_round_id: u32,
    #[serde(rename="CurrentRoundState")]
    current_round_state: String,
    #[serde(rename="RoundParameters")]
    round_parameters: RoundParametersDto,
    #[serde(rename="MyGameState")]
    my_game_state: String,
    #[serde(rename="MyGameStateDescription")]
    my_game_state_description: String,
    #[serde(rename="MyGameParticipants")]
    my_game_participants: Vec<GameParticipantDto>,
    #[serde(rename="MyInitialHand")]
    my_initial_hand: Vec<CardDto>,
    #[serde(rename="CardsPassedByMe")]
    cards_passed_by_me: Vec<CardDto>,
    #[serde(rename="CardsPassedToMe")]
    cards_passed_to_me: Vec<CardDto>,
    #[serde(rename="MyFinalHand")]
    my_final_hand: Vec<CardDto>,
    #[serde(rename="MyCurrentHand")]
    my_current_hand: Vec<CardDto>,
    #[serde(rename="MyGameDeals")]
    my_game_deals: Vec<DealDto>,
    #[serde(rename="MyInProgressDeal")]
    my_in_progress_deal: InProgressDealDto,
    #[serde(rename="IsMyTurn")]
    is_my_turn: bool,
}

impl From<GameStatusDto> for GameStatus {
    fn from(dto: GameStatusDto) -> GameStatus {
        GameStatus {
            current_game_id: dto.current_game_id,
            current_game_state: GameInstanceState::from(&dto.current_game_state as &str),
            current_round_id: dto.current_round_id,
            current_round_state: RoundState::from(&dto.current_round_state as &str),
            round_parameters: RoundParameters::from(dto.round_parameters),
            my_game_state: HeartsGameInstanceState::from(&dto.my_game_state as &str),
            my_game_players: dto.my_game_participants.into_iter().map(|participant| participant.team_name).collect(),
            my_initial_hand: dto.my_initial_hand.into_iter().map(Card::from).collect(),
            my_final_hand: dto.my_final_hand.into_iter().map(Card::from).collect(),
            my_current_hand: dto.my_current_hand.into_iter().map(Card::from).collect(),
            my_game_deals: dto.my_game_deals.into_iter().map(Deal::from).collect(),
            my_in_progress_deal: Deal::from(dto.my_in_progress_deal),
            is_my_turn: dto.is_my_turn,
        }
    }
}

#[derive(Deserialize, Debug)]
pub struct RoundParametersDto {
    #[serde(rename="RoundId")]
    round_id: u32,
    #[serde(rename="InitiationPhaseInSeconds")]
    initiation_phase_in_seconds: u32,
    #[serde(rename="PassingPhaseInSeconds")]
    passing_phase_in_seconds: u32,
    #[serde(rename="DealingPhaseInSeconds")]
    dealing_phase_in_seconds: u32,
    #[serde(rename="FinishingPhaseInSeconds")]
    finishing_phase_in_seconds: u32,
    #[serde(rename="NumberOfCardsTobePassed")]
    number_of_cards_to_be_passed: u32,
    #[serde(rename="CardPoints")]
    card_points: Vec<CardPointsDto>
}

impl From<RoundParametersDto> for RoundParameters {
    fn from(dto: RoundParametersDto) -> RoundParameters {
        RoundParameters {
            round_id: dto.round_id,
            initiation_phase_in_seconds: dto.initiation_phase_in_seconds,
            passing_phase_in_seconds: dto.passing_phase_in_seconds,
            dealing_phase_in_seconds: dto.dealing_phase_in_seconds,
            finishing_phase_in_seconds: dto.finishing_phase_in_seconds,
            number_of_cards_to_be_passed: dto.number_of_cards_to_be_passed,
            card_points: dto.card_points.into_iter().map(CardPointsDto::into).collect(),
        }
    }
}

#[derive(Deserialize, Debug)]
pub struct CardPointsDto {
    #[serde(rename="Card")]
    card: CardDto,
    #[serde(rename="Point")]
    points: i32,
}

impl From<CardPointsDto> for (Card, i32) {
    fn from(dto: CardPointsDto) -> (Card, i32) {
        (Card::from(dto.card), dto.points)
    }
}

#[derive(Deserialize, Debug)]
pub struct GameParticipantDto {
    #[serde(rename="TeamName")]
    team_name: PlayerName,
    #[serde(rename="LeftParticipant")]
    left_participant: PlayerName,
    #[serde(rename="NumberOfCardsInHand")]
    number_of_cards_in_hand: u32,
    #[serde(rename="HasTurn")]
    has_turn: bool,
    #[serde(rename="CurrentScore")]
    current_score: u32,
}
<|endoftext|>


<commit_before>extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_bencode;

use serde_bencode::value::Value;
use serde_bencode::de::{from_bytes, from_str};
use serde_bencode::ser::{Serializer, to_bytes, to_string};
use serde_bencode::error::Result;
use serde::de::DeserializeOwned;
use serde::ser::Serialize;
use std::collections::HashMap;
use std::fmt::Debug;

fn test_value_ser_de<T: Into<Value>>(a: T) {
    let a = a.into();
    let mut ser = Serializer::new();
    a.serialize(&mut ser).unwrap();
    println!("bytes: {:?}", String::from_utf8_lossy(ser.as_ref()));
    let b: Value = from_bytes(ser.as_ref()).unwrap();
    assert_eq!(a, b);
}

fn test_value_de_ser(s: &str) {
    let d: Value = from_str(s).unwrap();
    let e = to_string(&d).unwrap();
    assert_eq!(s, e);
}

fn test_ser_de_eq<T>(a: T)
    where T: Serialize + DeserializeOwned + Debug + Eq
{
    let mut ser = Serializer::new();
    a.serialize(&mut ser).unwrap();
    println!("bytes: {:?}", String::from_utf8_lossy(ser.as_ref()));
    let b: T = from_bytes(ser.as_ref()).unwrap();
    assert_eq!(a, b);
}

#[test]
fn ser_de_int() {
    test_value_ser_de(666i64);
}

#[test]
fn ser_de_string() {
    test_value_ser_de("yoda");
}

#[test]
fn ser_de_value_list_mixed() {
    test_value_ser_de(Value::List(vec!["one".into(), "two".into(), "three".into(), 4i64.into()]));
}

#[test]
fn ser_de_value_list_nested() {
    let l_grandchild = Value::List(vec!["two".into()]);
    let l_child = Value::List(vec!["one".into(), l_grandchild]);
    test_value_ser_de(vec!["one".into(),
                           "two".into(),
                           "three".into(),
                           4i64.into(),
                           l_child]);
}

#[test]
fn ser_de_value_map() {
    let mut m = HashMap::new();
    m.insert("Mc".into(), "Burger".into());
    test_value_ser_de(m);
}

#[test]
fn ser_de_map_value_mixed() {
    let mut ma = HashMap::new();
    ma.insert("M jr.".into(), "nuggets".into());
    let s = Value::List(vec!["one".into(), "two".into(), "three".into(), 4i64.into()]);
    let mut m = HashMap::new();
    m.insert("Mc".into(), "Burger".into());
    m.insert("joint".into(), ma.into());
    m.insert("woah".into(), s);
    test_value_ser_de(m);
}

#[test]
fn serialize_i64() {
    assert_eq!(to_string(&666i64).unwrap(), "i666e");
}

#[test]
fn serialize_str() {
    assert_eq!(to_string(&"xxx").unwrap(), "3:xxx");
}

#[test]
fn serialize_bool() {
    assert_eq!(to_string(&false).unwrap(), "i0e");
    assert_eq!(to_string(&true).unwrap(), "i1e");
}

#[test]
fn deserialize_to_string() {
    let r: String = from_str("3:yes").unwrap();
    assert_eq!(r, "yes");
}

#[test]
fn deserialize_to_i64() {
    let r: i64 = from_str("i666e").unwrap();
    assert_eq!(r, 666);
}

#[test]
fn deserialize_to_vec() {
    let r: Vec<i64> = from_str("li666ee").unwrap();
    assert_eq!(r, [666]);
}

#[test]
fn deserialize_to_freestyle() {
    let s = "li666e4:wontd3:onei666e4:yoyoli69ei89e4:yoyoeee";
    test_value_de_ser(s);
}

#[test]
#[ignore]
#[should_panic(expected = "assertion failed")]
fn trailing_chars() {
    let s = "i666ed";
    let r: Result<Value> = from_str(s);
    assert!(r.is_err());
}

#[test]
fn stop_short() {
    let s = "3:we";
    let r: Result<Value> = from_str(s);
    assert!(r.is_err());
}

#[test]
fn multi_digit_string_length() {
    let s: String = from_str("1:o").unwrap();
    assert_eq!(s, "o");

    let s: String = from_str("10:oooooooooo").unwrap();
    assert_eq!(s, "oooooooooo");

    let s: String = from_str("100:oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo").unwrap();
    assert_eq!(s,
               "oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo");
}

#[test]
fn serialize_struct() {
    #[derive(Debug, Serialize)]
    struct Fake {
        x: i64,
        y: String,
    };
    let f = Fake {
        x: 1111,
        y: "dog".to_string(),
    };
    assert_eq!(to_string(&f).unwrap(), "d1:xi1111e1:y3:doge");
}

#[test]
fn deserialize_to_struct() {
    let b = "d1:xi1111e1:y3:doge";
    #[derive(PartialEq, Debug, Deserialize)]
    struct Fake {
        y: String,
        x: i64,
    };
    assert_eq!(from_str::<Fake>(b).unwrap(),
               Fake {
                   x: 1111,
                   y: "dog".to_string(),
               });
}

#[test]
fn deserialize_to_struct_with_option() {
    let b = "d1:xi1111e1:y3:dog1:z2:yoe";
    #[derive(PartialEq, Debug, Deserialize)]
    struct Fake {
        y: String,
        x: i64,
        #[serde(default)]
        z: Option<String>,
        #[serde(default)]
        a: Option<String>,
    };
    let r: Fake = from_str(b).unwrap();
    assert_eq!(r,
               Fake {
                   x: 1111,
                   y: "dog".to_string(),
                   z: Some("yo".to_string()),
                   a: None,
               });
}

#[test]
fn deserialize_to_value() {
    let b = "d1:xi1111e1:y3:doge";
    let r: Value = from_str(b).unwrap();
    let mut d = HashMap::new();
    d.insert("x".into(), 1111.into());
    d.insert("y".into(), "dog".into());
    assert_eq!(r, Value::Dict(d));
}

#[test]
fn deserialize_to_value_struct_mix() {
    let b = "d1:xi1111e1:y3:dog1:zi66e1:qli666eee";
    #[derive(PartialEq, Debug, Deserialize)]
    struct Fake {
        y: String,
        x: i64,
        z: Value,
        q: Vec<i64>,
    };
    let r: Fake = from_str(b).unwrap();
    assert_eq!(r,
               Fake {
                   x: 1111,
                   y: "dog".to_string(),
                   z: Value::Int(66),
                   q: vec![666],
               });
}

#[test]
fn serialize_lexical_sorted_keys() {
    #[derive(Serialize)]
    struct Fake {
        aaa: i32,
        bb: i32,
        z: i32,
        c: i32,
    };
    let f = Fake {
        aaa: 1,
        bb: 2,
        z: 3,
        c: 4,
    };
    assert_eq!(to_string(&f).unwrap(), "d3:aaai1e2:bbi2e1:ci4e1:zi3ee");
}

#[test]
fn serialize_newtype_struct() {
    #[derive(Serialize)]
    struct Fake(i32);
    let f = Fake(66);
    assert_eq!(to_string(&f).unwrap(), "i66e");
}

#[test]
fn serialize_some() {
    let f = Some(1);
    assert_eq!(to_string(&f).unwrap(), "i1e");
}

#[test]
fn serialize_none() {
    let f: Option<Value> = None;
    assert_eq!(to_string(&f).unwrap(), "");
}

#[test]
fn serialize_tuple() {
    let f = (1, 2, 3, "one");
    assert_eq!(to_string(&f).unwrap(), "li1ei2ei3e3:onee");
}

#[test]
fn serialize_tuple_struct() {
    #[derive(Serialize)]
    struct Fake(i32, i32);
    let f = Fake(66, 66);
    assert_eq!(to_string(&f).unwrap(), "li66ei66ee");
}

#[test]
fn readme_value_example() {
    let list: Vec<Value> = vec!["one".into(), "two".into(), "three".into(), 4i64.into()];
    assert_eq!(to_string(&list).unwrap(), "l3:one3:two5:threei4ee");
}

#[test]
fn struct_none_vals() {
    #[derive(Serialize)]
    struct Fake {
        a: Option<i32>,
        b: Option<i32>,
    };
    let f = Fake {
        a: None,
        b: Some(1),
    };
    assert_eq!(to_string(&f).unwrap(), "d1:bi1ee");
}

#[test]
fn ser_de_variant_unit() {
    #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
    enum Mock {
        A,
        B,
    };
    test_ser_de_eq(Mock::A);
    test_ser_de_eq(Mock::B);
}

#[test]
fn ser_de_variant_newtype() {
    #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
    enum Mock {
        A(i64),
        B(i64),
    };
    test_ser_de_eq(Mock::A(123));
    test_ser_de_eq(Mock::B(321));
}

#[test]
fn ser_de_variant_tuple() {
    #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
    enum Mock {
        A(i64, i64),
        B(i64, i64),
    };
    test_ser_de_eq(Mock::A(123, 321));
    test_ser_de_eq(Mock::B(321, 123));
}

#[test]
fn ser_de_variant_struct() {
    #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
    enum Mock {
        A { a: i64, b: i64 },
        B { c: i64, d: i64 },
    };
    test_ser_de_eq(Mock::A { a: 123, b: 321 });
    test_ser_de_eq(Mock::B { c: 321, d: 123 });
}

#[test]
fn test_to_bytes() {
    assert_eq!(to_bytes(&"test").unwrap(), b"4:test");
}
<commit_msg>improve variant tests<commit_after>extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_bencode;

use serde_bencode::value::Value;
use serde_bencode::de::{from_bytes, from_str};
use serde_bencode::ser::{Serializer, to_bytes, to_string};
use serde_bencode::error::Result;
use serde::de::DeserializeOwned;
use serde::ser::Serialize;
use std::collections::HashMap;
use std::fmt::Debug;

fn test_value_ser_de<T: Into<Value>>(a: T) {
    let a = a.into();
    let mut ser = Serializer::new();
    a.serialize(&mut ser).unwrap();
    println!("bytes: {:?}", String::from_utf8_lossy(ser.as_ref()));
    let b: Value = from_bytes(ser.as_ref()).unwrap();
    assert_eq!(a, b);
}

fn test_value_de_ser(s: &str) {
    let d: Value = from_str(s).unwrap();
    let e = to_string(&d).unwrap();
    assert_eq!(s, e);
}

fn test_ser_de_eq<T>(a: T)
    where T: Serialize + DeserializeOwned + Debug + Eq
{
    let mut ser = Serializer::new();
    a.serialize(&mut ser).unwrap();
    println!("bytes: {:?}", String::from_utf8_lossy(ser.as_ref()));
    let b: T = from_bytes(ser.as_ref()).unwrap();
    assert_eq!(a, b);
}

#[test]
fn ser_de_int() {
    test_value_ser_de(666i64);
}

#[test]
fn ser_de_string() {
    test_value_ser_de("yoda");
}

#[test]
fn ser_de_value_list_mixed() {
    test_value_ser_de(Value::List(vec!["one".into(), "two".into(), "three".into(), 4i64.into()]));
}

#[test]
fn ser_de_value_list_nested() {
    let l_grandchild = Value::List(vec!["two".into()]);
    let l_child = Value::List(vec!["one".into(), l_grandchild]);
    test_value_ser_de(vec!["one".into(),
                           "two".into(),
                           "three".into(),
                           4i64.into(),
                           l_child]);
}

#[test]
fn ser_de_value_map() {
    let mut m = HashMap::new();
    m.insert("Mc".into(), "Burger".into());
    test_value_ser_de(m);
}

#[test]
fn ser_de_map_value_mixed() {
    let mut ma = HashMap::new();
    ma.insert("M jr.".into(), "nuggets".into());
    let s = Value::List(vec!["one".into(), "two".into(), "three".into(), 4i64.into()]);
    let mut m = HashMap::new();
    m.insert("Mc".into(), "Burger".into());
    m.insert("joint".into(), ma.into());
    m.insert("woah".into(), s);
    test_value_ser_de(m);
}

#[test]
fn serialize_i64() {
    assert_eq!(to_string(&666i64).unwrap(), "i666e");
}

#[test]
fn serialize_str() {
    assert_eq!(to_string(&"xxx").unwrap(), "3:xxx");
}

#[test]
fn serialize_bool() {
    assert_eq!(to_string(&false).unwrap(), "i0e");
    assert_eq!(to_string(&true).unwrap(), "i1e");
}

#[test]
fn deserialize_to_string() {
    let r: String = from_str("3:yes").unwrap();
    assert_eq!(r, "yes");
}

#[test]
fn deserialize_to_i64() {
    let r: i64 = from_str("i666e").unwrap();
    assert_eq!(r, 666);
}

#[test]
fn deserialize_to_vec() {
    let r: Vec<i64> = from_str("li666ee").unwrap();
    assert_eq!(r, [666]);
}

#[test]
fn deserialize_to_freestyle() {
    let s = "li666e4:wontd3:onei666e4:yoyoli69ei89e4:yoyoeee";
    test_value_de_ser(s);
}

#[test]
#[ignore]
#[should_panic(expected = "assertion failed")]
fn trailing_chars() {
    let s = "i666ed";
    let r: Result<Value> = from_str(s);
    assert!(r.is_err());
}

#[test]
fn stop_short() {
    let s = "3:we";
    let r: Result<Value> = from_str(s);
    assert!(r.is_err());
}

#[test]
fn multi_digit_string_length() {
    let s: String = from_str("1:o").unwrap();
    assert_eq!(s, "o");

    let s: String = from_str("10:oooooooooo").unwrap();
    assert_eq!(s, "oooooooooo");

    let s: String = from_str("100:oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo").unwrap();
    assert_eq!(s,
               "oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo");
}

#[test]
fn serialize_struct() {
    #[derive(Debug, Serialize)]
    struct Fake {
        x: i64,
        y: String,
    };
    let f = Fake {
        x: 1111,
        y: "dog".to_string(),
    };
    assert_eq!(to_string(&f).unwrap(), "d1:xi1111e1:y3:doge");
}

#[test]
fn deserialize_to_struct() {
    let b = "d1:xi1111e1:y3:doge";
    #[derive(PartialEq, Debug, Deserialize)]
    struct Fake {
        y: String,
        x: i64,
    };
    assert_eq!(from_str::<Fake>(b).unwrap(),
               Fake {
                   x: 1111,
                   y: "dog".to_string(),
               });
}

#[test]
fn deserialize_to_struct_with_option() {
    let b = "d1:xi1111e1:y3:dog1:z2:yoe";
    #[derive(PartialEq, Debug, Deserialize)]
    struct Fake {
        y: String,
        x: i64,
        #[serde(default)]
        z: Option<String>,
        #[serde(default)]
        a: Option<String>,
    };
    let r: Fake = from_str(b).unwrap();
    assert_eq!(r,
               Fake {
                   x: 1111,
                   y: "dog".to_string(),
                   z: Some("yo".to_string()),
                   a: None,
               });
}

#[test]
fn deserialize_to_value() {
    let b = "d1:xi1111e1:y3:doge";
    let r: Value = from_str(b).unwrap();
    let mut d = HashMap::new();
    d.insert("x".into(), 1111.into());
    d.insert("y".into(), "dog".into());
    assert_eq!(r, Value::Dict(d));
}

#[test]
fn deserialize_to_value_struct_mix() {
    let b = "d1:xi1111e1:y3:dog1:zi66e1:qli666eee";
    #[derive(PartialEq, Debug, Deserialize)]
    struct Fake {
        y: String,
        x: i64,
        z: Value,
        q: Vec<i64>,
    };
    let r: Fake = from_str(b).unwrap();
    assert_eq!(r,
               Fake {
                   x: 1111,
                   y: "dog".to_string(),
                   z: Value::Int(66),
                   q: vec![666],
               });
}

#[test]
fn serialize_lexical_sorted_keys() {
    #[derive(Serialize)]
    struct Fake {
        aaa: i32,
        bb: i32,
        z: i32,
        c: i32,
    };
    let f = Fake {
        aaa: 1,
        bb: 2,
        z: 3,
        c: 4,
    };
    assert_eq!(to_string(&f).unwrap(), "d3:aaai1e2:bbi2e1:ci4e1:zi3ee");
}

#[test]
fn serialize_newtype_struct() {
    #[derive(Serialize)]
    struct Fake(i32);
    let f = Fake(66);
    assert_eq!(to_string(&f).unwrap(), "i66e");
}

#[test]
fn serialize_some() {
    let f = Some(1);
    assert_eq!(to_string(&f).unwrap(), "i1e");
}

#[test]
fn serialize_none() {
    let f: Option<Value> = None;
    assert_eq!(to_string(&f).unwrap(), "");
}

#[test]
fn serialize_tuple() {
    let f = (1, 2, 3, "one");
    assert_eq!(to_string(&f).unwrap(), "li1ei2ei3e3:onee");
}

#[test]
fn serialize_tuple_struct() {
    #[derive(Serialize)]
    struct Fake(i32, i32);
    let f = Fake(66, 66);
    assert_eq!(to_string(&f).unwrap(), "li66ei66ee");
}

#[test]
fn readme_value_example() {
    let list: Vec<Value> = vec!["one".into(), "two".into(), "three".into(), 4i64.into()];
    assert_eq!(to_string(&list).unwrap(), "l3:one3:two5:threei4ee");
}

#[test]
fn struct_none_vals() {
    #[derive(Serialize)]
    struct Fake {
        a: Option<i32>,
        b: Option<i32>,
    };
    let f = Fake {
        a: None,
        b: Some(1),
    };
    assert_eq!(to_string(&f).unwrap(), "d1:bi1ee");
}

#[test]
fn ser_de_variant_unit() {
    #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
    enum Mock {
        A,
        B,
    };
    test_ser_de_eq(("pre".to_string(), Mock::A, "post".to_string()));
    test_ser_de_eq(("pre".to_string(), Mock::B, "post".to_string()));
}

#[test]
fn ser_de_variant_newtype() {
    #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
    enum Mock {
        A(i64),
        B(i64),
    };
    test_ser_de_eq(("pre".to_string(), Mock::A(123), "post".to_string()));
    test_ser_de_eq(("pre".to_string(), Mock::B(321), "post".to_string()));
}

#[test]
fn ser_de_variant_tuple() {
    #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
    enum Mock {
        A(i64, i64),
        B(i64, i64),
    };
    test_ser_de_eq(("pre".to_string(), Mock::A(123, 321), "post".to_string()));
    test_ser_de_eq(("pre".to_string(), Mock::B(321, 123), "post".to_string()));
}

#[test]
fn ser_de_variant_struct() {
    #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
    enum Mock {
        A { a: i64, b: i64 },
        B { c: i64, d: i64 },
    };
    test_ser_de_eq(("pre".to_string(), Mock::A { a: 123, b: 321 }, "post".to_string()));
    test_ser_de_eq(("pre".to_string(), Mock::B { c: 321, d: 123 }, "post".to_string()));
}

#[test]
fn test_to_bytes() {
    assert_eq!(to_bytes(&"test").unwrap(), b"4:test");
}
<|endoftext|>


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

//! The `Default` trait for types which may have meaningful default values

#![stable]

/// A trait that types which have a useful default value should implement.
pub trait Default {
    /// Return the "default value" for a type.
    ///
    /// # Example
    ///
    /// ```
    /// use std::default::Default;
    ///
    /// let i: i8 = Default::default();
    /// let (x, y): (Option<String>, f64) = Default::default();
    /// let (a, b, (c, d)): (int, uint, (bool, bool)) = Default::default();
    /// ```
    fn default() -> Self;
}

macro_rules! default_impl(
    ($t:ty, $v:expr) => {
        impl Default for $t {
            #[inline]
            fn default() -> $t { $v }
        }
    }
)

default_impl!((), ())
default_impl!(bool, false)
default_impl!(char, '\x00')

default_impl!(uint, 0u)
default_impl!(u8,  0u8)
default_impl!(u16, 0u16)
default_impl!(u32, 0u32)
default_impl!(u64, 0u64)

default_impl!(int, 0i)
default_impl!(i8,  0i8)
default_impl!(i16, 0i16)
default_impl!(i32, 0i32)
default_impl!(i64, 0i64)

default_impl!(f32, 0.0f32)
default_impl!(f64, 0.0f64)
<commit_msg>Beef up Default documentation<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! The `Default` trait for types which may have meaningful default values.
//!
//! Sometimes, you want to fall back to some kind of default value, and
//! don't particularly care what it is. This comes up often with `struct`s
//! that define a set of options:
//!
//! ```
//! struct SomeOptions {
//!     foo: int,
//!     bar: f32,
//! }
//! ```
//!
//! How can we define some default values? You can use `Default`:
//!
//! ```
//! use std::default::Default;
//!
//! #[deriving(Default)]
//! struct SomeOptions {
//!     foo: int,
//!     bar: f32,
//! }
//!
//!
//! fn main() {
//!     let options: SomeOptions = Default::default();
//! }
//! ```
//!
//! Now, you get all of the default values. Rust implements `Default` for various primitives types.
//! If you have your own type, you need to implement `Default` yourself:
//!
//! ```
//! use std::default::Default;
//!
//! enum Kind {
//!     A,
//!     B,
//!     C,
//! }
//!
//! impl Default for Kind {
//!     fn default() -> Kind { A }
//! }
//!
//! #[deriving(Default)]
//! struct SomeOptions {
//!     foo: int,
//!     bar: f32,
//!     baz: Kind,
//! }
//!
//!
//! fn main() {
//!     let options: SomeOptions = Default::default();
//! }
//! ```
//!
//! If you want to override a particular option, but still retain the other defaults:
//!
//! ```
//! # use std::default::Default;
//! # #[deriving(Default)]
//! # struct SomeOptions {
//! #     foo: int,
//! #     bar: f32,
//! # }
//! fn main() {
//!     let options = SomeOptions { foo: 42, ..Default::default() };
//! }
//! ```

#![stable]

/// A trait that types which have a useful default value should implement.
///
/// A struct can derive default implementations of `Default` for basic types using
/// `#[deriving(Default)]`.
///
/// # Examples
///
/// ```
/// #[deriving(Default)]
/// struct SomeOptions {
///     foo: int,
///     bar: f32,
/// }
/// ```
pub trait Default {
    /// Returns the "default value" for a type.
    ///
    /// Default values are often some kind of initial value, identity value, or anything else that
    /// may make sense as a default.
    ///
    /// # Examples
    ///
    /// Using built-in default values:
    ///
    /// ```
    /// use std::default::Default;
    ///
    /// let i: i8 = Default::default();
    /// let (x, y): (Option<String>, f64) = Default::default();
    /// let (a, b, (c, d)): (int, uint, (bool, bool)) = Default::default();
    /// ```
    ///
    /// Making your own:
    ///
    /// ```
    /// use std::default::Default;
    ///
    /// enum Kind {
    ///     A,
    ///     B,
    ///     C,
    /// }
    ///
    /// impl Default for Kind {
    ///     fn default() -> Kind { A }
    /// }
    /// ```
    fn default() -> Self;
}

macro_rules! default_impl(
    ($t:ty, $v:expr) => {
        impl Default for $t {
            #[inline]
            fn default() -> $t { $v }
        }
    }
)

default_impl!((), ())
default_impl!(bool, false)
default_impl!(char, '\x00')

default_impl!(uint, 0u)
default_impl!(u8,  0u8)
default_impl!(u16, 0u16)
default_impl!(u32, 0u32)
default_impl!(u64, 0u64)

default_impl!(int, 0i)
default_impl!(i8,  0i8)
default_impl!(i16, 0i16)
default_impl!(i32, 0i32)
default_impl!(i64, 0i64)

default_impl!(f32, 0.0f32)
default_impl!(f64, 0.0f64)
<|endoftext|>


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

//! Failure support for libcore
//!
//! The core library cannot define failure, but it does *declare* failure. This
//! means that the functions inside of libcore are allowed to fail, but to be
//! useful an upstream crate must define failure for libcore to use. The current
//! interface for failure is:
//!
//! ```ignore
//! fn begin_unwind(fmt: &fmt::Arguments, file: &str, line: uint) -> !;
//! ```
//!
//! This definition allows for failing with any general message, but it does not
//! allow for failing with a `~Any` value. The reason for this is that libcore
//! is not allowed to allocate.
//!
//! This module contains a few other failure functions, but these are just the
//! necessary lang items for the compiler. All failure is funneled through this
//! one function. Currently, the actual symbol is declared in the standard
//! library, but the location of this may change over time.

#![allow(dead_code, missing_doc)]

use fmt;
use intrinsics;

#[cfg(stage0)]
#[cold] #[inline(never)] // this is the slow path, always
#[lang="fail_"]
fn fail_(expr: &'static str, file: &'static str, line: uint) -> ! {
    format_args!(|args| -> () {
        begin_unwind(args, &(file, line));
    }, "{}", expr);

    unsafe { intrinsics::abort() }
}

#[cfg(stage0)]
#[cold]
#[lang="fail_bounds_check"]
fn fail_bounds_check(file: &'static str, line: uint,
                     index: uint, len: uint) -> ! {
    format_args!(|args| -> () {
        begin_unwind(args, &(file, line));
    }, "index out of bounds: the len is {} but the index is {}", len, index);
    unsafe { intrinsics::abort() }
}

#[cfg(stage0)]
#[cold]
pub fn begin_unwind(fmt: &fmt::Arguments, file_line: &(&'static str, uint)) -> ! {
    #[allow(ctypes)]
    extern {
        #[lang = "begin_unwind"]
        fn begin_unwind(fmt: &fmt::Arguments, file: &'static str,
                        line: uint) -> !;
    }
    let (file, line) = *file_line;
    unsafe { begin_unwind(fmt, file, line) }
}

#[cfg(not(stage0))]
#[cold] #[inline(never)] // this is the slow path, always
#[lang="fail_"]
fn fail_(expr: &'static str, file: &'static str, line: uint) -> ! {
    format_args!(|args| -> () {
        begin_unwind(args, &(file, line));
    }, "{}", expr);

    unsafe { intrinsics::abort() }
}

#[cfg(not(stage0))]
#[cold]
#[lang="fail_bounds_check"]
fn fail_bounds_check(file: &'static str, line: uint,
                     index: uint, len: uint) -> ! {
    format_args!(|args| -> () {
        begin_unwind(args, &(file, line));
    }, "index out of bounds: the len is {} but the index is {}", len, index);
    unsafe { intrinsics::abort() }
}

#[cfg(not(stage0))]
#[cold]
pub fn begin_unwind(fmt: &fmt::Arguments, file_line: &(&'static str, uint)) -> ! {
    #[allow(ctypes)]
    extern {
        #[lang = "begin_unwind"]
        fn begin_unwind(fmt: &fmt::Arguments, file_line: &'static str,
                        line: uint) -> !;
    }
    let (file, line) = *file_line;
    unsafe { begin_unwind(fmt, file, line) }
}
<commit_msg>core: Remove unneeded cfgs<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Failure support for libcore
//!
//! The core library cannot define failure, but it does *declare* failure. This
//! means that the functions inside of libcore are allowed to fail, but to be
//! useful an upstream crate must define failure for libcore to use. The current
//! interface for failure is:
//!
//! ```ignore
//! fn begin_unwind(fmt: &fmt::Arguments, file: &str, line: uint) -> !;
//! ```
//!
//! This definition allows for failing with any general message, but it does not
//! allow for failing with a `~Any` value. The reason for this is that libcore
//! is not allowed to allocate.
//!
//! This module contains a few other failure functions, but these are just the
//! necessary lang items for the compiler. All failure is funneled through this
//! one function. Currently, the actual symbol is declared in the standard
//! library, but the location of this may change over time.

#![allow(dead_code, missing_doc)]

use fmt;
use intrinsics;

#[cold] #[inline(never)] // this is the slow path, always
#[lang="fail_"]
fn fail_(expr: &'static str, file: &'static str, line: uint) -> ! {
    format_args!(|args| -> () {
        begin_unwind(args, &(file, line));
    }, "{}", expr);

    unsafe { intrinsics::abort() }
}

#[cold]
#[lang="fail_bounds_check"]
fn fail_bounds_check(file: &'static str, line: uint,
                     index: uint, len: uint) -> ! {
    format_args!(|args| -> () {
        begin_unwind(args, &(file, line));
    }, "index out of bounds: the len is {} but the index is {}", len, index);
    unsafe { intrinsics::abort() }
}

#[cold]
pub fn begin_unwind(fmt: &fmt::Arguments, file_line: &(&'static str, uint)) -> ! {
    #[allow(ctypes)]
    extern {
        #[lang = "begin_unwind"]
        fn begin_unwind(fmt: &fmt::Arguments, file: &'static str,
                        line: uint) -> !;
    }
    let (file, line) = *file_line;
    unsafe { begin_unwind(fmt, file, line) }
}

<|endoftext|>


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

//! Integer and floating-point number formatting

// FIXME: #6220 Implement floating point formatting

#![allow(unsigned_negation)]

use fmt;
use iter::IteratorExt;
use num::{Int, cast};
use slice::SliceExt;
use str;

/// A type that represents a specific radix
#[doc(hidden)]
trait GenericRadix {
    /// The number of digits.
    fn base(&self) -> u8;

    /// A radix-specific prefix string.
    fn prefix(&self) -> &'static str { "" }

    /// Converts an integer to corresponding radix digit.
    fn digit(&self, x: u8) -> u8;

    /// Format an integer using the radix using a formatter.
    fn fmt_int<T: Int>(&self, mut x: T, f: &mut fmt::Formatter) -> fmt::Result {
        // The radix can be as low as 2, so we need a buffer of at least 64
        // characters for a base 2 number.
        let zero = Int::zero();
        let is_positive = x >= zero;
        let mut buf = [0u8; 64];
        let mut curr = buf.len();
        let base = cast(self.base()).unwrap();
        if is_positive {
            // Accumulate each digit of the number from the least significant
            // to the most significant figure.
            for byte in buf.iter_mut().rev() {
                let n = x % base;                         // Get the current place value.
                x = x / base;                             // Deaccumulate the number.
                *byte = self.digit(cast(n).unwrap());     // Store the digit in the buffer.
                curr -= 1;
                if x == zero { break };                   // No more digits left to accumulate.
            }
        } else {
            // Do the same as above, but accounting for two's complement.
            for byte in buf.iter_mut().rev() {
                let n = zero - (x % base);                // Get the current place value.
                x = x / base;                             // Deaccumulate the number.
                *byte = self.digit(cast(n).unwrap());     // Store the digit in the buffer.
                curr -= 1;
                if x == zero { break };                   // No more digits left to accumulate.
            }
        }
        let buf = unsafe { str::from_utf8_unchecked(&buf[curr..]) };
        f.pad_integral(is_positive, self.prefix(), buf)
    }
}

/// A binary (base 2) radix
#[derive(Clone, PartialEq)]
struct Binary;

/// An octal (base 8) radix
#[derive(Clone, PartialEq)]
struct Octal;

/// A decimal (base 10) radix
#[derive(Clone, PartialEq)]
struct Decimal;

/// A hexadecimal (base 16) radix, formatted with lower-case characters
#[derive(Clone, PartialEq)]
struct LowerHex;

/// A hexadecimal (base 16) radix, formatted with upper-case characters
#[derive(Clone, PartialEq)]
pub struct UpperHex;

macro_rules! radix {
    ($T:ident, $base:expr, $prefix:expr, $($x:pat => $conv:expr),+) => {
        impl GenericRadix for $T {
            fn base(&self) -> u8 { $base }
            fn prefix(&self) -> &'static str { $prefix }
            fn digit(&self, x: u8) -> u8 {
                match x {
                    $($x => $conv,)+
                    x => panic!("number not in the range 0..{}: {}", self.base() - 1, x),
                }
            }
        }
    }
}

radix! { Binary,    2, "0b", x @  0 ...  2 => b'0' + x }
radix! { Octal,     8, "0o", x @  0 ...  7 => b'0' + x }
radix! { Decimal,  10, "",   x @  0 ...  9 => b'0' + x }
radix! { LowerHex, 16, "0x", x @  0 ...  9 => b'0' + x,
                             x @ 10 ... 15 => b'a' + (x - 10) }
radix! { UpperHex, 16, "0x", x @  0 ...  9 => b'0' + x,
                             x @ 10 ... 15 => b'A' + (x - 10) }

/// A radix with in the range of `2..36`.
#[derive(Clone, Copy, PartialEq)]
#[unstable(feature = "core",
           reason = "may be renamed or move to a different module")]
pub struct Radix {
    base: u8,
}

impl Radix {
    fn new(base: u8) -> Radix {
        assert!(2 <= base && base <= 36, "the base must be in the range of 2..36: {}", base);
        Radix { base: base }
    }
}

impl GenericRadix for Radix {
    fn base(&self) -> u8 { self.base }
    fn digit(&self, x: u8) -> u8 {
        match x {
            x @  0 ... 9 => b'0' + x,
            x if x < self.base() => b'a' + (x - 10),
            x => panic!("number not in the range 0..{}: {}", self.base() - 1, x),
        }
    }
}

/// A helper type for formatting radixes.
#[unstable(feature = "core",
           reason = "may be renamed or move to a different module")]
#[derive(Copy)]
pub struct RadixFmt<T, R>(T, R);

/// Constructs a radix formatter in the range of `2..36`.
///
/// # Example
///
/// ```
/// use std::fmt::radix;
/// assert_eq!(format!("{}", radix(55, 36)), "1j".to_string());
/// ```
#[unstable(feature = "core",
           reason = "may be renamed or move to a different module")]
pub fn radix<T>(x: T, base: u8) -> RadixFmt<T, Radix> {
    RadixFmt(x, Radix::new(base))
}

macro_rules! radix_fmt {
    ($T:ty as $U:ty, $fmt:ident, $S:expr) => {
        #[stable(feature = "rust1", since = "1.0.0")]
        impl fmt::Debug for RadixFmt<$T, Radix> {
            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                fmt::Display::fmt(self, f)
            }
        }
        #[stable(feature = "rust1", since = "1.0.0")]
        impl fmt::Display for RadixFmt<$T, Radix> {
            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                match *self { RadixFmt(ref x, radix) => radix.$fmt(*x as $U, f) }
            }
        }
    }
}
macro_rules! int_base {
    ($Trait:ident for $T:ident as $U:ident -> $Radix:ident) => {
        #[stable(feature = "rust1", since = "1.0.0")]
        impl fmt::$Trait for $T {
            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                $Radix.fmt_int(*self as $U, f)
            }
        }
    }
}

macro_rules! show {
    ($T:ident with $S:expr) => {
        #[stable(feature = "rust1", since = "1.0.0")]
        impl fmt::Debug for $T {
            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                fmt::Display::fmt(self, f)
            }
        }
    }
}
macro_rules! integer {
    ($Int:ident, $Uint:ident) => {
        integer! { $Int, $Uint, stringify!($Int), stringify!($Uint) }
    };
    ($Int:ident, $Uint:ident, $SI:expr, $SU:expr) => {
        int_base! { Display  for $Int as $Int   -> Decimal }
        int_base! { Binary   for $Int as $Uint  -> Binary }
        int_base! { Octal    for $Int as $Uint  -> Octal }
        int_base! { LowerHex for $Int as $Uint  -> LowerHex }
        int_base! { UpperHex for $Int as $Uint  -> UpperHex }
        radix_fmt! { $Int as $Int, fmt_int, $SI }
        show! { $Int with $SI }

        int_base! { Display  for $Uint as $Uint -> Decimal }
        int_base! { Binary   for $Uint as $Uint -> Binary }
        int_base! { Octal    for $Uint as $Uint -> Octal }
        int_base! { LowerHex for $Uint as $Uint -> LowerHex }
        int_base! { UpperHex for $Uint as $Uint -> UpperHex }
        radix_fmt! { $Uint as $Uint, fmt_int, $SU }
        show! { $Uint with $SU }
    }
}
integer! { isize, usize, "i", "u" }
integer! { i8, u8 }
integer! { i16, u16 }
integer! { i32, u32 }
integer! { i64, u64 }
<commit_msg>Cleanup in the fmt::num module<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Integer and floating-point number formatting

// FIXME: #6220 Implement floating point formatting

#![allow(unsigned_negation)]

use fmt;
use iter::IteratorExt;
use num::{Int, cast};
use slice::SliceExt;
use str;

/// A type that represents a specific radix
#[doc(hidden)]
trait GenericRadix {
    /// The number of digits.
    fn base(&self) -> u8;

    /// A radix-specific prefix string.
    fn prefix(&self) -> &'static str { "" }

    /// Converts an integer to corresponding radix digit.
    fn digit(&self, x: u8) -> u8;

    /// Format an integer using the radix using a formatter.
    fn fmt_int<T: Int>(&self, mut x: T, f: &mut fmt::Formatter) -> fmt::Result {
        // The radix can be as low as 2, so we need a buffer of at least 64
        // characters for a base 2 number.
        let zero = Int::zero();
        let is_positive = x >= zero;
        let mut buf = [0u8; 64];
        let mut curr = buf.len();
        let base = cast(self.base()).unwrap();
        if is_positive {
            // Accumulate each digit of the number from the least significant
            // to the most significant figure.
            for byte in buf.iter_mut().rev() {
                let n = x % base;                         // Get the current place value.
                x = x / base;                             // Deaccumulate the number.
                *byte = self.digit(cast(n).unwrap());     // Store the digit in the buffer.
                curr -= 1;
                if x == zero { break };                   // No more digits left to accumulate.
            }
        } else {
            // Do the same as above, but accounting for two's complement.
            for byte in buf.iter_mut().rev() {
                let n = zero - (x % base);                // Get the current place value.
                x = x / base;                             // Deaccumulate the number.
                *byte = self.digit(cast(n).unwrap());     // Store the digit in the buffer.
                curr -= 1;
                if x == zero { break };                   // No more digits left to accumulate.
            }
        }
        let buf = unsafe { str::from_utf8_unchecked(&buf[curr..]) };
        f.pad_integral(is_positive, self.prefix(), buf)
    }
}

/// A binary (base 2) radix
#[derive(Clone, PartialEq)]
struct Binary;

/// An octal (base 8) radix
#[derive(Clone, PartialEq)]
struct Octal;

/// A decimal (base 10) radix
#[derive(Clone, PartialEq)]
struct Decimal;

/// A hexadecimal (base 16) radix, formatted with lower-case characters
#[derive(Clone, PartialEq)]
struct LowerHex;

/// A hexadecimal (base 16) radix, formatted with upper-case characters
#[derive(Clone, PartialEq)]
struct UpperHex;

macro_rules! radix {
    ($T:ident, $base:expr, $prefix:expr, $($x:pat => $conv:expr),+) => {
        impl GenericRadix for $T {
            fn base(&self) -> u8 { $base }
            fn prefix(&self) -> &'static str { $prefix }
            fn digit(&self, x: u8) -> u8 {
                match x {
                    $($x => $conv,)+
                    x => panic!("number not in the range 0..{}: {}", self.base() - 1, x),
                }
            }
        }
    }
}

radix! { Binary,    2, "0b", x @  0 ...  2 => b'0' + x }
radix! { Octal,     8, "0o", x @  0 ...  7 => b'0' + x }
radix! { Decimal,  10, "",   x @  0 ...  9 => b'0' + x }
radix! { LowerHex, 16, "0x", x @  0 ...  9 => b'0' + x,
                             x @ 10 ... 15 => b'a' + (x - 10) }
radix! { UpperHex, 16, "0x", x @  0 ...  9 => b'0' + x,
                             x @ 10 ... 15 => b'A' + (x - 10) }

/// A radix with in the range of `2..36`.
#[derive(Clone, Copy, PartialEq)]
#[unstable(feature = "core",
           reason = "may be renamed or move to a different module")]
pub struct Radix {
    base: u8,
}

impl Radix {
    fn new(base: u8) -> Radix {
        assert!(2 <= base && base <= 36, "the base must be in the range of 2..36: {}", base);
        Radix { base: base }
    }
}

impl GenericRadix for Radix {
    fn base(&self) -> u8 { self.base }
    fn digit(&self, x: u8) -> u8 {
        match x {
            x @  0 ... 9 => b'0' + x,
            x if x < self.base() => b'a' + (x - 10),
            x => panic!("number not in the range 0..{}: {}", self.base() - 1, x),
        }
    }
}

/// A helper type for formatting radixes.
#[unstable(feature = "core",
           reason = "may be renamed or move to a different module")]
#[derive(Copy)]
pub struct RadixFmt<T, R>(T, R);

/// Constructs a radix formatter in the range of `2..36`.
///
/// # Example
///
/// ```
/// use std::fmt::radix;
/// assert_eq!(format!("{}", radix(55, 36)), "1j".to_string());
/// ```
#[unstable(feature = "core",
           reason = "may be renamed or move to a different module")]
pub fn radix<T>(x: T, base: u8) -> RadixFmt<T, Radix> {
    RadixFmt(x, Radix::new(base))
}

macro_rules! radix_fmt {
    ($T:ty as $U:ty, $fmt:ident) => {
        #[stable(feature = "rust1", since = "1.0.0")]
        impl fmt::Debug for RadixFmt<$T, Radix> {
            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                fmt::Display::fmt(self, f)
            }
        }
        #[stable(feature = "rust1", since = "1.0.0")]
        impl fmt::Display for RadixFmt<$T, Radix> {
            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                match *self { RadixFmt(ref x, radix) => radix.$fmt(*x as $U, f) }
            }
        }
    }
}
macro_rules! int_base {
    ($Trait:ident for $T:ident as $U:ident -> $Radix:ident) => {
        #[stable(feature = "rust1", since = "1.0.0")]
        impl fmt::$Trait for $T {
            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                $Radix.fmt_int(*self as $U, f)
            }
        }
    }
}

macro_rules! debug {
    ($T:ident) => {
        #[stable(feature = "rust1", since = "1.0.0")]
        impl fmt::Debug for $T {
            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                fmt::Display::fmt(self, f)
            }
        }
    }
}
macro_rules! integer {
    ($Int:ident, $Uint:ident) => {
        int_base! { Display  for $Int as $Int   -> Decimal }
        int_base! { Binary   for $Int as $Uint  -> Binary }
        int_base! { Octal    for $Int as $Uint  -> Octal }
        int_base! { LowerHex for $Int as $Uint  -> LowerHex }
        int_base! { UpperHex for $Int as $Uint  -> UpperHex }
        radix_fmt! { $Int as $Int, fmt_int }
        debug! { $Int }

        int_base! { Display  for $Uint as $Uint -> Decimal }
        int_base! { Binary   for $Uint as $Uint -> Binary }
        int_base! { Octal    for $Uint as $Uint -> Octal }
        int_base! { LowerHex for $Uint as $Uint -> LowerHex }
        int_base! { UpperHex for $Uint as $Uint -> UpperHex }
        radix_fmt! { $Uint as $Uint, fmt_int }
        debug! { $Uint }
    }
}
integer! { isize, usize }
integer! { i8, u8 }
integer! { i16, u16 }
integer! { i32, u32 }
integer! { i64, u64 }
<|endoftext|>


<commit_before>pub const MD_HEADER_SIGNATURE : u32 = 0x504d444d;

pub type MDRVA = u32;

#[derive(Copy, Clone)] #[packed] #[allow(dead_code)]
pub struct MDRawHeader {
  pub signature            : u32,
  pub version              : u32,
  pub stream_count         : u32,
  pub stream_directory_rva : MDRVA,  /* A |stream_count|-sized array of
                                      * MDRawDirectory structures. */
  pub checksum             : u32,    /* Can be 0.  In fact, that's all that's
                                      * been found in minidump files. */
  pub time_date_stamp      : u32,    /* time_t */
  pub flags                : u64
}
<commit_msg>fix struct repr<commit_after>pub const MD_HEADER_SIGNATURE : u32 = 0x504d444d;

pub type MDRVA = u32;

#[derive(Copy, Clone)]
#[repr(C)]
#[packed]
#[allow(dead_code)]
pub struct MDRawHeader {
  pub signature            : u32,
  pub version              : u32,
  pub stream_count         : u32,
  pub stream_directory_rva : MDRVA,  /* A |stream_count|-sized array of
                                      * MDRawDirectory structures. */
  pub checksum             : u32,    /* Can be 0.  In fact, that's all that's
                                      * been found in minidump files. */
  pub time_date_stamp      : u32,    /* time_t */
  pub flags                : u64
}
<|endoftext|>